(canna-self-insert-string-filter): Define for every cases; add DOC.
[elisp/emacs-canna.git] / canna.el
1 ;;; canna.el --- Interface to the Canna input method.
2
3 ;; Copyright (C) 1994 Akira Kon, NEC Corporation.
4 ;; Copyright (C) 1996,1997,1998,2004 MORIOKA Tomohiko
5 ;; Copyright (C) 1997 Stephen Turnbull
6
7 ;; Author: Akira Kon <kon@d1.bs2.mt.nec.co.jp>
8 ;;         MORIOKA Tomohiko <morioka@jaist.ac.jp>
9 ;;         Stephen Turnbull <turnbull@sk.tsukuba.ac.jp>
10 ;; Keywords: Canna, Japanese, input method, mule, multilingual
11
12 ;; This file is part of Emacs-Canna.
13
14 ;; This program is free software; you can redistribute it and/or
15 ;; modify it under the terms of the GNU General Public License as
16 ;; published by the Free Software Foundation; either version 2, or (at
17 ;; your option) any later version.
18
19 ;; This program is distributed in the hope that it will be useful, but
20 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
21 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
22 ;; 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 ;; Egg offered some influences to the implementation of Canna on
32 ;; Nemacs/Mule, and this file contains a few part of Egg which is
33 ;; written by S.Tomura, Electrotechnical Lab.  (tomura@etl.go.jp)
34
35 ;; This program is rewritten for Emacs/mule and XEmacs/mule by MORIOKA
36 ;; Tomohiko.
37
38 ;;; Code:
39
40 (require 'poem)
41
42 (defvar canna-dl-module
43   (expand-file-name "canna.so" exec-directory))
44
45 (defvar canna-dl-handle
46   (and (not (boundp 'CANNA))
47        (fboundp 'dynamic-link)
48        (dynamic-link canna-dl-module)))
49
50 (and canna-dl-handle
51      (dynamic-call "emacs_canna_init" canna-dl-handle))
52
53 (or (boundp 'CANNA)
54     (featurep 'CANNA)
55     (error "Canna is not built into this Emacs"))
56
57 (defvar self-insert-after-hook nil)
58 ;; (defalias 'self-insert-internal 'self-insert-command)
59 ;; end
60
61 (defconst canna-version "Emacs-Canna 1.5")
62
63 (defun canna-version ()
64   "Display version of canna.el in mini-buffer."
65   (interactive)
66   (message (concat canna-version " ...")))
67
68 (defvar canna-self-insert-string-filter nil
69   "*\e$B3NDj;~$K8F$P$l$k%U%#%k%?!<4X?t$r;XDj$9$k$?$a$NJQ?t!#\e(B
70 \e$B@_Dj$5$l$k%U%#%k%?!<4X?t$O#10z?t$N4X?t$G!"\e(B
71 \e$B$=$N0z?t$K3NDjJ8;zNs$,EO$5$l$k!#\e(B
72 \e$B$^$?!"%U%#%k%?!<4X?t$OJ8;zNs$rJV$5$J$1$l$P$J$i$J$$!#\e(B
73 \e$B>e5-$N;HMQ$rK~$?$94X?t$NB>!"\e(Bnil \e$B$r;XDj$9$k$3$H$,$G$-!"\e(B
74 \e$B$=$N>l9g$OL5JQ49$rI=$9!#\e(B")
75
76 (cond
77  ((featurep 'xemacs)
78   (defun canna-self-insert-string (string)
79     (if (functionp canna-self-insert-string-filter)
80         (setq string (funcall canna-self-insert-string-filter string)))
81     (let ((len (length string))
82           (i 0)
83           ;; \e$BA^F~$NESCf$G\e(B blink \e$B$,5/$-$k$H$&$C$H$*$7$$$N$G!"\e(B
84           ;; \e$B0l;~E*$K\e(B blink \e$B$rM^;_$9$k!#\e(B
85           (blink-matching-paren nil))
86       (while (< i len)
87         (self-insert-internal (aref string i))
88         (setq i (1+ i)))))
89   )
90  (t
91   ;; (defalias 'canna-self-insert-string 'insert)
92   (defun canna-self-insert-string (string)
93     (if canna-self-insert-string-filter
94         (setq string (funcall canna-self-insert-string-filter string)))
95     (insert string))
96   ))
97
98
99 ;;; \e$B$+$s$J$NJQ?t\e(B
100
101 (defvar canna-save-undo-text-predicate nil)
102 (defvar canna-undo-hook nil)
103
104 (defvar canna-do-keybind-for-functionkeys t)
105 (defvar canna-use-functional-numbers nil)
106 (defvar canna-use-space-key-as-henkan-region t)
107
108 (defvar canna-server nil)
109 (defvar canna-file   nil)
110
111 (defvar canna-underline nil)
112 (defvar canna-with-fences (not canna-underline))
113
114 (defvar canna-initialize-minibuffer-state-when-exit nil
115   "*Non-nil \e$B$N$H$-$O\e(B, \e$B%_%K%P%C%U%!$rH4$1$k;~F|K\8l>uBV$r=i4|2=$9$k\e(B.")
116
117 (defvar canna-inhibit-hankakukana nil
118   "*Non-nil \e$B$N;~!";z<oJQ49$GH>3Q$+$J$KJQ49$7$J$$\e(B")
119
120 ;;;
121 ;;; \e$B%b!<%I%i%$%s$N=$@0\e(B
122 ;;;
123
124 (defvar canna:*kanji-mode-string* "[ \e$B$"\e(B ]")
125 (defvar canna:*alpha-mode-string* "\e$B$+$s$J\e(B")
126 (defvar canna:*saved-mode-string* "[ \e$B$"\e(B ]")
127
128 (defvar mode-line-canna-mode canna:*alpha-mode-string*)
129 (defvar mode-line-canna-mode-in-minibuffer canna:*alpha-mode-string*)
130
131 (defvar display-minibuffer-mode-in-minibuffer nil) ; same name as TAKANA
132\e$B$?$+$J$G$O\e(B t \e$B$,%G%U%)%k%H$@$1$I!"\e(Bnil \e$B$r%G%U%)%k%H$K$7$F$*$3$&$+$J!#\e(B
133
134 (make-variable-buffer-local 'mode-line-canna-mode)
135
136 ; select-window-hook \e$B$O\e(B mule \e$B$+$iF~$C$?$s$@$H;W$&$1$I!"\e(B
137\e$B$3$l$,L5$$$H\e(B preprompt \e$B$,$"$C$F$b$I$&$7$h$&$b$J$$$N$G$J$$$H$-$O\e(B
138 ; display-minibuffer-mode-in-minibuffer \e$B$r\e(B nil \e$B$K$9$k!#\e(B
139
140 (if (not (boundp 'select-window-hook))
141     (setq display-minibuffer-mode-in-minibuffer nil))
142
143 (defun canna:select-window-hook (old new)
144   (if (and (eq old (minibuffer-window))
145            (not (eq new (minibuffer-window))))
146       (save-excursion
147         (set-buffer (window-buffer (minibuffer-window)))
148         ;; minibuffer\e$B$N%G%U%)%k%H$O%"%k%U%!%Y%C%H%b!<%I\e(B
149         (setq mode-line-canna-mode-in-minibuffer canna:*alpha-mode-string*
150               canna:*japanese-mode-in-minibuffer* nil   
151               minibuffer-preprompt nil)))
152   (if (eq new (minibuffer-window))
153       (setq minibuffer-window-selected t)
154     (setq minibuffer-window-selected nil)))
155
156 ; egg:select-window-hook \e$B$G$b==J,$J$N$G!"\e(Begg:select-window-hook \e$B$,\e(B
157\e$B@_Dj$5$l$F$$$J$$>l9g$N$_Dj5A$9$k!#\e(B
158
159\e$BNI$/9M$($F$_$k$H\e(B display-minibuffer-mode-in-minibuffer \e$B$,\e(B t \e$B$N;~$O\e(B
160\e$B$d$O$j>e5-$N\e(B canna:select-window-hook \e$B$,I,MW$@$J$"!#$I$&$7$h$&!#\e(B
161
162 (if (and (boundp 'select-window-hook)
163          (not (eq select-window-hook 'egg:select-window-hook)))
164     (setq select-window-hook 'canna:select-window-hook))
165
166 (defun mode-line-canna-mode-update (str)
167   (if (eq (current-buffer) (window-buffer (minibuffer-window)))
168       (if (and display-minibuffer-mode-in-minibuffer
169                (boundp 'minibuffer-preprompt))
170           (setq minibuffer-preprompt str)
171         ;else
172         (setq mode-line-canna-mode-in-minibuffer str))
173     (setq mode-line-canna-mode str) )
174   (set-buffer-modified-p (buffer-modified-p)) )
175
176 ;; memq \e$B$r6/D4$9$k$J$i!"0J2<$@$,!"\e(B
177 ;(defun canna:memq-recursive (a l)
178 ;  (or (eq a l)
179 ;      (and (consp l)
180 ;          (or (canna:memq-recursive a (car l))
181 ;              (canna:memq-recursive a (cdr l)) ))))
182 ;; \e$B<!$NDj5A$r;H$*$&\e(B...
183 (defun canna:memq-recursive (a l)
184   (if (atom l) (eq a l)
185     (or (canna:memq-recursive a (car l))
186         (canna:memq-recursive a (cdr l)) )))
187
188 (defun canna:create-mode-line ()
189   "Add Canna status string into mode-line."
190   (cond ((featurep 'xemacs)
191          (or (canna:memq-recursive 'mode-line-canna-mode
192                                    default-modeline-format)
193              (setq-default default-modeline-format
194                            (append '("" mode-line-canna-mode)
195                                    default-modeline-format))
196              )
197          (mapcar (function
198                   (lambda (buffer)
199                     (save-excursion
200                       (set-buffer buffer)
201                       (or (canna:memq-recursive 'mode-line-canna-mode
202                                                 modeline-format)
203                           (setq modeline-format
204                                 (append '("" mode-line-canna-mode)
205                                         modeline-format))
206                           )
207                       )))
208                  (buffer-list))
209          )
210         (t
211          (or (canna:memq-recursive 'mode-line-canna-mode mode-line-format)
212              (setq-default
213               mode-line-format
214               (append (list (list 'minibuffer-window-selected
215                                   (list 'display-minibuffer-mode-in-minibuffer
216                                         "-" "m") "-")
217                             (list 'minibuffer-window-selected
218                                   (list 'display-minibuffer-mode-in-minibuffer
219                                         'mode-line-canna-mode
220                                         'mode-line-canna-mode-in-minibuffer)
221                                   'mode-line-canna-mode))
222                       mode-line-format))
223              )))
224   (mode-line-canna-mode-update mode-line-canna-mode))
225
226 (defun canna:mode-line-display ()
227   (mode-line-canna-mode-update mode-line-canna-mode))
228
229 ;;;
230 ;;; Canna local variables
231 ;;;
232
233 (defvar canna:*japanese-mode* nil "T if canna mode is ``japanese''.")
234 (make-variable-buffer-local 'canna:*japanese-mode*)
235 (set-default 'canna:*japanese-mode* nil)
236
237 (defvar canna:*japanese-mode-in-minibuffer* nil
238   "T if canna mode is ``japanese'' in minibuffer.")
239
240 (defvar canna:*exit-japanese-mode* nil)
241 (defvar canna:*fence-mode* nil)
242 ;(make-variable-buffer-local 'canna:*fence-mode*)
243 ;(setq-default canna:*fence-mode* nil)
244
245 ;;;
246 ;;; global variables
247 ;;;
248
249 (defvar canna-sys:*global-map* (copy-keymap global-map))
250 (defvar canna:*region-start* (make-marker))
251 (defvar canna:*region-end*   (make-marker))
252 (defvar canna:*spos-undo-text* (make-marker))
253 (defvar canna:*epos-undo-text* (make-marker))
254 (defvar canna:*undo-text-yomi* nil)
255 (defvar canna:*local-map-backup*  nil)
256 (defvar canna:*last-kouho* 0)
257 (defvar canna:*initialized* nil)
258 (defvar canna:*previous-window* nil)
259 (defvar canna:*minibuffer-local-map-backup* nil)
260 (defvar canna:*cursor-was-in-minibuffer* nil)
261 (defvar canna:*menu-buffer* " *menu*")
262 (defvar canna:*saved-minibuffer*)
263 (defvar canna:*saved-redirection* nil)
264 (defvar canna:*use-region-as-henkan-region* nil)
265 (make-variable-buffer-local 'canna:*use-region-as-henkan-region*)
266 (setq-default canna:*use-region-as-henkan-region* nil)
267
268 ;;;
269 ;;; \e$B?'$N@_Dj\e(B
270 ;;;
271 (defvar canna-use-color nil
272   "*Non-nil \e$B$G%+%i!<%G%#%9%W%l%$$G?'$rIU$1$k\e(B.
273\e$B$N;~$O%G%U%)%k%H$N?'$r;HMQ$9$k!#\e(B
274 \e$B?'$r;XDj$7$?$$;~$O\e(B, \"\e$BFI$_$N?'\e(B\", \"\e$BJQ49BP>]$N?'\e(B\", \"\e$BA*BrBP>]$N?'\e(B\" \e$B$N\e(B
275 \e$B%j%9%H$r@_Dj$9$k\e(B")
276 (defvar canna:color-p nil "\e$B?'$,;H$($k$+\e(B")
277 (defvar canna:attr-mode nil "\e$B8=:_$N%G%#%9%W%l%$%b!<%I\e(B")
278 (defvar canna:attr-yomi nil "\e$BFI$_$N?'B0@-\e(B")
279 (defvar canna:attr-taishou nil "\e$BJQ49BP>]ItJ,$N?'B0@-\e(B")
280 (defvar canna:attr-select nil
281   "\e$B%_%K%P%C%U%!J,N%;~$N%a%K%e!<$NA*BrBP>]HV9f$N?'B0@-\e(B")
282 (defvar canna:attribute-alist           ;colored by tagu@ae.keio.ac.jp
283   '((yomi (normal . "red") 
284           (reverse . "moccasin"))
285     (taishou (normal . "blue/lavender") 
286              (reverse . "yellow/cadet blue"))
287     (select (normal . "DarkOliveGreen1/cadet blue")
288             (reverse . "light sea green/burlywood1")))
289   "\e$B$+$s$JJQ49;~$NG[?'$N\e(Balist")
290
291 (make-variable-buffer-local (defvar canna:*yomi-overlay* nil))
292 (make-variable-buffer-local (defvar canna:*henkan-overlay* nil))
293 (make-variable-buffer-local (defvar canna:*select-overlay* nil))
294
295 ;;;
296 ;;; Keymap table
297 ;;;
298
299 ;; Fence mode local map
300 (defvar canna-mode-map (make-sparse-keymap))
301
302 (let ((ch 0))
303   (while (<= ch 127)
304     (define-key canna-mode-map (make-string 1 ch) 'canna-functional-insert-command)
305     (setq ch (1+ ch))))
306
307 (cond ((featurep 'xemacs)
308        (define-key canna-mode-map [up]              "\C-p")
309        (define-key canna-mode-map [(shift up)]      "\C-p")
310        (define-key canna-mode-map [(control up)]    "\C-p")
311        (define-key canna-mode-map [down]            "\C-n")
312        (define-key canna-mode-map [(shift down)]    "\C-n")
313        (define-key canna-mode-map [(control down)]  "\C-n")
314        (define-key canna-mode-map [right]           "\C-f")
315        (define-key canna-mode-map [(shift right)]   "\C-f")
316        (define-key canna-mode-map [(control right)] "\C-f")
317        (define-key canna-mode-map [left]            "\C-b")
318        (define-key canna-mode-map [(shift left)]    "\C-b")
319        (define-key canna-mode-map [(control left)]  "\C-b")
320        (define-key canna-mode-map [kanji]           " ")
321        (define-key canna-mode-map [(control space)] [(control @)])
322        (define-key canna-mode-map [delete] "\C-?")
323        (define-key canna-mode-map [backspace] "\C-h")
324        )
325       (t
326        (define-key canna-mode-map [up]      [?\C-p])
327        (define-key canna-mode-map [S-up]    [?\C-p])
328        (define-key canna-mode-map [C-up]    [?\C-p])
329        (define-key canna-mode-map [down]    [?\C-n])
330        (define-key canna-mode-map [S-down]  [?\C-n])
331        (define-key canna-mode-map [C-down]  [?\C-n])
332        (define-key canna-mode-map [right]   [?\C-f])
333        (define-key canna-mode-map [S-right] [?\C-f])
334        (define-key canna-mode-map [C-right] [?\C-f])
335        (define-key canna-mode-map [left]    [?\C-b])
336        (define-key canna-mode-map [S-left]  [?\C-b])
337        (define-key canna-mode-map [C-left]  [?\C-b])
338        (define-key canna-mode-map [kanji]   [? ])
339        (define-key canna-mode-map [?\C- ]   [?\C-@])
340        ))
341
342 ;; \e$B%_%K%P%C%U%!$K2?$+$rI=<($7$F$$$k;~$N%m!<%+%k%^%C%W\e(B
343 (defvar canna-minibuffer-mode-map (make-sparse-keymap))
344
345 (let ((ch 0))
346   (while (<= ch 127)
347     (define-key canna-minibuffer-mode-map (make-string 1 ch) 'canna-minibuffer-insert-command)
348     (setq ch (1+ ch))))
349
350 (cond ((featurep 'xemacs)
351        (define-key canna-minibuffer-mode-map [up]              "\C-p")
352        (define-key canna-minibuffer-mode-map [(shift up)]      "\C-p")
353        (define-key canna-minibuffer-mode-map [(control up)]    "\C-p")
354        (define-key canna-minibuffer-mode-map [down]            "\C-n")
355        (define-key canna-minibuffer-mode-map [(shift down)]    "\C-n")
356        (define-key canna-minibuffer-mode-map [(control down)]  "\C-n")
357        (define-key canna-minibuffer-mode-map [right]           "\C-f")
358        (define-key canna-minibuffer-mode-map [(shift right)]   "\C-f")
359        (define-key canna-minibuffer-mode-map [(control right)] "\C-f")
360        (define-key canna-minibuffer-mode-map [left]            "\C-b")
361        (define-key canna-minibuffer-mode-map [(shift left)]    "\C-b")
362        (define-key canna-minibuffer-mode-map [(control left)]  "\C-b")
363        (define-key canna-minibuffer-mode-map [kanji]           " ")
364        (define-key canna-minibuffer-mode-map [(control space)] [(control @)])
365        )
366       (t
367        (define-key canna-minibuffer-mode-map [up]      [?\C-p])
368        (define-key canna-minibuffer-mode-map [S-up]    [?\C-p])
369        (define-key canna-minibuffer-mode-map [C-up]    [?\C-p])
370        (define-key canna-minibuffer-mode-map [down]    [?\C-n])
371        (define-key canna-minibuffer-mode-map [S-down]  [?\C-n])
372        (define-key canna-minibuffer-mode-map [C-down]  [?\C-n])
373        (define-key canna-minibuffer-mode-map [right]   [?\C-f])
374        (define-key canna-minibuffer-mode-map [S-right] [?\C-f])
375        (define-key canna-minibuffer-mode-map [C-right] [?\C-f])
376        (define-key canna-minibuffer-mode-map [left]    [?\C-b])
377        (define-key canna-minibuffer-mode-map [S-left]  [?\C-b])
378        (define-key canna-minibuffer-mode-map [C-left]  [?\C-b])
379        (define-key canna-minibuffer-mode-map [kanji]   [? ])
380        (define-key canna-minibuffer-mode-map [?\C- ]   [?\C-@])
381        ))
382
383 ;;;
384 ;;; \e$B%0%m!<%P%k4X?t$N=q$-BX$(\e(B
385 ;;;
386
387
388 ;; Keyboard quit
389
390 ;(if (not (fboundp 'canna-sys:keyboard-quit))
391 ;    (fset 'canna-sys:keyboard-quit (symbol-function 'keyboard-quit)) )
392
393 ;(defun canna:keyboard-quit ()
394 ;  "See documents for canna-sys:keyboard-quit"
395 ;  (interactive)
396 ;  (if canna:*japanese-mode*
397 ;      (progn
398 ;;      (setq canna:*japanese-mode* nil)
399 ;       (setq canna:*fence-mode* nil)
400 ;       (if (boundp 'disable-undo)
401 ;           (setq disable-undo canna:*fence-mode*))
402 ;       (canna:mode-line-display) ))
403 ;  (canna-sys:keyboard-quit) )
404
405 ;; Abort recursive edit
406
407 ;(if (not (fboundp 'canna-sys:abort-recursive-edit))
408 ;    (fset 'canna-sys:abort-recursive-edit 
409 ;         (symbol-function 'abort-recursive-edit)) )
410
411 ;(defun canna:abort-recursive-edit ()
412 ;  "see documents for canna-sys:abort-recursive-edit"
413 ;  (interactive)
414 ;  (if canna:*japanese-mode*
415 ;      (progn
416 ;       (setq canna:*japanese-mode* nil)
417 ;       (setq canna:*fence-mode* nil)
418 ;       (if (boundp 'disable-undo)
419 ;           (setq disable-undo canna:*fence-mode*))
420 ;       (canna:mode-line-display) ))
421 ;  (canna-sys:abort-recursive-edit) )
422
423 ;; Exit-minibuffer
424
425 (defun canna:exit-minibuffer ()
426   "Exit minibuffer turning off canna Japanese mode.
427 See also document for canna:saved-exit-minibuffer."
428   (interactive)
429   (if canna-initialize-minibuffer-state-when-exit
430       (setq canna:*japanese-mode-in-minibuffer* nil
431             mode-line-canna-mode-in-minibuffer canna:*alpha-mode-string*))
432   )
433
434 (add-hook 'minibuffer-exit-hook 'canna:exit-minibuffer)
435
436 ;; kill-emacs
437
438 (add-hook 'kill-emacs-hook 'canna:finalize)
439
440 ;;;
441 ;;; function for mini-buffer
442 ;;;
443
444 (defun adjust-minibuffer-mode ()
445   (if (eq (current-buffer) (window-buffer (minibuffer-window)))
446       (progn
447         (setq canna:*japanese-mode* canna:*japanese-mode-in-minibuffer*)
448         t)
449     nil))
450
451 ;;;
452 ;;; keyboard input for japanese language
453 ;;;
454
455 (defun canna-functional-insert-command (arg)
456   "Use input character as a key of complex translation input such as
457 kana-to-kanji translation."
458   (interactive "*p")
459   (let ((ch))
460     (if (char-or-char-int-p arg)
461         (setq ch last-command-char)
462       (setq ch (event-to-character last-command-event)))
463     (canna:functional-insert-command2 ch arg) ))
464
465 (defun canna:functional-insert-command2 (ch arg)
466   "This function actually inserts a converted Japanese string."
467   ;; \e$B$3$N4X?t$OM?$($i$l$?J8;z$rF|K\8lF~NO$N$?$a$N%-!<F~NO$H$7$F<h$j07\e(B
468   ;; \e$B$$!"F|K\8lF~NO$NCf4V7k2L$r4^$a$?=hM}$r\e(BEmacs\e$B$N%P%C%U%!$KH?1G$5$;$k\e(B
469   ;; \e$B4X?t$G$"$k!#\e(B
470   (canna:display-candidates (canna-key-proc ch)) )
471
472 (defun canna:delete-last-preedit ()
473   (if (not (zerop canna:*last-kouho*))
474       (progn
475         (if canna-underline
476         ; \e$B$^$:!"B0@-$r>C$9!#\e(B
477             (progn
478               (canna:henkan-attr-off canna:*region-start* canna:*region-end*)
479               (canna:yomi-attr-off canna:*region-start* canna:*region-end*)))
480         (delete-region canna:*region-start* canna:*region-end*)
481         (setq canna:*last-kouho* 0) )))
482
483 (defun canna:insert-fixed (strs)
484   (cond ((> strs 0)
485          (cond ((and canna-kakutei-yomi
486                      (or (null canna-save-undo-text-predicate)
487                          (funcall canna-save-undo-text-predicate
488                                   (cons canna-kakutei-yomi
489                                         canna-kakutei-romaji) )))
490                 (setq canna:*undo-text-yomi*
491                       (cons canna-kakutei-yomi canna-kakutei-romaji))
492                 (set-marker canna:*spos-undo-text* (point))
493 ;;
494 ;; update kbnes
495                 (canna-self-insert-string canna-kakutei-string)
496                 ;; \e$BL$3NDj$NJ8;z$,$J$/!"3NDjJ8;zNs$N:G8e$,JD$83g8L$N\e(B
497                 ;; \e$BN`$@$C$?$H$-$O\e(B blink \e$B$5$;$k!#\e(B
498                 (if (and canna-empty-info
499                          (eq (char-syntax (char-before (point))) ?\)) )
500                     (blink-matching-open))
501
502 ;               (if overwrite-mode
503 ;                   (let ((num strs)
504 ;                         (kanji-compare 128))
505 ;                     (catch 'delete-loop 
506 ;                       (while (> num 0)
507 ;                         (if (eolp)
508 ;                             (throw 'delete-loop nil))
509 ;                         (if (>= (following-char) kanji-compare)
510 ;                             (setq num (1- num)))
511 ;                         (delete-char 1)
512 ;                         (setq num (1- num))))))
513 ;; end kbnes
514 ;               (insert canna-kakutei-string)
515                 (if self-insert-after-hook
516                     (funcall self-insert-after-hook
517                              canna:*region-start* canna:*region-end*))
518                 (canna:do-auto-fill)
519                 (set-marker canna:*epos-undo-text* (point)) )
520                (t
521 ;;
522 ;; update kbnes
523                 (canna-self-insert-string canna-kakutei-string)
524                 ;; \e$BL$3NDj$NJ8;z$,$J$/!"3NDjJ8;zNs$N:G8e$,JD$83g8L$N\e(B
525                 ;; \e$BN`$@$C$?$H$-$O\e(B blink \e$B$5$;$k!#\e(B
526                 (if (and canna-empty-info
527                          (eq (char-syntax (char-before (point))) ?\)) )
528                     (blink-matching-open))
529
530 ;               (if overwrite-mode
531 ;                   (let ((num strs)
532 ;                         (kanji-compare 128))
533 ;                     (catch 'delete-loop 
534 ;                       (while (> num 0)
535 ;                         (if (eolp) 
536 ;                             (throw 'delete-loop nil))
537 ;                         (if (>= (following-char) kanji-compare)
538 ;                             (setq num (1- num)))
539 ;                         (delete-char 1)
540 ;                         (setq num (1- num))))))
541 ;; end kbnes
542 ;               (insert canna-kakutei-string)
543                 (if self-insert-after-hook
544                     (funcall self-insert-after-hook
545                              canna:*region-start* canna:*region-end*))
546                 (canna:do-auto-fill) ))
547          ) ))
548
549 (defun canna:insert-preedit ()
550   (cond ((> canna-henkan-length 0)
551          (set-marker canna:*region-start* (point))
552          (if canna-with-fences
553              (progn
554                (insert "||")
555                (set-marker canna:*region-end* (point))
556                (backward-char 1)
557                ))
558          (insert canna-henkan-string)
559          (if (not canna-with-fences)
560              (set-marker canna:*region-end* (point)) )
561          (if canna-underline
562              (canna:yomi-attr-on canna:*region-start* canna:*region-end*))
563          (setq canna:*last-kouho* canna-henkan-length)
564          ))
565   
566   ;; \e$B8uJdNN0h$G$O6/D4$7$?$$J8;zNs$,B8:_$9$k$b$N$H9M$($i\e(B
567   ;; \e$B$l$k!#6/D4$7$?$$J8;z$O\e(BEmacs\e$B$G$O%+!<%=%k%]%8%7%g%s$K$FI=<(\e(B
568   ;; \e$B$9$k$3$H$H$9$k!#6/D4$7$?$$J8;z$,$J$$$N$G$"$l$P!"%+!<%=%k\e(B
569   ;; \e$B$O0lHV8e$NItJ,\e(B(\e$BF~NO$,9T$o$l$k%]%$%s%H\e(B)\e$B$KCV$$$F$*$/!#\e(B
570   
571   ;; \e$B%+!<%=%k$r0\F0$9$k!#\e(B
572   (if (not canna-underline)
573       (backward-char 
574        (- canna:*last-kouho*
575           ;; \e$B%+!<%=%k0LCV$O!"H?E>I=<(ItJ,$,B8:_$7$J$$$N$G$"$l$P!"\e(B
576           ;; \e$B8uJdJ8;zNs$N:G8e$NItJ,$H$7!"H?E>I=<(ItJ,$,B8:_$9$k$N\e(B
577           ;; \e$B$G$"$l$P!"$=$NItJ,$N;O$a$H$9$k!#\e(B
578           (cond ((zerop canna-henkan-revlen)
579                  canna:*last-kouho*)
580                 (t canna-henkan-revpos) )) )
581     (if (and (> canna-henkan-revlen 0)
582              (> canna-henkan-length 0))
583                                         ; \e$B8uJd$ND9$5$,\e(B0\e$B$G$J$/!"\e(B
584                                         ; \e$BH?E>I=<($ND9$5$,\e(B0\e$B$G$J$1$l$P!"\e(B
585                                         ; \e$B$=$NItJ,$rJQE>I=<($9$k!#\e(B
586         (let ((start (+ canna:*region-start*
587                         (if canna-with-fences 1 0)
588                         canna-henkan-revpos) ))
589           (if canna-underline
590               (canna:henkan-attr-on start 
591                                     (+ start canna-henkan-revlen)))))
592     ) )
593
594 (defun canna:display-candidates (strs)
595   (cond ((stringp strs) ; \e$B%(%i!<$,5/$3$C$?>l9g\e(B
596          (beep)
597          (message strs) )
598         (canna-henkan-string
599          ;; \e$B$b$78uJdI=<($,A0$N7k2L$+$iJQ$o$C$F$$$J$/$J$$$H$-$O\e(B......
600
601          ;; \e$B<h$j9g$($::G=i$OA0$K=q$$$F$*$$$?Cf4V7k2L$r>C$9!#\e(B
602          (canna:delete-last-preedit)
603
604          ;; \e$B3NDj$7$?J8;zNs$,$"$l$P$=$l$rA^F~$9$k!#\e(B
605          (canna:insert-fixed strs)
606
607          ;; \e$B<!$O8uJd$K$D$$$F$N:n6H$G$"$k!#\e(B
608
609          ;; \e$B8uJd$rA^F~$9$k!#8uJd$O=DK@FsK\$K$F64$^$l$k!#\e(B
610          (canna:insert-preedit)
611          ))
612
613   ;; \e$B%b!<%I$rI=$9J8;zNs$,B8:_$9$l$P$=$l$r%b!<%I$H$7$F<h$j07$&!#\e(B
614   (if (stringp canna-mode-string)
615       (mode-line-canna-mode-update canna-mode-string))
616
617   ;; \e$B8uJdI=<($,$J$1$l$P%U%'%s%9%b!<%I$+$iH4$1$k!#\e(B
618   (cond (canna-empty-info (canna:quit-canna-mode)))
619
620   ;; \e$B%_%K%P%C%U%!$K=q$/$3$H$,B8:_$9$k$N$G$"$l$P!"$=$l$r%_%K%P%C%U%!\e(B
621   ;; \e$B$KI=<($9$k!#\e(B
622   (cond (canna-ichiran-string
623          (canna:minibuffer-input canna-ichiran-string
624                                  canna-ichiran-length
625                                  canna-ichiran-revpos
626                                  canna-ichiran-revlen
627                                  strs) )
628         (canna:*cursor-was-in-minibuffer*
629 ;        (select-frame (window-frame (minibuffer-window)))
630          (select-window (minibuffer-window))
631          (set-window-buffer (minibuffer-window)
632                             (get-buffer-create canna:*menu-buffer*))
633          (use-local-map canna-minibuffer-mode-map) ))
634   )
635
636 (defun canna:minibuffer-input (str len revpos revlen nfixed)
637   "Displaying misc informations for kana-to-kanji input."
638
639   ;; \e$B:n6H$r%_%K%P%C%U%!$K0\$9$N$K:]$7$F!"8=:_$N%&%#%s%I%&$N>pJs$rJ]B8\e(B
640   ;; \e$B$7$F$*$/!#\e(B
641   (setq canna:*previous-window* (selected-window))
642 ;  (select-frame (window-frame (minibuffer-window)))
643
644 ;; \e$B<+J,$KMh$kA0$,%_%K%P%C%U%!$+$I$&$+$rJQ?t$K$G$b$$$l$F$*$$$?J}$,$$$$$J$"!#\e(B
645
646   (if (not canna:*cursor-was-in-minibuffer*)
647       (progn
648         ;; \e$B%_%K%P%C%U%!$r%/%j%"$9$k!#\e(B
649 ;       (if (eq canna:*previous-window* (selected-window))
650 ;           (progn
651 ;             (canna:henkan-attr-off (point-min) (point-max))
652 ;             (canna:delete-last-preedit) ))
653
654         ;; \e$B%_%K%P%C%U%!%&%#%s%I%&$K8uJd0lMwMQ$N%P%C%U%!$r3d$jEv$F$k!#\e(B
655         (setq canna:*saved-minibuffer* (window-buffer (minibuffer-window)))
656 ;       (set-window-buffer (minibuffer-window)
657 ;                          (get-buffer-create canna:*menu-buffer*))
658         ;; modified by \e$B<i2,\e(B \e$BCNI'\e(B <morioka@jaist.ac.jp>, 1996/6/7
659         (unless (featurep 'xemacs)
660           ;; \e$B$H$j$"$($:\e(B XEmacs \e$B$G$OF0$+$5$J$$$3$H$K$7$F$*$3$&\e(B (^_^;
661           (setq canna:*saved-redirection* (frame-focus (selected-frame)))
662           (redirect-frame-focus (selected-frame) 
663                                 (window-frame (minibuffer-window)))
664           )
665         ;; \e$B%_%K%P%C%U%!$N%-!<%^%C%W$rJ]B8$7$F$*$/!#\e(B
666         (setq canna:*minibuffer-local-map-backup* (current-local-map))
667         ))
668   (select-window (minibuffer-window))
669   (set-window-buffer (minibuffer-window)
670                      (get-buffer-create canna:*menu-buffer*))
671
672   (use-local-map canna-minibuffer-mode-map)
673
674 ;  (canna:yomi-attr-off (point-min) (point-max) )
675 ;  (canna:henkan-attr-off (point-min) (point-max) )
676   (canna:select-attr-off (point-min) (point-max) )
677   (setq canna:*cursor-was-in-minibuffer* t)
678   (delete-region (point-min) (point-max))
679   (if (not (eq canna:*previous-window* (selected-window)))
680       (setq minibuffer-window-selected nil))
681
682   (insert str)
683
684   ;; \e$B%_%K%P%C%U%!$GH?E>I=<($9$k$Y$-J8;z$N$H$3$m$K%+!<%=%k$r0\F0$9$k!#\e(B
685   (cond ((> revlen 0)
686          (backward-char (- len revpos)) ))
687   ;;(message "%s" (selected-frame)) (sit-for 3)
688   (raise-frame (window-frame (minibuffer-window)))
689 ;  (select-frame (window-frame (minibuffer-window)))
690   (and canna:color-p (not (eobp)) 
691        (canna:select-attr-on (point) 
692                              (save-excursion (forward-char 1) (point))))
693   
694   ;; \e$B%_%K%P%C%U%!$KI=<($9$k$Y$-J8;zNs$,%L%kJ8;zNs$J$N$G$"$l$P!"A0$N%&%#\e(B
695   ;; \e$B%s%I%&$KLa$k!#\e(B
696   (if (or (zerop len) canna-empty-info)
697       (progn
698         (setq canna:*cursor-was-in-minibuffer* nil)
699         (use-local-map canna:*minibuffer-local-map-backup*)
700
701         ;; \e$B%_%K%P%C%U%!%&%#%s%I%&$N%P%C%U%!$r85$KLa$9!#\e(B
702         (set-window-buffer (minibuffer-window) canna:*saved-minibuffer*)
703 ;       (setq canna:*saved-minibuffer* nil)
704         ;; modified by \e$B<i2,\e(B \e$BCNI'\e(B <morioka@jaist.ac.jp>, 1996/6/7
705         (unless (featurep 'xemacs)
706           ;; \e$B$H$j$"$($:\e(B XEmacs \e$B$G$OF0$+$5$J$$$h$&$K$7$F$*$3$&\e(B (^_^;
707           (redirect-frame-focus (window-frame canna:*previous-window*)
708                                 canna:*saved-redirection*)
709           )
710         ; \e$B%_%K%P%C%U%!$GF~NO$7$F$$$?$N$J$i0J2<$b$9$k!#\e(B
711 ;       (if (eq canna:*previous-window* (selected-window))
712 ;           (progn
713 ;             (canna:insert-fixed nfixed)
714 ;             (canna:insert-preedit) ))
715
716         (if (and canna-empty-info (> len 0))
717             (progn
718 ;             (delete-region (point-min) (point-max))
719               (message str) ))
720         (select-window canna:*previous-window*) ))
721   )
722
723 (defun canna-minibuffer-insert-command (arg)
724   "Use input character as a key of complex translation input such as\n\
725 kana-to-kanji translation, even if you are in the minibuffer."
726   (interactive "p")
727   (use-local-map canna:*minibuffer-local-map-backup*)
728   (set-window-buffer (minibuffer-window) canna:*saved-minibuffer*)
729   (select-window canna:*previous-window*)
730   (let ((ch))
731     (if (char-or-char-int-p arg)
732         (setq ch last-command-char)
733       (setq ch (event-to-character last-command-event)))
734     (canna:functional-insert-command2 ch arg) ))
735
736 ;;;
737 ;;; \e$B$+$s$J%b!<%I$N<gLr$O!"<!$N\e(B canna-self-insert-command \e$B$G$"$k!#$3$N\e(B
738 ;;; \e$B%3%^%s%I$OA4$F$N%0%i%U%#%C%/%-!<$K%P%$%s%I$5$l$k!#\e(B
739 ;;;
740 ;;; \e$B$3$N4X?t$G$O!"8=:_$N%b!<%I$,F|K\8lF~NO%b!<%I$+$I$&$+$r%A%'%C%/$7$F!"\e(B
741 ;;; \e$BF|K\8lF~NO%b!<%I$G$J$$$N$G$"$l$P!"%7%9%F%`$N\e(B self-insert-command 
742 ;;; \e$B$r8F$V!#F|K\8lF~NO%b!<%I$G$"$l$P!"%U%'%s%9%b!<%I$KF~$j!"\e(B
743 ;;; canna-functional-insert-command \e$B$r8F$V!#\e(B
744 ;;;
745
746 ;; (if (not (boundp 'MULE)) ; for Nemacs
747 ;;     (defun cancel-undo-boundary ()))
748
749 (defun canna-self-insert-command (arg)
750   "Self insert pressed key and use it to assemble Romaji character."
751   (interactive "*p")
752   (adjust-minibuffer-mode)
753   (if (and canna:*japanese-mode*
754            ;; \e$B%U%'%s%9%b!<%I$@$C$?$i$b$&0lEY%U%'%s%9%b!<%I$KF~$C$?$j$7\e(B
755            ;; \e$B$J$$!#\e(B
756            (not canna:*fence-mode*) )
757       (canna:enter-canna-mode-and-functional-insert)
758     (progn
759       ;; \e$B0J2<$NItJ,$O\e(B egg.el \e$B$N\e(B 3.09 \e$B$N\e(B egg-self-insert-command \e$B$NItJ,$+$i\e(B
760       ;; \e$B%3%T!<$7!"<j$rF~$l$F$$$^$9!#\e(B93.11.5 kon
761       ;; treat continuous 20 self insert as a single undo chunk.
762       ;; `20' is a magic number copied from keyboard.c
763 ;      (if (or                          ;92.12.20 by T.Enami
764 ;          (not (eq last-command 'canna-self-insert-command))
765 ;          (>= canna:*self-insert-non-undo-count* 20))
766 ;         (setq canna:*self-insert-non-undo-count* 1)
767 ;       (cancel-undo-boundary)
768 ;       (setq canna:*self-insert-non-undo-count*
769 ;             (1+ canna:*self-insert-non-undo-count*)))
770       (if (and (eq last-command 'canna-self-insert-command)
771                (> last-command-char ? ))
772           (cancel-undo-boundary))
773       (self-insert-command arg)
774 ;      (if canna-insert-after-hook
775 ;         (run-hooks 'canna-insert-after-hook))
776       (if self-insert-after-hook
777           (if (<= 1 arg)
778               (funcall self-insert-after-hook
779                        (- (point) arg) (point)))
780         (if (= last-command-char ? ) (canna:do-auto-fill))))))
781
782 ;; wire us into pending-delete
783 (put 'canna-self-insert-command 'pending-delete t)
784
785 (defun canna-toggle-japanese-mode ()
786   "Toggle canna japanese mode."
787   (interactive)
788   (let ((in-minibuffer (adjust-minibuffer-mode)))
789     (cond (canna:*japanese-mode*
790            (setq canna:*japanese-mode* nil) 
791            (canna-abandon-undo-info)
792            (setq canna:*use-region-as-henkan-region* nil)
793            (setq canna:*saved-mode-string* mode-line-canna-mode)
794            (mode-line-canna-mode-update canna:*alpha-mode-string*) )
795           (t
796            (setq canna:*japanese-mode* t)
797            (if (fboundp 'canna-query-mode)
798                (let ((new-mode (canna-query-mode)))
799                  (if (string-equal new-mode "")
800                      (setq canna:*kanji-mode-string* canna:*saved-mode-string*)
801                    (setq canna:*kanji-mode-string* new-mode)
802                    )) )
803            (mode-line-canna-mode-update canna:*kanji-mode-string*) ) )
804     (if in-minibuffer
805         (setq canna:*japanese-mode-in-minibuffer* canna:*japanese-mode*)) ))
806
807 (defun canna:initialize ()
808   (let ((init-val nil))
809     (cond (canna:*initialized*) ; initialize \e$B$5$l$F$$$?$i2?$b$7$J$$\e(B
810           (t
811            (setq canna:*initialized* t)
812            (setq init-val (canna-initialize 
813                            (if canna-underline 0 1)
814                            canna-server canna-file))
815            (cond ((car (cdr (cdr init-val)))
816                   (canna:output-warnings (car (cdr (cdr init-val)))) ))
817            (cond ((car (cdr init-val))
818                   (error (car (cdr init-val))) ))
819            ) )
820
821     (if (fboundp 'canna-query-mode)
822         (progn
823           (canna-change-mode canna-mode-alpha-mode)
824           (setq canna:*alpha-mode-string* (canna-query-mode)) ))
825
826     (canna-do-function canna-func-japanese-mode)
827
828     (if (fboundp 'canna-query-mode)
829         (setq canna:*kanji-mode-string* (canna-query-mode)))
830
831     init-val))
832
833 (defun canna:finalize ()
834   (cond ((null canna:*initialized*)) ; initialize \e$B$5$l$F$$$J$+$C$?$i2?$b$7$J$$\e(B
835         (t
836          (setq canna:*initialized* nil)
837          (let ((init-val (canna-finalize)))
838            (cond ((car (cdr (cdr init-val)))
839                   (canna:output-warnings (car (cdr (cdr init-val)))) ))
840            (cond ((car (cdr init-val))
841                   (error (car (cdr init-val))) ))
842            )
843          (message "\e$B!X$+$s$J!Y$N<-=q$r%;!<%V$7$^$9!#\e(B")
844          )))
845
846 (defun canna:enter-canna-mode ()
847   (if (not canna:*initialized*)
848       (progn 
849         (message "\e$B!X$+$s$J!Y$N=i4|2=$r9T$C$F$$$^$9\e(B....")
850         (canna:initialize)
851         (message "\e$B!X$+$s$J!Y$N=i4|2=$r9T$C$F$$$^$9\e(B....done")
852         ))
853   (canna-set-width (- (window-width (minibuffer-window))
854                       (minibuffer-prompt-width)
855                       (if (and display-minibuffer-mode-in-minibuffer
856                                (eq (selected-window) (minibuffer-window)))
857                           (string-width
858                            (let ((new-mode (canna-query-mode)))
859                              (if (string-equal new-mode "")
860                                  canna:*saved-mode-string*
861                                new-mode)))
862                         0)))
863   (setq canna:*local-map-backup* (current-local-map))
864   (setq canna:*fence-mode* t)
865   ;; XEmacs change:
866   ;; (buffer-disable-undo (current-buffer))
867   ;; Original:
868   ;; (if (boundp 'disable-undo)
869   ;;     (setq disable-undo canna:*fence-mode*))
870   (use-local-map canna-mode-map))
871
872 (defun canna:enter-canna-mode-and-functional-insert ()
873   (canna:enter-canna-mode)
874   (setq canna:*use-region-as-henkan-region* nil)
875   (setq unread-command-events (list last-command-event)))
876
877 (defun canna:quit-canna-mode ()
878   (cond (canna:*fence-mode*
879          (use-local-map canna:*local-map-backup*)
880          (setq canna:*fence-mode* nil)
881          (if canna:*exit-japanese-mode*
882              (progn
883                (setq canna:*exit-japanese-mode* nil)
884                (setq canna-mode-string canna:*alpha-mode-string*)
885                (if canna:*japanese-mode*
886                    (canna-toggle-japanese-mode)
887                  (mode-line-canna-mode-update canna:*alpha-mode-string*) )))
888          ;; XEmacs change:
889          ;; (buffer-enable-undo (current-buffer))
890          ;; Original:
891          ;; (if (boundp 'disable-undo)
892          ;;     (setq disable-undo canna:*fence-mode*))
893          ))
894   (set-marker canna:*region-start* nil)
895   (set-marker canna:*region-end* nil)
896   )
897
898 (defun canna-touroku ()
899   "Register a word into a kana-to-kanji dictionary."
900   (interactive)
901 ;  (if canna:*japanese-mode*
902   (if (not canna:*fence-mode*)
903       (progn
904         (setq canna:*exit-japanese-mode* (not canna:*japanese-mode*))
905         (canna:enter-canna-mode)
906         (canna:display-candidates (canna-touroku-string "")) )
907     (beep)
908   ))
909
910 (defun canna-without-newline (start end)
911   (and (not (eq start end))
912        (or 
913         (and (<= end (point))
914              (save-excursion
915                (beginning-of-line)
916                (<= (point) start) ))
917         (and (<= (point) start)
918              (save-excursion 
919                (end-of-line) 
920                (<= end (point)) ))
921         )))
922
923 (defun canna-touroku-region (start end)
924   "Register a word in the selected region into a kana-to-kanji dictionary."
925   (interactive "r")
926   (if (canna-without-newline start end)
927 ;      (if canna:*japanese-mode*
928       (if (not canna:*fence-mode*)
929           (progn
930             (setq canna:*use-region-as-henkan-region* nil)
931             (setq canna:*exit-japanese-mode* (not canna:*japanese-mode*))
932             (canna:enter-canna-mode)
933             (canna:display-candidates
934              (canna-touroku-string (buffer-substring start end))) ))
935     (message "\e$B%j!<%8%g%s$,IT@5$G$9!#%L%k%j!<%8%g%s$+!"2~9T$,4^$^$l$F$$$^$9!#\e(B")
936     ))
937
938 (defun canna-extend-mode ()
939   "To enter an extend-mode of Canna."
940   (interactive "*")
941 ;  (if (and (not (eq (window-frame (minibuffer-window)) (selected-frame)))
942 ;          (not canna:*fence-mode*))
943            ;; \e$B%_%K%P%C%U%!$rJ,N%$7$F$$$k;~$O0l;~E*$K%U%'%s%9%b!<%I$KF~$k\e(B
944            ;; \e$B$=$&$7$J$$$H%a%K%e!<$rA*$Y$J$$\e(B
945            ;; (focus\e$B$,%_%K%P%C%U%!$K9T$+$J$$$+$i\e(B)
946   (if (not canna:*fence-mode*)
947       (progn
948         (setq canna:*exit-japanese-mode* (not canna:*japanese-mode*))
949         (canna:enter-canna-mode)
950         (canna:display-candidates
951          (canna-do-function canna-func-extend-mode) ))
952     (beep)))
953
954 (defun canna-kigou-mode ()
955   "Enter symbol choosing mode."
956   (interactive "*")
957 ;  (if canna:*japanese-mode*
958   (if (not canna:*fence-mode*)
959       (progn
960         (setq canna:*exit-japanese-mode* (not canna:*japanese-mode*))
961         (canna:enter-canna-mode)
962         (canna:display-candidates (canna-change-mode canna-mode-kigo-mode)) )
963     (beep)
964     ))
965
966 (defun canna-hex-mode ()
967   "Enter hex code entering mode."
968   (interactive "*")
969 ;  (if canna:*japanese-mode*
970   (if (not canna:*fence-mode*)
971       (progn
972         (setq canna:*exit-japanese-mode* (not canna:*japanese-mode*))
973         (canna:enter-canna-mode)
974         (canna:display-candidates (canna-change-mode canna-mode-hex-mode)) )
975     (beep)
976     ))
977
978 (defun canna-bushu-mode ()
979   "Enter special mode to convert by BUSHU name."
980   (interactive "*")
981 ;  (if canna:*japanese-mode*
982   (if (not canna:*fence-mode*)
983       (progn
984         (setq canna:*exit-japanese-mode* (not canna:*japanese-mode*))
985         (canna:enter-canna-mode)
986         (canna:display-candidates (canna-change-mode canna-mode-bushu-mode)) )
987     (beep)
988     ))
989
990 (defun canna-reset ()
991   (interactive)
992   (message "\e$B!X$+$s$J!Y$N<-=q$r%;!<%V$7$^$9!#\e(B");
993   (canna:finalize)
994   (message "\e$B!X$+$s$J!Y$N:F=i4|2=$r9T$C$F$$$^$9\e(B....")
995   (canna:initialize)
996   (message "\e$B!X$+$s$J!Y$N:F=i4|2=$r9T$C$F$$$^$9\e(B....done")
997   )
998   
999
1000 (defun canna ()
1001   (interactive)
1002   (message "\e$B!X$+$s$J!Y$r=i4|2=$7$F$$$^$9\e(B....")
1003   (let (init-val)
1004     (cond ((and (fboundp 'canna-initialize) (fboundp 'canna-change-mode) )
1005            
1006            ;; canna \e$B$,;H$($k;~$O<!$N=hM}$r$9$k!#\e(B
1007            
1008            ;; \e$BG[?'@_Dj\e(B (by yuuji@ae.keio.ac.jp)
1009            (setq canna:color-p (and canna-use-color 
1010                                     window-system 
1011                                     (x-display-color-p)))
1012            ;;\e$B%+%i!<$N;~\e(Bunderline\e$B%b!<%I$HF1$8>uBV$G=i4|2=$9$kI,MW$,$"$k\e(B
1013            (setq canna-underline (or canna:color-p canna-underline))
1014            (cond 
1015             (canna:color-p
1016              (setq canna:attr-mode
1017                    (cond
1018                     ((or (and (boundp 'hilit-background-mode)
1019                               (eq hilit-background-mode 'dark))
1020                          (string-match
1021                           "on\\|t"
1022                           (or (if (featurep 'xemacs)
1023                                   (x-get-resource "ReverseVideo"
1024                                                   "reverseVideo" 'string)
1025                                 (x-get-resource "ReverseVideo" "reverseVideo"))
1026                               "")))
1027                      'reverse)  ;\e$BH?E>$7$F$$$k$J$i\e(B 'reverse
1028                     (t 'normal)))
1029              (setq canna:attr-yomi
1030                    (if (listp canna-use-color)
1031                        (car canna-use-color)
1032                      (cdr (assq canna:attr-mode 
1033                                 (assq 'yomi canna:attribute-alist)))))
1034              (setq canna:attr-taishou
1035                    (if (listp canna-use-color)
1036                        (car (cdr canna-use-color))
1037                      (setq canna:attr-taishou
1038                            (cdr (assq 
1039                                  canna:attr-mode
1040                                  (assq 'taishou canna:attribute-alist))))))
1041              (setq canna:attr-select
1042                    (if (listp canna-use-color)
1043                        (car (cdr (cdr canna-use-color)))
1044                      (setq canna:attr-select
1045                            (cdr (assq canna:attr-mode
1046                                       (assq 'select canna:attribute-alist))))))
1047              ;;\e$B?'$E$1MQ\e(Bface\e$B$N:n@.\e(B
1048              (mapcar
1049               (function
1050                (lambda (face)
1051                  (let* ((color (symbol-value
1052                                 (intern (concat "canna:" (symbol-name face)))))
1053                         backp)
1054                    (make-face face)
1055                    (if (stringp color)
1056                        (progn
1057                          (setq backp (string-match "/" color))
1058                          (set-face-foreground
1059                           face (substring color 0 backp))
1060                          (if backp 
1061                              (set-face-background
1062                               face (substring color (1+ backp)))))
1063                      (copy-face color face)))))
1064               '(attr-yomi attr-taishou attr-select))
1065              ))
1066            ;;\e$BG[?'@_Dj=*N;\e(B
1067            
1068            ;; \e$B!X$+$s$J!Y%7%9%F%`$N=i4|2=\e(B
1069            
1070            (setq init-val (canna:initialize))
1071            
1072            ;; \e$B%-!<$N%P%$%s%G%#%s%0\e(B
1073            
1074            (let ((ch 32))
1075              (while (< ch 127)
1076                (define-key global-map (make-string 1 ch) 'canna-self-insert-command)
1077                (setq ch (1+ ch)) ))
1078
1079            (cond
1080             ;; #### I'm just guessing that this should come before the
1081             ;;      init-val setting
1082             ;; if registered with LEIM, no-op
1083             ((featurep 'canna-leim) t)
1084             ;; check to see if an X resource or the like is available in
1085             ;; init-val
1086             ((let ((keys (car init-val)) (ok nil))
1087                     (while keys
1088                       (cond ((< (car keys) 128)
1089                              (global-set-key
1090                               (make-string 1 (car keys))
1091                               'canna-toggle-japanese-mode)
1092                              (setq ok t) ))
1093                       (setq keys (cdr keys))
1094                       ) ok))
1095             ;; \e$B%G%U%)%k%H$N@_Dj\e(B
1096             ;; Since XEmacs provides canna-leim.el, we should leave this
1097             ;; as is.
1098             (t (global-set-key "\C-o" 'canna-toggle-japanese-mode) ))
1099
1100            ;; #### should these global bindings be conditional on LEIM?
1101            ;;      LEIM doesn't use kanji key yet AFAIK, so leave them.
1102            (if (not (keymapp (global-key-binding "\e[")))
1103                (global-unset-key "\e[") )
1104            (global-set-key "\e[210z" 'canna-toggle-japanese-mode) ; XFER
1105            (define-key global-map [kanji] 'canna-toggle-japanese-mode)
1106            (if canna-do-keybind-for-functionkeys
1107                (progn
1108                  (global-set-key "\e[28~" 'canna-extend-mode) ; HELP on EWS4800
1109                  (global-set-key "\e[2~"  'canna-kigou-mode)  ; INS  on EWS4800
1110                  (global-set-key "\e[11~" 'canna-kigou-mode)
1111                  (global-set-key "\e[12~" 'canna-hex-mode)
1112                  (global-set-key "\e[13~" 'canna-bushu-mode)
1113                  (define-key global-map [help] 'canna-extend-mode)
1114                  (define-key global-map [insert] 'canna-kigou-mode)
1115                  (define-key global-map [f1] 'canna-kigou-mode)
1116                  (define-key global-map [f2] 'canna-hex-mode)
1117                  (define-key global-map [f3] 'canna-bushu-mode)
1118                  ))
1119
1120            (if canna-use-space-key-as-henkan-region
1121                (progn
1122                  (global-set-key "\C-@" 'canna-set-mark-command)
1123                  ;; X Window \e$B$O\e(B C-@ \e$B$H\e(B C-SPC \e$B$r6hJL$9$k$N$G!"$3$l$,I,MW!#\e(B
1124                  (global-set-key [?\C-\ ] 'canna-set-mark-command)
1125                  (global-set-key " " 'canna-henkan-region-or-self-insert) ))
1126
1127          ;; \e$B%b!<%I9T$N:n@.\e(B
1128
1129            (canna:create-mode-line)
1130            (mode-line-canna-mode-update canna:*alpha-mode-string*)
1131
1132          ;; \e$B%7%9%F%`4X?t$N=q$-BX$(\e(B
1133
1134 ;          (fset 'abort-recursive-edit 
1135 ;                (symbol-function 'canna:abort-recursive-edit))
1136 ;          (fset 'keyboard-quit 
1137 ;                (symbol-function 'canna:keyboard-quit))
1138
1139            )
1140
1141           ((fboundp 'canna-initialize)
1142            (beep)
1143            (with-output-to-temp-buffer "*canna-warning*"
1144              (princ "\e$B$3$N\e(B Mule \e$B$G$O\e(B new-canna \e$B$,;H$($^$;$s\e(B")
1145              (terpri)
1146              (print-help-return-message)) )
1147
1148           (t ; \e$B!X$+$s$J!Y%7%9%F%`$,;H$($J$+$C$?;~$N=hM}\e(B
1149            (beep)
1150            (with-output-to-temp-buffer "*canna-warning*"
1151              (princ "\e$B$3$N\e(B Mule \e$B$G$O\e(B canna \e$B$,;H$($^$;$s\e(B")
1152              (terpri)
1153              (print-help-return-message))
1154            ))
1155     (message "\e$B!X$+$s$J!Y$r=i4|2=$7$F$$$^$9\e(B....done")
1156     ) )
1157
1158 ;;;
1159 ;;; auto fill controll (from egg)
1160 ;;;
1161
1162 (defun canna:do-auto-fill ()
1163   (if (and auto-fill-function (not buffer-read-only)
1164            (> (current-column) fill-column))
1165       (let ((ocolumn (current-column)))
1166         (funcall auto-fill-function)
1167         (while (and (< fill-column (current-column))
1168                     (< (current-column) ocolumn))
1169           (setq ocolumn (current-column))
1170           (funcall auto-fill-function)))))
1171
1172 (defun canna:output-warnings (mesg)
1173   (with-output-to-temp-buffer "*canna-warning*"
1174     (while mesg
1175       (princ (car mesg))
1176       (terpri)
1177       (setq mesg (cdr mesg)) )
1178     (print-help-return-message)))
1179
1180 (defun canna-undo (&optional arg)
1181   (interactive "*p")
1182   (if (and canna:*undo-text-yomi*
1183            (eq (current-buffer) (marker-buffer canna:*spos-undo-text*))
1184 ;          (canna-without-newline canna:*spos-undo-text*
1185 ;                                 canna:*epos-undo-text*)
1186            )
1187       (progn
1188         (message "\e$BFI$_$KLa$7$^$9!*\e(B")
1189 ;       (switch-to-buffer (marker-buffer canna:*spos-undo-text*))
1190         (goto-char canna:*spos-undo-text*)
1191         (delete-region canna:*spos-undo-text*
1192                        canna:*epos-undo-text*)
1193
1194         (if (null canna:*japanese-mode*)
1195             (progn
1196               (setq canna:*exit-japanese-mode* t) ))
1197 ;             (canna-toggle-japanese-mode) ))
1198         (if (not canna:*fence-mode*)
1199             ;; \e$B%U%'%s%9%b!<%I$@$C$?$i$b$&0lEY%U%'%s%9%b!<%I$KF~$C$?$j$7\e(B
1200             ;; \e$B$J$$!#\e(B
1201             (canna:enter-canna-mode) )
1202         (canna:display-candidates 
1203          (let ((texts (canna-store-yomi (car canna:*undo-text-yomi*)
1204                                         (cdr canna:*undo-text-yomi*) )) )
1205            (cond (canna-undo-hook
1206                   (funcall canna-undo-hook))
1207                  (t texts) )))
1208         (canna-abandon-undo-info)
1209         )
1210     (canna-abandon-undo-info)
1211     (undo arg) ))
1212
1213 (defun canna-abandon-undo-info ()
1214   (interactive)
1215   (setq canna:*undo-text-yomi* nil)
1216   (set-marker canna:*spos-undo-text* nil)
1217   (set-marker canna:*epos-undo-text* nil) )
1218
1219 (defun canna-henkan-region (start end)
1220   "Convert a text which is indicated by region into a kanji text."
1221   (interactive "*r")
1222   (if (null canna:*japanese-mode*)
1223       (progn
1224         (setq canna:*exit-japanese-mode* t) ))
1225 ;       (canna-toggle-japanese-mode) ))
1226   (let ((res nil))
1227     (setq res (canna-store-yomi (buffer-substring start end)))
1228     (delete-region start end)
1229     (canna:enter-canna-mode)
1230     (if (fboundp 'canna-do-function)
1231         (setq res (canna-do-function canna-func-henkan)))
1232     (canna:display-candidates res) ))
1233
1234 ;;;
1235 ;;; \e$B%^!<%/%3%^%s%I!$\e(Bcanna-henkan-region-or-self-insert \e$B$G;H$&$+$b\e(B
1236 ;;;
1237
1238 (defun canna-set-mark-command (arg)
1239   "Set mark, also set mark as HENKAN region if in Japanese mode."
1240   (interactive "P")
1241   (set-mark-command arg)
1242   (if canna:*japanese-mode*
1243       (progn
1244         (setq canna:*use-region-as-henkan-region* t)
1245         (message "Mark set(\e$BJQ49NN0h3+;O\e(B)") )))
1246
1247 (defun canna-henkan-region-or-self-insert (arg)
1248   "Do kana-to-kanji convert region if HENKAN region is defined, else insert."
1249   (interactive "*p")
1250   (if (and canna:*use-region-as-henkan-region*
1251 ;          (< (mark) (point))
1252 ;          (not (save-excursion (beginning-of-line) (< (mark) (point)))) )
1253            (canna-without-newline (region-beginning) (region-end)))
1254       (progn
1255         (setq canna:*use-region-as-henkan-region* nil)
1256         (canna-henkan-region (region-beginning) (region-end)))
1257     (canna-self-insert-command arg) ))
1258
1259 ;;
1260 ;; for C-mode
1261 ;;
1262
1263 (defun canna-electric-c-terminator (arg)
1264   (interactive "P")
1265   (if canna:*japanese-mode*
1266       (canna-self-insert-command arg)
1267     (electric-c-terminator arg) ))
1268
1269 (defun canna-electric-c-semi (arg)
1270   (interactive "P")
1271   (if canna:*japanese-mode*
1272       (canna-self-insert-command arg)
1273     (electric-c-semi arg) ))
1274
1275 (defun canna-electric-c-brace (arg)
1276   (interactive "P")
1277   (if canna:*japanese-mode*
1278       (canna-self-insert-command arg)
1279     (electric-c-brace arg) ))
1280
1281 (defun canna-c-mode-hook ()
1282   (define-key c-mode-map "{" 'canna-electric-c-brace)
1283   (define-key c-mode-map "}" 'canna-electric-c-brace)
1284   (define-key c-mode-map ";" 'canna-electric-c-semi)
1285   (define-key c-mode-map ":" 'canna-electric-c-terminator) )
1286
1287 (defun canna-set-fence-mode-format (fence sep underline)
1288   (setq canna-with-fences fence)
1289   (canna-set-bunsetsu-kugiri sep)
1290   (setq canna-underline underline)
1291 )
1292
1293 ;; \e$B%j!<%8%g%s$K$"$k%m!<%^;z$r!X$+$s$J!Y$K?)$o$9!#\e(B
1294 ;; \e$B7k2L$H$7$F!"!X$+$s$J!Y$NFI$_%b!<%I$K$J$k!#\e(B
1295 ;; \e$B%j!<%8%g%s$KB8:_$7$F$$$k6uGrJ8;z$H@)8fJ8;z$O<N$F$i$l$k!#\e(B
1296
1297 (defun canna-rk-region (start end)
1298   "Convert region into kana."
1299   (interactive "*r")
1300   (let ((str nil) (len 0) (i 0) (res 0))
1301     (setq str (buffer-substring start end))
1302     (setq len (length str))
1303     (while (< i len)
1304       (let ((ch (elt str i)))
1305         (if (> ch ? )
1306             (setq res (canna-do-function canna-func-functional-insert ch)) ))
1307       (setq i (1+ i)) )
1308     res))
1309
1310 (defun canna-rk-trans-region (start end)
1311   "Insert alpha-numeric string as it is sent from keyboard."
1312   (interactive "*r")
1313   (let ((res))
1314     (setq res (canna-rk-region start end))
1315     (delete-region start end)
1316     (if (null canna:*japanese-mode*)
1317         (progn
1318           (setq canna:*exit-japanese-mode* t) ))
1319     (setq res (canna-do-function canna-func-henkan))
1320     (canna:enter-canna-mode)
1321     (canna:display-candidates res) ))
1322
1323 ;; \e$B%+!<%=%k$N:8$K$"$k\e(B arg \e$B%o!<%I$N%m!<%^;z$r!X$+$s$J!Y$K?)$o$9!#\e(B
1324
1325 (defun canna-rk-trans (arg)
1326   (interactive "*p")
1327   (let ((po (point)))
1328     (skip-chars-backward "-a-zA-Z.,?!~")
1329     (if (not (eq (point) po))
1330         (canna-rk-trans-region (point) po) )))
1331
1332 (defun canna-henkan-kakutei-and-self-insert (arg)
1333   (interactive "*p")
1334   (if canna:*japanese-mode*
1335       (canna-functional-insert-command arg)
1336     (progn
1337       (setq unread-command-events (list last-command-event))
1338       (canna-kakutei-to-basic-stat)) ))
1339
1340 (defun canna-kakutei-to-basic-stat ()
1341   (let ((res 0)
1342         (kakutei canna-henkan-string))
1343     (while (not canna-empty-info)
1344 ;      (setq res (canna-key-proc ?\C-m)))
1345       (setq res (canna-do-function canna-func-kakutei)))
1346     (setq canna-kakutei-string kakutei)
1347     (canna:display-candidates (length canna-kakutei-string))
1348     (if (not canna:*japanese-mode*)
1349         (mode-line-canna-mode-update canna:*alpha-mode-string*))
1350     ))
1351
1352 (defun canna-minibuffer-henkan-kakutei-and-self-insert (arg)
1353   (interactive "p")
1354   (set-window-buffer (minibuffer-window) canna:*saved-minibuffer*)
1355   (select-window canna:*previous-window*)
1356   (if canna:*japanese-mode*
1357       (canna:functional-insert-command2 last-command-event arg)
1358     (progn
1359       (setq unread-command-events (list last-command-event))
1360       (canna-kakutei-to-basic-stat)) ))
1361
1362 (defun canna-setup-for-being-boiled ()
1363   (let ((ch (1+ ? )))
1364     (while (< ch 127)
1365       (define-key canna-mode-map (make-string 1 ch) 'canna-henkan-kakutei-and-self-insert)
1366       (define-key canna-minibuffer-mode-map (make-string 1 ch) 'canna-minibuffer-henkan-kakutei-and-self-insert)
1367       (setq ch (1+ ch)))))
1368
1369 (defvar rK-trans-key "\C-j" "for `boil' only")
1370 (make-variable-buffer-local 'rK-trans-key)
1371
1372 (defun canna-boil ()
1373   "`canna-boil' cooks `canna' as if `boil' does for `egg'."
1374   (interactive)
1375   (canna-setup-for-being-boiled)
1376   (local-set-key rK-trans-key 'canna-rk-trans)
1377   (message "boiled"))
1378
1379 ;;
1380 ;; \e$B?'$E$1$N$?$a$N4X?t\e(B
1381 ;;
1382 (defun canna:yomi-attr-on (start end)
1383   (if (overlayp canna:*yomi-overlay*)
1384       (move-overlay canna:*yomi-overlay* start end)
1385     (overlay-put (setq canna:*yomi-overlay* (make-overlay start end nil nil t))
1386                  'face 
1387                  (if canna:color-p 'attr-yomi 'underline))
1388     )
1389   )
1390
1391 (defun canna:yomi-attr-off (start end);
1392   (and (overlayp canna:*yomi-overlay*) 
1393        (delete-overlay canna:*yomi-overlay*)
1394        )
1395   )
1396
1397 (defun canna:henkan-attr-on (start end)
1398   (if (overlayp canna:*henkan-overlay*)
1399       (move-overlay canna:*henkan-overlay* start end)
1400     (overlay-put (setq canna:*henkan-overlay*
1401                        (make-overlay start end nil nil t))
1402                  'face 
1403                  (if canna:color-p 'attr-taishou 'region))
1404         )
1405   )
1406
1407 (defun canna:henkan-attr-off (start end)
1408   (and (overlayp canna:*henkan-overlay*)
1409        (delete-overlay canna:*henkan-overlay*)
1410        )
1411   )
1412
1413 (defun canna:select-attr-on (start end)
1414   (if (overlayp canna:*select-overlay*)
1415       (move-overlay canna:*select-overlay* start end)
1416     (overlay-put (setq canna:*select-overlay*
1417                        (make-overlay start end nil nil t))
1418                  'face 
1419                  'attr-select))
1420   )
1421
1422 (defun canna:select-attr-off (start end)
1423   (and (overlayp canna:*select-overlay*)
1424        (delete-overlay canna:*select-overlay*)
1425        )
1426   )
1427
1428
1429 (provide 'canna)
1430
1431 ;;; canna.el ends here