vimbook-OPL(18-20)
Contents
vimbook-OPL(18-20)
CH18 更多基本编辑命令
18.1 word 和 WORD
在 Vim 有两个’单词’,其中 word 表示由字符、数字和下划线等组成,类似于 C 中的标识符。 word 由 ‘iskeyword’ 来指定哪些字符构成一个单词。而 WORD 的中文翻译是字串,就是用空白符分割的任何非空白符序列。Vim 中的移动操作是针对单词的,另外一些则是针对字串的。
word 的定制之所以需要用 ‘iskeyword’ 选项来界定的原因在于,Lisp 语言允许标识符中有’-’,PHP 中的标识符中允许 ‘$’ 符,特定的文件类型可以指定不同的单词定义,方便做跳转。
值得说明的是 iskeyword 默认的值是 iskeyword=@,48-57,_,192-255
,此中 @ 表示所有 C 语言中 isalpha() 返回 true 的字符,如果需要 @ 字符本身得用 @-@
表示。数字可以用 0-9 或者 48-57,超过两位的数字就是 ASCII 码表示。如果要排除某些字符,用 ^ 作为前导字符,如: ^x 排除 x 字符,^a-c 排除 a 到 c 的字符。
‘isfname’ 中的字符集控制 gf
命令判断光标下的字符串是否为文件路径; ‘isident’ 定制的字符集控制 [d
命令查找宏定义; ‘isprint’ 中的字符集控制 \p 元字符所表示的可打印字符。
18.2 跳转命令
绝大数为程序员设计的编辑都会有回跳和前进的功能,当在函数定义之前做跳转或者搜索时可以回到以前的位置。Vim 定义了跳跃栈的概念,调用 :jumps
可以查看当前的跳跃栈。> 字符指示的行表示当前的位置,CTRL-O
将会跳一次跳跃栈,CTRL-I
或者 <TAB>
将前进一次跳跃栈。
18.3 回绕控制
Vim 可以用 ‘whichwrap’ 选项来定制比如 h l 这些操作是否可以跨行。
字符 | 键 | 模式 |
---|---|---|
b | <BS> | 普通和可视 |
s | <Space> | 普通和可视 |
h | “h” | 普通和可视 (不建议) |
l | “l” | 普通和可视 (不建议) |
< | <Left> | 普通和可视 |
> | <Right> | 普通和可视 |
~ | “~” | 普通 |
[ | <Left> | 插入和替换 |
] | <Right> | 插入和替换 |
‘whichwrap’ 选项是以逗号分隔的以上选项的字符集,指定对应的字符则对应的键可以跨行移动光标。
18.4 滚动屏幕
向上滚动屏幕导致光标往前面的行号。
CTRL-U
向上滚动由 ‘scroll’ 选项指定的行数;
CTRL-Y
向上滚动一行;
CTRL-B
向上滚动一屏;
向下滚动则刚好相反。
CTRL-D
向下滚动由 ‘scroll’ 选项指定的行数;
CTRL-E
向下滚动一行;
CTRL-F
向下滚动一屏;
当移动光标顶到了顶部或者底部时,将滚动 ‘scrolljump’ 选项指定的行数,如::set scrolljump=5
,表示当光标到达边缘时将滚动 5 行。‘sidescroll’ 控制水平方向的屏幕滚动。:set scrolloff=3
控制光标距离边缘的行数必须至少大于 3 行,否则会引起屏幕的滚动。
z<Enter>
导致当前行滚动到屏幕的顶部;zt
的效果一样会移动到屏幕的顶部,除了 zt
保持光标在原来的列上,而 z<Enter>
将光标移动到第一个非空字符上。
z-
导致当前行滚动到屏幕的底部,并且将光标移动到第一个非空字符上;zb
则在将当前行移动到底部时,光标保持在当前列不动;
z.
将当前行滚动到屏幕中央,并且将光标移动到第一个非空字符;zz
将当前行移动到屏幕中央,光标保持在当前列不动;
18.5 编辑命令
D
从当前字符删除直到行尾;
C
从光标处删除直到行尾,并进入插入模式;
s
删除光标下的字符,并进入插入模式,相当于 xi
命令组合;
S
删除整行并进入插入模式;
x
删除光标下的字符,并将光标向右移动一个字符,X
删除光标前的一个字符,并将光标向左移动一个字符;
I
在当前行的第一个非空白字符 ^
命令的位置前插入,gI
在当前行的行首 0
命令的位置开始插入;
18.5.1 Vim 算术运算
Vim 还可以对光标下的数字进行递增,CTRL-A
命令就能够完成;使用 CTRL-X
能够对光标下的数字进行递减;Vim 能够识别十进制、八进制和十六进制以及字母序列和二进制数字格式。而且如果在调用这两个命令前提供一个数字,光标底下的数字将加上或者减去提供的那个数字。如:设光标底下的数字是 123, 调用 5
-> CTRL-X
,光标底下的数字将变成 118 。记住调用 .
命令可以重复上一次的命令调用。
默认情况下识别除了字母序列以外的所有数字格式,这个由选项 ’nrformats’ 控制。
18.5.2 替换模式
J
命令将光标下相邻两个行的换行符替换成空格,gJ
则将此两行的换行符去掉。后面的行的前导空白符将会被删除,但是尾部空白不会删除;
R
命令将进入替换模式,输入的内容将替换掉原本光标下的内容。这里有一个小问题:当遇到 <Tab> 时输入的字符会把整个 <Tab> 给覆盖掉,为了保持原本文本的对齐,调用 gR
进入 virtual replace mode,这样遇到 <Tab> 时不会立即将 <Tab> 给覆盖掉,而是一次一点点这样持续进行。
18.5.3 改变大小写
g~
后接移动命令,将导致对应的移动过的字符的改变大小写的,如: g~$
将直到行尾的字符大写变小写,小写变大写。g~~
将整一行改变大小写;
gU motion
将移动过的字符变成大写。gUU
将一整行变成大写;
gu motion
和 guu
将字符变成小写;
18.5.4 小技巧
在很多终端中的 Vim 是不允许复制的,为了复制某个日志文件的第 18903 行,该怎么办呢?总不能把整个文件都 cat 下,然后再复制吧!很简单,:.,.w /tmp/a.log
就可以将当前行输出到一个特定的文件。
.,.
表示 Ex 命令中的一个 range (范围),这在 Vim 中是非常重要的一个概念。其中 . 表示当前行, $ 表示最后一行,可以用 /pattern/
?pattern?
表示搜索或回溯搜索的位置,中间用逗号分隔就组成一个特定的 range。如果仅指定逗号前面的部分就选中那一行作为范围。在帮助文档 :range 中可以找到非常详细的文档描述。
CH19 Vim 正则表达式
19.1 搜索
Vim 中大部分的特性都是通过选项来控制的,导致 Vim 中选项非常之多。搜索通过 ‘ignorecase’ 和 ’noignorecase’ 来控制是否大小写敏感。通过 ‘wrapscan’ 和 ’nowrapscan’ 来控制是否回绕搜索。
*
向下搜索整个匹配整个单词,相当于 <\word\>
,而 #
则执行相反方向的整词搜索。g*
和 g#
执行类似的搜索,但是不必精确匹配整个单词。如:g*
能够搜索 const 和 constant ,而 *
如果在 const 处执行,将不会搜索到 constant , 这是两者之间的区别。
搜索命令还支持指定 offset 的方式,如:/const/2
将光标停留在搜索到的 const 所在行的后两行。offset 可以是负数,这样就停留在上两行。如果 offset 以字母 b 开头,则为从搜索到的模式的第一个字符向后偏移 offset 个字符。如:/const/b2
光标将停留在字母 n 的位置。偏移以字母 e 开头,则从搜索的匹配串的最后一个字符开始偏移。如:/const/e2
从停留在字母 t 的后两个字符处。/const/e-2
将停留在字母 n 处。
当执行完以上命令时,调用 n
命令移动到下一个匹配的位置,值得注意的是所有的搜索都是从当前位置开始的,如上:/const/-2
会继续搜索到同一个位置,并将光标又置于上两行,这样导致光标不动。
//5
将重复上一次的搜索,并将光标置于下 5 行,这是是一个快捷的重复搜索。//
将取消 offset 并进行重复搜索。/
则直接重复上次搜索,我更倾向于使用 n
命令。
反向搜索的命令是 ?
,如:?const?2
?const?b2
?const?e2
?const?e-2
??5
??
?
的功能都类似于以上 /
命令的用法,除了是反向搜索以外。
19.2 正则表达式
正则表达式的最小单位是 atom,原子可以是字符、元字符、单词边界(\<
\\>
)、行边界(^
$
)这些特殊位置。除此之外还包括限定词(Quantifiers)和捕获组(Grouping)以及 or (\|
) 。其它的详见 vim正则表达式 笔记。
CH20 文本块和多文件复杂处理
20.1 register
寄存器在 Vim 中是个特别的概念,在别的编辑器中只有一个剪切板,所有复制的数据都进入此剪切板,而 Vim 中有 26 个普通剪切板以及多个特殊专用剪切板。Vim 成这些剪切板为寄存器(register)。最常用的寄存器是无名寄存器 ""
,调用 y
命令进入的就是这个寄存器。寄存器的名字必须以引号开头,而这个无名寄存器的名字就是引号。普通的寄存器由字母 a~z 组成,比如用 a 寄存器进行 yank 和 paste 的命令如下: "ayy
进行复制 "ap
进行粘贴。如果用大写字母调用则向寄存器中添加新的行,如:"Ayy
向寄存器 a 中增加新行。
调用 :registers
查看所有寄存器中的内容,:registers ax
则指定查看寄存器 a 和 x 的内容。特殊寄存器 1~9 表示最近删除的文本,最近的为 1 一直到最远的 9 。"1p
将最近删除的文本粘贴回去。除此之外还有一些特殊的寄存器如下表:
寄存器 | 描述 |
---|---|
0 | 最近复制的内容 |
- | 行内删除寄存器 |
. | 最近插入的文本 |
% | 当前文件名 |
# | CTRL-^ 命令打开的轮换文件名 |
: | 最近执行的 Ex 命令名 |
/ | 最近搜索过的内容 |
* | 鼠标选中的内容,这个可以访问别的应用的剪切板,方便多应用交流数据 |
_ | 黑洞寄存器,将吞噬所有删除的内容,如:"_dd 将内容吞噬掉,并且不会出现在 “1 寄存器中 |
= | 表达式寄存器,调用 "= 将给用户一个机会输入算术表达式,回车后,调用 p 将结果粘贴在文档中 |
20.2 +cmd
有时我们编辑文件的时候需要打开文件并直接定位到特定的一行,特别是用 Vim 查看日志文件的时候。我们可以用 vim file.c +1297
打开文件并将光标定位到 1297 行。除此之外 +
后面还可以接 /pattern
将光标定位第一个查找到的 pattern 处,如:vim +/#include file.c
定位到第一个 #include 处。另外,有一个我自己很少用的,+
后还可以接任何 Ex 命令。还有其它一些命令可以接 +
命令,如::next
:previous
:rewind
:last
20.3 全局标记
小写字母是局部于文件的标记,大写字母是全局标记(mark),局部标记 ma
每个文件都可以标记,调用 'a
或 `a
是回到当前文件的标记。如果想即便离开了标记文件还可以回去的话,得用 mA
,那就可以通过 `A
回到标记的文件。全局标记只能存在一个,也就是说当在另外一个文件做了 mA
标记将导致之前的标记失效。
20.4 viminfo 文件
Vim 定义了一个成为 viminfo 的文件,用来当 Vim 退出时保存历史信息,如:Ex 命令历史、搜索历史、输入历史、寄存器内容、标记以及缓冲列表和全局变量。viminfo 的启用通过 ‘viminfo’ 选项来设定,选项中的参数用逗号分隔,如以下设定:
:set viminfo='50,<1000,s100,:0,n~/vim/viminfo
下面解释为 ‘viminfo’ 而设定的参数的含义。
控制符 | 描述 |
---|---|
' | 保存编辑过的文件的最大数目,为它们记住位置标记(marks),viminfo 选项必须包含此参数。 |
f | 值为 1 或 0,如果为 1 或者不设置则表示保存位置标记,只有为 0 时不保存位置标记 |
< | 每个寄存器保存的最大行数 |
: | Ex 命令历史的行数 |
/ | 搜索历史的最大项目数,保存的数目不会超过 ‘history’ 选项的值 |
@ | 保存输入行历史的最大项目数目 |
% | 是否保存和恢复缓冲区列表,设定了的话只有在 Vim 启动不指定文件名时才生效 |
s | 所有寄存器能够保存的 KB 长度,超过后将不保存 |
! | 设定时保存大写字母开头并且不包含小写字母的全局变量 |
n | 后接 viminfo 的文件名,此参数必须是最后一个参数 |
以上示例中的选项值表示*保存最近编辑过的 50 个文件的位置信息,寄存器中的内容保存少于 1000 行的内容,所有寄存器的内容最多保存 100KB ,不保存 Ex 命令历史,将 viminfo 信息保存在 ~/vim/viminfo。其它参数使用默认值。在 Vim 中可以调用 :wviminfo[!] [file]
将 viminfo 写入到文件 file 中,以及调用 :rviminfo[!] [file]
从文件 file 中读取内容到当前 Vim session 中。
20.5 处理长行
gk
gj
两个命令可以长行回绕时移动到屏幕中的下/上一行,而不是逻辑上的下/上一行。这个命令当查看长行日志时很有用。
长行的回绕有好几个选项:’linebreak’ ‘breakat’ ‘showbreak’ ‘display’ ,在此不打算介绍。因为我觉得不重要 :-)
Author zoro.wang
LastMod 2018-01-21