Tizen 2.1 base
[platform/core/uifw/anthy.git] / src-util / anthy.el
1 ;;; anthy.el -- Anthy
2
3 ;; Copyright (C) 2001 - 2007 KMC(Kyoto University Micro Computer Club)
4
5 ;; Author: Yusuke Tabata<yusuke@kmc.gr.jp>
6 ;;         Tomoharu Ugawa
7 ;;         Norio Suzuki <suzuki@sanpobu.net>
8 ;; Keywords: japanese
9
10 ;; This file is part of Anthy
11
12 ;;; Commentary:
13 ;;
14 ;; \e$B$+$J4A;zJQ49%(%s%8%s\e(B Anthy\e$B$r\e(B emacs\e$B$+$i;H$&$?$a$N%W%m%0%i%`\e(B
15 ;; Anthy\e$B%i%$%V%i%j$r;H$&$?$a$N%3%^%s%I\e(Banthy-agent\e$B$r5/F0$7$F!"\e(B
16 ;; anthy-agent\e$B$H%Q%$%W$GDL?.$r$9$k$3$H$K$h$C$FJQ49$NF0:n$r9T$&\e(B
17 ;;
18 ;;
19 ;; Funded by IPA\e$BL$F'%=%U%H%&%'%"AOB$;v6H\e(B 2001 10/10
20 ;;
21 ;; \e$B3+H/$O\e(Bemacs21.2\e$B>e$G9T$C$F$$$F\e(Bminor-mode
22 ;; \e$B$b$7$/$O\e(Bleim\e$B$H$7$F$b;HMQ$G$-$k\e(B
23 ;; (set-input-method 'japanese-anthy)
24 ;;
25 ;; emacs19(mule),20,21,xemacs\e$B$GF0:n$9$k\e(B
26 ;;
27 ;;
28 ;; 2003-08-24 XEmacs \e$B$N8uJdA*Br%b!<%I%P%0$KBP1~\e(B(suzuki)
29 ;;
30 ;; 2001-11-16 EUC-JP -> ISO-2022-JP
31 ;;
32 ;; TODO
33 ;;  \e$B8uJdA*Br%b!<%I$G8uJd$r$$$C$-$K<!$N%Z!<%8$K$$$+$J$$$h$&$K$9$k\e(B(2ch\e$B%9%l\e(B78)
34 ;;  minibufffer\e$B$N07$$\e(B
35 ;;  isearch\e$BBP1~\e(B
36 ;;
37 ;; \e$BMQ8l\e(B
38 ;;  commit \e$BJ8;zNs$r3NDj$9$k$3$H\e(B
39 ;;  preedit(\e$B%W%j%(%G%#%C%H\e(B) \e$B3NDjA0$NJ8;zNs%"%s%@!<%i%$%s$d6/D4$NB0@-$b4^$`\e(B
40 ;;  segment(\e$BJ8@a\e(B) \e$BJ8K!E*$JJ8@a$G$O$J$/!$F1$8B0@-$NJ8;zNs$N$+$?$^$j\e(B
41 ;;
42
43 ;;; Code:
44 ;(setq debug-on-error t)
45
46 (defvar anthy-default-enable-enum-candidate-p t
47   "\e$B$3$l$r@_Dj$9$k$H<!8uJd$r?t2s2!$7$?:]$K8uJd$N0lMw$+$iA*Br$9$k%b!<%I$K$J$j$^$9!%\e(B")
48
49 (defvar anthy-personality ""
50   "\e$B%Q!<%=%J%j%F%#\e(B")
51
52 (defvar anthy-preedit-begin-mark "|"
53   "\e$BJQ49;~$N@hF,$KIU$/J8;zNs\e(B")
54
55 (defvar anthy-preedit-delim-mark "|"
56  "\e$BJQ49;~$NJ8@a$N6h@Z$j$K;H$o$l$kJ8;zNs\e(B")
57
58 (defvar anthy-accept-timeout 50)
59 (if (string-match "^22\." emacs-version)
60     (setq anthy-accept-timeout 1))
61
62 (defconst anthy-working-buffer " *anthy*")
63 (defvar anthy-agent-process nil
64   "anthy-agent\e$B$N%W%m%;%9\e(B")
65 (defvar anthy-use-hankaku-kana t)
66 ;;
67 (defvar anthy-agent-command-list '("anthy-agent")
68   "anthy-agent\e$B$N\e(BPATH\e$BL>\e(B")
69
70 ;; face
71 (defvar anthy-highlight-face nil)
72 (defvar anthy-underline-face nil)
73 (copy-face 'highlight 'anthy-highlight-face)
74 (set-face-underline-p 'anthy-highlight-face t)
75 (copy-face 'underline 'anthy-underline-face)
76
77 ;;
78 (defvar anthy-xemacs
79   (if (featurep 'xemacs)
80       t nil))
81 (if anthy-xemacs
82     (require 'overlay))
83 ;;
84 (defvar anthy-mode-map nil
85   "Anthy\e$B$N\e(BASCII\e$B%b!<%I$N%-!<%^%C%W\e(B")
86 (or anthy-mode-map
87     (let ((map (make-keymap))
88           (i 32))
89       (define-key map (char-to-string 10) 'anthy-insert)
90       (define-key map (char-to-string 17) 'anthy-insert)
91       (while (< i 127)
92         (define-key map (char-to-string i) 'anthy-insert)
93         (setq i (+ 1 i)))
94       (setq anthy-mode-map map)))
95 ;;
96 (defvar anthy-preedit-keymap nil
97   "Anthy\e$B$N\e(Bpreedit\e$B$N%-!<%^%C%W\e(B")
98 (or anthy-preedit-keymap
99     (let ((map (make-keymap))
100           (i 0))
101       ;; \e$BDL>o$NJ8;z$KBP$7$F\e(B
102       (while (< i 128)
103         (define-key map (char-to-string i) 'anthy-insert)
104         (setq i (+ 1 i)))
105       ;; \e$BJ8@a$N?-=L\e(B
106       (define-key map [(shift left)] 'anthy-insert)
107       (define-key map [(shift right)] 'anthy-insert)
108       ;; \e$BJ8@a$N0\F0\e(B
109       (define-key map [left] 'anthy-insert)
110       (define-key map [right] 'anthy-insert)
111       (define-key map [backspace] 'anthy-insert)
112       (setq anthy-preedit-keymap map)))
113
114 ;; anthy-agent\e$B$KAw$k:]$K%-!<$r%(%s%3!<%I$9$k$?$a$N%F!<%V%k\e(B
115 (defvar anthy-keyencode-alist
116   '((1 . "(ctrl A)") ;; \C-a
117     (2 . "(left)") ;; \C-b
118     (4 . "(ctrl D)") ;; \C-d
119     (5 . "(ctrl E)") ;; \C-e
120     (6 . "(right)") ;; \C-f
121     (7 . "(esc)") ;; \C-g
122     (8 . "(ctrl H)") ;; \C-h
123     (9 . "(shift left)") ;; \C-i
124     (10 . "(ctrl J)")
125     (11 . "(ctrl K)")
126     (13 . "(enter)") ;; \C-m
127     (14 . "(space)") ;; \C-n
128     (15 . "(shift right)") ;; \C-o
129     (16 . "(up)") ;; \C-p
130     (32 . "(space)")
131     (40 . "(opar)") ;; '('
132     (41 . "(cpar)") ;; ')'
133     (127 . "(ctrl H)")
134     ;; emacs map
135     (S-right . "(shift right)")
136     (S-left . "(shift left)")
137     (right . "(right)")
138     (left . "(left)")
139     (up . "(up)")
140     (backspace . "(ctrl H)")
141     ;; xemacs
142     ((shift right) . "(shift right)")
143     ((shift left) . "(shift left)")
144     ((right) . "(right)")
145     ((left) . "(left)")
146     ((up) . "(up)"))
147   "\e$B%-!<$N%$%Y%s%H$r\e(Banthy-agent\e$B$KAw$k$?$a$NBP1~I=\e(B")
148
149 ;; \e$B%b!<%I%i%$%s$NJ8;zNs\e(B
150 (defvar anthy-mode-line-string-alist
151   '(("hiragana" . " \e$B$"\e(B")
152     ("katakana" . " \e$B%"\e(B")
153     ("alphabet" . " A")
154     ("walphabet" . " \e$B#A\e(B")
155     ("hankaku_kana" . " \e(I1\e(B")
156     )
157   "\e$B%b!<%IL>$H%b!<%I%i%$%s$NJ8;zNs$NBP1~I=\e(B")
158
159 ;; \e$B:G8e$K3d$jEv$F$?\e(Bcontext id
160 (defvar anthy-last-context-id 1)
161
162 ;; From skk-macs.el From viper-util.el.  Welcome!
163 (defmacro anthy-deflocalvar (var default-value &optional documentation)
164   (` (progn
165        (defvar (, var) (, default-value)
166          (, (format "%s\n\(buffer local\)" documentation)))
167        (make-variable-buffer-local '(, var))
168        )))
169
170 ;; buffer local variables
171 (anthy-deflocalvar anthy-context-id nil "\e$B%3%s%F%-%9%H$N\e(Bid")
172\e$B%b!<%I$N4IM}\e(B
173 (anthy-deflocalvar anthy-minor-mode nil)
174 (anthy-deflocalvar anthy-mode nil)
175 (anthy-deflocalvar anthy-leim-active-p nil)
176 (anthy-deflocalvar anthy-saved-mode nil)
177\e$B%W%j%(%G%#%C%H\e(B
178 (anthy-deflocalvar anthy-preedit "")
179 (anthy-deflocalvar anthy-preedit-start 0)
180 (anthy-deflocalvar anthy-preedit-overlays '())
181 (anthy-deflocalvar anthy-mode-line-string " A")
182\e$B8uJdNs5s\e(B
183 (anthy-deflocalvar anthy-enum-candidate-p nil)
184 (anthy-deflocalvar anthy-enum-rcandidate-p nil)
185 (anthy-deflocalvar anthy-candidate-minibuffer "")
186 (anthy-deflocalvar anthy-enum-candidate-list '()
187                    "\e$B:#Ns5s$7$F$$$k8uJd$N>pJs\e(B((\e$B2hLLFb$N\e(Bindex \e$B8uJd$N\e(Bindex . \e$B8uJdJ8;zNs\e(B) ..)")
188 (anthy-deflocalvar anthy-enable-enum-candidate-p 
189   (cons anthy-default-enable-enum-candidate-p nil)
190   "\e$B$3$N%P%C%U%!$G8uJd$NNs5s$r9T$&$+$I$&$+\e(B")
191 (anthy-deflocalvar anthy-current-candidate-index 0)
192 (anthy-deflocalvar anthy-current-candidate-layout-begin-index 0)
193 (anthy-deflocalvar anthy-current-candidate-layout-end-index 0)
194\e$BF~NO>uBV\e(B
195 (anthy-deflocalvar anthy-current-rkmap "hiragana")
196 ; undo
197 (anthy-deflocalvar anthy-buffer-undo-list-saved nil)
198
199 ;;
200 (defvar anthy-wide-space "\e$B!!\e(B" "\e$B%9%Z!<%9$r2!$7$?;~$K=P$FMh$kJ8;z\e(B")
201
202 ;;; setup minor-mode
203 ;; minor-mode-alist
204 (if (not
205      (assq 'anthy-minor-mode minor-mode-alist))
206     (setq minor-mode-alist
207        (cons
208         (cons 'anthy-minor-mode '(anthy-mode-line-string))
209         minor-mode-alist)))
210 ;; minor-mode-map-alist
211 (if (not
212      (assq 'anthy-minor-mode minor-mode-map-alist))
213     (setq minor-mode-map-alist
214        (cons
215         (cons 'anthy-minor-mode anthy-mode-map)
216         minor-mode-map-alist)))
217
218 ;;
219 (defun anthy-process-sentinel (proc stat)
220   "\e$B%W%m%;%9$N>uBV$,JQ2=$7$?$i;2>H$r>C$7$F!$<!$K:F5/F0$G$-$k$h$&$K$9$k\e(B"
221   (message "%s" stat)
222   (anthy-mode-off)
223   (setq anthy-agent-process nil))
224
225 ;;; status
226 (defun anthy-update-mode-line ()
227   "\e$B%b!<%I%i%$%s$r99?7$9$k\e(B"
228   (let ((a (assoc anthy-current-rkmap anthy-mode-line-string-alist)))
229     (if a
230         (progn
231          (setq anthy-mode-line-string (cdr a))
232          (setq current-input-method-title
233                (concat "<Anthy:" (cdr a) ">")))))
234   (force-mode-line-update))
235
236 ;;; preedit control
237 (defun anthy-erase-preedit ()
238   "\e$B%W%j%(%G%#%C%H$rA4It>C$9\e(B"
239   (if (> (string-width anthy-preedit) 0)
240       (let* ((str anthy-preedit)
241              (len (length str))
242              (start anthy-preedit-start))
243         (delete-region start (+ start len))
244         (goto-char start)))
245   (setq anthy-preedit "")
246   (mapcar 'delete-overlay anthy-preedit-overlays)
247   (setq anthy-preedit-overlays nil))
248
249 (defun anthy-select-face-by-attr (attr)
250   "\e$BJ8@a$NB0@-$K1~$8$?\e(Bface\e$B$rJV$9\e(B"
251   (if (memq 'RV attr)
252       'anthy-highlight-face
253     'anthy-underline-face))
254
255 (defun anthy-enable-preedit-keymap ()
256   "\e$B%-!<%^%C%W$r%W%j%(%G%#%C%H$NB8:_$9$k;~$N$b$N$K@ZBX$($k\e(B"
257 ;  (setq anthy-saved-buffer-undo-list buffer-undo-list)
258 ;  (buffer-disable-undo)
259   (setcdr
260    (assq 'anthy-minor-mode minor-mode-map-alist)
261    anthy-preedit-keymap))
262
263 (defun anthy-disable-preedit-keymap ()
264   "\e$B%-!<%^%C%W$r%W%j%(%G%#%C%H$NB8:_$7$J$$;~$N$b$N$K@ZBX$($k\e(B"
265 ;  (buffer-enable-undo)
266 ;  (setq buffer-undo-list anthy-saved-buffer-undo-list)
267   (setcdr
268    (assq 'anthy-minor-mode minor-mode-map-alist)
269    anthy-mode-map)
270   (anthy-update-mode-line))
271
272 (defun anthy-insert-preedit-segment (str attr)
273   "\e$B%W%j%(%G%#%C%H$r0lJ8@aJ8DI2C$9$k\e(B"
274   (let ((start (point))
275         (end) (ol))
276     (cond ((or (memq 'ENUM attr) (memq 'ENUMR attr))
277            (setq str (concat "<" str ">")))
278           ((memq 'RV attr) 
279            (setq str (concat "[" str "]"))))
280     ; \e$B%W%j%(%G%#%C%H$NJ8;zNs$rDI2C$9$k\e(B
281     (insert-and-inherit str)
282     (setq end (point))
283     ;; overlay\e$B$K$h$C$FB0@-$r@_Dj$9$k\e(B
284     (setq ol (make-overlay start end))
285     (overlay-put ol 'face (anthy-select-face-by-attr attr))
286     (setq anthy-preedit-overlays
287           (cons ol anthy-preedit-overlays))
288     str))
289
290 (defvar anthy-select-candidate-keybind
291   '((0 . "a")
292     (1 . "s")
293     (2 . "d")
294     (3 . "f")
295     (4 . "g")
296     (5 . "h")
297     (6 . "j")
298     (7 . "k")
299     (8 . "l")
300     (9 . ";")))
301
302 ;;;
303 ;;; auto fill controll
304 ;;; from egg.el
305
306 (defun anthy-do-auto-fill ()
307   (if (and auto-fill-function (> (current-column) fill-column))
308       (let ((ocolumn (current-column)))
309         (funcall auto-fill-function)
310         (while (and (< fill-column (current-column))
311                     (< (current-column) ocolumn))
312           (setq ocolumn (current-column))
313           (funcall auto-fill-function)))))
314
315 ;;
316 (defun anthy-check-context-id ()
317   "\e$B%P%C%U%!$K%3%s%F%-%9%H\e(Bid\e$B$,3d$j?6$i$l$F$$$k$+$r%A%'%C%/$9$k\e(B"
318   (if (null anthy-context-id)
319       (progn
320         (setq anthy-context-id anthy-last-context-id)
321         (setq anthy-last-context-id
322               (+ anthy-last-context-id 1)))))
323
324 (defun anthy-get-candidate (idx)
325   "agent\e$B$+$i8uJd$r0l$D<hF@$9$k\e(B"
326   (anthy-send-recv-command 
327    (concat " GET_CANDIDATE "
328            (number-to-string idx) "\n")))
329
330 ;; \e$B8uJd%j%9%H$+$i%_%K%P%C%U%!$KI=<($9$kJ8;zNs$r9=@.$9$k\e(B
331 (defun anthy-make-candidate-minibuffer-string ()
332   (let ((cand-list anthy-enum-candidate-list)
333         (cur-elm)
334         (str))
335     (while cand-list
336       (setq cur-elm (car cand-list))
337       (let ((cand-str (cdr (cdr cur-elm)))
338             (cand-idx (car (cdr cur-elm)))
339             (sel-idx (car cur-elm)))
340         (setq str (format (if (= anthy-current-candidate-index cand-idx)
341                               "%s:[%s] "
342                               "%s: %s  ")
343                           (cdr (assoc sel-idx anthy-select-candidate-keybind))
344                           cand-str)))
345       (setq anthy-candidate-minibuffer
346             (concat str
347                     anthy-candidate-minibuffer))
348       (setq cand-list (cdr cand-list)))))
349
350 ;; \e$BI=<($9$k8uJd$N%j%9%H$K2hLLFb$G$N%$%s%G%C%/%9$rIU$1$k\e(B
351 (defun anthy-add-candidate-index (lst)
352   (let ((i 0)
353         (res nil))
354     (while lst
355       (setq res
356             (cons
357              (cons i (car lst))
358              res))
359       (setq i (1+ i))
360       (setq lst (cdr lst)))
361     res))
362
363
364 ;; \e$BJ8;z$NI}$r7W;;$7$F!"I=<($9$k8uJd$N%j%9%H$r:n$k\e(B
365 (defun anthy-make-candidate-index-list (base nr l2r)
366   (let ((width (frame-width))
367         (errorp nil)
368         (i 0)
369         (repl)
370         (cand-idx)
371         (lst))
372     ;; loop
373     (while (and
374             (if l2r
375                 (< (+ base i) nr)
376               (<= 0 (- base i)))
377             (> width 0)
378             (< i (length anthy-select-candidate-keybind))
379             (not errorp))
380       (if l2r
381           (setq cand-idx (+ base i))
382         (setq cand-idx (- base i)))
383       (setq repl (anthy-get-candidate cand-idx))
384       (if (listp repl)
385           ;; append candidate
386           (let ((cand-str (car repl)))
387             (setq width (- width (string-width cand-str) 5))
388             (if (or (> width 0) (null lst))
389                 (setq lst
390                       (cons
391                        (cons cand-idx cand-str)
392                        lst))))
393         ;; erroneous candidate
394         (setq errorp t))
395       (setq i (1+ i)))
396     (if errorp
397         nil
398       lst)))
399   
400
401 ;; \e$BI=<($9$k8uJd$N%j%9%H$r:n$k\e(B
402 (defun anthy-calc-candidate-layout (base nr l2r)
403   (let
404       ((lst (anthy-make-candidate-index-list base nr l2r)))
405     ;;\e$B%+%l%s%H$N8uJdHV9f$r@_Dj$9$k\e(B
406     (if l2r
407         (progn
408           ;; \e$B:8$+$i1&$N>l9g\e(B
409           ;; index\e$B$r0lHV1&$N8uJd$K@_Dj$9$k\e(B
410           (anthy-get-candidate (car (car lst)))
411           (setq lst (reverse lst))
412           (setq anthy-current-candidate-index (car (car lst))))
413       (progn
414         ;; \e$B1&$+$i:8$N>l9g\e(B
415         (setq anthy-current-candidate-index (car (car (reverse lst))))))
416     ;;\e$B7k2L$r%;%C%H\e(B
417     (setq anthy-enum-candidate-list
418           (if lst
419               (anthy-add-candidate-index lst)
420             nil))))
421
422 ;;
423 (defun anthy-layout-candidate (idx nr)
424   "\e$B8uJd%j%9%H$r\e(Bminibuffer\e$B$X%l%$%"%&%H$9$k\e(B"
425   (setq anthy-candidate-minibuffer "")
426   (setq anthy-enum-candidate-list '())
427   ;; \e$B:8\e(B->\e$B1&\e(B or \e$B1&\e(B->\e$B:8$K%l%$%"%&%H$9$k\e(B
428   (if anthy-enum-candidate-p
429       (anthy-calc-candidate-layout idx nr 't)
430     (anthy-calc-candidate-layout idx nr nil))
431   (anthy-make-candidate-minibuffer-string)
432   ;; \e$B7k2L$rI=<($9$k\e(B
433   (if anthy-enum-candidate-list
434       (progn
435         (message "%s" anthy-candidate-minibuffer)
436         (setq anthy-current-candidate-layout-begin-index
437               (car (cdr (car (reverse anthy-enum-candidate-list)))))
438         (setq anthy-current-candidate-layout-end-index
439               (car (cdr (car anthy-enum-candidate-list)))))
440
441     nil))
442
443 (defun anthy-update-preedit (stat ps)
444   "\e$B%W%j%(%G%#%C%H$r99?7$9$k\e(B"
445   (let ((cursor-pos nil)
446         (num-candidate 0)
447         (idx-candidate 0)
448         (enum-candidate
449          (or anthy-enum-candidate-p
450              anthy-enum-rcandidate-p)))
451     ;; erase old preedit
452     (anthy-erase-preedit)
453
454     ;; \e$BF~NO%-%c%s%;%k;~$K\e(Bundo\e$B%j%9%H$r7R$2$k\e(B
455     (if (and (= (length ps) 0)  anthy-buffer-undo-list-saved )
456         (progn
457 ;         (message "enable")
458           (buffer-enable-undo)
459           (setq buffer-undo-list anthy-buffer-undo-list)
460           (setq anthy-buffer-undo-list-saved nil)
461           ))
462
463     (anthy-disable-preedit-keymap)
464     ;; insert new preedit
465     (setq anthy-preedit-start (point))
466     (setq anthy-enum-candidate-p nil)
467     (setq anthy-enum-rcandidate-p nil)
468     (if (member stat '(2 3 4))
469         (progn
470           (setq anthy-preedit
471                 (concat anthy-preedit anthy-preedit-begin-mark))
472           (anthy-insert-preedit-segment anthy-preedit-begin-mark '())
473
474           ;; \e$BF~NO3+;O$HF1;~$K\e(Bundo\e$B%j%9%H$rL58z2=\e(B
475           (if (not anthy-buffer-undo-list-saved)
476               (progn
477                 ;(message "disable")
478                 (setq anthy-buffer-undo-list (cdr buffer-undo-list))
479                 (buffer-disable-undo)
480                 (setq anthy-buffer-undo-list-saved 't)
481                 )
482             ;(message "not saved")
483             )
484
485           ))
486
487     ;; \e$B3FJ8@a$KBP$7$F\e(B
488     (while ps
489       (let ((cur (car ps)))
490         (setq ps (cdr ps))
491         (cond
492          ((eq cur 'cursor)
493           (setq cursor-pos (point)))
494          ((string-equal (car (cdr cur)) "")
495           nil)
496          (t
497           (let ((nr (car (cdr (cdr (cdr cur)))))
498                 (idx (car (cdr (cdr cur))))
499                 (str (car (cdr cur)))
500                 (attr (car cur)))
501             (setq str (anthy-insert-preedit-segment str attr))
502             (cond ((and (car anthy-enable-enum-candidate-p) (memq 'ENUM attr))
503                    ;; \e$B=gJ}8~$N8uJdNs5s\e(B
504                    (setq anthy-enum-candidate-p t)
505                    (setq idx-candidate idx)
506                    (setq num-candidate nr))
507                   ((and (car anthy-enable-enum-candidate-p) (memq 'ENUMR attr))
508                    ;; \e$B5UJ}8~$N8uJdNs5s\e(B
509                    (setq anthy-enum-rcandidate-p t)
510                    (setq idx-candidate idx)
511                    (setq num-candidate nr)))
512             (setq anthy-preedit
513                   (concat anthy-preedit str))
514             (if (and (member stat '(3 4)) (not (eq ps '())))
515                 (progn
516                   (setq anthy-preedit
517                         (concat anthy-preedit anthy-preedit-delim-mark))
518                   (anthy-insert-preedit-segment anthy-preedit-delim-mark '()))))))))
519     ;; \e$B8uJd0lMw$NI=<(3+;O%A%'%C%/\e(B
520     (if (and (not enum-candidate)
521              (or anthy-enum-candidate-p anthy-enum-rcandidate-p))
522         (setq anthy-current-candidate-layout-begin-index 0))
523     ;; \e$B8uJd$NNs5s$r9T$&\e(B
524     (if (or anthy-enum-candidate-p anthy-enum-rcandidate-p)
525         (anthy-layout-candidate idx-candidate num-candidate))
526     ;; preedit\e$B$N\e(Bkeymap\e$B$r99?7$9$k\e(B
527     (if (member stat '(2 3 4))
528         (anthy-enable-preedit-keymap))
529     (if cursor-pos (goto-char cursor-pos))))
530
531 ; suzuki : Emacs / XEmacs \e$B$G6&DL$N4X?tDj5A\e(B
532 (defun anthy-encode-key (ch)
533   (let ((c (assoc ch anthy-keyencode-alist)))
534     (if c
535         (cdr c)
536       (if (and
537            (integerp ch)
538            (> ch 32))
539           (char-to-string ch)
540         nil))))
541
542 (defun anthy-restore-undo-list (commit-str)
543   (let* ((len (length commit-str))
544          (beginning (point))
545          (end (+ beginning len)))
546     (setq buffer-undo-list
547           (cons (cons beginning end)
548                 (cons nil anthy-saved-buffer-undo-list)))
549          ))
550
551 (defun anthy-proc-agent-reply (repl)
552   (let*
553       ((stat (car repl))
554        (body (cdr repl))
555        (commit "")
556        (commitlen nil)
557        (preedit nil))
558     ;; \e$B3FJ8@a$r=hM}$9$k\e(B
559     (while body
560       (let* ((cur (car body))
561              (pe nil))
562         (setq body (cdr body))
563         (if (and
564              (listp cur)
565              (listp (car cur)))
566             (cond
567              ((eq (car (car cur)) 'COMMIT)
568               (setq commit (concat commit (car (cdr cur)))))
569              ((eq (car (car cur)) 'CUTBUF)
570               (let ((len (length (car (cdr cur)))))
571                 (copy-region-as-kill (point) (+ (point) len))))
572              ((memq 'UL (car cur))
573               (setq pe (list cur))))
574           (setq pe (list cur)))
575         (if pe
576             (setq preedit (append preedit pe)))))
577     ;; \e$B%3%_%C%H$5$l$?J8@a$r=hM}$9$k\e(B
578 ;    (anthy-restore-undo-list commit)
579     (if (> (string-width commit) 0)
580         (progn
581           (setq commitlen (length commit))
582           (anthy-erase-preedit)
583           (anthy-disable-preedit-keymap)
584           ; \e$B@h$K%3%_%C%H$5$;$F$*$/\e(B
585           (insert-and-inherit commit)
586           (anthy-do-auto-fill)
587
588           ;; \e$B%3%_%C%H;~$K7R$2$k\e(B
589           (if anthy-buffer-undo-list-saved 
590               (progn
591                 ;(message "enable")
592                 ; \e$BI|5"$5$;$kA0$K!$:#\e(Bcommit\e$B$7$?FbMF$r%j%9%H$KDI2C\e(B
593                 (setq anthy-buffer-undo-list
594                       (cons (cons anthy-preedit-start
595                                   (+ anthy-preedit-start commitlen))
596                             anthy-buffer-undo-list))
597                 (setq anthy-buffer-undo-list (cons nil anthy-buffer-undo-list))
598
599                 (buffer-enable-undo)
600
601                 (setq buffer-undo-list anthy-buffer-undo-list)
602
603                 (setq anthy-buffer-undo-list-saved nil)
604                 ))
605
606           (run-hooks 'anthy-commit-hook)
607           ))
608     (anthy-update-preedit stat preedit)
609     (anthy-update-mode-line)))
610
611 (defun anthy-insert-select-candidate (ch)
612   (let* ((key-idx (car (rassoc (char-to-string ch)
613                                anthy-select-candidate-keybind)))
614          (idx (car (cdr (assq key-idx
615                               anthy-enum-candidate-list)))))
616     (if idx
617         (progn
618           (let ((repl (anthy-send-recv-command
619                        (format " SELECT_CANDIDATE %d\n" idx))))
620             (anthy-proc-agent-reply repl))
621           (setq anthy-enum-candidate-p nil)
622           (setq anthy-enum-rcandidate-p nil))
623       (message "%s" anthy-candidate-minibuffer))))
624
625 (defvar anthy-default-rkmap-keybind
626   '(
627     ;; q
628     (("hiragana" . 113) . "katakana")
629     (("katakana" . 113) . "hiragana")
630     ;; l
631     (("hiragana" . 108) . "alphabet")
632     (("katakana" . 108) . "alphabet")
633     ;; L
634     (("hiragana" . 76) . "walphabet")
635     (("katakana" . 76) . "walphabet")
636     ;; \C-j
637     (("alphabet" . 10) . "hiragana")
638     (("walphabet" . 10) . "hiragana")
639     ;; \C-q
640     (("hiragana" . 17) . "hankaku_kana")
641     (("hankaku_kana" . 17) . "hiragana")
642     ))
643
644
645 (defvar anthy-rkmap-keybind anthy-default-rkmap-keybind)
646
647
648 (defun anthy-find-rkmap-keybind (ch)
649   (let ((res
650          (assoc (cons anthy-current-rkmap ch) anthy-rkmap-keybind)))
651     (if (and res (string-equal (cdr res) "hankaku_kana"))
652         (if anthy-use-hankaku-kana res nil)
653       res)))
654
655 (defun anthy-handle-normal-key (chenc)
656   (let* ((repl
657           (if chenc (anthy-send-recv-command 
658                      (concat chenc "\n"))
659             nil)))
660     (if repl
661         (anthy-proc-agent-reply repl))))
662
663 (defun anthy-handle-enum-candidate-mode (chenc)
664   (anthy-handle-normal-key chenc))
665
666 ;;
667 (defun anthy-insert (&optional arg)
668   "Anthy\e$B$N%-!<%O%s%I%i\e(B"
669   (interactive "*p")
670   ;; suzuki : last-command-char \e$B$r\e(B (anthy-last-command-char) \e$B$KJQ99\e(B
671   (let* ((ch (anthy-last-command-char))
672          (chenc (anthy-encode-key ch)))
673     (anthy-handle-key ch chenc)))
674
675 (defun anthy-handle-key (ch chenc)
676   (cond
677    ;; \e$B8uJdA*Br%b!<%I$+$i8uJd$rA*$V\e(B
678    ((and (or anthy-enum-candidate-p anthy-enum-rcandidate-p)
679          (integerp ch)
680          (assq (car (rassoc (char-to-string ch)
681                             anthy-select-candidate-keybind))
682                anthy-enum-candidate-list))
683     (anthy-insert-select-candidate ch))
684    ;; \e$B%-!<%^%C%W$rJQ99$9$k%3%^%s%I$r=hM}$9$k\e(B
685    ((and (anthy-find-rkmap-keybind ch)
686          (string-equal anthy-preedit ""))
687     (let ((mapname (cdr (anthy-find-rkmap-keybind ch))))
688       (let ((repl (anthy-send-recv-command
689                    (concat " MAP_SELECT " mapname "\n"))))
690         (if (eq repl 'OK)
691             (progn
692               (setq anthy-current-rkmap
693                     (cdr (assoc (cons anthy-current-rkmap ch)
694                                 anthy-rkmap-keybind)))
695               (anthy-update-mode-line))))))
696    ;; \e$B%"%k%U%!%Y%C%H%b!<%I$N>l9g$OD>@\F~NO\e(B
697    ((and (string-equal anthy-current-rkmap "alphabet")
698          (string-equal anthy-preedit ""))
699     (self-insert-command 1))
700    ;; \e$B%W%j%(%G%#%C%H$,$J$/$F%9%Z!<%9$,2!$5$l$?\e(B
701    ((and
702      (string-equal anthy-preedit "")
703      (= ch 32)
704      (not
705       (string-equal anthy-current-rkmap "alphabet")))
706     (progn
707       (insert-and-inherit anthy-wide-space)
708       (anthy-do-auto-fill)))
709    ((or anthy-enum-candidate-p anthy-enum-rcandidate-p)
710     (anthy-handle-enum-candidate-mode chenc))
711    ;; \e$BIaDL$NF~NO\e(B
712    (t
713     (anthy-handle-normal-key chenc))))
714
715 ;;
716 (defun anthy-do-invoke-agent (cmd)
717   (if (and (stringp anthy-personality)
718            (> (length anthy-personality) 0))
719       (start-process "anthy-agent"
720                      anthy-working-buffer
721                      cmd
722                      (concat " --personality=" anthy-personality))
723     (start-process "anthy-agent"
724                    anthy-working-buffer
725                    cmd)))
726 ;;
727 (defun anthy-invoke-agent ()
728   (let ((list anthy-agent-command-list)
729         (proc nil))
730     (while (and list (not proc))
731       (setq proc 
732             (anthy-do-invoke-agent (car list)))
733       (if (not (boundp 'proc))
734           (setq proc nil))
735       (setq list (cdr list)))
736     proc))
737 ;;
738 ;;
739 ;;
740 (defun anthy-check-agent ()
741   ;; check and do invoke
742   (if (not anthy-agent-process)
743       (let
744           ((proc (anthy-invoke-agent)))
745         (if anthy-agent-process
746             (kill-process anthy-agent-process))
747         (setq anthy-agent-process proc)
748         (process-kill-without-query proc)
749         (if anthy-xemacs
750             (if (coding-system-p (find-coding-system 'euc-japan))
751                 (set-process-coding-system proc 'euc-japan 'euc-japan))
752           (cond ((coding-system-p 'euc-japan)
753                  (set-process-coding-system proc 'euc-japan 'euc-japan))
754                 ((coding-system-p '*euc-japan*)
755                  (set-process-coding-system proc '*euc-japan* '*euc-japan*))))
756         (set-process-sentinel proc 'anthy-process-sentinel))))
757 ;;
758 (defun anthy-do-send-recv-command (cmd)
759   (if (not anthy-agent-process)
760       (anthy-check-agent))
761   (let ((old-buffer (current-buffer)))
762     (unwind-protect
763         (progn
764           (set-buffer anthy-working-buffer)
765           (erase-buffer)
766           (process-send-string anthy-agent-process cmd)
767           (while (= (buffer-size) 0)
768             (accept-process-output nil 0 anthy-accept-timeout))
769           (read (buffer-string)))
770       (set-buffer old-buffer))))
771 ;;
772 (defun anthy-send-recv-command (cmd)
773   (if anthy-context-id
774       (anthy-do-send-recv-command
775        (concat " SELECT_CONTEXT "
776                (number-to-string anthy-context-id)
777                "\n")))
778   (anthy-do-send-recv-command cmd))
779 ;;
780 (defun anthy-minibuffer-enter ()
781   (setq anthy-saved-mode anthy-mode)
782   (setq anthy-mode nil)
783   (setq anthy-enable-enum-candidate-p 
784         (cons nil anthy-enable-enum-candidate-p))
785   (anthy-update-mode))
786 ;;
787 (defun anthy-minibuffer-exit ()
788   (setq anthy-mode anthy-saved-mode)
789   (setq anthy-enable-enum-candidate-p 
790         (cdr anthy-enable-enum-candidate-p))
791   (anthy-update-mode))
792 ;;
793 (defun anthy-kill-buffer ()
794   (if anthy-context-id
795       (anthy-send-recv-command
796        " RELEASE_CONTEXT\n")))
797 ;;
798 (defun anthy-mode-on ()
799   (add-hook 'minibuffer-setup-hook 'anthy-minibuffer-enter)
800   (add-hook 'minibuffer-exit-hook 'anthy-minibuffer-exit)
801   (add-hook 'kill-buffer-hook 'anthy-kill-buffer)
802   (anthy-check-context-id)
803   (setq anthy-minor-mode t)
804   (anthy-update-mode-line))
805 ;;
806 (defun anthy-mode-off ()
807   (setq anthy-minor-mode nil)
808   (anthy-update-mode-line))
809 ;;
810 (defun anthy-update-mode ()
811   (if (or anthy-mode anthy-leim-active-p)
812       (progn
813         (anthy-check-agent)
814         (anthy-mode-on))
815     (anthy-mode-off))
816   (run-hooks 'anthy-mode-hook))
817
818 (defun anthy-mode (&optional arg)
819   "Start Anthy conversion system."
820   (interactive "P")
821   (setq anthy-mode
822         (if (null arg)
823             (not anthy-mode)
824           (> (prefix-numeric-value arg) 0)))
825   (anthy-update-mode))
826
827 (defun anthy-select-map (map)
828   (anthy-send-recv-command (concat " MAP_SELECT " map "\n"))
829   (setq anthy-current-rkmap map)
830   (anthy-update-mode-line))
831 ;;
832 (defun anthy-hiragana-map (&optional arg)
833   "Hiragana mode"
834   (interactive "P")
835   (anthy-select-map "hiragana"))
836 ;;
837 (defun anthy-katakana-map (&optional arg)
838   "Katakana mode"
839   (interactive "P")
840   (anthy-select-map "katakana"))
841 ;;
842 (defun anthy-alpha-map (arg)
843   "Alphabet mode"
844   (interactive "P")
845   (anthy-select-map "alphabet"))
846 ;;
847 (defun anthy-wide-alpha-map (arg)
848   "Wide Alphabet mode"
849   (interactive "P")
850   (anthy-select-map "walphabet"))
851 ;;
852 (defun anthy-hankaku-kana-map (arg)
853   "Hankaku Katakana mode"
854   (interactive "P")
855   (anthy-select-map "hankaku_kana"))
856 ;;
857 ;;
858 ;; leim \e$B$N\e(B inactivate
859 ;;
860 (defun anthy-leim-inactivate ()
861   (setq anthy-leim-active-p nil)
862   (anthy-update-mode))
863 ;;
864 ;; leim \e$B$N\e(B activate
865 ;;
866 (defun anthy-leim-activate (&optional name)
867   (setq inactivate-current-input-method-function 'anthy-leim-inactivate)
868   (setq anthy-leim-active-p t)
869   (anthy-update-mode)
870   (when (eq (selected-window) (minibuffer-window))
871     (add-hook 'minibuffer-exit-hook 'anthy-leim-exit-from-minibuffer)))
872
873 ;;
874 ;; emacs\e$B$N%P%0Hr$1$i$7$$$G$9\e(B
875 ;;
876 (defun anthy-leim-exit-from-minibuffer ()
877   (inactivate-input-method)
878   (when (<= (minibuffer-depth) 1)
879     (remove-hook 'minibuffer-exit-hook 'anthy-leim-exit-from-minibuffer)))
880
881 ;;
882 ;; Emacs / XEmacs \e$B%3%s%Q%A%V%k$J\e(B last-command-char
883 ;; suzuki : \e$B?7@_\e(B
884 ;;
885 (defun anthy-last-command-char ()
886   "\e$B:G8e$NF~NO%$%Y%s%H$rJV$9!#\e(BXEmacs \e$B$G$O\e(B int \e$B$KJQ49$9$k\e(B"
887   (if anthy-xemacs
888       (let ((event last-command-event))
889         (cond
890          ((event-matches-key-specifier-p event 'left)      2)
891          ((event-matches-key-specifier-p event 'right)     6)
892          ((event-matches-key-specifier-p event 'backspace) 8)
893          (t
894           (char-to-int (event-to-character event)))))
895     last-command-char))
896
897 ;;
898 ;;
899 ;;
900 ;(global-set-key [(meta escape)] 'anthy-mode)
901 (provide 'anthy)
902
903 (require 'anthy-dic)
904 (require 'anthy-conf)
905
906 ;; is it ok for i18n?
907 (set-language-info "Japanese" 'input-method "japanese-anthy")
908 (if (equal current-language-environment "Japanese")
909     (progn
910       (if (boundp 'default-input-method)
911           (setq-default default-input-method "japanese-anthy"))
912       (setq default-input-method "japanese-anthy")))
913
914 (defun anthy-default-mode ()
915   (interactive)
916   (setq anthy-rkmap-keybind anthy-default-rkmap-keybind)
917   (anthy-send-recv-command " MAP_CLEAR 1\n")
918   (anthy-send-recv-command " SET_PREEDIT_MODE 0\n")
919   (anthy-hiragana-map))
920
921 (defun anthy-insert-and-convert (ch)
922   (interactive "P")
923   (if (< 0 (length anthy-preedit))
924       (progn
925         (anthy-insert ch)
926         (anthy-handle-normal-key "(space)"))
927     (anthy-insert ch)))
928
929 ;;;
930 ;;; anthy.el ends here