用于在vim中编号的列表的宏?

时间:2010-11-19 11:13:41

标签: vim macros

通常看起来我有一个项目列表,我需要在它们前面添加数字。例如:

Item one
Item two
Item three

应该是:

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

在vim中,我可以在编辑模式下按I,插入“1”,然后点击“转义”。然后我转到下一行,按.,然后按^A增加数字。这看起来非常低效......我怎样才能创建一个宏,以便我可以转到下一行,并在开头插入一个比之前的行大一号的数字?

8 个答案:

答案 0 :(得分:21)

您可以轻松录制宏来执行此操作。

首先在第一行的开头插入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播放录音(第一次;对于后续时间,您可以@@重复上一次执行的宏)并且它将添加一个新的递增数字到每行的开头。

答案 1 :(得分:13)

在视觉模式中选择您的行:V,然后输入:

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

这很容易放入命令:

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

答案 2 :(得分:6)

如果有时必须这样做,还有一些用于完成此类工作的插件:

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

答案 3 :(得分:2)

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

请参阅:帮助记录

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

你可以做'20 @a'这样的事情连续做二十次。

重复文本修改非常方便。

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

答案 4 :(得分:2)

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

为所有行添加数字

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

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

为选定的行添加数字

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

<强>格式化

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

要在数字后添加一些字符(:%!cat -n.:),请在可视区块中选择它们( Ctrl + v < / kbd>),然后追加字符( A ,键入字符,然后用 Esc 完成)。

答案 5 :(得分:1)

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

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

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

    I0. <Esc>
    
  3. 0重新选择视觉选择(现在是所有gv),并将它们按顺序g<C-A>递增:

    gvg<C-A>
    

整个序列:^<C-V>2jI0. <Esc>gvg<C-A>

A recording of the process in action

答案 6 :(得分:0)

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

1. Item One

输入vim normal mode命令,如下所示:

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 :(得分:0)

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

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>

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