【问题标题】:Macro for making numbered lists in vim?在vim中制作编号列表的宏?
【发布时间】:2011-05-12 14:01:39
【问题描述】:

很多时候我似乎有一个项目列表,我需要在它们前面添加数字。例如:

Item one
Item two
Item three

应该是:

1. Item one
2. Item two
3. Item three

在 vim 中,我可以在编辑模式下按I,插入“1.”,然后点击转义。然后我转到下一行,按.,然后按^A 增加数字。这似乎非常低效......我将如何制作一个宏以便我可以转到下一行,并在开头插入一个比前一行大一的数字?

【问题讨论】:

    标签: vim macros


    【解决方案1】:

    在可视模式下选择您的线条:V,然后输入:

    :'<,'>s/^\s*\zs/\=(line('.') - line("'<")+1).'. '
    

    这很容易放入命令中:

    command! -nargs=0 -range=% Number <line1>,<line2>s/^\s*\zs/\=(line('.') - <line1>+1).'. '
    

    【讨论】:

    • 我喜欢它的可重复性。对于单行来说,这很棒。不幸的是,出于 my 的目的,在插入编号时,我倾向于在 reStructuredText 中执行,因此基本上需要 } 功能 - 但由于它进行行计数的方式,只需将 ^ 替换为 @ 987654327@ 不会削减它。可惜,不然会进入我的.vimrc。好代码,反正我不知道\=() - 而且我在vim帮助中找不到!
    • 您可以使用任何您喜欢的函数,例如一个为自己保留计数的函数。在这种情况下,您可能必须使用封装“循环”的命令,例如stackoverflow.com/questions/1809571/… 。否则,请参阅:h sub-replace-\=
    • 这是一种创建简单编号列表的好方法。我在我的 .vimrc 中添加了以下条目;要使用它,请进行视觉选择,然后按“领导”键(我的重新映射到空格键)+“n”;即 n。 vnoremap n :s/^\s*\zs/\=(line('.') - line("'
    • @VictoriaStuart。首选:xnoremap,以免弄乱选择模式——这是大多数sn-p插件使用的模式。
    • 对应的:UnNumberLines就简单多了:command! -nargs=0 -range=% UnNumberLines &lt;line1&gt;,&lt;line2&gt;s/\d\+\. //g
    【解决方案2】:

    您可以使用“记录”功能。 这是在 Vim 中录制宏的简单方法。

    参见:帮助记录

    在正常模式下“qa”开始记录您在“a”寄存器中键入的内容 键入必要的命令以在行首插入一个数字,将其复制到下一行并使用 CTRL-A 增加其值。 'q' 结束录音 然后'@a'重播存储在寄存器'a'中的宏 ('@@' 重复最后一个宏)。

    您可以连续执行 20 次类似“20@a”的操作。

    重复文本修改非常方便。

    根据具体情况,它比正则表达式更容易或更难使用。

    【讨论】:

      【解决方案3】:

      您可以轻松地录制一个宏来做到这一点。

      首先在第一行的开头插入1.1. 后面有几个空格,但你看不到它们)。

      转到第二行的开头并使用qa 进入记录模式。

      按以下按键顺序:

      i                         # insert mode
      <ctrl-Y><ctrl-Y><ctrl-Y>  # copy the first few characters from the line above  
      <ESC>                     # back to normal mode
      |                         # go back to the start of the line
      <ctrl-A>                  # increment the number
      j                         # down to the next line
      q                         # stop recording
      

      现在您可以使用@a 回放录音(第一次;以后可以使用@@ 重复上次执行的宏),它会在每个宏的开头添加一个新的递增数字行。

      【讨论】:

      • 使用3@a执行宏3次
      • 我会选择k^yWjP^&lt;ctrl-a&gt;j。文本可能不在行首,更重要的是,您的宏在第十行之后将不起作用。
      • 点对点,@Luc - 正是我自己拥有它的方式,只是我将 ^ 添加到末尾,以便在完成后将光标定位在行首。由于开头的^没有功能差异,只是感觉更整洁。
      • @Luc Hermitte: 将转到最后一位。之后我建议^
      • @PrabhatKumarSingh,您可以在宏的每个部分调用:h 以了解它的作用。在这里会很好用。 k -> 上一行,^ -> 行首,yW -> 我需要展示这个吗?,j -> 将光标移动到下一行,P -> 你如果您是 vim 用户,应该知道它会做什么,^-> 再次开始,&lt;C-A&gt; 是这里的工作:它增加光标下的数字,j-> 下一个再行。
      【解决方案4】:

      如果您有时必须这样做,也有一些插件可以完成此类工作:

      http://vim.sourceforge.net/scripts/script.php?script_id=670

      【讨论】:

      • 不能再同意了,专用于该任务的插件比自制宏要好得多,这是因为创建系列是一项您将拥有不止一次的任务。
      【解决方案5】:

      也许这不是一个宏观的解决方案,但至少它很容易。

      向所有行添加数字

      可以使用:%!nl -ba:%!cat -n 命令将行号添加到所有行。

      在 Windows 上,您必须安装 Cygwin/MSYS/SUA

      向选定的行添加数字

      要仅为选定行添加数字,请在可视模式下选择它们(v 和光标),然后在完成后 - 执行命令::%!nl(忽略空白行)或:%!cat -n (包括空白行)。

      格式化

      要删除多余的空格,请在可视块中选择它们 (Ctrl+v) 并删除它们 (x)。

      要在数字后添加一些字符(.:)),在可视块中选择它们(Ctrl+v),然后附加字符(A,键入字符,然后以 Esc 结束)。

      【讨论】:

      • 要添加一些字符 (.),您可以在选定的行上使用 :'&lt;,'&gt;normal a.。由于之前已完成选择,请使用 gv 重复此操作。
      【解决方案6】:

      在文本块的开头插入一个数字,例如。

      1. Item One

      输入vim普通模式命令如下:

      qb^yW+P^<Ctrl-A>q
      

      这意味着:

      qb       # start recording macro 'b'
      ^        # move to start of text on the line
      yW       # 'yank' or copy a word including the ending whitespace.
      +        # move one line down to the start of the next line
      P        # place text ahead of the cursor
      ^        # move to start of text
      <Ctrl-A> # increment text
      q        # Finish recording macro
      

      这使您可以根据需要多次在编号列表的最后一行重播宏。

      【讨论】:

        【解决方案7】:

        这是一种简单的方法,无需录制宏:

        1. 对每个列表项的第一个字符进行逐块可视化选择:

          ^<C-V>2j
          
        2. 在这些行的开头插入0.

          I0. <Esc>
          
        3. 使用gv 重新选择视觉选择(现在是所有0s),并将它们作为序列g&lt;C-A&gt; 递增:

          gvg<C-A>
          

        整个序列:^&lt;C-V&gt;2jI0. &lt;Esc&gt;gvg&lt;C-A&gt;

        A recording of the process in action.

        【讨论】:

        • 这是最好的解决方案。甚至不知道gvg&lt;C-a&gt;,现在我已经学会了它们,它们也可以用于其他情况。
        【解决方案8】:

        过了一段时间,我认为是时候升级这个答案了,至少对于 neovim 用户来说。 这里我写了一个可以绑定到 Enter 的 lua 函数,它适用于任何可以想象的列表类型,例如

        1. foo
         1.99-> bar
        

        按回车后,会添加这一行:

         1.100-> 
        

        都使用这个功能

        vim.api.nvim_set_keymap('i','<Enter>','v:lua.enter_or_list()', {expr = true})
        
        function _G.enter_or_list()
          local line = vim.api.nvim_buf_get_lines(0, vim.fn.line('.') - 1, -1, false)[1]:match('^%s*[^%a%s]+')
          if not line then
            return '\r'
          else
            local start, finish = line:find('[^%a%s]*%d')
            local main = line:sub(start,finish)
            local suffix = line:sub(finish+1)
            return table.concat({
              '\r',
              main,
              vim.api.nvim_replace_termcodes('<Esc><C-a>a', true, true, true),
              suffix,
              ' '
            })
          end
        end
        

        对于 vim 用户,我有一个更简单但功能稍差的键绑定:

        imap <silent> <S-Enter> <CR><Esc>kk<End>Ev<Home>yjpk<End>e<C-a><End>a<Space>
        

        我希望这对其他人也有用,因为它非常方便。 干杯

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-03-14
          • 2022-10-06
          • 2014-08-15
          相关资源
          最近更新 更多