如何在Emacs Lisp中以编程方式获取区域(选择)?

sai*_*ing 21 emacs elisp

我需要访问Emacs缓冲区中的选择.我发现这篇文章如何访问Emacs Lisp中当前区域的内容? 这对我很有帮助.

但有一个问题.我第一次选择(突出显示)一个区域时,它可以正常工作,但是当我按下Cg,并将光标正常移动到另一个地方而不突出显示任何字符时,我从最后一个标记到当前点有一个字符串,而我期望一个空字符串.

实际上我需要实现一个函数,它将当前选择(突出显示)作为字符串返回,如果没有突出显示,则返回空字符串.以下代码可能更清楚地表达我.


(defun get-search-term ()
  (interactive)
  (let (
        (selection (buffer-substring-no-properties (region-beginning) (region-end))))
    (if (= (length selection) 0)
        (message "empty string")
      (message selection))))

Run Code Online (Sandbox Code Playgroud)

有什么建议?非常感谢!

eve*_*_jr 27

交互式的"r"规范是愚蠢的.你看到了原因.

(defun get-search-term (beg end)
  "message region or \"empty string\" if none highlighted"
  (interactive (if (use-region-p)
                   (list (region-beginning) (region-end))
                 (list (point-min) (point-min))))
  (let ((selection (buffer-substring-no-properties beg end)))
    (if (= (length selection) 0)
        (message "empty string")
      (message selection))))
Run Code Online (Sandbox Code Playgroud)

我并不是说"愚蠢",就像愚蠢而无用; 只是它不关心标记是否有效.我认为它早于瞬态标记模式.

编辑:使用(point-min)上面两次使重新阅读时难以理解代码.这是一个更好的实现:

(defun get-search-term (beg end)
  "message region or \"empty string\" if none highlighted"
  (interactive (if (use-region-p)
                   (list (region-beginning) (region-end))
                 (list nil nil)))
  (message "%s" (if (and beg end)
                    (buffer-substring-no-properties beg end)
                  "empty string")))
Run Code Online (Sandbox Code Playgroud)