VIM 笔记

3 篇文章 0 订阅

VIM 笔记

阙荣文 - Que's C++ Studio / 2017.9.14


0. 学会的是解决 VIM 相关问题的方法论而不仅仅是一些知识点.

1. 善用 VIM 自带的用户手册 :h
关键在于平时就一直使用 VIM,命令用得多了自然就记牢熟练了.

2. 基本常识 - 掌握之后可以代替Windows下一般的文本编辑器

2.1.1 VIM 的模式
VIM 的几种模式: 常规模式/可视模式/命令行模式/插入模式.
常规模式下可以使用快捷命令浏览,复制粘贴,查找替换文本.
可视模式下通常用来选中文本后使用编辑命令.
命令行模式可以使用 VIM Ex命令(以:开头),或者 !{cmd} 执行 shell 命令.
插入模式等同于普通的文本编辑器.

2.1.2 VIM 中的 {range}
见帮助 [:h [range]] - 主要指行范围,[.]代表当前行,[$]代表最后一行,所以 [1,$]=[%] 代表整个文件.
很多命令前使用 range 修饰作用于不同范围.

2.1.3 VIM 中的 {motion}
比如 [d/c/y] 命令都需要指定作用范围, {motion}据 VIM 文档指的是光标移动命令,即 [d0] 可以删除光标到行首的内容, [d$] 可以删除光标到行尾的内容.同理 [db] [dw] 都很好理解.
同理,[dl] 和 [x] 效果相同.
文本对象也属于一种 {motion}.
VIM 的文本对象以 [i](inner) 或者 [a](around / an) 开头,后续 [w] 表示一个单词, [(){}[]""'<>] 表示成对符号内的内容. [t]表示一对 XML 标签.

2.2 普通模式(这是VIM的最常状态,保持在普通模式是一个好习惯)

2.2.1 普通模式命令
[y]:复制
[d]:剪切需要后续动作,比如[dd]删除一行,[dw]删除一个单词
[x]:剪切光标位置或者选中的字符
[p]:粘贴
[u]:undo
[<C-r>] redo
g开头的命令,有些表示 "GUI",有些表示 "goto", 如 [gk/gj] 光标在屏幕行内移动, [gf] goto file with name eq word under cursor.
[gd] 跳转至变量定义处.

2.2.2 寄存器
[:reg] 列出所有寄存器的内容,如果上述复制粘贴命令前添加寄存器的名字就可以复制/粘贴指定寄存器的内容,否则使用默认寄存器[""].
可以看到系统剪切板的寄存器名称是["*],如果不做快捷键映射的话在 Windows 下使用会很不习惯.

2.2.3 移动光标
除了 [hjkl]之外,快速移动光标的常用技巧:
对于每个窗口,VIM会维护一个"跳转列表",[:jumps]查看,[<C-O>] 和 [C-i]/<TAB> 浏览跳转列表,这是非常重要的技巧大大加快编码速度(理解什么是"跳转"很微妙,总体而言"大"的移动才是跳转, hjkl<C-d><C-f> 等"小"移动/翻页不算跳转).
[<C-]>] 可以访问 VIM 里的链接,在查看 :h 时很方便.(这个功能其实是通过查找tags实现的, <C-]> 触发VIM查找光标下的单词为关键字定位 tags)
[`.] 光标跳转到上次修改的位置(这是一个自动设置的书签)
[:mark]/[m{a-zA-Z}]设置书签, [`{a-zA-Z}]访问书签
[w][b][e]]可以以单词为单位移动光标,[^][$]移动光标至行首行尾也比较常用.
[f{x}][;][,]配合飞快行内定位.
[3G]/[3gg] 跳转到第3行.[G]跳转到最后一行,[gg]跳转到第一行.[:3]也一样可以定位到第三行.
[zz] [zt]/[z<CR>] [zb] [<C-f>](forward 下翻页)/[<C-b>](backward 上翻页)/[<C-u>][<C-d>] 向上/下翻半屏, [<C-y>][<C-e>]上下滚动一行,把光标所在行滚动到屏幕中间/顶部/底部,可以代替鼠标滚轮让阅读更舒适.(我就是在熟悉了这些操作之后感觉终于可以舍去鼠标了)
[m{x}] [`{x}] :marks :delmarks 一组书签命令和 [``] [`.] 等自动书签组合使用也可以迅速定位光标

