有多少种方式可以在vim 中插入行号
1 在文本中插入行号
最近有朋友提到某编辑器有一个可以插入行号的插件,问Vim有没有办法可以在文章中插入行号。%$^&*#8~#$@#!……让我们看一下有多少种方式可以在vim中插入行号或数字序列!
建议看一下Vim官网的这篇文章。里面一部分内容与这篇是重叠的。不过这篇是中文的XD。
我们的目的是在当前编辑文中的每一行前面加上行号或数字序列并用空格分隔,如:
这是第一行
这是第二行
这是第四行
在插入行号后将成为:
1 这是第一行
2 这是第二行
3
4 这是第四行
但有时我们需要对部分行编号。下面的例子是对第二行以后的所有非空行依次编号:
这是第一行
1 这是第二行
2 这是第四行
3 这是第五行
为了区别行号,我这里就称之为数字序列。
进入正题。
1.1 使用line()函数
相信这是大多数人第一个想到的解法了——使用line()函数产生行号用:s命令插入行号。
" 为所有行加上行号
" 使用合适的范围或者正则表达式就可以限定作用的范围。
:g/^/ s//\=line('.').' '/
优点是简单易用。缺点是不够灵活,只能用以显示指定行的行号。
1.2 使用ex命令
vim提供了一些可以打印行号的ex命令,如,"=", "p #" 和"#"。为了捕捉Vim的命令输出,我们用redir命令。
" 为前30行加上行号
:redir @a | 1,30# | redir END
:1,30d | put! a
逻辑上很容易理解:1,30#显示前30行及其行号。保存到寄存器a中,删掉前30行,再贴上寄存器的内容。
没什么明显优点的一种方法。缺点同上。如果不是更改当前编辑区的内容而是直接保存到新文件的话,这种方法就比其他的方法方便。
1.3 使用range()函数
range()是个新的函数,用来产生包含数字序列的列表。当然也可以用来生成行号:
" 为前30行加上行号
:for i in range(31)
:call setline(i,i .' '. getline(i))
:endfor
对range(),setline()的用法见帮助文档。
range()函数相对前面的2个解法而言要灵活许多,除可用以表示行号,也可以用来编数字序列,相应地也要求一些编程基础。
1.4 加法运算
这是也是简单灵活的一种解法。好吧,也许大家第一个想到的解法不是使用line()函数。
" 为所有行加上行号
:let i=1
:g/^/ s//\=i . ' '/ |let i=i+1
注意:g后面的两条命令(:s, :let)一定要写在一起。这是比较通用的一种编号方式,可以应付大部分的编号问题。
1.5 使用<CTRL-A>
Vim提供了Ctrl-A和Ctrl-X来分别对光标下(或者光标右边第一个)数字进行增、减操作。按Ctrl-A一次可加一,按Ctrl-X则是减一。如果你用的是Windows,那很有可能Ctrl-A已被映射成全选了。输入
:nunmap <C-A>
使之恢复功能,当然你可以用:nnoremap重新映射到其他键。赶紧翻出文档吧:
:h CTRL-A
:h CTRL-X
:h unmap
:h o_v
先看一下,普通模式下的操作步骤:
第一、手工添加第一行序号和空格。
第二、输入0"ayw将序号放到寄存器a。
第三、移到下一行并输入:
qq0"aP0^A"ayawjq
上面的命令将指令序列存进寄存器q。^A表示按Ctrl-A组合键。
第四、28@q对接下来的28行添加行号。
上面添加空格是很重要的步骤(因为我们使用了yaw复制数字和空格),这里解释一下第三步:
`qq‘
开始录制宏,并保存到寄存器q中
`0‘
设定光标的位置到行首
`"aP‘
放上前面保存的序号和空格
`0^A‘
回到行首并按Ctrl-A加一
`"ayaw‘
复制当前数字和空格到寄存器A
`jq‘
移到下一行(这样我们才能确保28@q是对下面的28行进行操作而不是对当前行操作28次),然后结束宏。
通过与:g指令配合可以对指定行编号。下面的例子对所有以字母开头的行进行编号。为了说明方便我们直接对寄存器赋值,效果与上面普通模式下的操作是一样的。注意下面两例操作中的^A的输入方法与上面直接按组合键的方法有所不同,先按Ctrl-V(不行的话试Ctrl-Q),再按Ctrl-A:
" 先重置a寄存器。
" 再对所有以字母开头的行编号
:let @a='0 '
" 去掉了j指令
:let @q='0"aP0^A"ayaw'
:g/^\a/ norm @q
如果你用的分隔符不是空格,可以对它进行手工标记:
" 这个例子使用冒号作为分隔符
:let @a=0
:let @q='0"aPa:^[0^Amm"ayv`m'
:g/^\a/ norm @q
^[的输入方法是依次按Ctrl-V, <ESC>键。这个例子中使用了mm对最后一个数字做记号,yv`m确保复制时也包括了最后一个数字本身。
宏指令是Vi最有力的工具之一,在Vim中宏则比以往更强大。宏并非完成此工作最有效率的解法,但写宏的乐趣要比其他的脚本来得多得多。这个解法经过修改一样可以适用多种情况,缺点是在写出一个可行的宏之前要经过多次地调试。
<!-- @section 使用字母替换 -->
1.6 利用Vim的编程支持
除了内建的Vim Script以外,Vim还提供了对四种脚本语言的“支持”,Perl、Python、Ruby和TCL(是五种Sorry,还有MzScheme)。这里的支持包括了可以直接在Vim的命令窗口中使用其他语言的语句;在其他语言中可以操纵Vim对象,使用Vim命令。这里给出perl和Python实现的脚本。
perl版本:
" 对前30行进行编号,默认范围是所有行
" perldo命令中的$_表示当前行
:1,30perldo $_=++$i . ' ' . $_;
Python版本:
" Python中vim.current.buffer是个只读列表对象,
" 所以只能替换列表中项的值而无法替换列表本身。
:python <<EOF
from vim import current
for i in range(len(current.buffer)):
current.buffer[i]=str(i+1)+' '+current.buffer[i]
EOF
因为这四种脚本语言都是通用的编程语言,所以实际上可以完成任何形式的编号工作。缺点是这要求用户的Vim在编译时包含了相应的选项,同时(主要是Windows平台)还要另外装相应的脚本引擎。
1.7 外部命令
有许多的外部命令也可以用来完成这项工作,这里挑几个有代表性的。
下面的命令给出的是Windows下的版本(不过除findstr是XP自带的外,其他都是Linux下移过来的XD),将双引号改为单引号就可以在Linux下运行了。
1 :%!findstr /N "^"
2 :%!sed =|sed "N;s/\n/ /"
3 :%!diff --line-format=\%-dn\%L % -
4 :%!perl -pe "print ++$a . ' '" -
5 :%!python -c "import sys,fileinput as f;[sys.stdout.write(str(f.lineno())+a) for a in f.input()]"
6 ...
...
n ....
这里做些补充说明:
`findstr‘
findstr是grep的MS实现,可以是Windows XP上找到。这里使用正则字元^来匹配所有行,使用N选项显示行号。入选理由是这是我能想到的Windows自带的除WSH外惟一能过滤文本并添加行号的命令行工具。
`sed‘
见SED单行脚本快速参考。入选理由这是Vim的好搭档。
`diff‘
这里使用了diff的选项–line-format%-dn表示行号,%L表示行的内容。Vim会将%转义成为当前文件所以格式中的两个%号要加上反斜杠转义。入选理由是Vim自己带了这个工具。
`perl‘
不用解释了吧。入选理由是Perl是最强大灵活的文本处理工具。
`python‘
这个脚本用了fileinput模块捕捉输入,用sys模块进行输出到stdout(在这里就是Vim的编辑区)。如果手中的Vim是没带Python的版本(所以不能用上面的:python命令)又出于某种未知原因想用Python,可以试一下。
此外还有awk,cat,grep,nl,… 等不再赘述。
这种解法的优点在于简单易用,缺点在于要有相应的外部程序。而灵活性则取决于所使用的工具。
2 最后
可以看到添加行号对Vim来讲是小菜一碟。
考虑到Vim本身的脚本引擎及到其他编程语言的支持,在Vim实现某种功能在大部情况下是很容易的。Vim只需要负责显示逻辑,而文本处理的工作可以由外部的程序或脚本来完成。如果你觉得某个文本处理的功能在Vim中的实现要复杂得多时很多时,很可能还有其他的实现方式。
当然,肯定还有其他的方法可以实现在Vim中添加行号的目的。
分享到:
相关推荐
- **插入文本**: 如何在Vim中输入文本。 - **移动光标**: 使用各种快捷键来移动光标。 - **删除字符**: 删除文本的方法。 - **撤消与重做**: 撤销和重做操作的快捷键。 - **其它编辑命令**: 除了基本的编辑命令外的...
7. 集成Git:通过安装fugitive.vim,可以在Vim内进行Git操作。 8. 调整缓冲区:使用`:sp`分割屏幕,`:vsp`垂直分割,`:bn`和`:bp`在缓冲区之间切换。 9. 设置自动缩进:`set autoindent`开启自动缩进,`set ...
在Linux和其他类Unix系统中,`vim`几乎是必备的工具,对于程序员、系统管理员以及任何需要高效文本处理的用户来说,掌握`vim`的高级用法是十分必要的。 #### 基础配置解析 1. **兼容性设置**:`set nocompatible`...
而“vim-vertical-move”则扩展了这种移动方式,使得用户可以在列选中进行垂直移动。 2. 插件概览 “vim-vertical-move”是一个专注于垂直移动功能的Vim插件,它提供了一种在多行之间移动选区的新方法,这对于代码...
这样,习惯使用Vim的用户可以更加便捷地在Bash中输入命令。 以下是Vim在Bash中用于命令编辑的一些常用快捷键及其功能的详细说明: 1. 切换至命令模式: - ESC:用于从输入模式切换回命令模式。 2. 输入模式...
可以在`.bashrc`文件中添加以下内容: ```bash export LANG="zh_CN.UTF-8" export LC_ALL="zh_CN.UTF-8" ``` 这些设置确保了系统环境变量指向中文环境,从而帮助Vim正确处理中文字符。 ##### 3. 使用支持中文的字体...
例如,使用`:next`和`:previous`可以在多个打开的文件之间切换,使用`:split`和`:vsplit`可以水平或垂直地分割窗口。 通过以上介绍,可以看出Vim编辑器虽然有较陡峭的学习曲线,但它提供了高度可定制性和强大的功能...
要启用相对行号,可以在Vim中输入`set relativenumber`。同时,`set nu` 打开绝对行号显示,而 `set rnu` 开启相对行号显示。如果你希望在插入模式(Insert mode)中使用绝对行号,而在正常模式中使用相对行号,可以...
通过掌握这些基础操作,用户可以在日常工作中更加高效地使用Vim来处理文本文件。无论是简单的文本编辑还是复杂的脚本编写,Vim都能提供强大的支持。随着经验的积累,用户还可以进一步探索Vim的高级特性和插件,以...
- 启动:在命令行中输入`vim [filename]`,其中`[filename]`为要编辑的文件名。 - 退出:`:q!`(不保存退出)、`:wq`(保存并退出)。 #### 二、移动与导航 - **基本移动命令**: - `h`: 向左移动一格。 - `j`:...
在Vim中,行号可以帮助我们更容易地定位文本,可以按照以下方式控制行号的显示: #### (1) 显示文本内容行号 - **`:set nu` 命令**:在命令模式下输入`:set nu`,Vim会显示每一行的行号。这对于查看和编辑代码非常...
此外,snipMate支持自定义代码片段,你可以在~/.vim/snippets目录下创建对应语言的snippet文件,添加自己的代码模板。例如,创建一个名为`javascript.snippets`的文件,并添加如下内容: ```snippet snippet if if...
- **命令模式**:Vim启动后的默认模式,在该模式下可以通过键入特定命令来进行文件编辑操作。 - `i`:进入插入模式。 - `a`:在光标后方插入文本。 - `A`:在行尾插入文本。 - `o`:在当前行下方新开一行并进入...
- **模式**:Vim 有三种主要的工作模式,分别是正常模式、插入模式和可视模式。 - **命令行模式**:通过按下 `:` 或 `/` 进入,用于执行 Vim 命令。 - **动词、名词、介词和数词**:这是 Vim 中一种形象化的记忆方式...
VIM 主要有三种基本的工作模式: 1. **普通模式**:启动 VIM 后默认进入的模式,可以执行大部分命令。 2. **插入模式**:用于输入文本的模式。 3. **命令行模式**:用于执行 VIM 命令的模式。 #### 三、基本操作 ...
- **模式切换**: vim有三种主要模式:命令模式、插入模式和可视模式。从命令模式进入插入模式,按`i`,从插入模式返回命令模式,按`Esc`。 - **基本移动**: 在命令模式下,使用`h`(左)、`j`(下)、`k`(上)、`l...