对于上下文,我是一个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
的框外思考。我会尝试你的建议。
答案 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)
@Justin:
执行宏时,它有点不同......增量搜索只会发生一次,如果你想再次搜索,你将不得不再次执行宏。你可以做更强大和复杂的事情,比如搜索一个关键词,跳到行的开头,标记,转到行尾,Mw(复制),然后跳到另一个缓冲区,然后Cy(粘贴) ),然后跳回到另一个缓冲区并结束您的宏。然后,每次执行宏时,您都会将一行复制到下一个缓冲区。
关于emacs宏的一个非常酷的事情是它会在看到铃声时停止...当你无法匹配增量搜索时(其中包括)。所以上面的宏,你可以做C-u 1000 C-x e,它将执行1000次宏...但是由于你进行了搜索,它只会复制1000行,或者直到搜索失败!这意味着如果有100个匹配,它将只执行100次宏。
编辑:查看C-hf highlight-lines-matching-regexp,它将显示一个命令的帮助,该命令突出显示与正则表达式匹配的所有内容...我不知道如何撤消突出显示但是...无论如何你可以使用存储的宏来突出显示所有匹配的正则表达式,然后使用另一个宏来查找下一个...?进一步编辑:M-x unhighlight-regexp将撤消突出显示,你必须输入最后一个正则表达式(但它默认为你用来突出显示的正则表达式)
答案 3 :(得分: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
模块似乎并没有真正针对你想要做的事情进行设置。但你可以用它来做类似的事情。