假设我有以下文本:

some random stuff
* asdf
* foo
* bar
some other random stuff


我想用数字替换星号项目符号,例如:
如何在vim中完成呢?

评论

你为什么不去寻找插件?类似的是Github中的增量.vim

真是太神奇了,每个人都回答得递增,但是Markdown会为您编号,为什么不把它们都设为1。因此:%s / ^ * / 1。 /会做到的。看来工作量要少得多。

#1 楼

您可以尝试以下命令:

:let c=0 | g/^* /let c+=1 | s//\=c.'. '



首先它初始化变量clet c=0),然后执行全局命令g来寻找模式^*(行的开头,后跟一个星号和一个空格)。

只要找到包含该模式的行,全局命令就会执行命令: (let c+=1 | s//\=c.'. '),然后(c)用表达式(let c+=1)的值替换(|)先前搜索的模式(s): >

如果您不想修改缓冲区中的所有行,而只想修改特定的段落,则可以将范围传递给全局命令。
例如,仅修改编号在5到10之间的行:

:let c=0 | 5,10g/^* /let c+=1 | s//\=c.'. '



如果文件包含se要转换的类似清单的清单,例如这样的东西:

这只是前一个命令的变体,当您切换到另一个列表时,它将重置变量//。为了检测您是否在另一个列表中,使用变量\=来存储进行替换的最后一行的号码。
global命令将当前行号(c)与.进行比较。如果它们相同,则意味着我们与以前在同一列表中,因此'. '递增(c),否则意味着我们在不同的列表中,因此d被重置(line('.'))。

在函数内部,可以这样重写命令d+1

some random stuff                 some random stuff                      
* foo                             1. foo                                 
* bar                             2. bar                                 
* baz                             3. baz                                 
some other random stuff           some other random stuff                
                           ==>                                                
some random stuff                 some random stuff                      
* foo                             1. foo                                 
* bar                             2. bar                                 
* baz                             3. baz                                 
* qux                             4. qux                                 
some other random stuff           some other random stuff                


或者这样:

:let [c,d]=[0,0] | g/^* /let [c,d]=[line('.')==d+1 ? c+1 : 1, line('.')] | s//\=c.'. '



要保存一些击键,您还可以定义自定义命令c,该命令接受一个默认值为c+1c)的范围: 1let [c,d]=[line('.')==d+1 ? c+1 : 1, line('.')]将自动替换为您使用的范围。

因此,要转换缓冲区中的所有列表,请键入::NumberedLists

仅行之间的列表10和20:1,$

仅视觉选择:-range=%


有关更多信息,请参见:

let c = line('.') == d+1 ? c+1 : 1
let d = line('.')


#2 楼

这仅适用于最新的Vim版本(具有:h v_g_CTRL-A): * 0。 >(如果要在每个数字后都有一个点,请将第一步更改为:* Ctrl-v j j r 0 gv

#3 楼

直观地选择行并执行以下替换命令:

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


请参阅:help sub-replace-expression:help line():help '<。 ,具有偏移量的向前和向后搜索可用于指定替换范围,例如:

:?^[^*]?+1,/^[^*]/-1s/*/\=line('.') - search('^[^[:digit:]]', 'bn') . '.'


请参阅:help cmdline-ranges

#4 楼

另一种方式:

:let n = 1 | g/^* /s//\=printf('%d. ', n)/g | let n = n + 1


#5 楼

您还可以定义自定义运算符

,可以将它们映射到键序列'*'#。标记*#不存在,因此您不会覆盖任何默认功能。
选择'作为前缀的原因是为了获得某种助记符。您要在某些行的前面添加符号/标记。通常要打标记时,请使用前缀'。脚本,但是对于交互式使用,一般的运算符可能更好,因为您可以将其与任何运动或文本对象组合。点击'*ip在当前段落中。在这里,'*是一个运算符,ip是它可以运行的文本对象。

通过敲击'#10j对在后10行带有数字前缀的列表执行相同的操作。在这里,'#是另一个运算符,而10j是一个运动,覆盖了该运算符所在的行。