1 ;;; its.el --- Input Translation Systam AKA "ITS(uDekirunDa!)"
3 ;; Copyright (C) 1997 Mule Project, Powered by Electrotechnical
5 ;; Project Leader: Satoru Tomura <tomura@etl.go.jp>
7 ;; Author: NIIBE Yutaka <gniibe@mri.co.jp>
8 ;; Maintainer: NIIBE Yutaka <gniibe@mri.co.jp>
9 ;; Keywords: mule, multilingual, input method
11 ;; This file will be part of GNU Emacs (in future).
13 ;; GNU Emacs is free software; you can redistribute it and/or modify
14 ;; it under the terms of the GNU General Public License as published by
15 ;; the Free Software Foundation; either version 2, or (at your option)
18 ;; GNU Emacs is distributed in the hope that it will be useful,
19 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
20 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 ;; GNU General Public License for more details.
23 ;; You should have received a copy of the GNU General Public License
24 ;; along with GNU Emacs; see the file COPYING. If not, write to the
25 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
26 ;; Boston, MA 02111-1307, USA.
32 ;; Data structure in ITS
35 ;; "SYL" stands for something like a syllable.
37 ;; <SYL> ::= ( <output> . ( <keyseq> . <terminal> )) ; Determined: DSYL
38 ;; | <state> ; Intermediate: ISYL
39 ;; | ( <output> . <point> ) ; Verbatim: VSYL
43 ;; ; ( <output> . ( <keyseq> . <key-state-table/terminal> ))
45 ;; <keyseq> ::= "string" of key sequence
46 ;; <output> ::= "string"
48 ;; <point> ::= integer which specifies point
50 ;; <cursor> ::= nil ; Previous SYL is active (input will go that SYL)
51 ;; | t ; input makes new SYL. DEL deletes previous SYL
52 ;; | its-cursor ; DEL breaks previous SYL, input makes new SYL
54 ;; Data structures in ITS
55 ;; (2) State machine which recognizes SYL
57 ;; <state> ::= ( <output> <keyseq> . <key-state-table/terminal> )
59 ;; <key-state-table/terminal> ::= <key-state-table> ; intermediate state
60 ;; | <terminal> ; terminal state
62 ;; <key-state-table> ::= ( <key-state-alist> . <expr-output-back-list> )
63 ;; <key-state-alist> ::= ( <key-state> ... )
64 ;; <key-state> ::= ( <key> . <state> )
65 ;; <key> ::= Positive INTEGER which specifies KEY STROKE
66 ;; | -1 ; means END of key stroke
68 ;; Only applicable for last transition.
69 ;; <expr-output-back-list> ::= ( (<output> . (<keyexpr> . <howmanyback>))... )
70 ;; <keyexpr> ::= something like "[a-z]" which specifies class of key.
71 ;; | NIL; means ANY of key (except END of the key stroke)
74 ;; <keyseq> ::= "string"
79 ;; <howmanyback> ::= integer which specifies how many key strokes we go back
81 ;; <output> ::= "string"
83 ;; Data structure in ITS (3) Map
85 ;; <map> ::= ( <name> . ( <indicator> . <start-state> ) )
86 ;; <start-state> ::= <state>
87 ;; <name> ::= "string"
88 ;; <indicator> ::= "string"
91 (defsubst its-new-state (output keyseq back)
92 (cons output (cons keyseq back)))
94 (defsubst its-new-map (name indicator)
95 (cons name (cons indicator (its-new-state "" "" nil))))
97 (defsubst its-get-indicator (map)
100 (defsubst its-set-indicator (map indicator)
101 (setcar (cdr map) indicator))
103 (defsubst its-get-start-state (map)
106 (defsubst its-reset-start-state (map)
107 (setcdr (cdr map) (its-new-state "" "" nil))
110 (defsubst its-get-kst/t (state)
113 (defsubst its-set-kst (state kst)
114 (setcdr (cdr state) kst))
116 (defsubst its-get-keyseq (state)
119 (defsubst its-set-keyseq (state keyseq)
120 (setcar (cdr state) keyseq))
121 (defun its-get-keyseq-cooked (state)
122 (let ((keyseq (its-get-keyseq state))
123 (back (its-get-kst/t state)))
125 (substring keyseq 0 back)
128 (defsubst its-kst-p (kst/t)
129 (not (or (numberp kst/t) (null kst/t))))
131 (defsubst its-get-output (syl/state)
134 (defsubst its-set-output (state output)
135 (setcar state output))
137 (defsubst its-get-keyseq-syl (syl)
139 (cond ((stringp l) ; DSYL
146 (defsubst its-eob-keyexpr (eob)
148 (defsubst its-eob-back (eob)
151 (defsubst its-make-class+back (class back)
153 (defsubst its-make-otherwise (output class+back)
154 (cons output class+back))
159 (let ((map (make-sparse-keymap))
161 (define-key map "\C-a" 'its-beginning-of-input-buffer)
162 (define-key map "\C-b" 'its-backward-SYL)
163 (define-key map "\C-d" 'its-delete-SYL)
164 (define-key map "\C-e" 'its-end-of-input-buffer)
165 (define-key map "\C-f" 'its-forward-SYL)
166 (define-key map "\C-]" 'its-cancel-input)
167 (define-key map "\C-h" 'its-mode-help-command)
168 (define-key map "\C-k" 'its-kill-line)
169 ;; (define-key map "\C-l" 'its-exit-mode)
170 (define-key map "\C-m" 'its-exit-mode) ; RET
171 (define-key map [return] 'its-exit-mode)
172 (define-key map "\C-t" 'its-transpose-chars)
173 (define-key map [delete] 'its-delete-backward-SYL)
174 (define-key map [right] 'its-forward-SYL)
175 (define-key map [left] 'its-backward-SYL)
176 (define-key map "\C-\\" 'its-exit-mode-off-input-method)
178 (define-key map (vector i) 'its-self-insert-char)
180 (define-key map " " 'its-kick-convert-region)
181 (define-key map "\177" 'its-delete-backward-SYL)
183 (define-key map "\C-p" 'its-previous-map)
184 (define-key map "\C-n" 'its-next-map)
185 ; (define-key map "\M-h" 'its-hiragana) ; hiragana-region for input-buffer
186 ; (define-key map "\M-k" 'its-katakana)
187 ; (define-key map "\M-<" 'its-hankaku)
188 ; (define-key map "\M->" 'its-zenkaku)
189 ; (define-key map "\M-\C-h" 'its-select-hiragana)
190 ; (define-key map "\M-\C-k" 'its-select-katakana)
191 ;;; (define-key map "\M-q" 'its-select-downcase) ;
192 ; (define-key map "\M-Q" 'its-select-upcase)
193 ; (define-key map "\M-z" 'its-select-zenkaku-downcase)
194 ; (define-key map "\M-Z" 'its-select-zenkaku-upcase)
196 "Keymap for ITS mode.")
198 (defvar its-fence-open "|" "*
\e$B%U%'%s%9$N;OE@$r<($9J8;zNs
\e(B (1
\e$BJ8;z
\e(B)")
199 (defvar its-fence-close "|" "*
\e$B%U%'%s%9$N=*E@$r<($9J8;zNs
\e(B (1
\e$BJ8;z
\e(B)")
200 (defvar its-fence-face nil "*
\e$B%U%'%s%9I=<($KMQ$$$k
\e(B face
\e$B$^$?$O
\e(B nil")
202 (defun its-put-cursor (cursor)
205 (add-text-properties p (point) (list 'local-map its-mode-map
207 'intangible 'its-part-2
211 ;; +-- START property
212 ;; | --- CURSOR Property
214 ;; v v v-- END Property
216 ;; ^^^ ^^^ ^^^------ SYL Property
218 ;; intangible intangible
221 (defun its-start (key)
224 (insert its-fence-open)
225 (add-text-properties p (point)
226 (let ((props '(its-start t intangible its-part-1)))
228 (append '(invisible t) props)
231 (setq cursor (its-input nil key))
232 (its-put-cursor cursor)
235 (insert its-fence-close)
236 (add-text-properties p (point)
237 (let ((props '(its-end t intangible its-part-2)))
239 (append '(invisible t) props)
242 (force-mode-line-update)))
244 (defun its-self-insert-char ()
246 (let ((key last-command-char)
247 (cursor (get-text-property (point) 'its-cursor))
250 (setq syl (get-text-property (1- (point)) 'its-syl)))
252 (delete-region (point) (1+ (point)))
253 (setq cursor (its-input syl key))
254 (its-put-cursor cursor)))
256 (defvar its-current-map nil)
257 (make-variable-buffer-local 'its-current-map)
258 (put 'its-current-map 'permanent-local t)
260 (defun its-initial-ISYL ()
261 (its-get-start-state its-current-map))
263 (defun its-make-VSYL (keyseq)
264 (cons keyseq (length keyseq)))
267 (defun its-input (syl key)
269 (setq syl (its-initial-ISYL)))
270 (let ((output (car syl))
273 ;; k/kk/s is "point in keyseq"
274 (its-input-to-vsyl syl key k/kk/s output)
276 (its-state-machine syl key 'its-buffer-ins/del-SYL))))
278 (defun its-input-to-vsyl (syl key point output)
281 (let ((len (length output)))
283 ;; point is at end of VSYL. Don't need to call state machine.
285 (its-buffer-ins/del-SYL
286 (its-make-VSYL (concat output (vector key))) syl)
288 ;; point is at middle of VSYL.
289 (let ((new-keyseq (concat (substring output 0 point)
291 (substring output point))))
292 (its-state-machine-keyseq new-keyseq 'its-buffer-ins/del-SYL))))))
294 (defvar its-barf-on-invalid-keyseq nil
295 "T means don't allow invalid key sequence in input buffer.")
298 ;;; ITS State Machine
302 (defun its-state-machine (state key emit)
303 (let ((next-state (its-get-next-state state key))
306 (let ((kst/t (its-get-kst/t next-state)))
307 (funcall emit next-state state)
308 (if (not (its-kst-p kst/t))
309 ;; Here we arrive to a terminal state.
310 ;; Emit a DSYL, and go ahead.
311 (let ((output (its-get-output next-state))
312 (keyseq (its-get-keyseq next-state))
315 ;; It's negative integer which specifies how many
316 ;; characters we go backwards
317 (its-state-machine-keyseq (substring keyseq back)
320 ;; Still, it's a intermediate state.
323 (setq expr-output-back (its-get-otherwise state key)))
324 (let ((keyseq (concat (its-get-keyseq state) (char-to-string key))))
325 (funcall emit expr-output-back state)
326 (its-state-machine-keyseq
327 (substring keyseq (its-eob-back expr-output-back)) emit))
328 ;; No next state for KEY. It's invalid sequence.
329 (if (< key 0) ; no next state for END of keystroke
331 (if its-barf-on-invalid-keyseq
332 (error its-barf-on-invalid-keyseq)
333 (funcall emit (cons (car state)
334 (list (its-get-keyseq state))) state)
336 (if its-barf-on-invalid-keyseq
337 (error its-barf-on-invalid-keyseq)
338 ;; XXX Should make DSYL (instead of VSYL)?
339 (let ((keyseq (concat (its-get-keyseq state) (vector key))))
340 (funcall emit (its-make-VSYL keyseq) state)
343 (defvar its-latest-SYL nil
344 "The latest SYL inserted.")
345 (defsubst its-update-latest-SYL (syl)
346 (setq its-latest-SYL syl))
349 (defun its-state-machine-keyseq (keyseq emit &optional eol)
351 (len (length keyseq))
352 (its-barf-on-invalid-keyseq nil) ; temporally disable DING
353 (syl (its-initial-ISYL))
356 (let ((key (aref keyseq i)))
358 (if (numberp (cdr syl)) ; VSYL
361 (its-make-VSYL (concat (car syl) (vector key)))
364 (its-state-machine syl key emit)))
367 (setq syl (its-initial-ISYL))
368 (setq syl its-latest-SYL))))
370 (its-state-machine syl -1 emit)
373 (defun its-buffer-ins/del-SYL (newsyl oldsyl)
374 (its-buffer-delete-SYL oldsyl)
375 (its-update-latest-SYL newsyl)
377 (insert (its-get-output newsyl))
378 (add-text-properties p (point)
379 (list 'its-syl newsyl
380 'intangible 'its-part-1))
382 (put-text-property p (point) 'face its-fence-face))))
384 (defun its-buffer-delete-SYL (syl)
385 (let ((len (length (its-get-output syl))))
386 (delete-region (- (point) len) (point))))
388 (defun its-get-next-state (state key)
389 (let ((kst/t (its-get-kst/t state)))
390 (cdr (assq key (car kst/t)))))
393 (defun its-otherwise-match (expr key)
394 (or (null expr) ; <expr>::= NIL means "ANY"
395 (let ((case-fold-search nil))
396 (string-match expr (char-to-string key)))))
398 (defun its-get-otherwise (state key)
399 (let* ((kst/t (its-get-kst/t state))
403 (setq expr-output-back (car ebl))
404 (let ((expr (its-eob-keyexpr expr-output-back)))
405 (if (its-otherwise-match expr key)
407 (setq ebl (cdr ebl)))))
415 (defvar its-map-alist nil)
417 (defun its-get-map (name)
418 (assoc name its-map-alist))
420 (defun its-register-map (map)
421 (let* ((name (car map))
422 (place (assoc name its-map-alist)))
424 (setcdr place (cdr map))
425 (setq its-map-alist (cons map its-map-alist)))
428 (defun its-define-state-machine (name indicator &optional continue)
429 "NAME
\e$B$G;XDj$5$l$?
\e(B State Machine
\e$B$NDj5A$r3+;O$9$k!#
\e(B
430 INDICATOR
\e$B$O
\e(B mode line
\e$B$KI=<($9$k
\e(B indicator
\e$B$r;XDj$9$k!#
\e(B
431 CONTINUE
\e$B$,
\e(B nil
\e$B$N;~$K$O
\e(B State Machine
\e$B$NDj5A$r6u$K$9$k!#
\e(Bits-defrule
433 (setq its-current-map
434 (if (null (its-get-map name))
435 (its-register-map (its-new-map name indicator))
436 (let ((map (its-get-map name)))
437 (its-set-indicator map indicator)
440 (its-reset-start-state map))))))
442 (defmacro define-its-state-machine (map name indicator doc &rest exprs)
443 `(let ((its-current-map (its-new-map ,name ,indicator)))
445 (defconst ,map its-current-map ,doc)))
447 ;;(defmacro define-its-state-machine (map name indicator doc &rest exprs)
448 ;; (let ((its-current-map (its-new-map name indicator)))
449 ;; (eval (cons 'progn exprs))
450 ;; `(defconst ,map ',its-current-map ,doc)))
452 (defmacro define-its-state-machine-append (map &rest exprs)
454 `(let ((its-current-map ,map)))
456 (list `(setq ,map its-current-map))))
459 ;; Construct State Machine
461 (defun its-defrule (input output &optional back enable-overwrite)
462 "
\e$BF~NO
\e(B INPUT
\e$B$rG'<1$7
\e(B, OUTPUT
\e$B$r=PNO$9$k$h$&$K%9%F!<%H%^%7%s$r9=@.$9$k!#
\e(B
463 BACK
\e$B$,
\e(B(
\e$BIi$N
\e(B)
\e$B@0?t$N;~$O
\e(B, OUTPUT
\e$B$r=PNO$7$?8e
\e(B, BACK
\e$B$NJ,
\e(B key stroke
\e$B$r
\e(B
464 \e$BLa$C$FF0$/$b$N$H$9$k!#JQ495,B'$O$b$C$H$b:G6a$K
\e(B its-define-state-machine
465 \e$B$5$l$?JQ49I=$KEPO?$5$l$k!#
\e(B
467 (let ((state (its-goto-state (substring input 0 -1) nil t))
468 (key (aref input (1- (length input)))))
469 (if (and (its-get-next-state state key) (not enable-overwrite))
470 (error "Duplicated definition (%s)" input)
471 (its-make-next-state state key input output back))))
473 (defun its-goto-state (input &optional initial-state build-if-none)
474 (let ((len (length input))
476 (state (or initial-state (its-get-start-state its-current-map))))
479 (or (its-get-next-state state (aref input i))
481 (let ((keyseq (substring input 0 (1+ i))))
482 (its-make-next-state state (aref input i) keyseq keyseq))
483 (error "No such state (%s)" input)))
487 (defun its-defoutput (input display)
488 (let ((state (its-goto-state input)))
489 (its-set-output state display)))
491 (defun its-define-otherwise (state otherwise)
492 (let ((kst (its-get-kst/t state)))
494 (setcdr kst (cons otherwise (cdr kst)))
495 (its-set-kst state (cons nil (cons otherwise nil))))))
497 (defconst its-otherwise-back-one
498 (its-make-class+back nil -1))
500 (defun its-defrule-otherwise (state output &optional class back)
503 (setq class+back its-otherwise-back-one)
504 (setq class+back (its-make-class+back class back)))
505 (its-define-otherwise state
506 (its-make-otherwise output class+back))))
508 (defun its-defrule* (input output)
509 (let ((state (its-defrule input output)))
510 (its-defrule-otherwise state output)))
512 (defun its-make-next-state (state key keyseq output &optional back)
513 (let ((next-state (its-new-state output keyseq back))
514 (kst (its-get-kst/t state)))
516 (setcar kst (cons (cons key next-state) (car kst)))
517 (its-set-kst state (list (list (cons key next-state)))))
521 (defun its-beginning-of-input-buffer ()
524 (if (not (get-text-property (1- (point)) 'its-start))
525 (let ((begpos (previous-single-property-change (point) 'its-start)))
526 ;; Make SYLs have property of "part 2"
527 (put-text-property begpos (point) 'intangible 'its-part-2)
529 (its-put-cursor t))))
531 (defun its-end-of-input-buffer ()
534 (if (not (get-text-property (point) 'its-end))
535 (let ((endpos (next-single-property-change (point) 'its-end)))
536 ;; Make SYLs have property of "part 1"
537 (put-text-property (point) endpos 'intangible 'its-part-1)
539 (its-put-cursor t))))
541 ;; TODO: move in VSYL
542 (defun its-backward-SYL (n)
545 (let ((syl (get-text-property (1- (point)) 'its-syl))
548 (while (and syl (> n 0))
549 (setq p (- p (length (its-get-output syl))))
550 (setq syl (get-text-property (1- p) 'its-syl))
552 ;; Make SYLs have property of "part 2"
553 (put-text-property p old-point 'intangible 'its-part-2)
557 (signal 'beginning-of-buffer nil))))
559 ;; TODO: move in VSYL
560 (defun its-forward-SYL (n)
563 (let ((syl (get-text-property (point) 'its-syl))
566 (while (and syl (> n 0))
567 (setq p (+ p (length (its-get-output syl))))
568 (setq syl (get-text-property p 'its-syl))
570 ;; Make SYLs have property of "part 1"
571 (put-text-property p old-point'intangible 'its-part-1)
575 (signal 'end-of-buffer nil))))
577 ;; TODO: handle VSYL. KILLFLAG
578 (defun its-delete-SYL (n killflag)
581 (let ((syl (get-text-property (point) 'its-syl))
583 (while (and syl (> n 0))
584 (setq p (+ p (length (its-get-output syl))))
585 (setq syl (get-text-property p 'its-syl))
590 (signal 'args-out-of-range (list p n)))
591 (delete-region (point) p)
593 (let ((s (get-text-property (1- (point)) 'its-start))
594 (e (get-text-property (point) 'its-end)))
596 (its-exit-mode-internal)
597 (its-put-cursor t))))))
600 (defun its-delete-backward-SYL (n killflag)
602 (let ((syl (get-text-property (1- (point)) 'its-syl))
603 (cursor (get-text-property (point) 'its-cursor)))
605 (signal 'beginning-of-buffer nil)
607 (its-delete-backward-SYL-internal n killflag)
608 (its-delete-backward-within-SYL syl n killflag)))))
611 (defun its-delete-backward-SYL-internal (n killflag)
612 (let ((syl (get-text-property (1- (point)) 'its-syl))
614 (while (and syl (> n 0))
615 (setq p (- p (length (its-get-output syl))))
616 (setq syl (get-text-property (1- p) 'its-syl))
619 (signal 'args-out-of-range (list p n))
620 (delete-region p (1+ (point))) ; also delete cursor
622 (let ((s (get-text-property (1- (point)) 'its-start))
623 (e (get-text-property (point) 'its-end)))
625 (its-exit-mode-internal)
626 (its-put-cursor t))))))
628 (defvar its-delete-by-keystroke nil)
631 (defun its-delete-backward-within-SYL (syl n killflag)
632 (let* ((keyseq (its-get-keyseq-syl syl))
633 (len (length keyseq))
636 (signal 'args-out-of-range (list p n)))
638 (delete-region p (1+ p))
639 (its-buffer-delete-SYL syl)
642 (let ((s (get-text-property (1- (point)) 'its-start))
643 (e (get-text-property (point) 'its-end)))
645 (its-exit-mode-internal)
646 (its-put-cursor (not its-delete-by-keystroke))))
647 (setq keyseq (substring keyseq 0 (- len n)))
648 (let ((r (its-state-machine-keyseq keyseq 'its-buffer-ins/del-SYL)))
649 (its-put-cursor r)))))
652 (defun its-transpose-chars (n)
654 (let ((syl (get-text-property (1- (point)) 'its-syl))
655 (cursor (get-text-property (point) 'its-cursor)))
657 (signal 'beginning-of-buffer nil)
659 (its-delete-backward-SYL-internal n nil)
660 (its-delete-backward-within-SYL syl 2 nil)))))
663 (defun its-input-end ()
664 (let ((cursor (get-text-property (point) 'its-cursor)))
667 (its-input (get-text-property (1- (point)) 'its-syl) -1))
668 (delete-region (point) (1+ (point)))))
670 (defun its-exit-mode ()
674 (its-exit-mode-internal))
676 (defun its-exit-mode-off-input-method ()
680 (its-exit-mode-internal)
681 (inactivate-input-method))
683 ;; TODO: handle overwrite-mode, insertion-hook, fill...
684 (defun its-exit-mode-internal (&optional proceed-to-conversion)
687 (if (get-text-property (1- (point)) 'its-start)
688 (setq start (1- (point)))
689 (setq start (1- (previous-single-property-change (point) 'its-start))))
690 (delete-region start (1+ start))
691 ;; Delete close fence
692 (if (get-text-property (point) 'its-end)
694 (setq end (next-single-property-change (point) 'its-end)))
695 (delete-region end (1+ end))
696 ;; Remove all properties added by ITS
697 (remove-text-properties start end '(its-syl nil
700 (if proceed-to-conversion
701 (egg-convert-region start end)
703 (run-hooks 'input-method-after-insert-chunk-hook))))
705 (defun its-kick-convert-region ()
708 (its-exit-mode-internal t))
710 (defvar its-translation-result nil "")
712 (defun its-ins/del-SYL-batch (newsyl oldsyl)
713 (its-update-latest-SYL newsyl)
716 (not (its-kst-p (its-get-kst/t newsyl))))
718 (setq its-translation-result
719 (cons (its-get-output newsyl) its-translation-result))))
721 (defun its-translate-region (start end &optional map)
723 (setq its-translation-result nil)
726 (syl (its-initial-ISYL))
727 ;; temporally enable DING
728 (its-barf-on-invalid-keyseq "Invalid Romaji Sequence")
730 (while (< (point) end)
731 (let ((key (following-char)))
732 (setq cursor (its-state-machine syl key 'its-ins/del-SYL-batch))
735 (setq syl (its-initial-ISYL))
736 (setq syl its-latest-SYL))))
737 (if (eq syl its-latest-SYL)
738 (its-state-machine syl -1 'its-ins/del-SYL-batch))
739 (delete-region start end)
740 (apply 'insert (reverse its-translation-result))))
742 (defvar its-select-map-menu '(menu "Map:" nil))
744 (defun its-select-map-from-menu ()
746 (setcar (nthcdr 2 its-select-map-menu) its-map-alist)
747 (setq its-current-map (menudiag-select its-select-map-menu))
748 (force-mode-line-update))
750 (defun its-select-hiragana ()
752 (its-select-map "roma-kana"))
754 (defun its-select-katakana ()
756 (its-select-map "roma-kata"))
758 (defun its-select-downcase ()
760 (its-select-map "downcase"))
762 (defun its-select-upcase ()
764 (its-select-map "upcase"))
766 (defun its-select-zenkaku-downcase ()
768 (its-select-map "zenkaku-downcase"))
770 (defun its-select-zenkaku-upcase ()
772 (its-select-map "zenkaku-upcase"))
774 (defun its-select-map (name)
775 (interactive (list (completing-read "ITS map: " its-map-alist)))
776 (if (its-get-map name)
778 (setq its-current-map (its-get-map name))
779 (force-mode-line-update))
782 ;; Escape character to Zenkaku inputs
783 (defconst its-zenkaku-escape "Z")
785 ;; Escape character to Hankaku inputs
786 (defconst its-hankaku-escape "~")
789 ;;; its.el ends here.