我正在寫基於comint模式的派生模式。該模式是一個命令行程序(GRASSIS)的接口,並且comint模式完成對程序起作用。我試圖通過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-
並且不提供這兩個選項。再次點擊標籤第二次插入my-completion-
,以便我現在有ls my-completion-mycompletion-
。
我的實際代碼包含幾行代碼來檢查多行命令,但不會更改完成代碼。使用這個版本的代碼,我打開一個以my-commands
中的程序名稱之一開頭的行上的選項卡,向其提供可能的參數列表以完成該命令,但沒有任何內容插入到緩衝區中,並且列表通過輸入參數的前幾個字母不會縮小。
我已經完成了手冊,但我無法弄清楚編寫completion-at-point
函數的正確方法。任何想法我失蹤?
我已經簡單地看過pcomplete
,但是沒有真正理解'文檔',並沒有取得任何進展。
如果我有一個以上的投票,你會得到一個!感謝您的回答。在我閱讀文檔時,向後搜索應該在與skip-syntax-back相同的位置留下點,但顯然它不是。我也開始使用加載,但功能名稱反轉和不正確的引用。現在一切正常。再次感謝! – Tyler 2012-04-23 11:46:58
很高興這有幫助!考慮到這一點,我懷疑「向後搜索」的問題與反向搜索時正則表達式操作符的貪婪有關。當然''\\ S *「'與空字符串匹配,但即使用'+'替換'*',它仍然只會返回一個非空格字符並停止。 – 2012-04-23 13:06:20