複数の展開候補を表示して補完する動的略語展開 (未完成)


新バージョン, そして, エントリ作成.

今度は, 上記 URL で更新してく.


まだ, 完全には, 完成してないけど, とりあえずアップしてみる.
今のまんまでも, 使えないことはない.
というか, 自分は, 使ってる.
まあ, 自分の場合は, 動作テストも兼ねてるけどね.



どんなもんかというと, 動的略語展開の候補をミニバッファに複数表示して,
それを(ユーザが)選択して補完できますよーっていう関数.


動的略語展開は, M-\M-/ (dabbrev-expand) に割り当てられていて,
ポイント下の語を以前に打った語句から補完してくれる, というもの.


例えば, test.txt を編集していて, バッファ内には,
既に「Perl」, 「Python」, 「Partner」という語句を打っていたとする.
ここで, ユーザは, Pまで押して, dabbrev-expand を実行したならば,
(ポイントから Perl の方が近ければ,) Perl と P を補完してくれる.
こういう機能.


ここで, 自分が作成したものは, 上記の例で言うと,
P で, 複数の補完候補を表示する動的略語展開の関数を実行したならば,
「(C-a): Perl (C-s): Python (C-d): Partner」
とミニバッファに表示し, 選択を促す.
ここで, \C-a を押すと, Perl と, \C-s を押すと, Python と補完される.
選択が表示されてるまま何もしないで 5 秒ほっておくとタイムアウトとなり,
勝手に関数の実行が終了する.



この関数のソース.

(defun dabbrev-expand-multiple ()
  "動的略語展開において, 補完候補を複数掲示する関数.
補完候補は, 3つまでミニバッファに表示される.
C-a, C-s, C-d により, 補完が可能.
ミニバッファに候補を表示したまま, 5秒間何もしないと,
タイムアウトとなり, 関数の実行が終了する.
現在, 前方検索するか, 後方検索するかを分ける前置引数,
最大の補完候補の数の変更,
補完に使用するキーの変更等の柔軟性は一切考慮していない.

補完候補の数を3つに制限しているのは,
補完候補が無いという場合に当たった場合(nil を返戻),
通常より処理に時間がかかってしまうため."
  (interactive)
  (let ((abbrev-list '()) (num 0) (max-loop 3)
        target length abbrev action)
    (setq target (dabbrev--abbrev-at-point))
    (setq length (string-width target))
    (while (and (< num max-loop)
                (setq abbrev (dabbrev--find-expansion target 0 t)))
      (add-to-list 'abbrev-list abbrev)
      (setq num (1+ num)))
    (dabbrev--reset-global-variables)
    (setq action (read-char
                  (format "(C-a): %s (C-s): %s (C-d): %s"
                          (nth 2 abbrev-list) (nth 1 abbrev-list)
                          (nth 0 abbrev-list))
                  nil 5))
    (cond ((equal action nil) (message "did timeout."))
          ((equal action ?^A) (insert (substring (nth 2 abbrev-list) length)))
          ((equal action ?^S) (insert (substring (nth 1 abbrev-list) length)))
          ((equal action ?^D) (insert (substring (nth 0 abbrev-list) length)))
          (t (message "quit.")))))

うはっ, 似たような処理, まとめずに書きまくり.
M-x dabbrev-expand-multiple で実行できる.
普段から使うならば, 何らかのキーに割り当てるといいと思う.
名前は, とりあえず, 分かりやすさ重視で, この名前にしてみた.
ほんとなら, 頭に my- とか, khiker- とかつけるべきやね. つけるか?
一応念のため書いとくけど, 上の ^A とかは, \C-q\C-a とか,
\C-a, \C-s, \C-d の頭に \C-q を付けて実行して挿入される文字やから.
(追記)たぶん, 上のそのままコピーしたんじゃ駄目やなあ. ^A を \C-q\C-a で挿入される文字に, ^D を \C-q\C-d で挿入される文字に・・・のようにしないと.
というか, 一度, M-/ を実行しないと使えないかも, これ.
うーん問題でまくりだ.



それで, 現在, この関数にある問題点.

  • 補完候補の表示は, 3つに固定される.
  • 補完に使用するキーも固定される.
  • 補完候補の数が 3 つより少い場合, 処理に時間がかかる.
  • 補完候補の数が 3 つより少い場合でも, 補完候補表示のミニバッファには, 3つの補完候補を表示してしまう. この場合は, nil と表示される.
  • 補完を前方にするとか, 後方にするとか考えていない.

ざっと上げたくらいでこんなにある.
一応, 補完候補を 3 つに固定したのは, 補完候補が 3 つ無い場合,
補完候補を探す処理が隅々まで探しに行ってしまうため, ちょっち処理に時間がかかってしまうから, ってのが理由.
補完候補数を増やすと, その問題にぶちあたりやすくなるし.


この関数を作ってみた理由は, 通常の動的略語展開だと,
欲しい補完が遠くにあった場合, 連続して, M-\M-/ を入力しなきゃならんから面倒ってのが始まり.
とりあえず, 3つにするだけで, どれだけ有効になるかを調べてみようと思う.
今回作成したこの関数だと, 通常の動的略語展開に比べて, 選択という処理が1つ増えてるからそれがどうだとかもあるし.
# 通常の動的略語展開だと, M-\M-/ を押した時点で略語が挿入される.
使い易そうなら, 略語の参照元をハイライトしてみたりしてもいいよね.

更新時刻

  • 1かいめ 2007年, 7月25日, 20:20
  • 2かいめ 2007年, 7月25日, 21:19