我正在写基于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