私はcomint-modeに基づいて派生モードを書いています。このモードは、コマンドラインプログラム(GRASS gis)へのインタフェースであり、プログラムのコミットモード補完が機能します。私はcompletion-at-point-functions
を介して、プログラムへの引数を完了するためのサポートを追加しようとしています。おもちゃの例です:Emacs完了時点の機能
(setq my-commands
'(("ls"
("my-completion-1")
("my-completion-2"))
("mv"
("my-completion-3")
("my-completion-4"))))
(defun my-completion-at-point()
(interactive)
(let ((pt (point)) ;; collect point
start end)
(save-excursion ;; collect the program name
(comint-bol)
(re-search-forward "\\(\\S +\\)\\s ?"))
(if (and (>= pt (match-beginning 1))
(<= pt (match-end 1)))
() ;; if we're still entering the command, pass completion on to
;; comint-completion-at-point by returning nil
(let ((command (match-string-no-properties 1)))
(when (member* command my-commands :test 'string= :key 'car)
;; If the command is one of my-commands, use the associated completions
(goto-char pt)
(re-search-backward "\\S *")
(setq start (point))
(re-search-forward "\\S *")
(setq end (point))
(list start end (cdr (assoc command my-commands)) :exclusive 'no))))))
(push 'my-completion-at-point completion-at-point-functions)
これはほとんど動作します。私はプログラム名の正常な完了を得る。ただし、コマンドラインでls
と入力した場合、タブを押すとmy-completion-
が挿入され、2つのオプションは表示されません。もう一度、タブを押すとmy-completion-
が挿入され、今度はls my-completion-mycompletion-
になります。
私の実際のコードには、複数行のコマンドをチェックするためにいくつかの行が含まれていますが、完了コードは変更されていません。このバージョンのコードでは、プログラム名の1つで始まる行にタブが表示されますmy-commands
コマンドを完了するための引数のリストが表示されますが、バッファに何も挿入されず、リスト議論の最初の数文字をタイプすることによって狭められることはありません。
私はこのマニュアルを読んできましたが、completion-at-point
関数を書く正しい方法を理解できません。私は何が欠けているすべてのアイデア?
私は簡単にpcomplete
を見ましたが、実際には「ドキュメント」を理解しておらず、進歩もありませんでした。
私は複数の投票権を持っていれば、それも得られます!ご回答有難うございます。私がドキュメントを読んでいるとき、後方検索は、skip-syntax-backwardと同じ場所にポイントを残すべきですが、明らかにそうではありません。私もadd-hookを使い始めましたが、関数名を逆にして間違って引用していました。今はすべてが完璧に動作します。再度、感謝します! – Tyler
うれしかったことがうれしい!もっと考えてみると、 're-search-backward'の問題は、後方検索の際にregexp演算子の貪欲さに関係していると考えられます。もちろん、 '' \\ S * ''は空の文字列にマッチしますが、' * 'を' + 'で置き換えても、空白以外の文字を1つ戻して停止します。 –