[ホーム]-> [Emacs]-> [活用法]-> [abbrev]

Abbrev (略称展開)

1. Abbrev とは

Abbrev とは要するに、略称展開です。 Emacs ファンの中には、この abbrev が便利だから離れられないのだという人も多いようです。 うまく使いこなせばかなりタイプ量が減らせることでしょう。

ただし、日本語との相性が今一つなことと、日本語の場合 IME の辞書登録でもある程度似たようなことが可能なこと (特に SKK の補完機能は使い勝手が良いと思う) から、 逆に全く使わない人もいます。 ただ、専用の略称展開はやはり便利です。 因みに後で expand.el という、こいつの拡張版を紹介しますが、これは abbrev を使えることが前提になっているので、まずはこちらから説明します。

Emacs には基本的に二種類の略称展開機能が備わっています。

1. は文章の前後関係を見ての展開、2. は予め予約しておいた略称の展開です。 プログラムを書くような場合を除き、1. の方を良く使うことが多いかもしれません。


2. 動的略称展開

2.1. 使い方

こちらは特に何も設定せずに使えます。例えば次のような文章を編集しているとしましょう。

     abbreviation というのは、略称とか省略形の意味である。例えば、いち    
     いち abb

当然、ここで abb の次には reviation が続かなければならないわけですが、 これを全てタイプする代わりに、M-/ とタイプしてみて下さい。

     abbreviation というのは、略称とか省略形の意味である。例えば、いち    
     いち abbreviation

