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

时间:2008-08-13 18:15:09

标签: regex emacs lisp

对于上下文,我是一个emacs新手。我没有使用它很长时间,但已经越来越多地使用它(我非常喜欢它)。我也很熟悉lisp,但不熟悉elisp。

我需要做的是将正则表达式绑定到键盘组合,因为我经常使用这个特殊的正则表达式。

我一直在做的事情:

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

注意,我上面使用了换行符,但我发现对于isearch-forward-regexp,您确实需要将正则表达式中的\n替换为 Cq Qj 。这会插入一个文字换行符(不会结束命令),这样我就可以在表达式中添加换行符并跨行匹配。

如何将其绑定到组合键?

我含糊地理解我需要创建一个用表达式执行isearch-forward-regexp的elisp函数,但我对细节很模糊。我搜索了谷歌,发现大多数文档都有点令人困惑。

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


到目前为止,Mike Stone得到了最好的答案 - 不是完全我正在寻找的东西但是它适用于我需要的东西

编辑 - 这种方式有效,但在存储宏之后,当我以后再使用它时,我无法将其与 C-x e 一起使用。 (即,如果我重新启动emacs,然后输入 Mx宏名称,然后输入 Cx e ,我会在迷你缓冲区中收到一条消息,例如'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 个答案:

答案 0 :(得分:6)

您可以使用宏,只需执行 Cx(然后为宏执行所有操作,然后 Cx)结束宏,然后 Cx e 将执行最后定义的宏。然后,您可以使用 Mx name-last-kbd-macro 命名它,它允许您为其指定一个名称,然后可以使用 Mx TESTIT 调用该名称,然后存储定义使用 Mx insert-kbd-macro 将宏放入当前缓冲区,然后将其存储在.emacs文件中。

示例:

C-x( abc *return* C-x)

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

C-xeee

立即执行上述宏,3次(首先执行它,然后执行2次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后反复使用指定的宏。

答案 1 :(得分: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")

关键组合现在只能在isearch模式下工作。您可以正常开始搜索,然后按键组合以插入预定义的字符串。

答案 2 :(得分: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 function-name和键绑定来调用该函数。

现在,特别是对于交互式搜索,这很棘手; isearch模块似乎并没有真正针对你想要做的事情进行设置。但你可以用它来做类似的事情。

答案 3 :(得分:1)

@Justin:

执行宏时,它有点不同......增量搜索只会发生一次,如果你想再次搜索,你将不得不再次执行宏。你可以做更强大和复杂的事情,比如搜索一个关键词,跳到行的开头,标记,转到行尾,Mw(复制),然后跳到另一个缓冲区,然后Cy(粘贴) ),然后跳回到另一个缓冲区并结束您的宏。然后,每次执行宏时,您都会将一行复制到下一个缓冲区。

关于emacs宏的一个非常酷的事情是它会在看到铃声时停止...当你无法匹配增量搜索时(其中包括)。所以上面的宏,你可以做C-u 1000 C-x e,它将执行1000次宏...但是由于你进行了搜索,它只会复制1000行,或者直到搜索失败!这意味着如果有100个匹配,它将只执行100次宏。

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

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