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 中收到一条消息,例如“没有最后一个 kbd 宏”或类似的东西)


@Mike Stone - 感谢您提供信息。我尝试像这样创建一个宏:

C-x( M-C-s ^.*Table\(\(.*C-q C-J\)*?GO\) C-x)

这创建了我的宏,但是当我执行我的宏时,我没有得到与我通常使用isearch-forward-regexp. 相反,它只是跳到表达式的下一个匹配项的末尾。所以这并不能满足我的需要。有任何想法吗?

编辑:看起来我可以使用宏来做我想做的事,我只需要跳出isearch-forward-regexp. 我会尝试你的建议。

4

4 回答 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 执行它,然后后面的 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 后一遍又一遍地使用命名宏。

于 2008-08-13T18:21:06.830 回答
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"))

键盘序列 from(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 模式下有效。您正常开始搜索,然后按组合键插入您的预定义字符串。

于 2008-09-13T00:34:28.763 回答
1

@贾斯汀:

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

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

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

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

于 2008-08-13T18:44:39.997 回答
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模块似乎并未真正针对您要执行的操作进行设置。但是你可以用它来做类似的事情。

于 2008-08-24T08:12:16.660 回答