2.3 命令行模式(普通模式下按[:]进入命令行模式, <ESC>返回普通模式)

2.3.1 常用的 Ex 命令: e,w,q
!{cmd} 和 {cmd}! 的区别
[:set] 设置参数,选项.
[@:][@@] 直接重复执行上一个 Ex 命令
[:r !cmd] / [:r <filename>] 读取命令输出或者文件插入到文档中.
[:!] 执行一个空命令相当于从 VIM 切换到 shell 窗口.
[:shell] 返回 shell, 在 shell 中 [exit] 返回 VIM
[K] 相当于执行 man <光标下单词>

2.3.2 查找
(1). [/] 向后查找, [?] 向前查找. [n][N] 跳转到下一个或者前一个匹配项.
(2). 进入查找命令行模式后,按 [<C-r>]可以粘贴寄存器的内容, [<C-u>]清空命令行.
(3). [:set hlsearch] [:set nohls][:noh] 可以高亮/关闭高亮匹配项
(4). [\C][\c]可以大小写或者忽略大小写查找.

2.3.3 替换
[:substitute]简写[:s]格式见 :h
:s/{pattern 需要查找的正则表达式}/替换的文本/标志位
标志位: c 依次确认, n 只报告不执行真正替换, g 替换当前行的全部匹配项, 用 [:%s] 配合 g 标志位就可以在整个文件范围内替换全部, & 重复上次 [:s] 命令的标志位.
在替换文本中可以用 \1 ~ \9 使用 pattern 中的捕获.
统计查找匹配个数
[:%s///gn] - :%s 表示在整个文件的范围内运行 :substitute 命令,pattern项留空表示使用上一次查找的 pattern,替换项留空因为不需要替换,标志位 g 表示处理行内的所有匹配项而不仅仅每行的第一项, n 表示不执行真正的替换.所以整个命令就是统计匹配项的个数.
可以用 [map] 映射一个快捷键.
[:s] 命令使用 :s 后的第一个字符作为分隔符,所以有时候会看到这样的写法: [:s|pattern|replace|opt]

2.3.4 正则表达式查找替换
[\v] 开启简洁模式,VIM认为输入的文本就是正则文本,否则需要输入很多很多的\
[()] 可以捕获, [\1] 则可以访问对应的捕获,而[\0]总是值匹配整个正则串的文本.
[:h usr_27.txt] 有关于正则表达式很详细的说明.

2.3.5 [:global] 命令
[:g/{pattern}/ex cmd] 意思是在整个文件范围内(这是 global 命令的默认 range,和其他命令通常默认行内 range 不同)对匹配 {pattern} 的文本执行后续的 ex 命令.可以想象这是一个强大的命令.

2.4 插入模式(普通模式下按 i, I, a, A, o, O 进入插入模式)
除了快捷键,其他都很普通, <C-r> 可以在插入模式下粘贴寄存器的内容.
<o>直接插入新行并进入插入模式,这是非常好用的.

2.5 可视模式([v] / [V] 行选择)
进入可视模式后用光标移动命令选择文本 [w,b,e,%, gg, G] 等都比较常用
一个有用的技巧是 [vi({["] 选中{}[]""()等成对符合内的内容 [va..] 则连同符号一起选中, 比如普通模式下在括号内 [vi(] 会选中括号内的所有内容,不含括号. [va(] 则会选中包含括号的文本. ([i]表示 inside, [a]表示 around)

2.6 块编辑模式(<C-v>)
[d] 删除所选内容
[I] 在列前插入, [A] 在列后插入.处于块编辑模式时,选中的块是作为一个"文本对象"处理 [i/a] 分别表示 "inside" 和 "around"
[<ESC>] 退出块编辑模式后会把插入内容应用到选中的所有行.

3. 实用技巧 - 掌握之后可以应付多文件编辑
3.1 多buffer
理解 buffer 和 file 的区别和联系.
[:ls] 列出 buffer
[:b {x}] 切换 buffer,可以用序号或者 buffer名(也就是文件名) 中的部分字符然后用 <tab> 补齐
[:bn] 切换到下一个 buffer
如果buffer修改后未保存,则需要使用 [!] 强制切换 [:bn!], [:set autowrite] 之后会自动保存,就不需要 [!] 了.

3.2 多窗口 - [:h window]
除非特别修饰,命令行只对当前窗口有效.
窗口命令以 [<C-w>] 开头
[<C-w>]hjkl/w 循环激活窗口
[:close] 关闭窗口.
[:sp]/[<C-w>s] 水平分割当前窗口
[:vsp]/[<C-w>v] 垂直分割当前窗口
[:res +/-N] 改变窗口高度
[:vertical res +/-N] 改变窗口宽度

3.3 多标签
标签是对窗口的分组
[:tabnew]
理解了 buffer - window - tabpage 的关系之后就知道 buffer 才是核心.

4. 程序员的VIM - 掌握之后可以应付中大规模程序开发
4.1 列出所有函数,结构体,类等 tag 定义 -> ctags,[<C-[>] -> taglist 插件
4.2 关键字,变量上下文自动补齐 intelligent sense, [<C-l>]/[<C-p>]/[<C-n>],理解实现这个功能的插件的原理.
4.3 会话保存和恢复[:mks]
4.3.1 [:mks] 保存当前工作区至会话文件.
4.3.2 "vim -S mysession_file" 直接恢复工作区,包括工作路径.
4.4 在 VIM 内部运行 [:make] 并利用 QuickFix 信息迅速定位编译错误的位置. [:copen] 参考 [:h quickfix]
4.5 使用 grep 在多个文件中搜索
4.6 对 C++ 函数名和变量着色
4.6.1 基本原理是定一个变量用一个正则表达式捕获所有函数名,然后对这个变量着色:
    "highlight Functions,这可以高亮函数
    syn match cFunction /\<\w\+\%(\s*(\)\@=/
    hi default link cFunction Include
4.6.2 写出合适的正则表达式捕获类名,函数名比较容易.捕获变量名则很麻烦.

5. 编写VIM脚本 - 掌握之后达到需要定制VIM的时候知道大概方向,通过查找资料就可以编写脚本
参考[:h] usr_41.txt Write a Vim script

所谓"VIM脚本"和 shell 脚本是一样的,包括命令和语言函数 .vimrc 就是一个"VIM脚本",一个脚本不仅仅只有语言函数,C程序员往往会忽略着一点.事实上脚本中的大多数功能都是由命令(如 echo, set, exec, norm, syntax 等)实现的,较少情况下才需要用到语言通过各种控制语句,函数等实现.所以可以在执行Ex命令的 "exec" 和可以执行普通模式下命令的 "norm" 两个命令可以完成大多数功能(完整列表在[:h index.txt])

基本语法和PHP基本一致,实际使用的时候再 Google 一下细节.
变量声明: let var = 123; exists("var") 可以检查变量var是否被定义,注意是以变量名字符串为参数,而不是 exists(var). 每次赋值都需要使用 let, 而不能直接 var += 1 应该写为 let var += 1
字符串连接: '.', 字符串是否相等 =~, 是否不相等 !~, !~? !~# 忽略/匹配大小写.
调用函数: 需要使用关键字 call, eg. call MyFunc(), 如果指定返回值则又不需要 call 关键字, eg. let ret = MyFunc();
变量的作用域: a:name - 函数参数 / s:name - 当前脚本内有效 / b:name - buffer 作用域 / w:name - 窗口作用域 / g:name - 全局变量 / v:name - vim 内部变量 / l:name - local 函数内部的局部变量
环境变量: $VIM, $VIMRUNTIME 等, [:version] 可以查看
VIM option: &开头, 直接给这些变量赋值可以起到和 :set 命令同样的效果, eg. &tabstop = 4 等效于 set &tabstop = 4. 区别是 set 命令可以用vim选项的简写形式,而赋值语句不能.
register 变量: @开头 引用 vim 寄存器内的内容. eg. @/ 引用搜索内容, @" 引用无名寄存器
可以用 a:1 来引用 ... 中的第一个参数, a:0 参数个数,查看 [:h a:0]
在脚本中调用普通模式命令的写法 [norm gg]
在脚本中调用 Ex 命令的写法 [exec "colorscheme default"]
script 和 当前 buffer 的交互:  getline()/setline() 获取/设置行内容 "." 表示当前行

5.2 常用库函数
5.2.1 再次强调库函数都可以用 [:h 函数名] 查看帮助
5.2.2 库函数基本上就是操作各种 VIM 类型的变量,比如 string, list, dictionary 各自有一组工具函数,以及一些数学函数, printf 等
5.2.3 :h 调出 vim 帮助,在 [index] 目录可以找到内置函数索引,以及 option, vim-variables的索引,需要的时候结合 google 再调试一下问题应该不大.

5.3 在脚本中使用正则表达式
5.3.1 正则表达式的选项是通过把 \opt 插入 pattern 文本实现的 \v \i \c
5.3.2 由于字符串会对 \ 做一次转义,所以要注意 \\ 才能把反斜杠传递给解释器,如 "\\v^[0-9]{5}$" 或者 "\\^\\[0-9]\\{5}\\$" 表述相同意思.

6. 杂项
6.1 :set guifont=Consolas:h10 和 :set guifontwide=新宋体:h10 在 Windows 下就可以把字体设置为和 Visual studio 相同,注意 _vimrc 要保存为 utf8 编码,否则中文字符"新宋体"识别不了.
6.2 其它在 Windows 下便利的设置 baidu 都能找到.
6.3 添加帮组文件之后,[:helptags ALL] 命令更新帮助索引.
6.4 在 Ubuntu 16.04 中, 如果 vim 不支持系统剪贴板,可以利用输入法的一个特性:在中文输入状态下按 <C-;> 可以输入剪贴板中的内容.

7. 重点插件
7.1 netrw(内置)
    [:E] 或者 [:e <path>]/[:e.] 打开目录窗口,浏览后 <CR> 用选中文件的内容替换目录窗口.
7.2 ctags(必装)
    这是另外一个程序,`apt install exuberant-ctags`.运行 ctags 生成一个 tags 文件(这是一个文本文件), vim 通过选项 tags [:echo &tags] 指定搜索 tag 文件的路径,根据 tag 文件中记录的关键字对应的 PATTERN 通过查找定位到对应位置.
    <C-]> 或者 :tag {keyword} 跳转到定义.
    <C-t> / <C-o> 跳转回编辑处.
    源文件变化之后需要重新运行 ctags 以生成新的 tag 文件. [!ctags -R]
    VIM之所以是"程序员的编辑器"很大程度上是因为 ctags 提供的跳转,必装,毫无疑问.
7.3 taglist(选装,依赖 ctags)
    github.com 搜索 taglist 下载 doc/taglist.txt 和 plugin/taglist.vim 复制到 vim 对应目录
    按照 taglist.txt 的说明映射 F8 为打开/关闭 tag 窗口的快捷键
    tag 窗口对应条目 <CR> 跳转.
    tag窗口列出的是当前文件内的函数,结构体等的定义,阅读代码时相当方便,推荐安装.
7.4 MiniBufExplorer(选装)
    <C-w> 切换到顶部的MiniBufExplorer窗口后 <TAB> 或者其他光标移动命令选择对应的 buffer, <CR>/o | s | v 在不同的窗口内打开指定 buffer
    set mouse=a 用鼠标操作.
    个人不是很喜欢用此类插件,[:b]命令就足够了.开发时工作目录下大概有哪些文件其实是很清楚的,没必要一直显示在屏幕上.一方面可以节省屏幕空间,另外开启 MiniBufExplorer 会导致窗口布局比较混乱.
7.5 nerdtree - 目录树窗口(选装)
    因为有 netrw 可以很方便的用 [:e.] 或者 [:E] 打开工作目录下的文件,并且在 Linux 下开发一般都会打开多个控制台窗口可以随时了解工作目录的状况,所以没有太大必要让 nerdtree 占用宝贵的屏幕空间.
7.6 Quickfix - 定位编译错误(内置)
    [:make] 编译工程(哪怕只有一个源文件的小工程,也使用Makefile,这是个好习惯)
    [:copen/cclose/cw] 打开/关闭 Quickfix 窗口, [:cnext/cprev] 浏览编译错误, 或者在 Quickfix 窗口内 <CR> 定位到源文件.
    [:h Quickfix] 查看更多命令.
    ctags 和 Quickfix 让VIM真正成为一个 "IDE".
7.7 各种颜色主题(必装)
    颜色主题文件都是 vim 脚本,存放在 $VIMRUNTIME/colors 目录下,把从网上下载的主题文件放入该目录, [:color <主题文件名>] 即可切换至该主题.
    之所以是"必装"插件,是因为多尝试不同颜色后会让你爱上 VIM.推荐 http://bytefluent.com/vivify/ 有很多主题可选,并可在线编辑后下载.
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值