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

时间:2012-05-15 04:39:52

标签: emacs elisp

我需要访问Emacs缓冲区中的选择。 我找到了这篇文章How do I access the contents of the current region in 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))))

有什么建议吗?非常感谢!

2 个答案:

答案 0 :(得分:25)

交互式的“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))))

我并不是说“愚蠢”,因为愚蠢而无用;只是它不关心 关于商标是否有效。我认为它早于此 瞬态标记模式。

编辑:上面两次使用(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")))

答案 1 :(得分:1)

检查变量标记 - 活动例如。 C-h v mark-active

==> mark-active是在`C源代码'中定义的变量。 它的价值是零 缓冲区中的本地 Apropos ;全球价值为零

以任何方式设置时自动变为缓冲区本地。

文档: 非零意味着此缓冲区中的标记和区域当前处于活动状态。

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