のように補完されるはずです。つまり M-/ (dabbrev-expand) は、カーソル直前の単語を、 バッファ内にある単語で補完するコマンドなのです。今の場合で言えば、カーソル直前には `abb' があるので、これを同じバッファ内にある abbreviation で補完したというわけです。

バッファ内に複数の abb で始まる単語がある場合はどうかというと、 テキストの後方 (つまり、普通に文章を書いている場合に過去に書いた部分) にある一番カーソルに近いものがまず補完されます。 そうしてもしバッファの先頭まで行っても補完する単語が見つからない場合は、 テキストの前方 (普通に文章を書いている場合に、これから書いていく方向) に向かって探します。それでも無ければ何もしません。

もし最初に補完された単語が気に入らない場合は、更に続けて M-/ (dabbrev-expand) をタイプすることで次の候補が補完されます。 即補完するのではなく、取り敢えずどんな候補があるか見たい場合は M-C-/ (dabbrev-completion) を使います。 窓を二つに分割して、補完候補を表示してくれるはずです。 もし順序が最初から分かっているなら、数値引数を与えることで明示的に補完することもできます。 例えば C-u 3 M-/ とすれば、3番目にでてくるべき候補で補完されます。

動的略称展開は、次に説明する静的略称展開と同時に使うことができます。

2.2. カスタマイズ

動的略称展開の欠点は日本語の文章と相性が悪いことです。 全く使えないわけではありませんが、単語の区切というものが判然としないので、たいてい補完しすぎてしまうのです。以前は, 設定である程度回避できたのですが, Emacs 20 の頃から一筋なわではいかないようになってしまいました。

この問題の解消には土屋さんが knagano さんの技法 を reimplement された dabbrev-ja.el を使うのが良いようです。使い方は dabbrev-ja.elload-pathに置き, .emacs.elなどの初期ファイルに
(require 'dabbrev)
(load "dabbrev-ja")
と書いておけばよいでしょう。 なお土屋さんの 強調表示付き動的略称展開 の項も参考になります。

なお、私はキー設定もいじってますが、 それについては次の静的略称展開の設定の所を御覧下さい。

3. 静的略称展開

3.1. 設定

取り敢えず、私の .emacs.el の abbrev 関係の設定です。

(setq abbrev-file-name "~/.abbrev_defs")
(setq save-abbrevs t)
(quietly-read-abbrev-file)
;; 以下は単なる好み。
(global-set-key "\C-x'" 'just-one-space)
(global-set-key "\M- " 'dabbrev-expand)
(global-set-key "\M-/" 'expand-abbrev)
(eval-after-load "abbrev" '(global-set-key "\M-/" 'expand-abbrev))

下のキーの設定部分については、明示的な略称展開キーを使った展開のところも参照して下さい。

3.2. 略称の登録

静的略称展開は、展開する略称を書いた略称 table を書かないことには何もしてくれません。 固有の table を持っているモードも多いのですが、中身は基本的には空っぽです。 そのセッション限りの使い捨て略称を使うことも多いでしょう。 また特定のモードで恒常的に使うような略称も、編集しながら少しずつ略称を足していく方が実際に使える table ができることでしょう。

普通の文章を書いている時で説明します。例えば longlongword という単語をよく使うのだが、 次からいちいちこのように入力するのは大変だと思ったとしましょう。 その場合 longlongword の直後にカーソルがある状態で C-x a l (add-mode-abbrev) とします。 (各モードに共通の略称の場合は C-x a g (add-global-abbrev) を使います。) すると、ミニバッファで

    Mode abbrev for "longlongword":    

と聞いてくるので、例えば llw と答えます。すると、 text-mode-abbrev-tablellw が longlongword と展開できるように登録されます。

試しに llw と書いて、カーソルが llw の直後にある所で C-x ' (expand-abbrev) (上の私の設定のように、 M-SPCexpand-abbrev を割り当ててる場合は M-SPC) としてみて下さい。 longlongword と展開されるはずです。

ところで lisp-mode ではハイフン (-) を単語の区切として認識してしまうので、 このような方法ではうまくないです。 直接登録するには、 M-x define-mode-abbrevM-x define-global-abbrev を使います。例えば M-x define-mode-abbrevとすると、

    Define mode abbrev:            

と聞いてくるので、ここで rfm と入力します。すると

    Expansion for rfm:            

と聞いてくるので、read-from-minibuffer と答えます。 これで、rfm が read-from-minibuffer と展開できるようになります。

いちいちこのようなことをせずに、直接 table を編集したいときには、 M-x edit-abbrevs とします。すると *Abbrevs* というバッファが開いて、そこに

(java-mode-abbrev-table)
.....

などと表示されるので、編集したい table のところに移ります。後は

(lisp-mode-abbrev-table)
"rfm"          0    "read-from-minibuffer"
"i"            0    "interactive"

などと編集していきます。編集し終わったら C-c C-c とすると、 そこに書いた内容が反映されるようになります。 真中の数字は略称展開が使われた回数を表します。 あまり使わないものを削除したりするときに参考になるでしょう。

今回の table を次回からも使いたいときは、 M-x write-abbrev-file とすると、保存するファイル名を聞いてくるので、 適当なファイルを答えます。 デフォルトは ~/.abbrev_defs です。 これは、abbrev-file-name という変数で設定できますが、 普通は変更しなくてもよいでしょう。

Info を見ると明示的に指定しなくても Emacs を終了する際や、 C-x s などのコマンド実行時に保存するか聞いてくると書かれているのですが、 私の場合は何もしなくても save-abbrevs という変数が nil になっているようで、何もせずに終了してしまいました。 ちゃんと .emacs.el

(setq save-abbrevs t)

と書いとくと良いでしょう。

3.3. 展開の仕方

基本的な展開方法は二種類あります。一つは M-x abbrev-mode として、自動的な略称展開機能を使う方法。 もう一つは明示的な展開キーを使って略称展開する方法です。

3.4. 自動的な略称展開

M-x abbrev-mode とすると、minor mode である abbrev-mode が on になり、モードラインが

 [--]E.:--**-Emacs: test.el           (Emacs-Lisp Abbrev)--L31--Bot-------- 

のように変化するはずです。off にしたい場合はもう一度 M-x abbrev-modeとするだけです。

abbrev-mode を on にした状態では SPCや句読点等を押した時に自動的に略称展開がなされます。 例えば、Emacs Lisp mode で read-from-minibuffer を rfm で登録した場合には、rfm とタイプした時点で SPC を 押せば、自動的に read-from-minibuffer と展開されるわけです。 また、interactive を i に登録してあれば、(i に続けて ) SPC を押すと (interactive) となります。 勝手に略称展開されて困る場合は、C-q に続けて文字をタイプします。

3.5. 明示的な略称展開キーを使った展開

略称展開キーは、デフォルトでは C-x ' です。 longlongword を llw に登録してあれば、llw の直後で C-x ' とタイプすれば longlongword に展開できます。

4. キーの交換について

しつこいですが、プログラムを良く書く人など、動的な略称展開よりもこちらを多用する場合は、M-SPC などと交換するのもよいかもしれません。 「GNU Emacs ガイドブック」を書かれた亀井信義さんは、

   M-SPC => C-x ' => M-/    

というふうに割り当てをぐるりと回した形で変更しているらしいです。 これはなかなか賢いなあーと思いました。 デフォルトでは M-SPC はカーソル付近の TAB や空白を一つの空白に圧縮するコマンドである just-one-space に割り当てられています。 欧文中心の方は良く使うかもしれませんが、日本語中心の人は多分 M-\ (delete-horizontal-space) の方を多用するのではないでしょうか。 このような設定にする方法は、上にも書いてますが、次のような感じです。

(global-set-key "\C-x'" 'just-one-space)
(global-set-key "\M- " 'dabbrev-expand)
(global-set-key "\M-/" 'expand-abbrev)
(eval-after-load "abbrev" '(global-set-key "\M-/" 'expand-abbrev))

[ホーム]-> [Emacs]-> [活用法]-> [abbrev]