補完(completion)は、長いキー入力を助けてくれる機能です。 マウスなどを使用して指示をするGUIの場合と違って、 多くのコマンドシステムやプログラムの記述などの場合には、 させたい操作を文字列的にタイプして指示をします。 指示しようとする機能の名前を与えて、それを実行/記述させるわけです。 この場合、もし名前が長かったり、あるいは複雑な構文をしている 場合、それらをすべて覚えておいてそれを正確にタイプするのは至難の技 になります。そして、それを利用者にいつも強いるのはいいシステムとはいえません。
そうすると選択は二つになります。短い名前にしてタイプしやすくするか、 長い名前の入力を助ける機能を用意し、ユーザが困らないようにするか、 です。前者の例には、たとえば、Unixのコマンドなどをあげることができるでしょう。 たとえば、moveのかわりにmv、remove-directoryのかわりにrmdir、といった ものです。これは、大変便利なことが多い半面、「しろうと」には 分かりにくいものになります。けれども頻繁に使う機能の場合には、 簡単に入力できるので、大変使いやすいものでもあります。 後者は、あまり頻繁には使わない機能を用意するような場合、 あるいは初心者の利用が多い場合などに便利でしょう。 名前を説明的にしたりできるからです。 TSSのコマンドシステムでは入力している途中でエスケープキーを たたくと、次には何を入れればよいのか補助する情報を出してくれる ようなものもありました。現在のUNIXのtcshなどのシェルでも 補完機能があります。
Emacsには補完機能があります。これがあるので、Emacsが持っている さまざまな機能を呼び出すのに、完全にそのつづりを覚えていなくても かまいません。また、ファイルを指す際のパス名も「決まり字」まで 入力すればあとは補ってくれます。あるいは候補を出してくれて その中から選択すればいいようになっています。 エディタでは、この連載にでてきたTECOそしてそのOSであったITSなどは もともと名前が長くなるような概念がなく、短い入力で済みました。
今回は、この入力補完機能についてとりあげます。
◎補完機能はどこから来たのか。
「補完機能はどこからはじまったんだろう?」 どうしてもこういうことが気になって多少調べてみました。 たとえばVMSには、コマンド入力中にESCキーをたたくとその先には 何をいれればよいかを助ける情報が出ます。VMSができたのは、 70年台後半です。ITSでは、どうもそうした機能はなかったようです。 前々回のRichardの話のところでも述べましたが、ITSはハッカーマシンで あって、初心者への補助機能などという概念はなかったようです。 もちろんTECOにもITS Emacsにも入力補完の概念はありません。
それで、ひとまずMITコミュニティに聞いてみようと思い立ちました。 (それにはGuy Steele博士の助けを借りました。また、思いもかけず いろいろな人からの反応がありました。紙面を借りて謝意を表します。)
その結果以下のようなことがわかりました。
1)TENEX OSにはESC によるコマンド行の補完機能はあった。
(GLSより)
2)20年前にバークレーで開発されていたSDS 940のOSにその原型があった
のだと思う。また、Jed Donnelleyの RATS system for RISOSには
predictive command completionという機構があった。これは
ESCキーをたたかず最小のキー入力だけで指示に対応しようとするものだ。
70年代の初期のことだと思う。(Mike McMahon氏)
3)CDC 6000シリーズはNSOとKRONOSというOSがあったけれど、それでも
コンソール操作にはコマンド補完機能があった。(Marty Connor氏)
70年代初期のことだが、Tenexより前ともいえないだろう。
4)ITSのDDTにはパス名の補完機能があったとおもう。
けれども6文字で済んでしまうものの補完だから使うほどのことはなく、
実際には使った覚えはない。(Carl Hoffman氏)
5)XDS940にコマンド補完機能があって、Tenexはそれに強く影響を
受けた。Dan Murphyに聞けばもっとよくわかるだろう。
(Mark Crispin氏)
6)Tenexのかなりのアイデアはバークレータイムシェアリングシステムから
来ている。(David A. Moon氏)
これらを総合すると、コマンド行の補完機能は70年代初頭には
いくつかのシステムで存在していたようです。
CDCでは、コマンドを入力していくとその先の可能性を薄い色で提示してくれる、
というような指摘もありました。
以上のことだけではなんとも言えませんが、
この辺のコマンドシステムでの補完は、XDS940に対するバークレーでの
OS開発に端を発しているように見えます。
◎エディタでの補完は?
結論から言って、肝心のこのことについては何も分かりませんでした。 (多少言い訳になりますが、引越し引越しで資料がダンボールの中に 埋もれてしまってお手上げということもあります。 したがって、この原稿をボツにすることも考えたのですが、 いろいろなことを知っているシニアの方々が、ひょっとして、 何か話してくれるのではないか?などとも考え、私の今のところ 調べてわかったことを書いているわけです。ごめんなさい。)
もっとも確実に真相にせまるには、当然のことながら Richard Stallmanに聞くのが一番です。 「tell me the origin of the GNU Emacs completion feature.」 という電子メールを書きました。そうしたら早速返事が来ました。
短い返事でした。 「I don't remember. Some of the design may have come from Gosling Emacs.」(rms)
Gosling Emacsに起源があるだろう(かもしれない)と言っています。 一般に彼とのやりとりのなかで、こういう表現をする場合は、 本当に忘れてしまっているというより、若干整理をして説明するのが 面倒だと思っている場合が多かったので、今回もそのように感じます。 これ以上聞くのは、面と向かってゆっくりと聞ける時でないと無理です。 Gosling Emacsは第X回にとりあげましたが、その資料もダンボールの 中です。また、彼はJavaで多忙しで返事はもらえそうにありません。 Javaの件で先日あった時もたいへんなスケジュールの中でした。 それで、もし、私自身がフォローするなら、 後日あらためてとりあげるしかないと思っています。
以上のようなことが補完についてのイントロです。
Emacsの補完機能については、そのことを詳しくしらべている
亀井さんに登場してもらい、彼にバトンタッチします。
以下は亀井さんの原稿をそのまま載せています。
(いだまさゆき)
◎ Emacsでの補完機能
Emacsの特徴の1つに補完機能があります。補完は、ある名前の省略形を与え た時に、名前の残りの部分を埋めてくれる機能です。Emacsでは、随所にこの補 完機能を使っているため、長ったらしい名前(ファイル名、バッファ名、関数名、 変数名等々)をいちいち全文字タイプしないで済むようになっています。数文字 タイプしては、残りを補完することで目的の文字列を得る、という使い方ができ る訳です。
例えばMule-2.3において、バッファ`*scratch*'で、 `find-read-file-coding-system-from-file-variables' 等という、恐ろしく長い名前の関数(48文字!)を使いたいとします。 これを1文字も間違えずに入力するのは大変なことです。然し、 こんな時に補完が使えれば、`f i n d - r M-TAB'と操作するだけで、 `find-read-file-coding-system-from-file-variables'と 入力したことになります。 また、候補が複数ある場合は、それらの一覧を表示させることもできます。 例えば、ミニバッファで`M-x f i n d ?'と入力すると、 `*Completions*'という名前のバッファが自動的に表示され、そこに`find'で始 まるコマンドの一覧が表示されていると思います(図1)。
---------- Buffer: *Completions* ---------- Click mouse-2 on a completion to select it. In this buffer, type RET to select the completion near point. Possible completions are: find-alternate-file find-dired find-file find-file-other-frame find-file-other-window find-file-read-only find-file-read-only-other-frame find-file-read-only-other-window find-grep-dired find-name-dired find-tag find-tag-noselect find-tag-other-frame find-tag-other-window find-tag-regexp finder-by-keyword ---------- Buffer: *Completions* ---------- 図01 'find'で始まるコマンドの補完候補一覧表示
補完を対話入力以外で使用することはありませんから、 必然的にユーザのミニバッファ入力と深い関連を持つことになります。
説明の方法には、 ・補完機能を構成するプリミティブから高度な関数へと説明してゆく方法 ・ユーザから見たミニバッファでの補完機能からプリミティブへ向けて説明してゆく方法 という2つの方法があります。どちらの切口から説明してゆこうかと考えたので すが、「羽か鉛か?」の質問に、「羽」が選ばれたので(謎)、今回はプリミティ ブの側から説明をしてゆきたいと思います。
なおここでは、
"Mule Version 2.3 (SUETSUMUHANA) of 1995.7.24"
"GNU Emacs 19.28.1 (i486-JE-linux, X toolkit) of Mon Sep 4 1995 on Roy"
を、使用しました。
◎補完プリミティブ
Emacsが提供する補完プリミティブは、次の2つです:
-- Function: try-completion STRING COLLECTION &optional; PREDICATE -- Function: all-completions STRING COLLECTION &optional; PREDICATE NOSPACE`try-completion'は1つの補完結果を得るために使用し、 `all-completions'は全ての一致(match)する補完候補(possible completion)を 得るために使用します (脚注1)。
これら補完プリミティブの処理の流れを表したのが、図02です(脚注2)。
*** ファイル abst-completion.eps を使うこと。 *** 図02
ここで、補完プリミティブに与える要素は、表01の様になります。
いづれのプリミティブも、補完候補の集合COLLECTIONから 入力文字列STRINGと一致する要素を選び出します。 これを一致した補完候補といいます。 各要素の冒頭部分が入力文字列に等しければ一致とみなすのです。 ここで、変数`completion-ignore-case'が非`nil'ならば、 文字列比較において大文字/小文字の区別をしません。
`try-completion'の戻り値は、表02のようになります。
`all-completions'の戻り値は、表03のようになります。
図表中の実行例において、補完候補の集合は、図03のようにalistで定義し、 述語フィルタ用関数は、図04のように定義しています。
(setq pico-table
(list
(cons "PI-CO" (cons "桜文鳥" "F"))
(cons "POPI-" (cons "桜文鳥" "F"))
(cons "FU-CHAN" (cons "セキセイインコ" "M"))
(cons "CHIBI" (cons "セキセイインコ" "M"))
(cons "MA-CHAN" (cons "セキセイインコ" "F"))
(cons "CHI-CHAN" (cons "セキセイインコ" "F"))
(cons "RO-RI-" (cons "カナリア" "M"))
(cons "RO-RA" (cons "カナリア" "F"))
(cons "PICO" (cons "ツキノワインコ" "M"))
(cons "PIPPI" (cons "コザクラインコ" "F"))
(cons "PICOPON" (cons "?" "F"))))
図03 補完候補の集合
(defun ftest (cell)
(string= (cddr cell) "F"))
図04 述語フィルタ用関数
◎プログラム補完(Programmed Completion)予め補完候補の集合を用意することが困難な場合、入力文字列を元にして 補完候補の集合を動的に求めることができます。これをプログラム補完といいま す。補完を行なう関数の、引数補完候補の集合に、自作関数のシンボルを渡して 使います (脚注3)。
自作関数は、3つの引数「入力文字列、述語フィルタ、フラグ」 を受け付けるように作成します。このフラグの値に応じた3つのモードで動作し なければなりません。
フラグの値と期待される動作は、表04の通りです。
プログラム補完の実行例を、図10に示します。
;; "PIPPI"の一致補完候補は、"PIPPI"唯一つであり、
;; それは入力文字列自身と等しいので、完全一致。
(try-completion "PIPPI" pico-table)
⇒ t
図05 完全一致の例
;; "PICO"の一致補完候補には、"PICO"と"PICOPON"の2つがあるので、
;; 両者の共通部分である"PICO"になる。完全一致ではない。
(try-completion "PICO" pico-table)
⇒ "PICO"
;; 今度は述語フィルタによって、一致補完候補が"PICOPON"唯一つになったが、
;; 入力文字列とその一致補完候補とは等しくないので、
;; やはり完全一致ではない。
(try-completion "PICO" pico-table 'ftest)
⇒ "PICOPON"
図06 一致補完候補ありの例
;; @r{"PIYO"で始まる補完候補は存在しない。}
(try-completion "PIYO" pico-table)
⇒ nil
;; "FU-CHAN"は唯一の一致補完候補であったが、
;; 述語フィルタによって除去された。
(try-completion "FU-CHAN" pico-table 'ftest)
⇒ nil
図07 一致補完候補無しの例
;; 複数の補完候補が一致する場合。
(all-completions "PICO" pico-table)
⇒ ("PICO" "PICOPON")
;; 上の例と同じだが、述語フィルタによって"PICO"は除去された。
(all-completions "PICO" pico-table 'ftest)
⇒ ("PICOPON")
図08 一致補完候補ありの例
;; "PIYO"に一致する補完候補は無い。
(all-completions "PIYO" pico-table)
⇒ nil
図09 一致補完候補無しの例
;; これが、自作関数です。
;; 入力文字列に、拡張子をつけたものを、補完候補の集合とします。
(defun zic-comp-func (input pred type)
(let*
((idx (string-match "\\.[^.]+$" input))
(substr (if idx
(substring input 0 idx)
input))
(zic-table
(list (cons (concat substr ".bdf") "X")
(cons (concat substr ".snf") "X")
(cons (concat substr ".pcf") "X")
(cons (concat substr ".fon") "WIN")
(cons (concat substr ".fnt") "DOSV"))))
(cond
((eq type 'lambda) (if (assoc input zic-table) t))
((eq type t) (all-completions input zic-table pred))
(t (try-completion input zic-table pred))
)))
;; これが、述語フィルタ。
(defun zic-test (s)
(string= (cdr s) "X"))
;; -------------------------------------------------------------
;; 述語フィルタ無しで、補完します。
(try-completion "name" 'zic-comp-func)
⇒ "name."
;; 同じく、補完候補のリストを見ます。
(all-completions "name" 'zic-comp-func)
⇒ ("name.bdf" "name.snf" "name.pcf" "name.fon" "name.fnt")
;; 述語フィルタをかけて、補完します。
(try-completion "name" 'zic-comp-func 'zic-test)
⇒ "name."
;; 同じく、補完候補のリストを見ます。
(all-completions "name" 'zic-comp-func 'zic-test)
⇒ ("name.bdf" "name.snf" "name.pcf")
;; 入力文字列に、拡張子の一部を書きます。
(try-completion "name.f" 'zic-comp-func)
⇒ "name.f"
;; 同じく、補完候補のリストを見ます。
(all-completions "name.f" 'zic-comp-func)
⇒ ("name.fon" "name.fnt")
図10 プログラム補完の実行例
◎ミニバッファ入力Emacsがユーザから入力を文字列で受け取る場合は、ミニバッファを使います。 ミニバッファからの入力を受け取るには、`interactive'宣言を使用するのが普 通ですが、直接ミニバッファ入力関数を使用することも可能です。
ミニバッファ入力で使用するプリミティブ関数は、表05の2つです(脚注4)。
Emacsは、文字列入力、ファイル名入力、バッファ名入力、 コマンド名入力等々といった使用目的に特化したミニバッファ入力コマンドも提 供しています。これら高水準補完関数は、上記プリミティブをラップ(wrap)する ことで、作られています。
`interactive'宣言でコード文字を使用した場合には、 それら高水準補完関数が、`call-interactively' (脚注5) の中から呼び出されるようになっています。これは、 Emacsのコマンドの引数をミニバッファ入力する場合に使用されます。
従って、標準のEmacsが補完を使ってミニバッファ入力を行なう場合、 いづれにせよ、最終的に`completing-read'が呼ばれます。
余談ですが、Emacsのミニバッファの入力モードの変更方法は、
キーマップを切替えることで実現しています。つまり、キーマップを切替えるこ
とで、キーに割り当てられているコマンドが変わるので、ユーザからはミニバッ
ファの入力モードが変わったように見えるのです。
○補完付ミニバッファ入力(Minibuffer Input with Completion)
Emacsにおける補完付ミニバッファ入力を理解するには、 結局`completing-read'を理解すれば良いことになります。
その前に、補完付ミニバッファ入力には、3種類あることを説明します。 補完付ミニバッファ入力では、SPCやTABによって、 文字列の補完を行なうことができます (脚注6)。 また、?によって、一致補完候補の一覧を別バッファに見ることができます (脚注7)。
補完付ミニバッファ入力は、その入力文字列の確定動作、 即ち、LFDあるいはRETの働きによって、表06の3通りに分類されます。
`completing-read'のインタフェースは、次の通りです: -- Function: completing-read PROMPT COLLECTION &optional; PREDICATE REQUIRE-MATCH INITIAL HIST
ここで、`completing-read'に与える引数は、表07の様になります。
◎その他の補完
標準のEmacsが提供するのとは少し違う、補完の仕組みもあります。 研究してみると面白いでしょう。
次の2つを紹介します:
・部分補完(Partial Completion) ・段階的補完(Incremental Completion)
○部分補完
部分補完とは、デリミタで区切られた単語の列がある場合に、 各単語がそれぞれ独立に補完できるというものです。図15が、その実行例です。
部分補完は、ライブラリ`complete'をロードすることで、利用可能になりま す。
○段階的補完
ミニバッファからコマンド名入力を行なう際に、今入力している文字列が どんなコマンドに補完され得るかを、入力1文字毎に、常に表示し続ける補完で す。
例を図16に示します。
段階的補完は、ライブラリ`icomplete'をロードすることで、 利用可能になります。Emacs 19.28でも利用可能ですが、 振舞が副モードのようになったEmacs 19.29以降で利用するのが望ましいでしょう。 (かめいのぶよし) ============================================================ 脚注: (1) `all-completions'の第4引数NOSPACEは、Emacs 19.29で追加さ れた。 (2) この辺りの処理の流れについては、`src/minibuf.c'の `try-completion'や`all-completions'の定義を見れば分かる。 (3) Emacsは、プログラム補完をファイル名補完に使用してる。 `src/fileio.c'の高水準補完関数`read-file-name'で使用する、 `read-file-name-internal'がそれである。ここでは、述語フィルタに相当 する引数を、ディレクトリ名を渡すために流用している。 (4) 実装は若干違うが、意味論的にはこう言い切って良いと思う。 `src/minibuf.c'を参照のこと。 (5) `src/callint.c' (6) `minibuffer-complete-word', `minibuffer-complete'。いづれ も、`try-completion'を利用。 (7) `minibuffer-completion-help'。`all-completions'利用。
(completing-read "Name: " pico-table nil t "C")
;; 評価すると、
---------- Buffer: Minibuffer ----------
Name: C■
---------- Buffer: Minibuffer ----------
;; RETをタイプ。
---------- Buffer: Minibuffer ----------
Name: CHI■
---------- Buffer: Minibuffer ----------
;; 一致補完候補が複数あるので、ミニバッファを抜けることができない。
;; 確認のため、?をタイプ。
---------- Buffer: *Completions* ----------
Click mouse-2 on a completion to select it.
In this buffer, type RET to select the completion near point.
Possible completions are:
CHI-CHAN CHIBI
---------- Buffer: *Completions* ----------
;; "CHIBI"を選択すべく、`B'とタイプし、
---------- Buffer: Minibuffer ----------
Name: CHIB■
---------- Buffer: Minibuffer ----------
;; RETをタイプ。
⇒ "CHIBI"
図12 厳密補完の例
(completing-read "Name: " pico-table nil 'lambda "C")
;; 評価すると、
---------- Buffer: Minibuffer ----------
Name: C■
---------- Buffer: Minibuffer ----------
;; RETをタイプ。
---------- Buffer: Minibuffer ----------
Name: CHI■
---------- Buffer: Minibuffer ----------
;; 一致補完候補が複数あるので、ミニバッファを抜けることができない。
;; "CHIBI"を選択すべく、`B'とタイプし、
---------- Buffer: Minibuffer ----------
Name: CHIB■
---------- Buffer: Minibuffer ----------
;; RETをタイプ。
---------- Buffer: Minibuffer ----------
Name: CHIBI■(Confirm)
---------- Buffer: Minibuffer ----------
;; "(Confirm)"という確認表示が現れたので、
;; 更に、RETをタイプ。
⇒ "CHIBI"
図13 確認補完の例(1)
(completing-read "Name: " pico-table nil 'lambda "C")
;; 評価すると、
---------- Buffer: Minibuffer ----------
Name: C■
---------- Buffer: Minibuffer ----------
;; RETをタイプ。
---------- Buffer: Minibuffer ----------
Name: CHI■
---------- Buffer: Minibuffer ----------
;; 一致補完候補が複数あるので、ミニバッファを抜けることができない。
;; "CHIBI"を選択すべく、`B'とタイプし、
---------- Buffer: Minibuffer ----------
Name: CHIB■
---------- Buffer: Minibuffer ----------
;; TABをタイプ。
---------- Buffer: Minibuffer ----------
Name: CHIBI■
---------- Buffer: Minibuffer ----------
;; 更に、RETをタイプ。
⇒ "CHIBI"
;; 既に補完候補に一致していたので、
;; "(Confirm)"という確認要求は無かった。
図14 確認補完の例(2)
;; `M-x l SPC l'とタイプする。
---------- Buffer: Minibuffer ----------
M-x l-l■
---------- Buffer: Minibuffer ----------
;; TABによって、(部分)補完する。
---------- Buffer: Minibuffer ----------
M-x lo■-library
---------- Buffer: Minibuffer ----------
;; `?'によって、補完候補を見る。
---------- Buffer: *Completions* ----------
Click mouse-2 on a completion to select it.
In this buffer, type RET to select the completion near point.
Possible completions are:
load-library locate-library
---------- Buffer: *Completions* ----------
;; `a'をタイプし、
---------- Buffer: Minibuffer ----------
M-x loa■-library
---------- Buffer: Minibuffer ----------
;; 更に、TABによって補完する。
---------- Buffer: Minibuffer ----------
M-x load-library■
---------- Buffer: Minibuffer ----------
;; 完全に補完された。
図15 部分補完の実行例
;; `M-x l'とタイプ。
---------- Buffer: Minibuffer ----------
M-x l■{ocate-library,isp-indent-line,ist-tags,ist-buffers,ist-faes-
---------- Buffer: Minibuffer ----------
;; このように、`l'で始まるコマンド名が表示される。
;; 更に1字、`o'とタイプ。
---------- Buffer: Minibuffer ----------
M-x lo■{cate-library,wer-frame,ad-file,ad-library,cal-unset-key,cal-
---------- Buffer: Minibuffer ----------
;; `lo'で始まるコマンド名に、候補が絞られる。
;; 更に、`a d'とタイプ。
---------- Buffer: Minibuffer ----------
M-x load■(-){file,library}
---------- Buffer: Minibuffer ----------
;; 更に、`SPC l'とタイプ。
---------- Buffer: Minibuffer ----------
M-x load-l■(ibrary) [Matched]
---------- Buffer: Minibuffer ----------
図16 段階的補完の実行例
=====================================================
***** 表のあつまり *****
=====================================================
┌───────────────────────────┬───────────────────────────────────┐
│ 要素 │ 意味 │
├────────┬──────────────────┼───────────────────────────────────┤
│入力文字列 │引数STRING │補完する文字列。 │
├────────┼──────────────────┼───────────────────────────────────┤
│補完候補の集合 │引数COLLECTION │入力文字列の一致対象。この集合の各要素に、入力文字列の一致を試みる。 │
│ │ │集合の与え方には、次の3通りがある: │
│ │ │ ┌─────┬──────────────────────────┐│
│ │ │ │タイプ │働き ││
│ │ │ ├─────┼──────────────────────────┤│
│ │ │ │obarray │各要素の印字名(printed name)が補完候補。 ││
│ │ │ ├─────┼──────────────────────────┤│
│ │ │ │alist │各要素のCAR部が補完候補。 ││
│ │ │ │ │CDR部は各要素の付加情報として利用可能。 ││
│ │ │ ├─────┼──────────────────────────┤│
│ │ │ │関数である│補完自体を行なう関数。入力文字列に応じて、 ││
│ │ │ │シンボル │動的に補完候補を生成/決定するために使用する。 ││
│ │ │ │ │これによって、プログラム補完(programmed completion) ││
│ │ │ │ │と呼ぶ独自の補完方法を定義することもできる。 ││
│ │ │ └─────┴──────────────────────────┘│
├────────┼──────────────────┼───────────────────────────────────┤
│正規表現フィルタ│変数'completion-regexp-list' │補完候補を絞り込むフィルタ。補完候補が満たすべき正規表現のリスト。 │
│ │ │'nil'ならば、絞込みはしない。 │
├────────┼──────────────────┼───────────────────────────────────┤
│述語フィルタ │引数PREDICATE │補完候補を絞込むフィルタ。 │
│ │ │補完候補はこの述語の検査を通過しなければならない。 │
│ │ │'nil'ならば、絞込みはしない。 │
│ │ │述語は補完候補の集合がobarrayならば、その要素のシンボルを、 │
│ │ │alistならば、その要素のconsセルを1つの引数として受け取る。 │
└────────┴──────────────────┴───────────────────────────────────┘
表01 補完プリミティブに与える要素
┌───────────────┬───────────────────────────┬───┐
│戻り値 │ 意味 │実行例│
├───────────────┼───────────────────────────┼───┤
│'t' │完全一致(exact match)の場合。 │ 図05 │
│ │入力文字列が、その唯一の一致補完候補と等しかった場合。│ │
├───────────────┼───────────────────────────┼───┤
│最長共通部分文字列 │一致補完候補ありの場合。 │ 図06 │
│(the longest common substring)│全ての一致補完候補に共通な冒頭部分の文字列。 │ │
├───────────────┼───────────────────────────┼───┤
│'nil' │一致補完候補無しの場合。 │ 図07 │
└───────────────┴───────────────────────────┴───┘
表02 'try-completion'の戻り値
┌───────┬────────────┬───┐
│ 戻り値 │ 意味 │実行例│
├───────┼────────────┼───┤
│文字列のリスト│一致補完候補ありの場合。│ 図08 │
├───────┼────────────┼───┤
│'nil' │一致補完候補なしの場合。│ 図09 │
└───────┴────────────┴───┘
表03 'all-completions'の戻り値
┌────┬──────────┬──────────────┐
│フラグ │期待される振舞 │ 戻り値 │
├────┼──────────┼────┬─────────┤
│ `nil' │ `try-completion' │ `t' │完全一致 │
│ │ │ 文字列│最長共通部分文字列│
│ │ │ `nil' │一致補完候補無し │
├────┼──────────┼────┼─────────┤
│`lambda'│ 完全一致の検査 │ `t' │完全一致 │
│ │(`assq', `assoc'等) │ `nil' │非完全一致 │
├────┼──────────┼────┴─────────┤
│ `t' │ `all-completions' │ 一致補完候補のリスト │
└────┴──────────┴──────────────┘
表04 プログラム補完のフラグに対応する、期待される振舞と戻り値
┌───────────┬─────────────────────┐
│ 関数 │ 機能 │
├───────────┼─────────────────────┤
│`read-from-minibuffer'│ミニバッファから文字列を読み込む。 │
├───────────┼─────────────────────┤
│`completing-read' │ミニバッファから補完付で文字列を読み込む。│
└───────────┴─────────────────────┘
表05 ミニバッファ入力関数
┌────────────┬──────────────────┬────────────────────────┬────┐
│補完タイプ │使用キーマップ │RETキーの働き │ 実行例 │
├────────────┼──────────────────┼────────────────────────┼────┤
│任意補完 │`minibuffer-local-completion-map' │補完可能だが、結果は補完候補でなくても良い。 │ 図11 │
│(permissive completion) │ │(ミニバッファの内容をそのままにして、 │ │
│ │ │ ミニバッファを抜ける) │ │
├────────────┼──────────────────┼────────────────────────┼────┤
│厳密補完 │`minibuffer-local-must-match-map' │結果は補完候補のいづれかでなければならない。 │ 図12 │
│(strict completion) │(変数`minibuffer-completion-confirm'│(ミニバッファの内容を補完した結果が、 │ │
│ │ が`nil'の時) │ 補完候補に等しければミニバッファを抜ける) │ │
├────────────┼──────────────────┼────────────────────────┼────┤
│確認補完 │`minibuffer-local-must-match-map' │厳密補完の一種。 │ 図13 │
│(cautious completion) │(変数`minibuffer-completion-confirm'│(ミニバッファの内容が既に補完候補に等しければ、 │ 図14 │
│ │ が非`nil'の時) │ そのままミニバッファを抜ける。 │ │
│ │ │ あるいは、ミニバッファの内容を補完した結果が、 │ │
│ │ │ 補完候補に等しければ確認を求めてくる) │ │
└────────────┴──────────────────┴────────────────────────┴────┘
表06 補完付ミニバッファ入力の3タイプ
┌───────┬───────────────────────┐
│引数 │意味 │
├───────┼───────────────────────┤
│PROMPT │ミニバッファに表示するプロンプト。 │
├───────┼───────────────────────┤
│COLLECTION │補完候補の集合。`try-completion'に同じ。 │
├───────┼───────────────────────┤
│PREDICATE │述語フィルタ。`try-completion'に同じ。 │
├───────┼───────────────────────┤
│REQUIRE-MATCH │補完動作の指定: │
│ │ ┌────┬──────┐ │
│ │ │ 値 │ 動作 │ │
│ │ ├────┼──────┤ │
│ │ │`nil' │ 任意補完。│ │
│ │ ├────┼──────┤ │
│ │ │`t' │ 厳密補完。│ │
│ │ ├────┼──────┤ │
│ │ │それ以外│ 確認補完。│ │
│ │ └────┴──────┘ │
├───────┼───────────────────────┤
│INITIAL │初期入力。ミニバッファの初期入力。 │
├───────┼───────────────────────┤
│HIST │履歴リスト変数。 │
│ │ミニバッファ履歴で使用する(今回は説明を省略)。│
└───────┴───────────────────────┘
表07 'completing-read'の引数