Elisp仅将命令应用于所选区域


18

说,我有一些这样的代码:

(defun some-function ()
  (interactive)
  ;; do something
  )

现在我只想some-function对缓冲区中的选定区域进行操作?我怎样才能做到这一点 ?另外,如果我选择了某个区域,是否可以有两个单独的代码路径来执行某项操作,而如果我还没有选择其他代码,则可以进行其他操作。

Answers:


22
(defun some-function (beginning end)
  (interactive "r")
  (if (use-region-p)
      (message "The region is active, and is from %d to %d" beginning end)
    (message "The region is still there (from % d to %d), but it is inactive" 
             beginning end)))

使用(interactive "r")意味着参数beginningend在调用函数时将分别自动接收区域开始和区域结束的值。(您也可以随时分别使用函数region-beginning和来获取这些值region-end。)

该区域始终存在(如果当前缓冲区中有标记),但是您可能不认为它存在。突出显示该区域(选择文本)后,该区域处于活动状态。您可以使用谓词测试区域是否处于活动状态region-active-p。但是更好的测试通常是use-region-p,因为(默认情况下)(nil仅当区域同时处于活动状态和非空状态(点和标记不同)时,它才返回true(非))。

最初,该区域没有突出显示。长期以来,即使突出显示可用,也不是默认行为。为了突出显示,您必须已transient-mark-mode打开(或至少暂时打开)。默认情况下,transient-mark-mode在最新的Emacs版本中处于打开状态。

查看谓词的定义会有所帮助use-region-p

(defun use-region-p ()
  (and (region-active-p)
       (or use-empty-active-region
           (> (region-end) (region-beginning)))))

use-empty-active-region是一个用户选项,其默认值为nil(true),这意味着use-region-p如果区域为空,默认情况下不会返回true。在这种情况下,要使其返回true,该区域的结尾必须大于开头(我在上文中描述的行为)。

如果我们看一下的定义region-active-p

(defun region-active-p ()
  (and transient-mark-mode
       mark-active
       (mark)))

我们看到,nil当所有这些都为真时,它将返回true(非):

  • transient-mark-mode 已开启。
  • 该标记处于活动状态(mark-active)。
  • 当前缓冲区中有一个标记。

激活标记实际上就是激活区域的全部含义。当它处于活动状态时,假设它transient-mark-mode已打开并且当前缓冲区中有一个标记,则该区域将突出显示。


AFAICS如果将标记设置为指向,即区域尚未扩展,则标记有效为零。因此,在这些相当冗余的功能中,只有标记激活和瞬态标记模式才是有价值的。
AndreasRöhler,2015年

1
@AndreasRöhler:不。C-SPC M-: mark-active=> t。您肯定可以有一个仍然活跃的空白区域。
提请

好的谢谢。仍然认为标记有效和区域有效p-定义为扩展更大的零-应该都需要。
AndreasRöhler,2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.