【问题标题】:Emacs macro to generate a sequence?Emacs 宏生成序列?
【发布时间】:2015-02-16 20:13:44
【问题描述】:

我正在阅读这篇关于如何创建 vi 宏的文章: vi sequence macro 我看到了一个有用的宏来在缓冲区中创建一个序列。

1.
2.
...
100.

在 vi 中,诀窍是可以在一个数字上按 ctrl-a,然后它会加一,所以这使宏变得简单。我希望能够在 emacs 中做同样的事情。

【问题讨论】:

    标签: emacs


    【解决方案1】:

    如果您使用的是 Emacs 23(也许是 22?),请使用默认绑定到 C-x C-k TABkmacro-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 来重复宏。
    【解决方案2】:

    那些觉得有太多技巧要记住的人可能会发现获得一些 elisp 更有利可图:

    M-: (dotimes (i 20) (插入 (格式 "%2d.\n" (1+ i))))

    【讨论】:

    • +1 提及M-: (eval-expression),我从未听说过。
    • @TörökGábor \,(eval-expression) 在查询替换正则表达式中也很整洁。
    【解决方案3】:

    Emacs 23 在 replace-regexp 的替换文本中支持 elisp sn-ps。

    我经常定义遵循这种模式的键盘宏:

    • 复制一段文字
    • 使用 isearch 导航到我想在复制的文本块中增加的数字
    • 激活标记并移动点以定义包含数字的区域
    • M-x 替换正则表达式
    • 在“替换正则表达式”提示下,输入 \([0-9]+\) 以捕获一组一个或多个数字
    • 在“Replace regexp ([0-9]+) with:”提示符下,输入\,(1+ \#1),其中,表示后面是要替换的elisp形式,1+是增量函数,@987654325 @ 是第一个捕获的匹配文本,被解释为一个数字。

    在花一分钟时间定义了键盘宏之后,这让我几乎可以方便地进行剪切和粘贴以生成大量几乎相同的代码块,例如 case 语句。

    请注意,这种技术可以很容易地适应例如双数(\,(* 2 \#1))或其他。你甚至可以使用'position'nth 的组合来替换任意序列中的下一个元素,但我现在不再赘述:)。

    【讨论】:

    • 感谢您演示如何使用 replace-regexp 将计数器替换为文本
    • \,(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" 之类的东西替换了它们。我该如何解决这个问题(除了正则表达式那个额外的文本)?
    • @Geremia:这就是我必须做的:C-:(setq kmacro-counter 0) 然后:\[sup\][0-9]+\[\/sup\][sup]\,(print (setq kmacro-counter (1+ kmacro-counter)))
    【解决方案4】:

    自 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 部分。

    【讨论】:

    • 要预设计数器,您只需要一个数字前缀 arg。例如:C-u 100 <f3> <f3> . RET <f4><f4> 的前缀参数表示重复宏的次数(包括录制),因此要立即从 100 数到 149,您可以使用 C-u 50 <f4> 而不仅仅是 <f4> 来完成它。
    • 谢谢菲尔斯。我用你们的 cmets 改进了我的答案(和知识)。
    • F3 F3 X F4 在一次性宏的易用性方面比C-x ( C-x C-k TAB X C-x ) 有了巨大的改进 - 现在我不必来这里了,因为我忘记了关键的杂技组合。我希望这个答案会冒泡到它所属的顶部。
    • 至少从 Emacs 23 开始,这不是在 Emacs 中了吗?因为我清楚地记得这是 Emacs 23 中的一个东西。但我可能是错的。
    【解决方案5】:

    除了scottfrazer's answer,还有另一种使用CUA mode 创建数字序列的方法,这在编辑现有内容时可能对您有很大帮助。从位置 2:30 见 Mark Mansour's screencast on Emacs Column Editing

    【讨论】:

      【解决方案6】:

      如果您打开 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 作为标准的人来说,这绝对是更可取的选择。)
      【解决方案7】:

      这里有一个extension 可能会有所帮助。

      【讨论】:

        【解决方案8】:

        您可以使用shell-command-on-region 否则:

        C-u M-! seq 1 100|xargs -I{} echo {}"."
        

        【讨论】:

          【解决方案9】:

          还有:

          <b>C-u M-!</b> jot -s '.<b>C-q C-j</b>' 10

          它不是纯elisp,但具有相同的效果。您可以编写一个命名宏来为您运行它。

          【讨论】:

          • 'jot' 和 'seq' 为这些目的做同样的事情。如果你在 Unix 上,你几乎肯定至少安装了其中一个。q
          【解决方案10】:

          这是一个简单的定义:

          (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))))
            )
          )
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2015-11-21
            • 1970-01-01
            • 2016-02-17
            • 1970-01-01
            • 1970-01-01
            • 2015-10-29
            • 1970-01-01
            相关资源
            最近更新 更多