我的目标是删除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
由于
乔
答案 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功能似乎就是这样。