1 ;;; egg/wnn.el --- WNN Support (high level interface) in Egg
2 ;;; Input Method Architecture
4 ;; Copyright (C) 1997, 1998 Mule Project, Powered by Electrotechnical
6 ;; Project Leader: Satoru Tomura <tomura@etl.go.jp>
8 ;; Author: NIIBE Yutaka <gniibe@mri.co.jp>
9 ;; KATAYAMA Yoshio <kate@pfu.co.jp> ; Korean, Chinese support.
11 ;; Maintainer: NIIBE Yutaka <gniibe@mri.co.jp>
13 ;; This file is part of EGG.
15 ;; EGG is free software; you can redistribute it and/or modify
16 ;; it under the terms of the GNU General Public License as published by
17 ;; the Free Software Foundation; either version 2, or (at your option)
20 ;; EGG is distributed in the hope that it will be useful,
21 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
22 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 ;; GNU General Public License for more details.
25 ;; You should have received a copy of the GNU General Public License
26 ;; along with GNU Emacs; see the file COPYING. If not, write to the
27 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
28 ;; Boston, MA 02111-1307, USA.
37 "Wnn interface for Tamagotchy"
40 (defconst wnn-support-languages '(Japanese Chinese-GB Chinese-CNS Korean))
43 (defmacro WNN-const (c)
44 (cond ((eq c 'BUN_SENTOU) -1)
49 ((eq c 'HINDO_NOP) -2)
50 ((eq c 'HINDO_INC) -3))))
52 (defconst wnn-conversion-backend
56 wnn-get-bunsetsu-converted
57 wnn-get-bunsetsu-source
59 wnn-get-number-of-candidates
60 wnn-get-current-candidate-number
61 wnn-get-all-candidates
63 wnn-change-bunsetsu-length
65 wnn-start-reverse-conversion
70 ;; <env> ::= [ <proc> <env-id> <server-type> <dic-set> <rev-flag>
71 ;; <daibunsetsu-info> ]
73 (defsubst wnnenv-create (proc env-id server-type dic-set rev-flag)
74 (vector proc env-id server-type dic-set rev-flag nil))
76 (defsubst wnnenv-get-proc (env)
79 (defsubst wnnenv-get-env-id (env)
82 (defsubst wnnenv-get-server-type (env)
85 (defsubst wnnenv-get-dictionary-set (env)
88 (defsubst wnnenv-get-reverse-flag (env)
91 (defsubst wnnenv-get-daibunsetsu-info (env)
93 (defsubst wnnenv-set-daibunsetsu-info (env d)
96 ;; <bunsetsu> ::= [ <env> <end> <start> <jiritsugo-end> <dic-no>
97 ;; <entry> <freq> <right-now> <hinshi> <status>
98 ;; <status-backward> <kangovect> <evaluation>
100 ;; <converted> <yomi> <fuzokugo>
101 ;; <zenkouho> <freq-down>
104 (defsubst wnn-bunsetsu-create (e end start jiritsugo-end dic-no entry freq
105 right-now hinshi status status-backward
106 kangovect evaluation)
107 (vector e end start jiritsugo-end dic-no entry freq right-now
108 hinshi status status-backward kangovect evaluation
109 nil nil nil nil nil nil))
111 (defsubst wnn-bunsetsu-get-env (bunsetsu)
114 (defsubst wnn-bunsetsu-get-converted (bunsetsu)
116 (defsubst wnn-bunsetsu-set-converted (bunsetsu converted)
117 (aset bunsetsu 13 converted))
119 (defsubst wnn-bunsetsu-get-hinshi (bunsetsu)
122 (defsubst wnn-bunsetsu-get-dic-no (bunsetsu)
125 (defsubst wnn-bunsetsu-get-entry (bunsetsu)
128 (defsubst wnn-bunsetsu-get-right-now (bunsetsu)
131 (defsubst wnn-bunsetsu-get-yomi (bunsetsu)
133 (defsubst wnn-bunsetsu-set-yomi (bunsetsu yomi)
134 (aset bunsetsu 14 yomi))
136 (defsubst wnn-bunsetsu-get-fuzokugo (bunsetsu)
138 (defsubst wnn-bunsetsu-set-fuzokugo (bunsetsu fuzokugo)
139 (aset bunsetsu 15 fuzokugo))
141 (defsubst wnn-bunsetsu-get-zenkouho (bunsetsu)
143 (defsubst wnn-bunsetsu-set-zenkouho (bunsetsu z)
144 (aset bunsetsu 16 z))
146 (defsubst wnn-bunsetsu-get-freq-down (bunsetsu)
148 (defsubst wnn-bunsetsu-set-freq-down (bunsetsu d)
149 (aset bunsetsu 17 d))
151 (defsubst wnn-bunsetsu-get-zenkouho-pos (bunsetsu)
153 (defsubst wnn-bunsetsu-set-zenkouho-pos (bunsetsu zp)
154 (aset bunsetsu 18 zp))
156 (defvar wnn-environments nil
157 "Environment for WNN kana-kanji conversion")
159 (defcustom wnn-jserver nil "jserver host list" :group 'wnn :type 'string)
160 (defcustom wnn-cserver nil "cserver host list" :group 'wnn :type 'string)
161 (defcustom wnn-tserver nil "tserver host list" :group 'wnn :type 'string)
162 (defcustom wnn-kserver nil "kserver host list" :group 'wnn :type 'string)
164 (defcustom wnn-jport 22273 "jserver port number" :group 'wnn :type 'integer)
165 (defcustom wnn-cport 22289 "cserver port number" :group 'wnn :type 'integer)
166 (defcustom wnn-tport 22321 "tserver port number" :group 'wnn :type 'integer)
167 (defcustom wnn-kport 22305 "kserver port number" :group 'wnn :type 'integer)
169 ;; The port number should be initialized from $WNNLIB/serverdefs by wnn-init
170 (defconst wnn-server-info-list
171 ;; language locale server port stream coding-system hostname
172 '((Japanese "ja_JP" jserver wnn-jport "Wnn" fixed-euc-jp wnn-jserver)
173 (Chinese-GB "zh_CN" cserver wnn-cport "cWnn" fixed-euc-cn wnn-cserver)
174 (Chinese-CNS "zh_TW" tserver wnn-tport "tWnn" fixed-euc-tw wnn-tserver)
175 (Korean "ko_KR" kserver wnn-kport "kWnn" fixed-euc-kr wnn-kserver)))
177 (defsubst wnn-server-get-info (lang)
178 (assq (or lang its-current-language) wnn-server-info-list))
180 (defsubst wnn-server-language (info)
183 (defsubst wnn-server-locale (info)
186 (defsubst wnn-server-type (info)
189 (defsubst wnn-server-port (info)
190 (symbol-value (nth 3 info)))
192 (defsubst wnn-server-stream-name (info)
195 (defsubst wnn-server-buffer-name (info)
196 (concat " *" (wnn-server-stream-name info) "*"))
198 (defsubst wnn-server-coding-system (info)
201 (defsubst wnn-server-hostname (info)
202 (symbol-value (nth 6 info)))
207 (defun wnn-start-conversion (yomi &optional language dic-set reverse)
208 "Convert YOMI string to kanji, and enter conversion mode.
209 Return the list of bunsetsu."
210 (let ((server-info (wnn-server-get-info language)))
212 (let* ((env (wnn-get-environment server-info dic-set reverse))
213 (result (wnnrpc-renbunsetsu-conversion env yomi
214 (WNN-const BUN_SENTOU) "")))
215 (wnnenv-set-daibunsetsu-info env (car result))
217 (signal 'lang-not-supported))))
219 (defun wnn-start-reverse-conversion (yomi &optional language dic-set)
220 (wnn-start-conversion yomi language dic-set t))
222 (defun wnn-get-bunsetsu-converted (bunsetsu)
223 (concat (wnn-bunsetsu-get-converted bunsetsu)
224 (wnn-bunsetsu-get-fuzokugo bunsetsu)))
226 ;; WNN-UNIQ-CANDIDATES
228 ;; Here, IMNSHO, WNN is broken.
229 ;; WNN must/should return unique one. The word is representative
230 ;; among possible words with same string literal.
232 ;; With no bunsetsu information to users, users have to chose
233 ;; the word based on the string literal only.
234 ;; How we could update frequency?
236 ;; We'll modify WNN in future.
239 (defun wnn-uniq-candidates (bunsetsu bunsetsu-list)
240 (let ((hash-table (make-vector 31 0)) ; XXX why 31?
243 (n 0) sym0 result p b sym)
244 (setq sym0 (intern (wnn-get-bunsetsu-converted bunsetsu) hash-table))
248 sym (intern (wnn-get-bunsetsu-converted b) hash-table))
249 (if (null (boundp sym)) ; new one
250 (let ((bl (cons b nil)))
253 (wnn-bunsetsu-set-zenkouho-pos bunsetsu (setq n i)))
255 (setq p (setcdr p bl))
256 (setq result (setq p bl)))
258 (wnn-bunsetsu-set-zenkouho bunsetsu result)
261 (defun wnn-list-candidates (bunsetsu prev-bunsetsu)
262 (let* ((candidates (wnn-bunsetsu-get-zenkouho bunsetsu))
263 (yomi (concat (wnn-bunsetsu-get-yomi bunsetsu)
264 (wnn-bunsetsu-get-fuzokugo bunsetsu)))
265 (converted (concat (wnn-bunsetsu-get-converted bunsetsu)
266 (wnn-bunsetsu-get-fuzokugo bunsetsu)))
267 (env (wnn-bunsetsu-get-env bunsetsu))
271 ;; We have the candidates already. Return the current position.
272 (wnn-bunsetsu-get-zenkouho-pos bunsetsu)
273 (if (null prev-bunsetsu)
276 (setq prev-hinshi (wnn-bunsetsu-get-hinshi prev-bunsetsu)
277 prev-fuzokugo (wnn-bunsetsu-get-fuzokugo prev-bunsetsu)))
279 (wnnrpc-get-bunsetsu-candidates env yomi
280 prev-hinshi prev-fuzokugo))
281 (wnn-uniq-candidates bunsetsu candidates))))
283 (defun wnn-get-number-of-candidates (bunsetsu)
284 (let ((l (wnn-bunsetsu-get-zenkouho bunsetsu)))
289 (defun wnn-get-current-candidate-number (bunsetsu)
290 (wnn-bunsetsu-get-zenkouho-pos bunsetsu))
292 (defun wnn-get-all-candidates (bunsetsu)
293 (let* ((l (wnn-bunsetsu-get-zenkouho bunsetsu))
294 (result (cons nil nil))
298 (let ((candidate (car l)))
299 (setcar r (concat (wnn-bunsetsu-get-converted candidate)
300 (wnn-bunsetsu-get-fuzokugo candidate)))
301 (if (null (setq l (cdr l)))
303 (setq r (setcdr r (cons nil nil)))))))
306 (defun wnn-decide-candidate (bunsetsu candidate-pos)
307 (let* ((candidate-list (wnn-bunsetsu-get-zenkouho bunsetsu))
308 (candidate (nth candidate-pos candidate-list)))
309 (wnn-bunsetsu-set-zenkouho candidate candidate-list)
310 (wnn-bunsetsu-set-zenkouho-pos candidate candidate-pos)
315 (defun wnn-change-bunsetsu-length (b0 b1 b2 len)
317 (wnn-get-bunsetsu-source b1)
318 (if b2 (wnn-get-bunsetsu-source b2))))
319 (env (wnn-bunsetsu-get-env b1))
320 yomi1 yomi2 prev-hinshi prev-fuzokugo
325 (setq prev-hinshi (wnn-bunsetsu-get-hinshi b0)
326 prev-fuzokugo (wnn-bunsetsu-get-fuzokugo b0)))
327 (setq yomi1 (substring yomi 0 len)
328 yomi2 (substring yomi len))
330 (car (wnnrpc-tanbunsetsu-conversion env yomi1
331 prev-hinshi prev-fuzokugo)))
333 (wnn-bunsetsu-set-freq-down bunsetsu1
334 (or (wnn-bunsetsu-get-freq-down b1)
338 (if (< 0 (length yomi2))
340 (cdr (wnnrpc-renbunsetsu-conversion
342 (wnn-bunsetsu-get-hinshi bunsetsu1)
343 (wnn-bunsetsu-get-fuzokugo bunsetsu1))))
344 (setq bunsetsu2 nil))
346 (append (list bunsetsu1) bunsetsu2)
350 (defun wnn-get-bunsetsu-source (bunsetsu)
351 (concat (wnn-bunsetsu-get-yomi bunsetsu)
352 (wnn-bunsetsu-get-fuzokugo bunsetsu)))
354 (defun wnn-end-conversion (bunsetsu-info-list abort)
357 (let ((env (wnn-bunsetsu-get-env (car bunsetsu-info-list))))
358 (wnn-update-frequency env bunsetsu-info-list)
359 (wnnenv-set-daibunsetsu-info env nil))))
361 (defvar wnn-sticky-environment-flag nil
362 "*Flag which specifies sticky environment.")
364 (defmacro wnn-for-each-environment (lang env &rest body)
365 `(let* ((server-info (wnn-server-get-info ,lang))
366 (server-type (wnn-server-type server-info))
367 (env-list wnn-environments))
370 (let ((,env (car env-list)))
372 (setq env-list (cdr env-list))))))
375 (let ((l wnn-support-languages))
377 (wnn-fini-lang (car l))
380 (defun wnn-fini-lang (lang &optional save-only)
381 (let* ((server-info (wnn-server-get-info lang))
382 (server-type (wnn-server-type server-info))
384 new-env-list del-list env proc)
387 (message "%s
\e$B$NIQEY>pJs!&<-=q>pJs$rB`Hr$7$F$$$^$9
\e(B"
388 (wnn-server-stream-name server-info))
391 (if (eq (wnnenv-get-server-type env) server-type)
394 (wnn-save-dictionaries env)
397 (setq del-list (nconc del-list (list env)))
398 (if wnn-sticky-environment-flag
399 (wnnrpc-make-env-sticky env)
400 (wnnrpc-make-env-unsticky env))
401 (wnnrpc-disconnect env))))
403 (setq new-env-list (nconc new-env-list (list env))))
405 (message "%s
\e$B$NIQEY>pJs!&<-=q>pJs$rB`Hr$7$^$7$?
\e(B"
406 (wnn-server-stream-name server-info))
409 (setq proc (and del-list (wnnenv-get-proc (car del-list))))
410 (if (and proc (eq (process-status proc) 'open))
413 (kill-buffer (process-buffer proc))))
414 (setq wnn-environments new-env-list)))))))
416 (defun wnn-close (lang)
417 (interactive (list (wnn-read-active-lang)))
419 (setq lang (list lang)))
421 (wnn-fini-lang (car lang))
422 (setq lang (cdr lang))))
424 (defun wnn-dictionary-save (lang)
425 (interactive (list (wnn-read-active-lang)))
427 (setq lang (list lang)))
429 (wnn-fini-lang (car lang) t)
430 (setq lang (cdr lang))))
432 (defun wnn-read-active-lang ()
433 (let ((completion-ignore-case t)
434 (env wnn-environments)
435 langs server server-list)
437 (setq server (wnnenv-get-server-type (car env))
439 (if (null (member server server-list))
440 (setq server-list (cons server server-list))))
441 (setq langs (delete nil
442 (mapcar (lambda (info)
443 (if (memq (wnn-server-type info) server-list)
444 (wnn-server-language info)))
445 wnn-server-info-list)))
446 (if (<= (length langs) 1)
448 (setq langs (cons (cons "All" langs)
449 (mapcar (lambda (lang) (cons (symbol-name lang) lang))
451 (cdr (assoc (completing-read "language? " langs nil t) langs)))))
454 (defun wnn-comm-sentinel (proc reason) ; assume it is close
455 ; tamago-971009 version
456 (let ((l wnn-environments)
458 (kill-buffer (process-buffer proc))
459 ;; delete env from the list.
462 (if (eq proc (wnnenv-get-proc env))
466 (setq wnn-environments (cdr l)))
472 (defvar wnn-open-message)
474 (defun wnn-open (server-info)
475 "Establish the connection to WNN server. Return process object."
476 ;; Open the session to WNN server,
477 (let ((buf (generate-new-buffer (wnn-server-buffer-name server-info)))
478 (server-type (wnn-server-type server-info))
479 (hostname-list (wnn-server-hostname server-info))
480 (msg-form "WNN: connecting to %S at %s...")
481 hostname proc result msg)
485 (buffer-disable-undo)
486 (setq egg-fixed-euc (wnn-server-coding-system server-info))
487 (set-buffer-multibyte nil))
489 ((null hostname-list)
490 (setq hostname-list '("localhost")))
491 ((null (listp hostname-list))
492 (setq hostname-list (list hostname-list))))
493 (while (and hostname-list (null proc))
494 (setq hostname (car hostname-list)
495 hostname-list (cdr hostname-list))
496 (message msg-form server-type hostname)
497 (condition-case result
498 (setq proc (open-network-stream (wnn-server-stream-name server-info)
501 (wnn-server-port server-info)))
505 (process-kill-without-query proc)
506 (set-process-coding-system proc 'no-conversion 'no-conversion)
507 (set-process-sentinel proc 'wnn-comm-sentinel)
508 (set-marker-insertion-type (process-mark proc) t)
509 (setq result (wnnrpc-open proc
510 (if (equal hostname "localhost")
516 (delete-process proc)
518 msg (format "Can't open WNN session (%s %S): %s"
520 (wnn-server-type server-info)
524 (setq wnn-open-message (format (concat msg-form "done")
529 (error "%s" (or msg (format "no %S available" server-type))))))
531 (defvar wnn-dictionary-specification-list
534 [2 10 2 45 100 200 5 1 40 -100 200 -100 200 80 200 200 200]
536 ["pubdic/kihon.dic" ("kihon.h") 5 nil t]
537 ["pubdic/setsuji.dic" ("setsuji.h") 5 nil t]
538 ["pubdic/koyuu.dic" ("koyuu.h") 1 nil t]
539 ["pubdic/chimei.dic" ("chimei.h") 1 nil t]
540 ["pubdic/jinmei.dic" ("jinmei.h") 1 nil t]
541 ["pubdic/special.dic" ("special.h") 5 nil t]
542 ["pubdic/computer.dic" ("computer.h") 5 nil t]
543 ["pubdic/symbol.dic" ("symbol.h") 1 nil t]
544 ["pubdic/tankan.dic" nil 1 nil nil]
545 ["pubdic/bio.dic" ("bio.h") 1 nil t]
546 ; ["gerodic/g-jinmei.dic" ("g-jinmei.h") 1 nil t]
547 ["wnncons/tankan2.dic" nil 1 nil nil]
548 ["wnncons/tankan3.dic" nil 1 nil nil]
551 [2 10 2 45 1 80 5 1 50 -20 400 -10 100 -100 200 0 200]
553 ["pubdic/kihon.dic" ("kihon.h") 5 nil t]
554 ["pubdic/setsuji.dic" ("setsuji.h") 5 nil t]
555 ["pubdic/koyuu.dic" ("koyuu.h") 1 nil t]
556 ["pubdic/chimei.dic" ("chimei.h") 1 nil t]
557 ["pubdic/jinmei.dic" ("jinmei.h") 1 nil t]
558 ["pubdic/special.dic" ("special.h") 5 nil t]
559 ["pubdic/computer.dic" ("computer.h") 5 nil t]
560 ["pubdic/symbol.dic" ("symbol.h") 1 nil t]
561 ["pubdic/tankan.dic" nil 1 nil nil]
562 ["pubdic/bio.dic" ("bio.h") 1 nil t]
563 ; ["gerodic/g-jinmei.dic" ("g-jinmei.h") 1 nil t]
564 ["wnncons/tankan2.dic" nil 1 nil nil]
565 ["wnncons/tankan3.dic" nil 1 nil nil]
571 ["sys/QianMa.dic" nil 1 nil nil])
575 ["sys/WuBi.dic" nil 1 nil nil])
577 [1 5 2 750 10 80 10 5 1000 50 0 -200 0 0 0 16 0]
579 ["sys/level_1.dic" ("level_1.h") 4 nil t]
580 ["sys/level_2.dic" ("level_2.h") 1 nil t]
581 ["sys/basic.dic" ("basic.h") 7 nil t]
582 ["sys/computer.dic" ("computer.h") 4 nil t]
583 ["sys/cwnn.dic" ("cwnn.h") 4 nil t]
588 ["sys/QianMa.dic" nil 1 nil nil])
592 ["sys/WuBi.dic" nil 1 nil nil])
594 [1 5 2 750 10 80 10 5 1000 50 0 -200 0 0 0 16 0]
596 ["sys/level_1.dic" ("level_1.h") 4 nil t]
597 ["sys/level_2.dic" ("level_2.h") 1 nil t]
598 ["sys/basic.dic" ("basic.h") 7 nil t]
599 ["sys/computer.dic" ("computer.h") 4 nil t]
600 ["sys/cwnn.dic" ("cwnn.h") 4 nil t]
604 [1 5 2 750 10 80 10 5 1000 50 0 -200 0 0 0 16 0]
606 ["sys/cns_ch.dic" ("cns_ch.h") 4 nil t]
607 ["sys/cns_wd.dic" ("cns_wd.h") 1 nil t]
610 [1 5 2 750 10 80 10 5 1000 50 0 -200 0 0 0 16 0]
612 ["sys/cns_ch.dic" ("cns_ch.h") 4 nil t]
613 ["sys/cns_wd.dic" ("cns_wd.h") 1 nil t]
617 [2 5 2 45 200 80 5 1 40 0 400 -100 400 80 200 2 200]
619 ["sys/hword.dic" ("hword.h") 5 nil t]
620 ["sys/single.dic" ("single.h") 1 nil t]
623 [2 10 2 45 1 80 5 1 50 -20 400 -10 100 -100 200 0 200]
625 ["sys/hword.dic" ("hword.h") 5 nil t]
626 ["sys/single.dic" ("single.h") 1 nil t]
627 [("ud") nil 2 t t]))))
629 (defsubst wnn-get-dic-spec (server)
630 (cdr (assoc server wnn-dictionary-specification-list)))
632 (defsubst wnn-dic-spec-dic-set (spec)
635 (defsubst wnn-dic-spec-reverse (spec)
638 (defsubst wnn-dic-spec-name (spec)
641 (defsubst wnn-dic-spec-param (spec)
644 (defsubst wnn-dic-spec-fuzokugo (spec)
647 (defsubst wnn-dic-spec-dic-list (spec)
651 (defcustom wnn-usr-dic-dir (concat "usr/" (user-login-name))
652 "*Directory of user dictionary for Wnn."
656 (defun wnn-filename (p)
658 (cond ((consp p) (concat wnn-usr-dic-dir "/" (car p)))
661 (defun wnn-open-file (proc env-id filename)
662 "Open the file FILENAME on the environment ENV-ID on server process PROC.
663 Return file descripter. NIL means NO-file.
664 On failure, return negate-encoded error code."
666 (wnnrpc-open-file proc env-id filename)
669 (defun wnn-create-directory (proc env-id path)
670 "Create directory to the path."
671 (let ((dir (directory-file-name path))
673 (while (and dir (/= (wnnrpc-access proc env-id 0 dir) 0))
674 (setq create-list (cons dir create-list)
675 dir (file-name-directory dir))
677 (setq dir (directory-file-name dir))))
678 (if (null create-list)
681 (if (y-or-n-p (format "
\e$B%G%#%l%/%H%j
\e(B(%s)
\e$B$,M-$j$^$;$s!#:n$j$^$9$+
\e(B? " path))
684 (let* ((dir (car create-list))
685 (ret (wnnrpc-mkdir proc env-id dir)))
688 (message "
\e$B%G%#%l%/%H%j
\e(B(%s)
\e$B$N:n@.$K<:GT$7$^$7$?
\e(B" dir)
689 (throw 'return nil))))
690 (setq create-list (cdr create-list)))
692 (message "
\e$B%G%#%l%/%H%j
\e(B(%s)
\e$B$r:n$j$^$7$?
\e(B" path)
697 (defun wnn-open-dictionary (proc env-id dicname mode)
698 (let ((dictionary (wnn-open-file proc env-id dicname)))
699 (if (null dictionary)
700 (throw 'wnn-set-dictionary-tag nil)
701 (while (< dictionary 0)
702 (let ((err-code (- dictionary)))
703 (if (or (null mode) (/= err-code (WNN-const NO_EXIST)))
704 (let ((msg (wnnrpc-get-error-message err-code)))
705 (message "
\e$B<-=q%U%!%$%k
\e(B(%s)
\e$B$,$"$j$^$;$s
\e(B: %s" dicname msg)
706 (throw 'wnn-set-dictionary-tag nil)) ; Failure
707 ;; Try to create new one
709 (format "
\e$B<-=q%U%!%$%k
\e(B(%s)
\e$B$,$"$j$^$;$s!#:n$j$^$9$+
\e(B? "
711 (wnn-create-directory proc env-id
712 (file-name-directory dicname))
713 (= (wnnrpc-create-dictionary proc env-id dicname) 0))
715 (message "
\e$B<-=q%U%!%$%k
\e(B(%s)
\e$B$r:n$j$^$7$?
\e(B" dicname)
717 (wnnrpc-open-file proc env-id dicname)))
718 (throw 'wnn-set-dictionary-tag nil)))))
721 (defun wnn-open-frequency (proc env-id freqname mode dic)
722 (let ((frequency (wnn-open-file proc env-id freqname)))
725 (while (< frequency 0)
726 (let ((err-code (- frequency)))
727 (if (or (null mode) (/= err-code (WNN-const NO_EXIST)))
728 (let ((msg (wnnrpc-get-error-message err-code)))
729 (message "
\e$BIQEY%U%!%$%k
\e(B(%s)
\e$B$,$"$j$^$;$s
\e(B: %s" freqname msg)
730 (throw 'wnn-set-dictionary-tag nil)) ; Failure
731 ;; Try to create new one
733 (format "
\e$BIQEY%U%!%$%k
\e(B(%s)
\e$B$,$"$j$^$;$s!#:n$j$^$9$+
\e(B? "
735 (wnn-create-directory proc env-id
736 (file-name-directory freqname))
737 (= (wnnrpc-create-frequency proc env-id freqname dic) 0))
739 (message "
\e$BIQEY%U%!%$%k
\e(B(%s)
\e$B$r:n$j$^$7$?
\e(B" freqname)
741 (wnnrpc-open-file proc env-id freqname)))
742 (throw 'wnn-set-dictionary-tag nil))))))
745 ;; Using local file (uploading/downloading) is not supported yet.
746 ;; Password is not supported (Password is questionable feature, anyway)
747 (defun wnn-set-dictionary (proc env-id reverse-flag dic-spec)
749 (catch 'wnn-set-dictionary-tag
750 (let ((dicname (wnn-filename (aref dic-spec 0)))
751 (freqname (wnn-filename (aref dic-spec 1)))
752 (priority (aref dic-spec 2))
753 (dic-mode (aref dic-spec 3))
754 (freq-mode (aref dic-spec 4))
755 dictionary frequency)
756 (setq dictionary (wnn-open-dictionary proc env-id dicname dic-mode))
758 (wnn-open-frequency proc env-id freqname freq-mode dictionary))
759 (wnn-set-dictionary-sub proc env-id reverse-flag
760 dictionary frequency priority dic-mode
761 freq-mode dicname freqname))))
763 (defun wnn-set-dictionary-sub (proc env-id reverse-flag
764 dictionary frequency priority dic-mode
765 freq-mode dicname freqname)
768 (let ((ret (wnnrpc-set-dictionary proc env-id reverse-flag
770 priority dic-mode freq-mode)))
772 (let ((err-code (- ret)))
773 (if (or (null freq-mode) (/= err-code (WNN-const NO_MATCH)))
774 (let ((msg (wnnrpc-get-error-message (- ret))))
775 (message "WNN: Error on setting dictionary (%s, %s): %s"
776 dicname freqname msg)
777 (setq trying nil)) ; done
778 ;; No-match: Create new frequency and try it again
779 (wnnrpc-discard-file proc env-id frequency) ; XXX: error?
781 (wnn-query-del/create-frequency proc env-id freqname
784 (setq trying nil))))))
786 (defun wnn-query-del/create-frequency (proc env-id freqname dictionary)
788 (format "
\e$B<-=q$HIQEY
\e(B(%s)
\e$B$N@09g@-$,$"$j$^$;$s!#:n$jD>$7$^$9$+
\e(B? "
791 (wnnrpc-remove-file proc freqname) ; XXX: error?
792 (wnnrpc-create-frequency proc env-id freqname dictionary) ; XXX: error?
793 (message "
\e$BIQEY%U%!%$%k
\e(B(%s)
\e$B$r:n$j$^$7$?
\e(B" freqname)
794 (wnnrpc-open-file proc env-id freqname)) ; XXX: error?
797 (defun wnn-get-environment (server-info &optional dic-set reverse)
798 "Return WNN Environemt for the conversion server specified
799 by SERVER-INFO. If none, create new environment. Optional
800 argument DIC-SET specifies dictionary set. Optional argument
801 REVERSE specifies reverse conversion, if non nil."
802 (let ((server-type (wnn-server-type server-info))
803 (env wnn-environments)
805 (setq reverse (null (null reverse)))
809 (if (and (eq (wnnenv-get-server-type e) server-type)
810 (eq (wnnenv-get-dictionary-set e) dic-set)
811 (eq (wnnenv-get-reverse-flag e) reverse))
813 (setq env (cdr env))))
815 (setq proc (wnn-open server-info)
816 spec (wnn-get-dic-spec server-type))
819 e (wnn-create-environment proc server-type s)
820 wnn-environments (cons e wnn-environments))
821 (if (and (eq (wnn-dic-spec-dic-set s) dic-set)
822 (eq (wnn-dic-spec-reverse s) reverse))
824 (setq spec (cdr spec)))
826 (error "WNN: environment for %S%s (%s) not found"
828 (if dic-set (format "(%S)" dic-set) "")
829 (if reverse 'reverse 'normal)))
830 (message "%s" wnn-open-message)
833 (defun wnn-create-environment (proc server-type spec)
835 ;; Create new data structure: something like wnn_buf
836 ;; Process, Environment-ID and Daibunsetsu-info.
837 (let (env-id parameters filename fuzokugo-fid ret dic-set reverse)
838 (setq env-id (wnnrpc-connect proc (wnn-make-env-name spec)))
840 (error "Can't connect new WNN environment: %s"
841 (wnnrpc-get-error-message (- env-id))))
842 (setq dic-set (wnn-dic-spec-dic-set spec)
843 reverse (wnn-dic-spec-reverse spec)
844 parameters (wnn-dic-spec-param spec)
845 filename (wnn-filename (wnn-dic-spec-fuzokugo spec))
846 fuzokugo-fid (wnn-open-file proc env-id filename))
847 (if (null fuzokugo-fid)
848 (setq fuzokugo-fid -1)
849 (if (< fuzokugo-fid 0)
851 (message "WNN: Can't open fuzokugo file (%s): %s"
853 (wnnrpc-get-error-message (- fuzokugo-fid)))
854 (setq fuzokugo-fid -1))))
855 (setq ret (wnnrpc-set-fuzokugo-file proc env-id fuzokugo-fid))
857 (let ((msg (wnnrpc-get-error-message (- ret))))
858 (message "WNN: Error on setting fuzokugo (%s): %s" filename msg)))
859 (setq spec (wnn-dic-spec-dic-list spec))
861 (wnn-set-dictionary proc env-id reverse (car spec))
862 (setq spec (cdr spec)))
864 (wnnrpc-set-conversion-parameters proc env-id parameters))
865 (wnnenv-create proc env-id server-type dic-set reverse)))
867 (defvar wnn-user-name nil)
869 (defun wnn-make-env-name (spec)
871 (setq wnn-user-name (getenv "WNNUSER"))
872 (setq wnn-user-name (user-login-name)))
873 (concat wnn-user-name (wnn-dic-spec-name spec)))
875 (defun wnn-update-frequency (env bunsetsu-info-list)
876 (let ((l bunsetsu-info-list))
879 (fd (wnn-bunsetsu-get-freq-down b))
880 (z (wnn-bunsetsu-get-zenkouho b)))
882 (let* ((fdb (car fd))
883 (dic-no (wnn-bunsetsu-get-dic-no fdb))
884 (entry (wnn-bunsetsu-get-entry fdb)))
885 (wnnrpc-set-frequency env dic-no entry
886 (WNN-const IMA_OFF) (WNN-const HINDO_NOP))
890 (right-now (wnn-bunsetsu-get-right-now zb))
891 (dic-no (wnn-bunsetsu-get-dic-no zb))
892 (entry (wnn-bunsetsu-get-entry zb)))
893 (if (and (/= right-now 0) (/= dic-no -1))
894 (wnnrpc-set-frequency env dic-no entry (WNN-const IMA_OFF)
895 (WNN-const HINDO_NOP)))
897 (let ((dic-no (wnn-bunsetsu-get-dic-no b))
898 (entry (wnn-bunsetsu-get-entry b)))
900 (wnnrpc-set-frequency env dic-no entry
902 (WNN-const HINDO_INC))))
905 ;;; XXX Need alternative implementation
906 ;(defun wnn-set-conversion-mode ()
907 ; (jl-set-environment))
909 (defsubst wnn-dicinfo-entry (info) (aref info 0))
910 (defsubst wnn-dicinfo-id (info freq) (aref info (+ 1 freq)))
911 (defsubst wnn-dicinfo-mode (info freq) (aref info (+ 3 freq)))
912 (defsubst wnn-dicinfo-enable (info) (aref info 5))
913 (defsubst wnn-dicinfo-nice (info) (aref info 6))
914 (defsubst wnn-dicinfo-reverse (info) (aref info 7))
915 (defsubst wnn-dicinfo-comment (info) (aref info 8))
916 (defsubst wnn-dicinfo-name (info freq) (aref info (+ 9 freq)))
917 (defsubst wnn-dicinfo-passwd (info freq) (aref info (+ 11 freq)))
918 (defsubst wnn-dicinfo-type (info) (aref info 13))
919 (defsubst wnn-dicinfo-words (info) (aref info 14))
920 (defsubst wnn-dicinfo-local (info freq) (aref info (+ 15 freq)))
922 (defun wnn-save-dictionaries (env)
923 (let ((dic-list (wnnrpc-get-dictionary-list-with-environment env))
924 (result 0) info freq)
927 (setq info (car dic-list)
928 dic-list (cdr dic-list)
931 (if (and (> (wnn-dicinfo-id info freq) 0)
932 (= (wnn-dicinfo-mode info freq) 0))
933 (if (= (wnn-dicinfo-local info freq) 1)
934 (setq result (wnnrpc-write-file env
935 (wnn-dicinfo-id info freq)
936 (wnn-dicinfo-name info freq)))
937 (message "WNN: remote dictionary (%s) not supported yet"
938 (wnn-dicinfo-name info freq))
942 (wnnrpc-disconnect env))
943 (setq freq (1+ freq))))))
945 (defun wnn-version (proc)
946 "Return version number string of WNN server."
947 (format "%x" (wnnrpc-version proc)))
949 (defun wnn-dai-bunsetsu-p ()
952 (defun wnn-next-dai-bunsetsu-pos ()
955 ;;; not implemented yet (NIY)
956 (defun wnn-delete-dictionary ()
959 ;;; NIY, might never be implemented
960 (defun wnn-server-inspect ())
963 (defun wnn-list-dictionaries ()
967 (defun wnn-get-conversion-parameters ()
970 ;;; Dictionary management (word registration) is not implemented yet.
972 ;; XXX: local file loaded into the server: Not supported yet
973 ;(defun wnn-list-dictionaries (env)
974 ; (wnnrpc-get-dictionary-list-with-environment env))
976 (defun wnn-find-dictionary-by-id (id dic-list)
979 (let ((dic (car dic-list)))
980 (if (= (wnndic-get-id dic) id)
982 (setq dic-list (cdr dic-list)))))))
984 (defun wnn-dict-name (dic)
985 (let ((name (wnndic-get-comment dic)))
986 (if (string= name "")
987 (file-name-nondirectory (wnndic-get-dictname dic))
990 (defun wnn-list-writable-dictionaries-byname (env)
991 (let ((dic-list (wnnrpc-get-dictionary-list-with-environment env))
992 (w-id-list (wnnrpc-get-writable-dictionary-id-list env)))
993 (mapcar (function (lambda (id)
994 (let ((dic (wnn-find-dictionary-by-id id dic-list)))
995 (cons (wnn-dict-name dic) dic))))
998 (defun wnn-hinshi-list (env dic name)
999 (let ((dic-number (wnndic-get-id dic)))
1000 (wnnrpc-get-hinshi-list env dic-number name)))
1002 (defun wnn-hinshi-number (env hinshi-name)
1003 (wnnrpc-hinshi-number (wnnenv-get-proc env) hinshi-name))
1005 (defun wnn-add-word (env dic yomi kanji comment hinshi-id initial-freq)
1006 (let ((dic-number (wnndic-get-id dic)))
1007 (wnnrpc-add-word env dic-number yomi kanji comment
1008 hinshi-id initial-freq)))
1015 (defun egg-activate-wnn (&rest arg)
1016 "Activate Wnn backend of Tamagotchy."
1017 (setq egg-conversion-backend wnn-conversion-backend)
1018 (if (not (fboundp 'wnnrpc-open))
1019 (load-library "egg/wnnrpc"))
1020 (apply 'egg-mode arg))
1022 ;;; egg/wnn.el ends here.