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

Regex 如何将正则表达式绑定到emacs中的键组合?,regex,emacs,lisp,Regex,Emacs,Lisp,就上下文而言,我是一个emacs新手。我用它的时间不长,但已经越来越多了(我非常喜欢它)。我对lisp也很熟悉,但对elisp不太熟悉 我需要做的是将正则表达式绑定到键盘组合,因为我经常使用这个特殊的正则表达式 我一直在做的是: M-C-s ^.*Table\(\(.*\n\)*?GO\) 注意,我使用了上面的换行符,但是我发现对于isearch forward regexp,您确实需要用C-q-j的结果替换正则表达式中的\n。这将插入文字换行符(不结束命令),使我能够将换行符放入表达式并跨行

就上下文而言,我是一个emacs新手。我用它的时间不长,但已经越来越多了(我非常喜欢它)。我对lisp也很熟悉,但对elisp不太熟悉

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

我一直在做的是:

M-C-s ^.*Table\(\(.*\n\)*?GO\)
注意,我使用了上面的换行符,但是我发现对于
isearch forward regexp
,您确实需要用C-q-j的结果替换正则表达式中的
\n
。这将插入文字换行符(不结束命令),使我能够将换行符放入表达式并跨行匹配

如何将其绑定到密钥组合

我模模糊糊地理解,我需要创建一个elisp函数,用表达式执行
isearch forward regexp
,但我对细节不太清楚。我搜索过谷歌,发现大多数文档都有点混乱

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


迈克·斯通(Mike Stone)得到了迄今为止最好的答案——这不完全是我想要的,但它满足了我的需要

编辑-这种方式很有效,但在存储宏之后,当我稍后返回使用它时,我无法将其与C-x e一起使用。(即,如果我重新启动emacs,然后键入M-x宏名称,然后键入C-x e,我会在微型缓冲区中收到一条消息,如“no last kbd macro”或类似消息)


@迈克·斯通-谢谢你提供的信息。我尝试创建一个宏,如下所示:

C-x( M-C-s ^.*Table\(\(.*C-q C-J\)*?GO\) C-x)
这创建了我的宏,但当我执行宏时,我没有得到与使用
isearch forward regexp
时通常得到的相同的高亮显示。相反,它只是跳到下一个表达式匹配的末尾。所以这并不能满足我的需要。有什么想法吗


编辑:看起来我可以使用宏来做我想做的事情,我只需要跳出
isearch forward regexp
的框框来思考。我将尝试您的建议。

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

例如:

C-x( abc *return* C-x)
将定义一个宏以键入“abc”并按return键

C-xeee
立即执行上述宏,执行3次(首先是e执行,然后是2个e将再执行两次)

将宏命名为“testit”

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

将以下内容放入当前缓冲区:

(fset 'testit
   [?a ?b ?c return])
然后可以将其保存在
.emacs
文件中,以便在重新启动emacs后反复使用命名宏。

@Justin:

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

emacs宏最酷的一点是它会在看到铃声时停止。。。当您无法匹配增量搜索(以及其他内容)时会发生这种情况。所以上面的宏,你可以做C-u 1000 C-x e,它会执行宏1000次。。。但由于您进行了搜索,它将只复制1000行,或者直到搜索失败!这意味着如果有100个匹配项,它将只执行宏100次

编辑:检查C-hf高亮显示与regexp匹配的行,它将显示一个命令的帮助,该命令高亮显示与regex匹配的所有内容。。。我不知道如何撤销突出显示。。。无论如何,您可以使用存储的宏高亮显示所有匹配的正则表达式,然后使用另一个宏查找下一个


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

通常,要在Emacs中定义自定义键绑定,您需要编写

(define-key global-map (kbd "C-c C-f") 'function-name)
define key
是定义新键的函数,这并不奇怪<代码>全局映射是全局键映射,与每个模式的单个映射相反
(kbd“C-C-f”)
返回表示键序列的字符串
C-C-f
。还有其他方法可以做到这一点,包括直接输入字符串,但这通常是最简单的方法,因为它采用正常的书面表示
“函数名”
是函数名的符号

现在,除非已经定义了函数,否则在使用此函数之前需要先定义它。要做到这一点,请写信

(defun function-name (args)
  (interactive)
  stuff
  ...)
defun
定义函数-使用
C-h f defun
了解更多具体信息。
(交互式)
实际上没有函数调用;它告诉编译器,用户可以使用
M-x function name
并通过键绑定调用函数


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

我已经开始逐字逐句地解决你的问题

(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"))
组合键现在只在isearch模式下工作。您可以正常启动搜索,然后按组合键插入预定义字符串

(define-key global-map (kbd "C-c C-f") 'function-name)
(defun function-name (args)
  (interactive)
  stuff
  ...)
(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"))
(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")