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