【发布时间】:2015-02-16 20:13:44
【问题描述】:
我正在阅读这篇关于如何创建 vi 宏的文章: vi sequence macro 我看到了一个有用的宏来在缓冲区中创建一个序列。
1.
2.
...
100.
在 vi 中,诀窍是可以在一个数字上按 ctrl-a,然后它会加一,所以这使宏变得简单。我希望能够在 emacs 中做同样的事情。
【问题讨论】:
标签: emacs
我正在阅读这篇关于如何创建 vi 宏的文章: vi sequence macro 我看到了一个有用的宏来在缓冲区中创建一个序列。
1.
2.
...
100.
在 vi 中,诀窍是可以在一个数字上按 ctrl-a,然后它会加一,所以这使宏变得简单。我希望能够在 emacs 中做同样的事情。
【问题讨论】:
标签: emacs
如果您使用的是 Emacs 23(也许是 22?),请使用默认绑定到 C-x C-k TAB 的 kmacro-insert-counter。所以对于你的例子,你会这样做:
C-x ( C-x C-k TAB . RET C-x )
所以开始宏,插入计数器,后跟'.',换行符,结束宏。然后C-x e e e e e e e 等。或者M-1 0 0 C-x e 获得 100 个。
编辑:
忘了提到您也可以将计数器设置为初始值。例如,从 1 而不是 0 开始,请执行 M-1 C-x C-k C-c。
如果您不希望计数器在特定点递增,请在其前面加上 C-u。当然,此时击键有点荒谬,所以我通常将键绑定到插入但不增加。
【讨论】:
kmacro-set-counter C-x C-k C-c kmacro-add-counter C-x C-k C-a kmacro-insert-counter C-x C-k TAB 所以想法是,设置计数器。然后定义宏并在宏内插入并递增计数器。然后反复运行宏。这对其他读者来说可能很明显,但我最初并没有明白。
C-x e 之后点击e 来重复宏。
那些觉得有太多技巧要记住的人可能会发现获得一些 elisp 更有利可图:
M-: (dotimes (i 20) (插入 (格式 "%2d.\n" (1+ i))))【讨论】:
M-: (eval-expression),我从未听说过。
\,(eval-expression) 在查询替换正则表达式中也很整洁。
Emacs 23 在 replace-regexp 的替换文本中支持 elisp sn-ps。
我经常定义遵循这种模式的键盘宏:
\([0-9]+\) 以捕获一组一个或多个数字\,(1+ \#1),其中,表示后面是要替换的elisp形式,1+是增量函数,@987654325 @ 是第一个捕获的匹配文本,被解释为一个数字。在花一分钟时间定义了键盘宏之后,这让我几乎可以方便地进行剪切和粘贴以生成大量几乎相同的代码块,例如 case 语句。
请注意,这种技术可以很容易地适应例如双数(\,(* 2 \#1))或其他。你甚至可以使用'position 和'nth 的组合来替换任意序列中的下一个元素,但我现在不再赘述:)。
【讨论】:
\,(eval-expression) 在查询替换正则表达式中非常简洁!我不得不重新编号从 1 开始的上标数字序列。它们都在 SMF [sup] 标记中,从 63 开始。所以我做了这个查询替换 regexp 以从 1 开始它们:(default \[sup\][0-9]+\[\/sup\]→[sup]\,(kmacro-insert-counter 1)[/sup]。但是,它用 [sup]New 宏计数器值:1 (1)[/sup]00" 之类的东西替换了它们。我该如何解决这个问题(除了正则表达式那个额外的文本)?
C-:(setq kmacro-counter 0) 然后:\[sup\][0-9]+\[\/sup\]→[sup]\,(print (setq kmacro-counter (1+ kmacro-counter)))。
自 Emacs 24.3 版以来(我相信实际上自 24.0 版以来),按键顺序已被简化:
<F3> <F3> . <ENTER> <F4>
然后重复<F4> 键将重复宏。
诀窍在于,在使用 <F3> 启动宏后,第二次按下 <F3> 键会将键盘宏的计数器的当前值插入缓冲区,并将计数器加 1。
其他技巧:
<F3> C-u 2 <F3> . <ENTER> <F4> 将增加 +2(而不是 +1)C-u 100 <F3> <F3> . <ENTER> C-u 50 <F4> 将从 100 开始,到 149 结束C-x C-k C-f %03d <ENTER> <F3> <F3> . <ENTER> <F4> 将用零填充,例如“000”来源:Emacs 手册中的Keyboard Macro Counter 部分。
【讨论】:
C-u 100 <f3> <f3> . RET <f4>。 <f4> 的前缀参数表示重复宏的次数(包括录制),因此要立即从 100 数到 149,您可以使用 C-u 50 <f4> 而不仅仅是 <f4> 来完成它。
F3 F3 X F4 在一次性宏的易用性方面比C-x ( C-x C-k TAB X C-x ) 有了巨大的改进 - 现在我不必来这里了,因为我忘记了关键的杂技组合。我希望这个答案会冒泡到它所属的顶部。
除了scottfrazer's answer,还有另一种使用CUA mode 创建数字序列的方法,这在编辑现有内容时可能对您有很大帮助。从位置 2:30 见 Mark Mansour's screencast on Emacs Column Editing。
【讨论】:
如果您打开 CUA 次要模式 (cua-mode),您可以选择一列文本,然后使用 cua-sequence-rectangle 填充一系列数字(默认绑定到 M-n)。
这与 Török Gábor 链接到的视频中提到的内容相同,但现在将其写在此处,因此除非您愿意,否则您不必观看整个视频。这是一个很好的视频。
【讨论】:
cua-mode* 来为矩形编号——从24.1 开始,有一个常规的矩形操作rectangle-number-lines 绑定到C-x r N。 (* 或cua-selection-mode,对于那些不使用cua-mode 作为标准的人来说,这绝对是更可取的选择。)
这里有一个extension 可能会有所帮助。
【讨论】:
您可以使用shell-command-on-region 否则:
C-u M-! seq 1 100|xargs -I{} echo {}"."
【讨论】:
还有:
<b>C-u M-!</b> jot -s '.<b>C-q C-j</b>' 10
它不是纯elisp,但具有相同的效果。您可以编写一个命名宏来为您运行它。
【讨论】:
这是一个简单的定义:
(defun insert-range (START END &optional STEP FORMAT)
"Inserts a range of integers from START to END with STEP (default to 1)
in a given format (default to \"\\n%d\")"
(interactive
(list (read-number "Start: " 1)
(read-number "End: " 10)
(read-number "Step: " 1)
(read-string "Format (default to \"\\n%d\"): " nil nil "\n%d") ))
(dotimes (i (1+ (/ (- END START) STEP)))
(insert (format FORMAT (+ START (* i STEP))))
)
)
【讨论】: