anthy.elでインクリメンタルサーチ

scim-modeでisearchできるようにするための予備調査としてisearch-x.elのコードを読んでいたのですが、だいたい仕組みがわかってきたところで、anthy.elなら簡単にできそうな気がしたのでやってみました。

(defvar anthy-preedit-empty-hook nil)
(defadvice anthy-insert (after anthy-preedit-empty-hook () activate)
  (if (string= anthy-preedit "")
      (run-hooks 'anthy-preedit-empty-hook)))
(defun anthy-isearch-process-commit-string ()
  (if preedit
      (setq unread-command-events
	    (cons ?\C-g (cons last-command-event unread-command-events)))))
(defadvice isearch-process-search-multibyte-characters
  (around anthy-isearch-process-search-characters () activate)
  (if (and (string= current-input-method "japanese-anthy")
	   (eq this-command 'isearch-printing-char))
      (let ((overriding-terminal-local-map nil)
	    (prompt (isearch-message-prefix))
	    (minibuffer-local-map isearch-minibuffer-local-map)
	    (anthy-preedit-empty-hook '(exit-minibuffer))
	    (anthy-commit-hook '(anthy-isearch-process-commit-string))
	    str junk-hist)
	(setq unread-command-events (cons last-char unread-command-events)
	      str (substring
		   (read-string prompt isearch-string 'junk-hist nil t)
		   (length isearch-string)))
	(if (and str (> (length str) 0))
	    (let ((unread-command-events nil))
	      (isearch-process-search-string str str))
	  (isearch-update)))
    ad-do-it))

あと、キーバインドの設定は以下のようにすればいいと思います。

(substitute-key-definition
 'toggle-input-method 'isearch-toggle-input-method isearch-mode-map global-map)

GNU Emacs 21, 22, 23 でテストしたところ、いずれもうまく動作するようです。
Anthyにはanthy-isearch.elというファイルが含まれていますが、未完成のまま放置されているようで使い物になりません。
今まではMigemoを使っていましたけど、動作が重たいし、意図しない文字列が検索にヒットするとイライラしてあまり使う気になりませんでした。scim-modeをメインで使っているのにisearchのためにわざわざTamagoを入れるつもりもありません。
当分はこの方法でいきます。
追記(11/7):コードを少し修正しました。変更点↓

  • フック変数anthy-preedit-empty-hookをdefvarするようにした
  • (load "isearch-x")は不要なので削除