(defvar prime-pat "") (make-variable-buffer-local 'prime-pat) (defvar prime-start-pat "" "convert-region をキャンセルした時に元に戻す文字列") (make-variable-buffer-local 'prime-start-pat) (defvar prime-pat-for-undo "") (make-variable-buffer-local 'prime-pat-for-undo) (defvar prime-cands nil) (make-variable-buffer-local 'prime-cands) (defvar prime-cands-for-undo nil) (make-variable-buffer-local 'prime-cands-for-undo) (defvar prime-context nil) ; 検索候補のコンテキスト. 主に前回入力単語 (make-variable-buffer-local 'prime-context) (defvar prime-context-for-undo nil) (make-variable-buffer-local 'prime-context-for-undo) (defvar prime-nth-cand 0) ; いくつめの候補を選択しているか (make-variable-buffer-local 'prime-nth-cand) (defvar prime-nth-cand-for-undo 0) (make-variable-buffer-local 'prime-nth-cand-for-undo) (defvar prime-conv-mode-for-undo nil) (make-variable-buffer-local 'prime-conv-mode-for-undo) ;;;; ------------------------------------------------------------ ;;;; 初期化用関数 ;;;; ------------------------------------------------------------ (defun prime-reset-pat () (setq prime-pat-for-undo prime-pat) (setq prime-pat "") ) (defun prime-reset-cands () (setq prime-cands-for-undo prime-context) (setq prime-cands nil) ) (defun prime-set-context (word) (setq prime-context-for-undo prime-context) (setq prime-context word) ) (defun prime-reset-context () (setq prime-context-for-undo prime-context) (setq prime-context "") ) (defun prime-reset-nth-cand () (setq prime-nth-cand-for-undo prime-nth-cand) (setq prime-nth-cand 0) ) ;;;; ------------------------------------------------------------ ;;;; undo 用関数 ;;;; ------------------------------------------------------------ (defun prime-undo () (interactive) (cond (prime-fund-mode (prime-fund-undo)) (prime-narrow-mode (if (= (length prime-narrow-pat) 1) (progn (prime-narrow-mode-off) (prime-disp-conv)) (setq prime-narrow-pat (substring prime-narrow-pat 0 -1)) (setq prime-narrow-column (1- prime-narrow-column)) (prime-disp-narrow))) (prime-conv-mode (prime-conv-prev)) (t (if (= (length prime-pat) 1) (prime-conv-cancel-all) (setq prime-pat (substring prime-pat 0 -1)) (setq prime-input-column (1- prime-input-column)) (prime-disp-input) )))) ;;;; ============================================================ ;; 候補一覧の位置情報を計算 (defun prime-cand-set-column-list () ;; コードが汚ねえ!!! (let ((i 0) (col 0) (col-stop (window-width)) list column-list) (while (< i (length prime-cands)) (let ((length (+ (string-width (prime-nth-candidate i)) 2))) ; 2 = margin (and (> (+ col length 3) col-stop) (progn (setq list (cons (cons col nil) list)) (setq col col-stop) (setq col-stop (+ col-stop (window-width))) )) (setq list (cons (cons col i) list)) (setq col (+ col length)) (setq i (1+ i)) )) (setq list (cons (cons col-stop nil) (cons (cons col nil) list))) (setq prime-cand-column-list (reverse list)) (setq prime-cand-column-length col-stop) )) (defun prime-toggle-mode-line () (cond ((not prime-mode) (setq mode-line-format prime-modeline-original) (setq prime-modeline-original nil)) (t (or prime-modeline-original (setq prime-modeline-original mode-line-format)) (setq mode-line-format (cons prime-modeline-status (cdr mode-line-format))) )) ;; 2001/09/06 これを入れないと mode-line 表示の更新が遅れる. (and (functionp 'force-mode-line-update) (force-mode-line-update)) ) (defun prime-face-find-color (arg) (if (listp arg) ;; '(X TTY) (mell-color-find (nth 0 arg) (nth 1 arg)) arg) ) (defun prime-set-cursor-color () (let ((current-color (mell-color-find (mell-color-get-cursor) 7)) (mode-color (cond (prime-narrow-mode (prime-face-find-color prime-narrow-cursor-color)) ((and prime-cand-mode (featurep 'xemacs)) ;; Emacs だと余計な気を使って白色で表示してしまう. (mell-color-get-background)) (prime-mode (prime-face-find-color prime-cursor-color)) (t prime-default-cursor-color)))) (if (not (eq current-color mode-color)) (set-cursor-color mode-color)) )) (defun prime-init (&optional forcep) (prime-keymap-init forcep) (prime-mode-init forcep) (prime-server-init forcep) ;; TODO: 動的に変更できるようにしよう. (cond ((eq prime-style 'default) (prime-style-default)) ((eq prime-style 'capital-only) (prime-style-capital-only)) ((eq prime-style 'komatsu) (prime-style-komatsu)) ) (run-hooks 'prime-init-hook) ) (defun prime-reset-before-input () (prime-reset-pat) (setq prime-prev-pattern nil) ; 検索パタン (prime-reset-cands) (prime-reset-nth-cand) (mell-marker-set 'prime-curstr-begin (point)) (mell-marker-set 'prime-curstr-end (point)) (mell-marker-set 'prime-cand-list-begin (point)) (mell-marker-set 'prime-cand-list-end (point)) ) (defun prime-reset-after-fix () (prime-reset-pat) (setq prime-start-pat "") (setq prime-prev-pattern nil) ; 検索パタン (setq prime-input-column 0) ;; ここでも設定されているのは負け. (prime-reset-cands) (prime-reset-nth-cand) (mell-marker-set 'prime-curstr-begin (point)) (mell-marker-set 'prime-curstr-end (point)) (setq prime-curstr "") ; テンポラリに選択/表示されている文字列 (mell-marker-set 'prime-cand-list-begin (point)) (mell-marker-set 'prime-cand-list-end (point)) (setq prime-conv-exact-p nil) (setq prime-conv-mode-for-undo prime-conv-mode) (setq prime-narrow-mode nil) (prime-narrow-mode-reset) (prime-enum-mode-reset) ) ;; n番目の候補を得る。最初の候補は0番目。 (defun prime-nth-candidate (n) (let (s) (setq s (nth n prime-cands)) (if (stringp s) s "") )) (defun prime-disp-input (&optional pattern) (setq prime-pat (or pattern prime-pat)) (prime-erase-curstr) (prime-disp-curstr) (when (sit-for 0.01) (prime-erase-cand-list) (prime-set-cands prime-pat) (prime-disp-cand-list)) ) (defun prime-disp-conv (&optional nth) (setq prime-nth-cand (or nth prime-nth-cand)) (prime-erase-cand-list) (prime-erase-curstr) (prime-disp-curstr) (prime-disp-cand-list) ) (defun prime-disp-narrow (&optional nth) (setq prime-nth-cand (or nth prime-nth-cand)) (setq prime-cands (if (string= prime-narrow-pat "") prime-narrow-orig-cands (delete nil (prime-narrow-compare-list prime-narrow-orig-cands (prime-search prime-narrow-pat))))) (prime-cand-set-column-list) (prime-erase-cand-list) (prime-erase-curstr) (prime-disp-curstr) (prime-disp-cand-list) ) ;; 候補リスト表示を消す (defun prime-erase-cand-list () (if (not (equal prime-cand-list-begin prime-cand-list-end)) (delete-region (1- prime-cand-list-begin) prime-cand-list-end)) (mell-marker-set 'prime-cand-list-begin (point)) (mell-marker-set 'prime-cand-list-end (point)) ; (setq prime-cand-list-begin (point)) ; (setq prime-cand-list-end (point)) ) ;; 選択候補を消す (defun prime-erase-curstr () (if (not (equal prime-curstr-begin prime-curstr-end)) (delete-region prime-curstr-begin prime-curstr-end)) (mell-marker-set 'prime-curstr-begin (point)) (mell-marker-set 'prime-curstr-end (point)) ; (setq prime-curstr-begin (point)) ; (setq prime-curstr-end (point)) ) ;; 選択候補を表示 ;; 汚くなってきた. narrow-mode は分けよう. (defun prime-disp-curstr () (setq prime-curstr (cond (prime-conv-mode (prime-nth-candidate prime-nth-cand)) ;; prime-input-mode ((and (= prime-input-column (length prime-pat)) (eq prime-language-default 'japanese)) (or (prime-input-get-kana) prime-pat)) (t prime-pat))) (mell-marker-set 'prime-curstr-begin (point)) (if prime-narrow-mode (insert "[" prime-curstr "|" (prime-get-hiragana prime-pat) "*" ;; キタネー, 死ぬー. (if (= prime-narrow-column (length prime-narrow-pat)) (prime-get-hiragana prime-narrow-pat) prime-narrow-pat) "]") (insert "[" prime-curstr "]")) (mell-marker-set 'prime-curstr-end (point)) (if prime-narrow-mode (and (/= prime-narrow-column (length prime-narrow-pat)) (backward-char (1+ (- (length prime-narrow-pat) prime-narrow-column)))) (and (not prime-conv-mode) (/= prime-input-column (length prime-pat)) (backward-char (1+ (- (length prime-pat) prime-input-column)))) ) ) ;; 候補リストをカーソルの1行下に表示 (defun prime-disp-cand-list () (save-excursion (cond ((or prime-disp-cand-list-oneline ;; カーソル位置によっては候補が見えないので, 1 行で表示 (and (>= (1+ (count-lines (window-end nil t) (window-start))) (window-height)) (<= (count-lines (window-end nil t) (point)) 1))) (goto-char prime-curstr-end) ;; marker との兼ね合いでちょっと直感的でないことになっている. ;; marker は (] である. (insert " ") (mell-marker-set 'prime-cand-list-begin (point)) (prime-disp-cand-list-one) ) (prime-cand-mode (end-of-line) ;; marker との兼ね合いでちょっと直感的でないことになっている. (insert "\n") (mell-marker-set 'prime-cand-list-begin (point)) ;; (prime-disp-cand-list-all) ) (t (let (col) (goto-char prime-curstr-begin) (setq col (+ (% (current-column) (window-width)) (/ (current-column) (window-width)))) (end-of-line) ;; marker との兼ね合いでちょっと直感的でないことになっている. (insert "\n") (mell-marker-set 'prime-cand-list-begin (point)) ;; (insert (make-string col 32)) ; 32 = space (prime-disp-cand-list-one) ))) ;; marker との兼ね合いでちょっと直感的でないことになっている. (mell-marker-set 'prime-cand-list-end (point)) ;; )) ;; 候補を表示 (1 行) ;(defun prime-disp-cand-list-one () ; (let ((i (+ prime-nth-cand (if prime-conv-mode 1 0)))) ; (while (and (< i (+ prime-nth-cand 10)) (nth i prime-cands)) ; (if (and prime-enum-mode (< i (length prime-enum-char-list))) ; (insert (char-to-string (nth i prime-enum-char-list)) ; (prime-nth-candidate i) " ") ; (insert "(" (prime-nth-candidate i) ")")) ; (setq i (1+ i)) ; ))) (defun prime-disp-cand-list-one () (let ((i 0) (offset (+ prime-nth-cand (if prime-conv-mode 1 0)))) (while (and (< i 10) (nth (+ i offset) prime-cands)) (if (and prime-enum-mode (or prime-conv-mode (not prime-enum-mode-ignorep)) (< i (length prime-enum-char-list))) (insert (char-to-string (nth i prime-enum-char-list)) (prime-nth-candidate (+ i offset)) " ") (insert "(" (prime-nth-candidate (+ i offset)) ")")) (setq i (1+ i)) ) )) (defun prime-disp-cand-list-all () (let ((i 0)) (while (< i (length prime-cands)) (and (> (+ (current-column) (string-width (prime-nth-candidate i)) 5) (window-width)) (insert "\n")) (if (= i prime-nth-cand) (let (beginning end) (setq beginning (point)) (insert "[" (prime-nth-candidate i) "]") (setq end (point)) (font-lock-prepend-text-property beginning end 'face 'prime-cand-cursor-face) ; これは XEmacs only ; (font-lock-set-face beginning end 'prime-cand-cursor-face) ) (insert "(" (prime-nth-candidate i) ")")) (setq i (1+ i)) ))) (defun prime-fontify-region (beg end &optional loudly) nil) (defun prime-register (&optional word pattern) (interactive) (or word (if (mell-region-active-p) (setq word (buffer-substring (region-beginning) (region-end))) (setq word (read-from-minibuffer "[単語登録] 単語: ")))) (or pattern (setq pattern (read-from-minibuffer (concat "[単語登録] 「" word "」の読み: ")))) (prime-server-dict-register-word word pat) ) (defun prime-register-word (&optional pat) (interactive) (setq pat (or pat prime-pat)) (let ((minibuffer-setup-hook (cons 'prime-mode-on minibuffer-setup-hook)) (prime-learn-p nil) kana word) ; (setq kana (read-string "単語登録「読み」: " (prime-get-hiragana pat))) (setq kana (prime-get-hiragana pat)) (setq word (read-string (concat "[単語登録] 「" kana "」の変換: "))) (prime-server-dict-register-word word kana) (prime-fix-without-learn word) (prime-fund-mode t) ) ) ;(defun prime-register-word (&optional pat) ; (interactive) ; (setq pat (or pat prime-pat)) ; (prime-server-dict-register-word word pat) ; (prime-fix-without-learn word) ; (prime-fund-mode t) ; ) ;(defun prime-register-read-pattern-romaji (&optional pat) ; (let ((prime-learn-p nil)) ; (read-from-minibuffer "単語登録「読み(ローマ字)」: " pat) ; )) ;(defun prime-register-read-pattern (&optional pat) (defun prime-get-nth (&optional word pattern) (if (not word) prime-nth-cand (or pattern (setq pattern prime-pat)) (mell-list-member-get-nth word (prime-search pattern)) )) (defun prime-fix (cand) ; 候補をcandに確定 (and (> (length cand) 0) (prime-server-select cand)) (prime-fix-internal cand) ) (defun prime-fix-without-learn (cand) (prime-fix-internal cand)) (defun prime-fix-internal (word) (prime-erase-cand-list) (prime-erase-curstr) (and (> (length word) 0) (prime-insert word)) (prime-reset-after-fix) (prime-conv-mode-off) ) (defun prime-after-fix (&optional next-char) (if next-char (if (= (length prime-next-pattern) 0) (setq prime-next-pattern (char-to-string next-char)) (if (not (string= (downcase (char-to-string next-char)) (substring prime-next-pattern 0 1))) (setq prime-next-pattern (char-to-string next-char)) ))) (if (or prime-predict-after-fix (> (length prime-next-pattern) 0)) (progn (setq prime-pat prime-next-pattern) (setq prime-next-pattern "") (setq prime-input-column (length prime-pat)) (prime-input-mode-on) (prime-disp-input)) (prime-fund-mode-on) ) ) (defun prime-insert (word) (let (undo-begin undo-end) (setq undo-begin (point)) (insert word) (prime-set-context word) ;; ここが適切? (setq prime-previous-substring (buffer-substring (max 1 (- (point) 5)) (point))) (set-marker prime-marker (point)) ;; ここが適切? (and auto-fill-function (funcall auto-fill-function)) (setq undo-end (point)) (setq prime-buffer-undo-list (cons (cons undo-begin undo-end) (cons nil prime-buffer-undo-list))) )) (defun prime-dict-word-delete () (interactive) (if (y-or-n-p (concat prime-curstr " を削除しますか? ")) (progn (prime-server-dict-delete-word prime-curstr prime-pat) (prime-conv-next)) )) (defun prime-undefined () (interactive) (message (concat (key-description (this-command-keys)) " は定義されていません. (" (key-description (car (where-is-internal 'prime-conv-cancel))) " が取り消しキーです.)")) (beep) (if (eq last-command this-command) (and (> (setq prime-undefined-count (1+ prime-undefined-count)) 2) (if (y-or-n-p "PRIME モードを終了しますか? ") (prime-mode-off) (message (concat (key-description (car (where-is-internal 'prime-mode))) " で PRIME モードを終了可能です.")) )) (setq prime-undefined-count 1)) ) (defun prime-language-toggle () (interactive) (let ((lang-list (member prime-language-default prime-language-list))) (setq prime-language-default (or (nth 2 lang-list) (car prime-language-list))) (setq prime-modeline-status (or (nth 3 lang-list) (nth 1 prime-language-list))) ) (prime-toggle-mode-line) (cond (prime-input-mode (prime-disp-input)) (prime-conv-mode (prime-disp-conv))) ) (defun prime-conv-ascii () (interactive) (prime-fix prime-pat) (prime-after-fix) (prime-fund-mode-on) ) (defun prime-get-hiragana (&optional pattern) (or pattern (setq pattern prime-pat)) ; (kata2hira (roma2kana pattern)) ; (japanese-hiragana (roma2kana pattern)) (suikyo-convert-romaji-kana pattern) ) ; (or pattern (setq pattern prime-pat)) ; (let ((cands (prime-search pattern t))) ; (and (> (length cands) 1) ; (car cands)) ; )) (defun prime-conv-hiragana () (interactive) (prime-fix (prime-get-hiragana prime-pat)) (prime-after-fix) (prime-fund-mode-on) ) (defun prime-conv-hiragana-without-learn () (interactive) (prime-fix-without-learn (prime-get-hiragana prime-pat)) (prime-after-fix) (prime-fund-mode-on) ) (defun prime-get-katakana (&optional pattern) (or pattern (setq pattern prime-pat)) ; (roma2kana pattern) (japanese-katakana (suikyo-convert-romaji-kana pattern)) ) ; (or pattern (setq pattern prime-pat)) ; (let ((cands (prime-search pattern t))) ; (and (> (length cands) 1) ; (nth 1 cands)) ; )) (defun prime-conv-katakana () (interactive) (prime-fix (prime-get-katakana prime-pat)) (prime-after-fix) (prime-fund-mode-on) ) (defun prime-context-keep-p () (or prime-input-mode prime-conv-mode (and (eq (marker-position prime-marker) (point)) (string= (buffer-substring (max 1 (- (point) 5)) (point)) prime-previous-substring))) ) ;; ----- prime-keyin 関係 ---------- (defun prime-keyin-direct (char) ;; 入力文字が prime-direct-keymap に登録されているなら, 即確定. (let ((direct-pair (assoc char prime-direct-key-alist))) (if direct-pair (progn (prime-fix prime-curstr) (prime-after-fix) (prime-insert (nth 1 direct-pair)) t) nil))) (defun prime-input-all-capital-p (input) (let ((case-fold-search nil)) (string-match "^[A-Z]+$" input))) (defun prime-input-no-japanese-p (input) (string-match "\\cj+[a-zA-Z-]+\\cj+\\|^[a-zA-Z-]*$" (prime-get-hiragana input))) (defun prime-keyin-capital (char) ;; 大文字などが入力されかつ, 内容が妥当ならば確定. (if (and prime-fix-by-capital-p (>= char ?A) (<= char ?Z) (not (prime-input-no-japanese-p prime-pat)) (not (prime-input-all-capital-p prime-pat)) ) (progn (prime-fix prime-curstr) (prime-after-fix char) t) nil)) ;;;; コマンドにするべき (defun prime-keyin-kutouten (char) (cond ((eq char ?.) (prime-fix prime-curstr) (prime-after-fix) (if prime-style-kutouten-local (prime-insert (car prime-style-kutouten-local)) (prime-insert (car prime-style-kutouten))) t) ((eq char ?,) (prime-fix prime-curstr) (prime-after-fix) (if prime-style-kutouten-local (prime-insert (cdr prime-style-kutouten-local)) (prime-insert (cdr prime-style-kutouten))) t) (t nil))) (defun prime-keyin (&optional char) (interactive) (setq char (or char last-input-char)) (or (prime-context-keep-p) (setq prime-context nil)) (cond ((prime-enum-keyin char)) ((prime-keyin-kutouten char)) ((prime-keyin-direct char)) (prime-conv-mode (prime-fix prime-curstr) (prime-after-fix char) ) ((prime-keyin-capital char)) (t ;; prime-fund-mode (prime-input-mode-on) (prime-input-insert-char char) (prime-disp-input)) )) (defalias 'prime-cand-keyin 'prime-keyin) ;; スペースを挿入. (defun prime-space () ;; prime-conv-space ? (interactive) (prime-fix prime-curstr) (prime-fund-mode-on) (insert " ")) ;; prime-space その 2 ; (if (> prime-nth-cand 0) ; (progn ; (prime-fix prime-curstr) ; (prime-fund-mode) ; (insert " ")) ; (setq prime-pat (concat prime-pat " ")) ; (prime-disp-input prime-pat) ; )) (provide 'prime-main)