题
就上下文而言,我是一个 emacs 新手。我使用它的时间不长,但使用得越来越多(我非常喜欢它)。另外,我对 lisp 很熟悉,但对 elisp 不太熟悉。
我需要做的是将正则表达式绑定到键盘组合,因为我经常使用这个特定的正则表达式。
我一直在做什么:
M-C-s ^.*Table\(\(.*\n\)*?GO\)
注意,我在上面使用了换行符,但我发现 isearch-forward-regexp
, ,你确实需要更换 \n
在正则表达式中,结果为 C-q Q-j. 。这会插入一个文字换行符(不结束命令),使我能够将换行符放入表达式中并进行跨行匹配。
如何将其绑定到组合键?
我隐约明白我需要创建一个执行的 elisp 函数 isearch-forward-regexp
表达了,但我对细节很模糊。我搜索过谷歌,发现大多数文档都有点令人困惑。
如何将正则表达式绑定到 emacs 中的组合键?
到目前为止,迈克·斯通给出了最好的答案——不是 确切地 我正在寻找什么,但它满足了我的需要
编辑-这种方法有效,但是在存储宏之后,当我稍后回去使用它时,我无法将它与 C-x e. 。(即,如果我重新启动 emacs 然后输入 M-x 宏名称, , 进而 C-x e, ,我在迷你缓冲区中收到一条消息,例如“没有最后一个 kbd 宏”或类似的消息)
@Mike Stone - 感谢您提供的信息。我尝试创建一个宏,如下所示:
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 名称-最后-kbd-宏 它允许您为其分配一个名称,然后您可以使用它来调用 M-x 测试, ,然后使用存储定义 M-x 插入 kbd 宏 这会将宏放入当前缓冲区,然后您可以将其存储在您的 .emacs
文件。
例子:
C-x( abc *return* C-x)
将定义一个宏来输入“abc”并按回车键。
C-xeee
立即执行上述宏 3 次(第一个 e 执行它,然后后面的 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 后一遍又一遍地使用指定的宏。
其他提示
我已经开始从字面上解决你的问题,
(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>
. 。该解决方案基本上是一个 hack,但如果您想尝试一下,我会将其留在这里。
以下可能是最接近您需要的,
(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 模式下有效。您正常开始搜索,然后按组合键插入预定义的字符串。
@贾斯汀:
执行宏时,有点不同......增量搜索只会发生一次,如果要再次搜索,则必须再次执行宏。不过,您可以做更强大和复杂的事情,例如搜索关键字,跳转到行首,标记,转到行尾,M-w(复制),然后跳转到另一个缓冲区,然后 C-y(粘贴),然后跳回另一个缓冲区并结束宏。然后,每次执行宏时,您都会将一行复制到下一个缓冲区。
emacs 宏最酷的一点是它会在看到铃声时停止......当您无法匹配增量搜索(除其他外)时,就会发生这种情况。所以上面的宏,你可以执行 C-u 1000 C-x e 这将执行宏 1000 次......但既然您进行了搜索,它只会复制 1000 行,或者直到搜索失败!这意味着如果有 100 个匹配项,则只会执行宏 100 次。
编辑:查看 C-hfhighlight-lines-matching-regexp 它将显示一个命令的帮助,该命令突出显示与正则表达式匹配的所有内容...我不知道如何撤消突出显示...无论如何,您可以使用存储的宏来突出显示所有匹配正则表达式的内容,然后使用另一个宏来查找下一个...?
进一步编辑:M-x unhighlight-regexp 将撤消突出显示,但您必须输入最后一个正则表达式(但它默认为您用于突出显示的正则表达式)
一般来说,要在 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
模块似乎并没有真正针对您想要做的事情进行设置。但你可以用它来做类似的事情。