《Practical Vim》读书笔记

  • 本书有点太极端,作者过分强调了操作可重复的,很难适应这种思维,而是给了太多的 tricks,很难在工作中用到,另外书中对 vim 的概念的讲解很到位,有这些概念才能 think in vim,比如模式 / normal 命令 / Ex 命令 / 寄存器 / quickfix 等,总之, vim 很牛, 但是本质上只是个编辑器,如果造成太多的心智负担,编码时候满脑子都是怎么实现酷炫的 vim 操作,而不是编码本身,就本末倒置了。
  • 整理不易,转载请注明。
  • Practical vim V2
    • 插入模式
      • normal
      • tricks
    • 正常模式
      • mormal 模式的命令 op{motion}
      • 跳转
      • 模式匹配
      • 对象的使用
      • 多文件的管理
      • quickfix
    • 命令模式
      • 执行 shell 命令
      • substitude
      • global
    • 寄存器
    • 可视选择模式

Practical vim V2

插入模式

normal

i(nsert) / I(nsert at beigin) / c(hange) / a(ppend) / A(ppend at end) / o(A) / O(Ik) / r(eplace char) / R(eplace mode)
通过以上按键即可进入插入模式,在该模式下可以逐字,逐行的插入、删除或移动光标,跟其他任何的编辑器没有差别, 在以下情况下会考虑切换到其他模式:

  • 1, 浏览之前写的内容;
  • 2, 修改之前的输入,如批量化的修改(批量注释),或者距离较长,依赖插入模式下逐行/字的移动或退格比较麻烦;
  • 3, 撤销或控制撤销粒度,控制撤销粒度,连续的一次输入应该可以一次撤销,适用快速切换到正常模式。

tricks

id 命令 简述 其他
0 插入模式下,撤销前一个单词 shell通用
1 插入模式下,撤销整行 shell通用
2 插入模式切换到普通模式
3 插入模式临时切换到普通模式,执行下一个输入后返回 zz / u
4 0 插入模式下使用寄存器0粘贴复制的内容
4 + 插入模式下使用寄存器+粘贴系统栈贴板的内容
5 = 插入模式下使用数学运算寄存器快速计算表达式的值
6 encode 插入模式下使用寄存器0粘贴复制的内容 u00bf = ¿

ps.

  • tip3, 在文档的上下部分插入时, 临时退出,'zz'可以使得当前编辑的行移动到视图的中央
  • tip3, ‘.’重复及‘u’撤销的粒度都是从上次进入到退出编辑模式直接完整的编辑,因此临时切换到正常模式可以控制撤销的粒度
  • tip4, ‘0’为复制寄存器,‘=’为数学计算寄存器

正常模式

尽量使正常模式下的操作可重复 by Drew Neil, 尽管构造可重复的修改并使用‘.’来重复应用,及‘;’来重复应用定位很炫酷,但是对一般的使用者意义不大, 除非是真正的重复的编辑修改的场景,例如批量的格式化,单词的替换,此时列操作和替换命令看起来更加直观

mormal 模式的命令 op{motion}

normal 模式下命令的通常形式为 op{motion}形式, 指应用op从当前光标到移动命令结束的位置

cmd introduction
c change
d delete
y yank into register (does not change the text)
~ swap case (only if 'tildeop' is set)
g~ swap case
gu make lowercase
gU make uppercase
! filter through an external program
= filter through 'equalprg' or C-indenting if empty
gq text formatting
> shift right
< shift left
zf define a fold
g@ call function set with the 'operatorfunc' option
A $a
I ^i
C c$
s cl
S ^C
O A
gc commit, by commentary.vim

跳转

id 命令 简述 其他
0 gh/gj/gk/gl/g^/g$ 对于超长行的文本,会wrap成多个屏幕行,屏幕行上的移动使用
1 b-w, ge-e 移动到前/后一个单词的第/最后一个字符处
2 B-W, gE-E 移动到前/后一个字串的第/最后一个字符处
3 f/F/t/T ; , 向前/后移动到下一个匹配字符处[前一个字符],‘;’重复移动,‘,’ 撤销移动
4 /pat ?pat n/N, # / * 向后/前查找单词,跳转到下一个/上一个匹配项
5 % 匹配的括号之间的跳转
6 m[a-z],m[A-Z] marks, 'm 设置页内标签a-z页间标签A-Z,查看所有标签,快速跳回
7 :n +/-nG, gg, G 跳转到指定行
8 {/}, (/) 跳转到段首/尾,行首/尾
9 H / M / L 跳转到屏幕头部 / 中部 / 尾部
10 gf 跳转到光标下的文件名对应的文件中
11 跳转到光标下符号的定义处,配合 ctags 使用
12 / 返回到上一个位置
13 g; / g, 向前/后遍历修改列表中的位置

