如何在Emacs中将正则表达式绑定到键组合?

6

为了更好的理解背景,我是一位Emacs新手。虽然使用不长时间,但越来越多地开始使用它(我非常喜欢)。此外,我对Lisp很熟悉,但对Elisp并不是很了解。

我的需求是将一个常用的正则表达式绑定到键盘组合键上。

目前我一直在做的:

M-C-s ^.*Table\(\(.*\n\)*?GO\)

注意,我在上面使用了换行,但我发现对于 isearch-forward-regexp,你需要将正则表达式中的 \n 替换为 C-q Q-j 的结果。这将插入一个字面换行符(而不是结束命令),使我可以在表达式中输入换行符并跨越多行匹配。
如何将其绑定到键组合?我模糊地理解我需要创建一个执行带有该表达式的 isearch-forward-regexp 的Elisp函数,但我对细节还不太清楚。我搜索了谷歌并发现大部分文档有点混乱。
如何在Emacs中将正则表达式绑定到键组合?
迄今为止,Mike Stone的回答是最好的答案-虽然不完全是我要找的,但它可以满足我的需求
编辑-这种方式有点问题,因为在存储宏后,当我回来再次使用它时,我无法使用 C-x e。(即,如果我重新启动emacs,然后键入 M-x macro-name ,然后 C-x e ,我会在minibuffer中得到一个类似“no last kbd macro”或类似的消息)
@ Mike Stone - 感谢您提供的信息。我尝试创建如下的宏:
C-x( M-C-s ^.*Table\(\(.*C-q C-J\)*?GO\) C-x)

这是我创建的宏,但当我执行宏时,没有像平常使用 isearch-forward-regexp 时那样高亮显示。相反,它只是跳到表达式下一个匹配项的末尾。所以这对我所需的并不起作用。有什么想法吗?
编辑:看起来我可以使用宏来实现我想要的功能,我只需要跳出 isearch-forward-regexp 的思维定势。我会尝试你建议的方法。
4个回答

6
你可以使用宏,只需执行C-x (,然后为宏执行所有操作,最后使用C-x )结束宏录制,并使用C-x e执行最后定义的宏。然后,你可以使用M-x name-last-kbd-macro给宏命名,以便使用M-x TESTIT调用它,再使用M-x insert-kbd-macro将其放入当前缓冲区,最后将其存储在.emacs文件中。
例如:
C-x( abc *return* C-x)

将定义一个宏来输入“abc”并按回车键。
C-xeee

立即执行上述宏,共执行3次(第一个e执行它,接下来的两个e将再执行两次)。

M-x name-last-kbd-macro testit

将宏命名为“testit”

M-x testit

执行刚刚命名的宏(打印“abc”然后返回)。

M-x insert-kbd-macro

将以下内容放入当前缓冲区:
(fset 'testit
   [?a ?b ?c return])

然后可以将其保存在您的.emacs文件中,以便在重新启动emacs后重复使用命名宏。


2

我先从字面上解决你的问题开始:

(defun search-maker (s)
  `(lambda ()
     (interactive)
     (let ((regexp-search-ring (cons ,s regexp-search-ring)) ;add regexp to history
           (isearch-mode-map (copy-keymap isearch-mode-map)))
       (define-key isearch-mode-map (vector last-command-event) 'isearch-repeat-forward) ;make last key repeat
       (isearch-forward-regexp)))) ;`

(global-set-key (kbd "C-. t") (search-maker "^.*Table\\(\\(.*\\n\\)*?GO\\)"))
(global-set-key (kbd "<f6>") (search-maker "HELLO WORLD"))

(kbd ...)开始的键盘序列将开始一个新的空搜索。要实际搜索您的字符串,您需要再次按下最后一个键,如需多次重复,请按相同的次数按下该键。C-. t t t<f6> <f6> <f6>。此解决方案基本上是一种技巧,但如果您想尝试它,我将在此处保留它。
以下可能是最接近您所需内容的内容,
(defmacro define-isearch-yank (key string)
  `(define-key isearch-mode-map ,key 
     (lambda ()
       (interactive) 
       (isearch-yank-string ,string)))) ;`

(define-isearch-yank (kbd "C-. t") "^.*Table\\(\\(.*\\n\\)*?GO\\)")
(define-isearch-yank (kbd "<f6>") "HELLO WORLD")

现在,这些键盘组合键只能在搜索模式下使用。您需要正常开始搜索,然后按键盘组合键来插入预定义的字符串。请注意保留 HTML 标签。

1
通常情况下,在Emacs中定义自定义按键绑定,您需要编写:
(define-key global-map (kbd "C-c C-f") 'function-name)

define-key 是定义新键的函数。 global-map 是全局键映射表,与每种模式的单独映射不同。 (kbd "C-c C-f") 返回表示键序列 C-c C-f 的字符串。还有其他方法可以做到这一点,包括直接输入该字符串,但通常这是最直观的方法,因为它将采用正常的书写形式。'function-name 是函数名称的符号。

现在,除非您的函数已经定义,否则您需要在使用之前定义它。要做到这一点,请编写:

(defun function-name (args)
  (interactive)
  stuff
  ...)

defun 定义函数。可以使用 C-h f defun 获取更详细的信息。此处的 (interactive) 并没有真正的函数调用;它告诉编译器,允许用户通过 M-x 函数名 和按键绑定来调用该函数。

现在,特别是针对交互式搜索,这有点棘手;似乎 isearch 模块并未为您尝试执行的操作设置好。但您可以使用此方法来完成类似的操作。


1

@Justin:

执行宏时,有些不同...增量搜索只会发生一次,如果您想再次搜索,则必须再次执行宏。但是,您可以做更强大和复杂的事情,例如搜索关键字,跳转到行首,标记,跳转到行尾,M-w(复制),然后跳转到另一个缓冲区,然后C-y(粘贴),然后跳回到另一个缓冲区并结束您的宏。然后,每次执行宏时,您将把一行复制到下一个缓冲区。

Emacs宏的真正酷之处在于,当它看到铃声时会停止...这发生在无法匹配增量搜索(以及其他情况)时。因此,对于上述宏,您可以执行C-u 1000 C-x e,这将执行该宏1000次...但是由于进行了搜索,因此仅会复制1000行,或者直到搜索失败为止!这意味着如果有100个匹配项,则只会执行宏100次。

编辑:请查看 C-hf highlight-lines-matching-regexp,它将显示一个命令的帮助,该命令可以突出显示与正则表达式匹配的所有内容... 我不知道如何取消高亮... 无论如何,您可以使用存储的宏来突出显示所有匹配正则表达式的内容,然后使用另一个宏查找下一个匹配项...?

进一步编辑:M-x unhighlight-regexp 将撤消高亮显示,但您必须输入最后一个正则表达式(但默认为您用于突出显示的正则表达式)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接