【发布时间】:2012-04-23 04:00:56
【问题描述】:
我正在编写基于 comint-mode 的派生模式。该模式是命令行程序(GRASS gis)的接口,comint 模式完成适用于这些程序。我正在尝试通过completion-at-point-functions 添加对完成程序参数的支持。一个玩具例子是:
(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,但并没有真正理解“文档”,也没有取得任何进展。
【问题讨论】:
标签: emacs elisp tab-completion