错误停止执行后重复宏

时间:2013-11-06 09:14:32

标签: emacs macros repeat

我的目标是删除xml文件中的重复节。如果在文件中多次找到该节的第一行,我确信我有一个重复的节。

我创建了一个宏,通过交互式搜索找到我的节的第一行,然后再按Ctrl-S转到下一个节点。如果找到,我然后标记我要删除的部分并将其删除。我的宏终止于此。

如果我的Ctrl-s找不到下一个匹配项,我的宏停止,这是我想要它做的。但是,当我Esc 1000 Ctrl-x e多次执行我的宏时,当发现错误时,1000循环也停止。我很高兴宏停止,但我想在错误后再次执行它。这可能吗?或者是否已经有一个宏来从文件中删除重复的节或行组?

我的宏:

C-s         ;; isearch-forward
<Conduit        ;; self-insert-command * 8
SPC         ;; self-insert-command
6*C-w           ;; kill-region
C-s         ;; isearch-forward
C-a         ;; beginning-of-line
C-SPC           ;; set-mark-command
C-s         ;; isearch-forward
<           ;; self-insert-command
/           ;; nxml-electric-slash
Conduit>        ;; self-insert-command * 8
<right>         ;; forward-char
C-w         ;; kill-region

由于

3 个答案:

答案 0 :(得分:1)

如果你想要实现的是重复运行宏而不管错误,这将是一种方法:

(defun repeat-macro-until-abort ()
  (interactive)
  (while t
    (ignore-errors
      (kmacro-call-macro 0))))

它会运行你的最后一个宏,直到你点击C-g。请注意,即使到达缓冲区末尾也不会停止。

答案 1 :(得分:0)

有一种简单的方法可以删除与正则表达式相匹配的行:M-x flush-lines

如果您知道要删除的节的正则表达式,则可以键入C-M-% <your-regexp> RET RET,然后迭代重复删除要删除的内容(键入!以删除其中的每一个)。 C-M-%是query-replace-regexp的默认键绑定。

答案 2 :(得分:0)

嗯。如果Emacs提供了一种方便的交互方式来处理键盘宏中的错误条件,那将是很好的,但我怀疑juanleon的答案可能是你目前最好的选择。

一般的解决方法是不使用C-s,而是使用类似M-: (search-forward "foo" nil t) RET的内容来搜索“foo”而不会触发错误(如果它不存在)。在这个例子中,它会有更多的东西。

对于一次性处理,我倾向于在这种情况下做的是生成我感兴趣的结果的缓冲区,然后用键盘宏处理

这个例子实际上有点棘手,但您可以occur匹配模式的所有行,通过sort | uniq --all-repeated=separate,然后消除每个组的第一行。这为您留下了每个副本要删除的实例的确切数量,因此您的键盘宏可以从该列表中获取一行,在原始缓冲区中找到它的最后一个实例,删除它,然后移动到下一行在列表中。

如果这是一项常见活动,那么自定义elisp功能似乎就是这样。