leim-list.el
[elisp/tamago.git] / egg / anthy.el
1 ;;; egg/anthy.el --- ANTHY Support (high level interface) in Egg
2 ;;;                Input Method Architecture
3
4 ;; Copyright (C) 2002 The Free Software Initiative of Japan
5
6 ;; Author: NIIBE Yutaka <gniibe@m17n.org>
7
8 ;; Maintainer: NIIBE Yutaka <gniibe@m17n.org>
9
10 ;; Keywords: mule, multilingual, input method
11
12 ;; This file is part of EGG.
13
14 ;; EGG is free software; you can redistribute it and/or modify
15 ;; it under the terms of the GNU General Public License as published by
16 ;; the Free Software Foundation; either version 2, or (at your option)
17 ;; any later version.
18
19 ;; EGG is distributed in the hope that it will be useful,
20 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
21 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22 ;; GNU General Public License for more details.
23
24 ;; You should have received a copy of the GNU General Public License
25 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
26 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
27 ;; Boston, MA 02111-1307, USA.
28
29 ;;; Commentary:
30
31
32 ;;; Code:
33
34 (require 'egg)
35 (require 'egg-edep)
36
37 (defgroup anthy nil
38   "Anthy interface for Tamago 4."
39   :group 'egg)
40
41 (setplist 'anthy-conversion-backend
42           '(egg-start-conversion          anthy-convert
43             egg-get-bunsetsu-source       anthy-get-bunsetsu-source
44             egg-get-bunsetsu-converted    anthy-get-bunsetsu-converted
45             egg-list-candidates           anthy-get-candidates
46             egg-decide-candidate          anthy-select-candidate
47             egg-change-bunsetsu-length    anthy-resize-segment
48             egg-end-conversion            anthy-commit
49             ;;
50             egg-get-source-language       anthy-get-source-language
51             egg-get-converted-language    anthy-get-converted-language))
52
53 (defconst anthy-backend-alist '((Japanese ((anthy-conversion-backend)))))
54
55 (egg-set-finalize-backend '(anthy-finalize-backend))
56
57 (defvar anthy-proc nil
58   "Process of ANTHY helper agent.")
59
60 ;; <environments> ::= ( <env> ... <env> )
61 ;;
62 ;; <env> ::= <context-descriptor>
63 ;; <context-descriptor> ::= <integer>
64 (defvar anthy-environment-pool nil
65   "Environments for ANTHY kana-kanji conversion, to be used.")
66
67 (defvar anthy-environments-in-use nil
68   "Environments for ANTHY kana-kanji conversion, in use.")
69
70 ;;
71 ;; <anthy-bunsetsu> ::=
72 ;;  [ <env> <source> <converted> <candidates> <candidate-pos> <seg-no> ]
73 (defsubst anthy-make-bunsetsu (env source converted seg-no)
74   (egg-bunsetsu-create
75    'anthy-conversion-backend
76    (vector env source converted nil 0 seg-no)))
77
78 (defsubst anthybunsetsu-get-env (b)
79   (aref (egg-bunsetsu-get-info b) 0))
80 (defsubst anthybunsetsu-get-source (b)
81   (aref (egg-bunsetsu-get-info b) 1))
82 (defsubst anthybunsetsu-get-converted (b)
83   (aref (egg-bunsetsu-get-info b) 2))
84 (defsubst anthybunsetsu-get-candidates (b)
85   (aref (egg-bunsetsu-get-info b) 3))
86 (defsubst anthybunsetsu-set-candidates (b z)
87   (aset (egg-bunsetsu-get-info b) 3 z))
88 (defsubst anthybunsetsu-get-candidate-pos (b)
89   (aref (egg-bunsetsu-get-info b) 4))
90 (defsubst anthybunsetsu-set-candidate-pos (b zp)
91   (aset (egg-bunsetsu-get-info b) 4 zp))
92 (defsubst anthybunsetsu-get-seg-no (b)
93   (aref (egg-bunsetsu-get-info b) 5))
94
95 (defun anthy-get-bunsetsu-source (b)
96   (anthybunsetsu-get-source b))
97
98 (defun anthy-get-bunsetsu-converted (b)
99   (let ((cands (anthybunsetsu-get-candidates b)))
100     (if cands
101         (nth (anthybunsetsu-get-candidate-pos b) cands)
102       (anthybunsetsu-get-converted b))))
103
104 (defun anthy-get-source-language (b) 'Japanese)
105 (defun anthy-get-converted-language (b) 'Japanese)
106
107 ;; Getting new context-descriptor, and returns environment with 'inuse' bit
108 (defun anthy-new-environment ()
109   (if (null anthy-proc)
110       (let ((buf (generate-new-buffer " *ANTHY*"))
111             (process-connection-type nil)) ; avoid using pty
112         (setq anthy-proc
113               (start-process "anthy-agent" buf "anthy-agent" "--egg"))
114         (process-kill-without-query anthy-proc)
115         (set-process-coding-system anthy-proc 'euc-jp-dos 'euc-jp-dos)
116         (set-process-sentinel anthy-proc 'anthy-proc-sentinel)
117         (set-marker-insertion-type (process-mark anthy-proc) t)
118         (save-excursion
119           (set-buffer buf)
120           (erase-buffer)
121           (buffer-disable-undo))))
122   (anthyipc-get-greeting anthy-proc)
123   (anthyipc-new-context anthy-proc))
124
125 ;;; XXX: Don't kill buffer (for now) so that I can debug this program
126 (defun anthy-proc-sentinel (proc reason)
127 ;  (kill-buffer (process-buffer proc))
128   (setq anthy-proc nil
129         anthy-environments-in-use nil
130         anthy-environment-pool nil))
131
132 ;;; anthyipc-release-context
133
134
135 (defun anthy-get-environment ()
136   "Return the ANTHY environment."
137   (if anthy-environment-pool
138       (let ((env (car anthy-environment-pool)))
139         (setq anthy-environment-pool (cdr anthy-environment-pool))
140         (setq anthy-environments-in-use (cons env anthy-environments-in-use))
141         env)
142     (let ((env (anthy-new-environment)))
143       (setq anthy-environments-in-use (cons env anthy-environments-in-use))
144       env)))
145
146 ;;
147 ;; Returns list of bunsetsu
148 ;;
149 (defun anthy-convert (backend yomi &optional context)
150   "Convert YOMI string to kanji, and enter conversion mode.
151 Return the list of bunsetsu."
152   (let ((env (anthy-get-environment)))
153     (anthyipc-convert anthy-proc env yomi)))
154
155 ;;
156 ;;
157 ;;
158 (defun anthy-commit (bunsetsu-list abort)
159   (let ((env (anthybunsetsu-get-env (car bunsetsu-list))))
160     (anthyipc-commit anthy-proc env (if abort 1 0))
161     (setq anthy-environment-pool (cons env anthy-environment-pool))
162     (setq anthy-environments-in-use (delq env anthy-environments-in-use))))
163
164 ;;
165 ;; Returns ( <pos> <candidates> )
166 ;;
167 (defun anthy-get-candidates (bunsetsu-list prev-bunsetsu next-bunsetsu major)
168   (let ((bunsetsu (car bunsetsu-list)))
169     (if (anthybunsetsu-get-candidates bunsetsu)
170         (cons (anthybunsetsu-get-candidate-pos bunsetsu)
171               (anthybunsetsu-get-candidates bunsetsu))
172       (let* ((env (anthybunsetsu-get-env bunsetsu))
173              (seg-no (anthybunsetsu-get-seg-no bunsetsu))
174              (cands (anthyipc-get-candidates anthy-proc env seg-no)))
175         (cons (anthybunsetsu-set-candidate-pos bunsetsu 0)
176               (anthybunsetsu-set-candidates bunsetsu cands))))))
177
178 ;; Returns list of list of bunsetsu
179 (defun anthy-select-candidate (bunsetsu-list candidate-pos prev-b next-b)
180   (let* ((bunsetsu (car bunsetsu-list))
181          (candidate-list (anthybunsetsu-get-candidates bunsetsu))
182          (candidate (nth candidate-pos candidate-list))
183          (env (anthybunsetsu-get-env bunsetsu))
184          (seg-no (anthybunsetsu-get-seg-no bunsetsu)))
185     (anthybunsetsu-set-candidate-pos bunsetsu candidate-pos)
186     ;; Anthy doesn't have capability of changing another segment
187     ;; at the selection of a segment.
188     ;; So, just ignore the result of "SELECT-CANDIDATE"
189     (anthyipc-select-candidate anthy-proc env seg-no candidate-pos)
190     (list (list bunsetsu))))
191
192 ;; Returns list of list of bunsetsu
193 (defun anthy-resize-segment (bunsetsu-list prev-b next-b len major)
194   (let ((bunsetsu (car bunsetsu-list)))
195     (let ((env (anthybunsetsu-get-env bunsetsu))
196           (seg-no (anthybunsetsu-get-seg-no bunsetsu))
197           (prevlen (length (anthybunsetsu-get-source bunsetsu))))
198       (let ((r (anthyipc-resize-segment anthy-proc env seg-no
199                                         (if (< prevlen len) 0 1))))
200         ;; XXX: I don't know what this means, 
201         ;; but this works.  Blame EGG.
202         (list (list (car r)) nil (cdr r))))))
203
204 (defun anthy-finalize-backend ()
205   (if anthy-proc
206       (progn
207         (delete-process anthy-proc)
208         (setq anthy-proc nil))))
209
210 ;;; setup
211
212 (load "egg/anthyipc")
213 (run-hooks 'anthy-load-hook)
214
215 ;;;###autoload
216 (defun egg-activate-anthy (&rest arg)
217   "Activate ANTHY backend of Tamago 4."
218   (apply 'egg-mode (append arg anthy-backend-alist)))
219
220 ;;; egg/anthy.el ends here.