# Vim使用经验 [我的vim配置文件](https://github.com/caodan4linux/vimrc) # 缓冲区 查看vim当前的缓冲区(已打开的文件) `:ls[!]` 或 `buffers[!]` 例如: ``` :ls! 1 #h "/test/text" line 1 2u "asdf" line 0 3 %a + "version.c" line 1 ``` unlistted buffer通常用于显示帮助信息,如果不指定`!`, 是不会显示的在buffer list中的 编号后面的符号指示buffer的类型: `u` unisted buffer `%` 在当前窗口中的buffer `#` the alternate buffer `a` the active buffer,被加载并且可见的buffer `h` the hidden buffer,被加载当时没有显示在当前窗口中 `-` 不能被修改的buffer, a buffer with modifiable off `=` a readonly buffer `+` a modified buffer, 被修改尚未保存的buffer 每个buffer都有一个唯一的编号,可以通过`:buffer N`进入指定的buffer, 关于缓冲区的命令 * `:[N]bn[ext]` go to the [N]th next buffer in the buffer list, 如果没有指定N,默认为切换到下一个缓冲区 * `:[N]bp[revious]` go to the [N]th previous buffer in the buffer list, N默认值为1 # 移动光标 *normal模式* ``` 行首与行尾: 0 光标移动到行首 ^ 到本行的第一个非blank字符 $ 到行尾 移动到行内指定字符: f{char} 移动到光标右边{char}第[count]次出现的位置, 例如fa表示移动到右边第一次出现字符a处. 3fa 表示第3次出现a的位置 F{char} 和f类似,在光标左边寻找匹配的位置 在文件中移动: gg 移动到文件的首行 G 移动到文件的最后一行 在G或者gg前加上数字表示移动到第几行 {count}% 按百分比跳转,例如40%表示跳转到全文的40%的位置 按单词移动: 单词由字母数字下划线组成, 如果认为字母由blank字符(空格,tab, 换行,回车)分隔,则可以使用大写的W, B, E w 移动到下一个单词的开头 b 移动到前一个单词的开头 e 移动到下一个单词的结尾 ge 移动到前一个单词的结尾 W 移动到下一个字符串的开头 B 移动到前一个字符串的开头 E 移动到下一个字符串的结尾 gE 移动到前一个字符串的结尾 % 匹配括号移动,包括 (, {, [. (需要先把把光标先移到括号上) * 匹配光标当前所在的单词,移动光标到下一个匹配单词 # 匹配光标当前所在的单词,移动光标到上一个匹配单词 gd Goto local Declaration. 如果光标所在位置是一个局部变量,则跳转到该局部变量定义的位置. gD Goto global Declaration ``` # yank yank的本义是 *猛的一拉* *拽* 的意思, vim用yank来表示复制 motion的概念: 当输入命令使光标从一点移动到另外一点, 这两点之间的文本(包括这两点)称为被跨过的字符. 这里的命令称为motion `["x]y{motion} Yank {motion} text [into register x]` x表示寄存器的名字,`:registers` 可以查看所有寄存器中的内容 寄存器x是可选的,如果不指定x, 则复制到默认的寄存器"中, 例如: ``` y2j 将复制从当前行到下面第2行,总共3行的内容,因为2j表示下移2行 ygg 将复制从第一行到当前行的内容,因为gg表示移动到第一行 yG 将复制从当前行到最后一行的内容 ye 将从当前位置复制到本单词的最后一个字符 y$ 将从当前位置复制到本行的最后一个字符 ``` `["x]yy` 复制[count]行到寄存器x # 大小写转换 将motion命令跨过的字符转换为小写 ``` gu{motion} Make {motion} text lowercase gU{motion} Make {motion} text uppercase ``` gugu或者guu 将当前行的内容转换为小写 gUgU或者gUU 将当前行的内容转换为大写 # Visual可视化模式 三种visual模式 * `v` 启动单字符的visual模式, 按字符选择 * `V` 启动行模式的visual模式, 按行选择 * `Ctrl-v` 启动块visual模式, 按块选择一个区域, 在window上需要替换为`Ctrl-p` `gv` 启动上一次的visual模式,并选择相同的字符/行/区域 Operating on the Visual mode 在选择好字符/行/区域后,可通过如下操作符操作所选内容 * `~` 大小写转换 * `d` 删除 * `y` yank * `<` 向左缩进(4) * `>` 向右缩进(4) * `J` 把所有行连在一起,变成一行 * `=` 自动对齐选中区域 * `I` 在选中区域前插入字符串, 需按ESC退出visual模式后才生效 * `A` 在选中区域后插入字符串, 需按ESC退出visual模式后才生效 * `C` 从选中区域开始,删除到行尾 * `r` 将选中内容的都替换为同一字符 例: 在所有被选中的行尾插入字符 ``` 进入block visual mode, 选中相关的行(可以使用j或或者是/pattern等) 输入$到移动到行尾,输入A,输入要插入的字符串,按ESC 如果不移动到行尾, 即在选中块后面插入字符 通过I可以在选中块之前插入字符 ``` # 录制宏 将一串操作录制在一个寄存器中,然后可以回放录制的这个宏,也就是按照录制的顺序重新执行一次那些命令 ``` q{0-9a-zA-Z"+} Start Record, Record typed characters into registers {0-9a-zA-Z"} q Stop Record @{0-9a-zA-Z"+} replay(回放)寄存器中的内容 [count]次, @@ 执行上次replay的宏 [count]次 ``` 例如: qayypq > qa 开始录制 yyp 复制行 C-a 将数字加1 q 停止录制 > 例如文本中被复制的这一行只有一个数字1, 那么replay上面的宏,将在下一行生成一个数字2, 如果加上数字前缀,例如100@a,将产生2到101的行 # 分屏 *split与vsplit* ``` split 上下分屏 vsplit 垂直分屏 dir表示方向,可以是h,j,k,l中的一个,用来切换分屏 + 增加当前屏当前屏的大小 - 减小当前屏的大小 ``` # 折叠代码 折叠: folding 所有的折叠命令都以z开头,因为z看起来由点像折叠的意思. zf is used to create a fold: `zf{motion}` 折叠motion命令跨过的字符 `{Visual}zf` 折叠viusal模式选中的行 `zd` delete one folder at the cursor(取消光标处的折叠), 如果有嵌套的fold,那么只会展开第一级. 在visual模式下,选中区域内所有的折叠都被取消, 注意:*由于这个命令没有撤销操作,所以很有可能会撤销你不希望展开的fold* `zD` delete folds recursively # 有用的技巧 当你希望搜索一些已存在的文本,或在所有行里寻找某个用到的单词或短语时, 你可以简单地使用搜索命令、模式去找到它。但是也有更智能的方法: > 在normal模式下, 使用 * 命令,可以定位到当前光标所在处的单词,并搜索下一个 如果设置了“incsearch”选项,当你还在输入时,Vim将会显示第一个匹配模式的文本。这能迅速显示一个模式错误。 如果设置了“hlsearch”选项,Vim将用黄色背景高亮显示所有匹配的模式,让你对搜索命令的结果有个快速概览。它可以显示一个变量在程序代码哪个位置被使用。你甚至不需要移动光标去看匹配的文本。 例如 set incsearch set hlsearch > 在结构化的文本中还有更多可能性快速移动。Vim有针对C(以及类似语言,如C++和Java)程序的特定命令: 1. 使用%从一个左括号跳转到与其配对的右括号,或从一个“#if”到配对的“#endif”。实际上%可以跳转到许多不同的匹配项目。它对检查if()和{}的结构完整性非常有用。 2. 使用 [{ 跳回当前代码块起始的“{”。 3. 使用 gd 从变量的调用跳转到它的局部声明