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

如何在Emacs Lisp中以编程方式获取区域(选择)?,emacs,elisp,Emacs,Elisp,我需要访问Emacs缓冲区中的选择。 我找到了这篇文章 这对我帮助很大 但有一个问题。我第一次选择(高亮显示)一个区域时,它工作正常,但当我按C-g键,并正常地将光标移动到另一个位置而不高亮显示任何字符时,我得到了一个从最后一个标记到当前点的字符串,而我期望得到一个空字符串 实际上,我需要实现一个函数,该函数将以字符串形式返回当前选择(突出显示),如果没有突出显示,则返回空字符串。下面的代码可以更清楚地表达我的意思 (defun get-search-term () (interactiv

我需要访问Emacs缓冲区中的选择。 我找到了这篇文章 这对我帮助很大

但有一个问题。我第一次选择(高亮显示)一个区域时,它工作正常,但当我按C-g键,并正常地将光标移动到另一个位置而不高亮显示任何字符时,我得到了一个从最后一个标记到当前点的字符串,而我期望得到一个空字符串

实际上,我需要实现一个函数,该函数将以字符串形式返回当前选择(突出显示),如果没有突出显示,则返回空字符串。下面的代码可以更清楚地表达我的意思


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

有什么建议吗?非常感谢

交互式的“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))))
我的意思不是“愚蠢”和“愚蠢和无用”;只是它不在乎 关于标记是否处于活动状态。我认为这要早于 瞬态标记模式

编辑:在上面两次使用
(最小点)
会使代码更难理解 重读的时候。下面是一个更好的实现:

(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")))

检查可变标记激活,例如C-h v标记激活

==>标记活动是在“C源代码”中定义的变量。 它的值为零 缓冲区内的局部;全局值为零

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

文件: 非nil表示标记和区域当前在此缓冲区中处于活动状态

(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"))
  )

您有没有理由不使用Gareth Rees在您链接的问题中显示的
交互式
表单?谢谢您的回复,很抱歉没有仔细阅读该文章。(交互式“r”)解决了我的问题。我需要更多地了解interactive。可能的副本似乎还没有。我修改了代码并测试了Gareth Rees的代码,但问题仍然存在。也许我需要在获取区域之前清除点和标记?顺便说一句,很抱歉我的第一个评论,也许我没有进行足够的测试。
mark-active
仅在您使用瞬态标记模式时有效,因此您可以自己使用,但如果代码应该可供他人使用,您应该使用
region-active-p
(或
use-region-p
)取而代之的是,拉面,我刚刚纠正了它。然后我重新阅读了这个问题,min点是正确的,因为它生成了一个空字符串。现在我添加了一个更容易理解的实现。为什么不在
消息的
调用的
if
条件中使用
use-region-p
?使用
use-region-p
beg
end
设置为
nil
似乎是多余的,因为您不希望非交互调用依赖于交互上下文。这里适用的一个更普遍的规则是:不要执行两次相同的测试:如果您绝对100%完全确定测试的两次出现将始终返回完全相同的值,无论情况如何,那么通常最好提升测试并避免执行两次,如果您不绝对确定,然后,您需要开始考虑当它们不返回相同的值时该怎么办。例如,如果
beg/end
为零,但
use-region-p
返回非零,您会怎么做?