Japanese dabbrev in Emacs 20/21

dabbrev って何? という方は GNU Emacs Manual Dynamic Abbrev Expansion の項を読んで下さい。(便利なので是非使って下 さい。)

さて、Mule が merge された Emacs 20/21 で、日本語文字と ASCII 文字が 混じった buffer で、特に日本語文字と ASCII 文字との間に space などを何も 入れずに書いている時に (LaTeX で文書を書く時によくこうする)、 dabbrev-expand (M-/) すると悲惨な事態になることが よくあります。具体的には、

要するに、日本語文字とそれ以外との間が、補完時に認識する word の boundary にならなくなったのです。

僕に限って言えば、日本語文字とそれ以外をまとめて補完したい機会は全く ありません。ので、この挙動はたいへん困ります。それ以上に、 Emacs19.34@Mule2.3 の時代の dabbrev-expand は、完全に僕の意図通りの挙動 を示してくれていたのです。それが今やきかん坊になってしまい、もう悔しくて 悔しくて。

そこで、これをお手軽に何とかしよう、というのがこの page の議題です。


... と、以上の記述は、経緯説明として現在でも有効かと思いますが、具体的な対処法に関しては、土屋さんによる優れた re-implementation がありますので、是非こちらをお使い下さい。dabbbrev-ja.el 以下の記述をあえて消すことはしません。が、これは、古物趣味以上の価値を、もはや持ちません。(20 Apr 2003)


で、結論ですが僕は今この code chunk と共に暮しています。startup dotfile にはりつけて下さい。

(require 'dabbrev)		      ; for dabbrev-abbrev-char-regexp
(defun dabbrev-expand-by-category (arg)
  (interactive "*P")
  (unless (bobp)
    (let (ch ch-ca-set regexp)
	 (setq ch (char-before))
	 (setq ch-ca-set (char-category-set ch))
	 (setq regexp
	       (cond ((aref ch-ca-set ?a) ;"\\ca") ; ASCII
		      "[-_A-Za-z0-9]")	; 後ろ向き、うーんどうすればよいのやら
		     ((aref ch-ca-set ?j)	; Japanese
		      (cond ((aref ch-ca-set ?K) "\\cK") ; katakana
			    ((aref ch-ca-set ?A) "\\cA") ; 2byte alphanumeric
			    ((aref ch-ca-set ?H) "\\cH") ; hiragana
			    ((aref ch-ca-set ?C) ;"\\cC") ; kanji
			     ;"\\cC+\\cH*") ; for okuri-gana ; doesnot work
			     "\\cC")
			    (t "\\cj")))	; fool-proof
		     ((aref ch-ca-set ?k) "\\ck") ; hankaku-kana
		     ((aref ch-ca-set ?r) "\\cr") ; Japanese roman ?
		     ;; etc.
		     (t dabbrev-abbrev-char-regexp))) ; save all
	 (message (category-set-mnemonics ch-ca-set)) (message regexp)
	 (let ((dabbrev-abbrev-char-regexp regexp)
	       ;;(dabbrev-abbrev-skip-leading-regexp "\\s-")
	       )
	   (dabbrev-expand arg)))))
(substitute-key-definition 'dabbrev-expand 'dabbrev-expand-by-category esc-map)

この code は、meadow-users-jp で後藤さんが書かれた idea [meadow-users-jp:2579] をもとに、character set category regexp を使って revise したものです。 (当初の implementation が [meadow-users-jp:4006] にありますが、これは全然動かないので使わないで下さい。) comment がたくさ ん残してあるのは逡巡の軌跡です。

Emacs 20/21/Meadow で使用しています。今のところ不具合は感じていません が見るからに危険です。不具合を発見する度に更新していきたいと思っています。 ご意見ご感想よろしくお願いします。

Note: 松田さんの page には Mule2.3@19.28 の dabbrev.el を使うといい と書かれています。しかしこれには重大な欠陥があって、この dabbrev.el は古 くて dabbrev-expand を発行した buffer 以外の buffer を探す機能が欠けてい ます。これじゃイヤなんです僕は。

Future work: Emacs 20/21 でも、scan_words@syntax.c は word を日本語っ ぽく認識できています(漢字+かな文字で1単語、みたいな。ex. forward-word)。 これを dabbrev に導入できれば、もっと綺麗に robust にまとまると思われま す。頑張ってみたいのですが、上の code で満足してしまったのでやる気が起き ません。

* この文書は無保証です。 [XHTML 1.0 Strict]