如何改进这个Emacs Lisp函数?

3

意图是使用git grep作为M-x grep命令,并利用所有与其相关的缓冲区优势。期望功能如下:

  • 它将读取点处的单词/内容作为默认值(已完成,有点)
  • 如果设置了区域,则它将读取当前区域作为默认参数。

以下是我目前的代码:

(defun bw-read-string-at-point ()
  (interactive)
  (let ((word (word-at-point)))
    (set-text-properties 0 (length word) nil word)
    word))

(defun bw-git-grep (search-str)
  "Uses `git-grep` to find `search-str`"
  (interactive
   (list
    (read-string (format "Search for (%s): " (bw-read-string-at-point)))))
  (let ((search-str (if (= (length search-str) 0)
                        (bw-read-string-at-point) search-str)))
    (grep (concat "git --no-pager grep -i -I -nH --no-color --extended-regexp " search-str))))

我觉得这里的interactive有些笨拙,可以改进得更好。

2个回答

4

实际上,它看起来相当不错。除了你应该使用read-stringdefault参数,而bw-read-string-at-point中的interactive不应该存在。或者更好的方法是,只需使用grep-tag-default。以下是我对它进行微调的方式:

(defun bw-git-grep (search-str)
  "Uses `git-grep` to find `search-str`"
  (interactive
   (let ((default (grep-tag-default)))
    (list
     (read-string (format "Search for (default %s): " default)
                  nil nil default))))
  (grep (concat "git --no-pager grep -i -I -nH --no-color --extended-regexp " search-str)))

grep-tag-default 是从哪里来的?我在 Emacs 24.2 中找不到它。编辑:实际上没关系,我找到了。由于某种原因,C-h f 找不到它。 - Brad Wright
啊,是的,你可能需要(require 'grep)来确保grep-tag-default被定义。 - Stefan

1
我会使用read-from-minibuffer而不是read-string:
(defun bw-git-grep (pattern)
  (interactive
   (list
    (read-from-minibuffer
     "Search for: "
     (if (region-active-p)
         (buffer-substring-no-properties (region-beginning) (region-end))
       (thing-at-point 'word)))))

  (let* ((grep-command "git --no-pager grep -i -I -nH --no-color --extended-regexp ")
         (command      (concat grep-command pattern))
         (grep-use-null-device nil))
    (grep command)))

此外,您可能需要确保 grep-use-null-device 为 nil,以避免 grep/dev/null 添加到您的命令中(这似乎不太受 git 的欢迎)。

我建议不要这样做:通常情况下,read-stringread-from-minibuffer更可取,在你上面的例子中,`read-from-minibuffer'没有任何好处。 - Stefan
@Stefan,我对read-string的完整接口不是很熟悉,但你是对的:在这种情况下,read-from-minibuffer没有任何好处。然而,我在文档中没有找到任何暗示read-stringread-from-minibuffer更可取的内容。你有任何可以证明这一点的来源吗? - François Févotte
1
不,实际上它还没有被很好地记录下来。但是read-from-minibuffer是其他read-*函数所依赖的底层函数。在read-string的情况下,主要区别在于处理default的方式,你没有使用它,但这是在Emacs中提供默认值的推荐方式(而不是使用initial)。 - Stefan
感谢您提供“grep-use-null-device”提示! - Brad Wright

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接