模式匹配

id 命令 简述 其他
0 /foo\c, /foo\C 查找文本大小写不敏感 / 敏感
1 /\vpattern-pythonlike \v 使用python类似风格的正则表达式,避免了posix风格的大量转义字符
2 /\Vpattern-pythonlike \V按原义查找,不使用正则
3 /\v<(\w+)\s+\1> \1代之原括号内元组,<>表示匹配单词的起止,表示搜索重复的单词
4 :vimgrep /pat/[g] % vimgrep 在当前文件中查找pat, 查找结果在quickfix中, cnext/cprev 切换

ps.

* tip6, set incsearch, 在输入时自动预览第一处匹配
* tip7, set hls[earch] / nohls[earch] 切换搜索高亮,
* tip8, `/pat/e` 跳转至搜索并且将光标置于词尾
* tip9, %s/pat//gn 查找匹配的个数,不真正进行替换 
* tip4, copen 打开 quickfix 窗口
* tip0, 查找命令之后的 substitude / vimgrep 可以将 pat 置空表示使用之前的, 如 `/pat \n :s//str/` 

对象的使用

在 c[chang] / d[elete] / y[ank] / v[isual] 选取时,可以使用对象来快速的选取

sym introduction others
a( / a) '()'及内部 i(/i) 括号内部
a{ / a} '{}'及内部 i{/i} 括号内部
a[ '[]'及内部 i[ 括号内部
a' ''及内部 i' 引号内部
a" ""及内部 i" 双引号内部
a` ``及内部 i` 反引号内部
at 及内部 it 内部

多文件的管理

缓冲区的概念,vim在编辑时,可以将多个文件加载到缓存中,只有在write/edit命令才进行缓冲区文件的显式落盘或加载,内存中的文件对应一个缓冲区,vim可以同时打开多个 tab 每个 tab 中可以切分多个 windows, 每个 windows中可以打开多个缓冲区文件

id 命令 简述 其他
0 s/v, .. 水平/竖直切分窗口,上下左右切换窗口
1 :vsp/sp [file] 水平/竖直切分窗口,并打开文件
2 tabnew [file], tabn/tabp 新建标签页并打开文件,切换上/下一个标签页
3 vim files / ls / nnext/prev 打开多个缓冲区,查看,切换
4 :e %:hfile 使用相对目录打开文件
5 :find file 查找文件,查找path内的文件 set path+=dir

ps.

  • tip0, _/| 设置窗口高度/宽度为最大,[N] _/|设置宽度高度指定行
  • tip2, tabmove [N]将当前标签页移动到第n个,缺省为最后一个
  • tip3, 两个文件直接反复切换编辑,可借助缓冲区切换的快捷键,
  • tip3, 当一个文件被编辑未保存时,切换到其他缓冲区,操作会被组织,可set hidden,未被保存的文件会成为 hidden 文件,vim 退出时,询问是否需要保存

quickfix

  • vimgrepmake 的结果都会输出到一个特定的 quickfix 文件中,该文件中的每行点击后都会跳到对应文件中
  • 在 vimgrep 搜索的结果的 quickfix 目录中使用 cfdo 执行批量查找,可以提换完成所有缓冲区中的替换 cfdo %s/pat/str/g | update

命令模式

id 命令 简述 其他
0 [range]delete[x] 删除指定范围内容,保存到寄存器x中
1 [range]rank[x] 拷贝指定范围内容,保存到寄存器x中
2 [line]put[x] 粘贴寄存器x中内容到指定行
3 [range]copy{address}, t 拷贝指定范围的内容到指定位置,address=.表示当前位置
4 [range]move{address}, m 移动指定范围内的内用到指定位置
5 [range]join 连接指定范围内的行
6 [range]substitute/{pat}/{string}/[flags] 替换所有匹配处的内容
7 [range]normal{cmd} 对范围内每行执行normal模式下的命令
8 [range]global/{pattern}/[cmd] 对范围内匹配pattern的每行执行Ex命令
8 [range]vglobal/{pattern}/[cmd] 对范围内反向匹配pattern的每行执行Ex命令

ps.

* tip7,  `/delete/-2,131 normal $x` 删除表格末尾的'|',`121,131 normal A|` 反向加回
* tip10, ex命令中可以使用寄存器`{register}`, 可以使用 ` ` 撤销
* tip11, '.' 当前光标所在行,'$'最后一行, '%'所有行, '0' 表示第一行的上方, 'm 标签所在行, '< 高亮选取起始行 '> 选区结束行
* tip12, 范围的起始地址可以使用模式匹配加偏移量来表示,如 :/delete/-2, /global/p 
* tip13, `@:` 重复执行上次的 Ex命令, 执行一次后简化为 `@@`
* tip14, `set wildmenu \n wildmode=full`设置 Ex 命令的提示风格为 Zsh 风格,即列出所有可用项
* tip15, `` 可以复制光标处的单词到命令行, ``拷贝字符串
* tip16, `%` 表示当前文件的名称, `%:h`当前的文件的目录名称
* tip17, `:  / ` 回溯之前输入的命令, `q:` 打开命令历史

执行 shell 命令

id 命令 简述 其他
0 [!]cmd 执行shell命令,!表示执行一条立刻返回vim,否则会留在shell,直至exit退出
1 read !cmd 执行shell命令,并将标准输出重定向到当前文件中, 如read !ls获取文件列表
2 [range]write ! cmd 写出范围内的内容到新文件,文件名为cmd
3 [range]write !cmd 将范围内内容定义到标准输入,执行cmd 152,159write !xargs echo
4 [range]!{filter} 使用cmd处理范围range内的内容并替换原有内容, `152,158!sort -t' ' -k2`

substitude

:[range]s[ubstitude]/{pattern}/{string}/{flags}

  • pattern : 为空表示使用上一次模式, %s///gn 查找上一个模式共匹配几处

  • string :

    • /r : 换行
    • /t : 制表
    • // : /
    • /0, & : pattern匹配的整个字符串
    • /1 - /9 : pattern中对应编号的元组, 可以用来重排列表
    • ~ : 上一次替换是用的替换字符串
    • ={vim script}: 提交为脚本中的执行结果, %s//\=@0/g = %s//0/g 替换为寄存器0中的值,@寄存器解引用
  • flags :

    • g 替换每一行的所有匹配,否则仅替换第一个匹配
    • c 确认每一次修改, y(es) / n(ext) / q(uit) / l(ast one) / a(all before, invove this) / 向上滚屏 / 向下滚屏
    • n 不提换只显示匹配的个数
    • & 使用上一次命令的 flags
  • %s//~/& 重复上一次替换

global

  • [range] global[!] /pat/ {cmd} : 所有匹配项执行 Ex 命令
    • range : 默认 % 全文
    • [!] : 时能表示反向匹配, 同 vglobal
    • cmd 默认为 print, :190,195g/\V*/p = :190,195g/\V*/ 打印190-195中所有的列表项, g/^#/yank a | reg a 可以将本文中所有列表项保存到寄存器a中

寄存器

delete / yank / put 都可以使用 "{register} 方式指定寄存器,否则使用缺省的寄存器,Ex 命令中, delete / put / yank {register} 也可以指定寄存器

寄存器 简述 其他
"" 缺省寄存器,默认的复制粘贴内容都会拷贝到该寄存器中
"0 赋值专用寄存器,yank内容会自动拷贝到该寄存器中
"_ 黑洞寄存器,"_d{motion}删除内容不保留到寄存器中
"+ 系统剪贴板寄存器,可以用来同系统的内容交互 需要vim版本支持
"= 表达式寄存器,输入表达式输出结果
"% 当前文件名寄存器
". 上次插入的文本
": 上次执行的Ex命令
"/ 上次查找的模式

ps.

* tip0 : `reg "{register}` 打印寄存器中的内容 
* tip1 : vim 中寄存器 a-z 会替换其中的值, 而A-Z寄存器是追加写
* tip2 : `vim --version | grep clipboard` 查看,如果不支持,需要重新配置编译 vim

可视选择模式

  • v 普通可视模式,选取不规则的分区,o选择时会固定一端移动另一端,o可切换, 选择后可使用normal命令
  • 列选取编辑模式,调整列表项的空格,追加注释,追加行末分号很有效,^$ 可以选出不规则的选取

你可能感兴趣的:(《Practical Vim》读书笔记)