厚书读薄丨《Vim实用技巧》第六部分工具

第六部分 工具


第16章 通过ctags建立索引,并用其浏览源代码(实测不好用)

  1. ctags 是一个外部程序(要自己安装),它通过扫描代码库,生成关键字的索引。

    • ctags 使得我们可以快速地跳到函数及类的定义之处,从而实现浏览整个代码库的目的。
    • ctags 的输出结果也可以用于建立自动补全的单词列表
  2. ctags 的使用

    • 在系统命令行中调用 ctags,以要建立索引的文件路径作为它的参数,既可以是一个文件,也可以是多个文件
    • ctags会创建了一个名为 tags 的纯文本标签文件
      • 标签文件前几行由元数据组成。
      • 此后的每一行文本均由关键字文件名以及关键字在源代码中的位置这3项内容构成。
      • 关键字是按照字母顺序排列的,因此Vim可以采用折半查找法快速地定位到某个关键字。
  3. 配置vim使用ctags

    • tags 选项指定了 Vim 应该到哪里去找标签文件,当tags选项为 ./ 时,Vim将把它替换成当前文件所在的路径
  • 通过:set tags?查看tags选项的默认配置为tags=./tags,tags,即Vim会在当前文件所在目录以及工作目录中查找标签文件
    • 如果Vim已在第一个标签文件中找到了匹配项,就不会在第二个标签文件中继续查找了
  • 我们可以在工程的每一个子目录中都建立一个标签文件,或者为了简单起见,只在工程的根目录中维护一个全局的标签文件即可。
    • 之后按<C-]>可以到达定义,按<C-t>可以回来
  1. ctags的更新

    • ① 手动更新::!ctags -R 将从Vim当前的工作目录开始,遍历其所有的子目录,并为其中的每一个文件建立索引。最终,再把这个标签文件保存到当前工作目录中。每次改变文件都需要更新一下标签文件,可以使用 :nnoremap <f5> :!ctags -R<CR> 映射,这样按<F5>就能快捷激活这一命令
  • ② 每次保存缓冲区时自动更新:使用Vim的自动命令功能,它允许我们在某个事件发生时调用一条命令,这些事件包括缓冲区的创建、打开或者保存等,:autocmd BufWritePost * call system("ctags -R") 会在每次保存文件时自动调用ctags,这样每当我们保存文件的改动时,都会对整个代码库进行更新索引操作。
    • ③ 提交代码改动时,自动更新代码库的索引:可参见《Effortless Ctags with Git》一文
  • 但是编辑器之外的改动还是没办法及时更新,维护这个标签文件实在麻烦, 所以这个ctags我感觉还是比较鸡肋

第 17 章 编译代码,并通过Quickfix列表浏览错误信息

  1. Quickfix 列表会维护一组由文件名、行号、列号(可选)与消息组成的注释定位信息。

  2. ⭐️ 不用离开Vim也能编译代码

    • 使用:make编译代码

    • Vim会对输入结果进行某些智能的处理,除了会显示make命令的输出结果外,还会解析结果中的每一行内容,并把文件名、行号以及错误信息提取出来。对于每一条出错信息,Vim都会在quickfix列表中为其创建一项记录。我们可以上下浏览这些记录项,让Vim跳到错误信息所在的行上。

    • 运行完 :make后,Vim 会跳转到quickfix 列表的第一项记录

    • :make! 位于结尾处的符号 ! 将指示Vim只更新quickfix列表,而不跳到第一处错误。

    • 使用 <C-o> 命令将返回跳转列表(jumplist)的上一处位置

  3. Quickfix列表

    • quickfix列表会保存一组针对单个或多个文件内容的位置信息。

    • 每一项记录可以是在执行 :make 时由编译器产生的出错信息,也可以是在执行 :grep 时找到的查找匹配。

    • 浏览Quickfix列表

    命令用途
    :cnext跳转到下一项
    :cprev跳转到上一项
    :cfirst跳转到第一项
    :clast跳转到最后一项
    :cnfile跳转到下一个文件中的第一项
    :cpfile跳转到上一个文件中的最后一项
    :cc N跳转到第n项
    :copen打开quickfix窗口
    :cclose关闭quickfix窗口
    • :cnext:cprev 都可以在其前面附加执行次数
    • quickfix 窗口也有其特别之处。如果我们将光标置于某条列表项并按 <CR>键的话,Vim 将会打开相应的文件,并将光标置于包含匹配结果的那一行上。文件会显示在 quickfix 窗口上方的窗口中,但如果该文件已经在当前标签页的某个窗口中打开了,那么就会复用该缓冲区。
    • 通过运行 :colder 命令,我们可以回溯quickfix 列表之前的某个版本(Vim 会保存最近的 10 个列表)。为了从旧的quickfix 列表回到比较新的列表,我们可以运行 :cnewer。请注意,:colder:cnewer命令也都支持次数,这意味着可以分别让这两个命令运行指定的次数
    • 在运行 :colder 或者 :cnewer 之后打开quickfix窗口,状态栏将会显示刚刚用于创建此列表的命令。
    • 可以将 :colder与 :cnewer命令想象成针对quickfix列表的撤销(undo)与重做(redo)命令。就是说,我们可以试着执行其他重新生成 quickfix 列表的命令,而不必担心后果
  4. 位置列表

    • 对于每一条用于填充 quickfix 列表的命令,都有一条对应的命令(加了个l前缀),把结果保存到位置列表,如:make:grep以及 :vimgrep 会使用 quickfix 列表,类似地,:lmake:lgrep以及 :lvimgrep 将使用位置列表

    • 区别在于:quickfix列表是全局的,但是每个窗口都对应一个位置列表。

  5. 定制外部编译器

    • makeprg 选项允许我们指定运行 :make 时所调用的程序。通过以下命令,我们可以指示Vim运行nodelint:➾ :setlocal makeprg=NODE_DISABLE_COLORS=1\ nodelint\ %

      这相当于在shell中执行了

      export NODE_DISABLE_COLORS=1
      nodelint ~/quickfix/fizzbuzz.js
      
      • 在缺省情况下,nodelint采用ANSI色标编码把错误信息高亮为红色。而配置NODE_DISABLE_COLORS=1将会禁用颜色高亮,这样一来,就可以更容易地解析出错信息。
    • 让Vim解析不同外部编译器的报错信息,使得它可以填充quickfix列表

      • errorformat 选项允许我们指导 Vim 如何解析由 :make 产生的输出结果,配起来比较麻烦,详见:h errorformat
    • ⭐️ 可以将makeprgerrorformat保存到某个文件里,然后利用:compiler命令来激活它

      • :compiler nodelint就会激活nodelint编译器插件,它会自动配置makeprgerrorformat
      • :args $VIMRUNTIME/compiler/ *.vim可以查看vim自带的多个编译器插件
    • 在Vim的术语中,编译器是指任何可以针对我们的文档进行处理,并生成错误或警告列表的外部程序。而 :make命令只负责调用外部编译器,并对其输出进行解析,以此构建一个可供浏览的quickfix列表,因此编译器也可以是代码检查或者是什么转换器之类的

第18章 通过grep,vimgrep以及其他工具对整个工程进行查找

  1. Vim的 :grep 命令给外部 grep(或类似 grep的)程序提供了一层封装

  2. 在命令行执行grep

    • $ grep -n Waldo * 表示在当前目录的所有文件中查找单词“Waldo”
      • -n 指示grep在显示结果时加入行号信息。
    • 需要自己根据结果去往对应文件的对应行
  3. 在Vim内部调用grep

    • :grep Waldo *
    • Vim会在后台为我们在 shell 中执行 grep -n Waldo *,并且对结果进行处理,将它们加载进quickfix列表中。
    • -n参数默认添加,其他参数,如-i表示不区分大小写,需要手动添加
  4. 定制:grep

    • grepprg 选项负责指定所调用的shell程序

      • 缺省设置为grepprg="grep -n $* /dev/null"
      • $*表示占位符,将被替换成:grep命令的参数
    • grepformat 选项则指示Vim如何解析来自:grep命令的输出结果

      • 缺省设置为grepformat="%f:%l:%m,%f:%l%m,%f %l%m"

      • %f 表示文件名,%l表示行号,而 %m则表示匹配行的文本。

      • 逗号分隔了多组格式,缺省设置也能匹配%f:%l%m%f %l%m

    • ack替换grep

      • 缺省情况下,ack会用单独的一行列出文件名,然后再从下一行起,列出此文件匹配行的行号及内容

      • ack -nogroup = grep -n

      • 因此可以设置:set grepprg=ack\ --nogroup\ $*

      • --columm参数会给出每一处匹配的行号与列号,下面的配置使得之后可以定位行+列

        :set grepprg=ack\ --nogroup\ --column\ $*

        :set grepformat=%f:%l:%c:%m (%c表示列号)

    • Ack.vim插件可以完全模拟ack的行为

      • grep采用的是 POSIX 风格的正则表达式,而 ack 则采用的是 Perl 风格的正则表达式。如果 :grep命令在后台调用ack,可能会引起误导。
  5. 使用:vimgrep

    • 允许我们使用Vim自带的正则表达式引擎,实现跨文件的查找功能。
    • 语法::vim[grep][!] /{pattern}/[g][j] {file} ...
    • 一行中有多处匹配时,默认为整行文本创建一项记录,g 标志位可以为一行中的每处匹配创建一条记录
    • 设置j 标志位使得只更新quickfix列表,但不跳到第一处匹配
    • {file}可接受的参数与 :args 命令的相同(文件名、通配符、反引号表达式以及这些内容的组合),还可以使用##,它将被扩展成参数列表中的所有文件
    • ⚠️ :vimgrep 命令与Vim查找历史之间的关联程度并不高。因此,如果我们想重用最近一次的查找模式,不能空着,必须通过 <C-r>/ 将其直接粘贴至查找域才行。

第 19 章 自动补全

  1. Vim的自动补全可以在插入模式下被触发,Vim首先会根据当前编辑会话内所有缓冲区的内容建立一份补全列表,然后再检测光标左侧的字符,看能否找到单词的一部分。如果找到的话,会用这个未完成的单词对补全列表进行过滤,所有不是以它开头的内容都将被过滤掉。最终的补全列表将以菜单形式出现,供我们选择。

  2. 大小写敏感问题:

    • ignorecase选项开启后,除了查找忽略大小写,自动补全也会忽略大小写
    • infercase 选项可以修正这一副作用,只不过Vim只会按照你输入的格式进行插入,如文档中有One,你输了一个o,那么虽然可以匹配one,但第一个字母是小写
  3. 触发Vim自动补全的方式

    命令补全类型
    <C-n>普通关键字
    <C-x><C-n>当前缓冲区关键字
    <C-x><C-i>包含文件关键字
    <C-x><C-]>标签文件关键字
    <C-x><C-k>字典查找
    <C-x><C-l>整行补全
    <C-x><C-f>文件名补全
    <C-x><C-o>全能(Omni)补全
  4. 与自动补全的弹出式菜单进行交互

    • 详见:h popumenu-completion
    按键操作作用
    <C-n>使用来自补全列表的下一个匹配项(next匹配项)
    <C-p>使用来自补全列表的上一个匹配项(previous匹配项)
    <Down>选择来自补全列表的下一个匹配项
    <Up>选择来自补全列表的上一个匹配项
    <C-y>确认使用当前选中的匹配项(yes)
    <C-e>还原最早输入的文本(从自动补全中exit)
    <C-h> / <BS>从当前匹配项中删除一个字符
    <C-l>从当前匹配项中增加一个字符
    {char}中止自动补全并插入字符{char}
    • 最好用的方式:直接按<C-n><C-p> 或者 <C-p><C-n> 是比较好用,其中第一项用来触发自动补全功能,第二项用来回到输入的文本,这样可以继续输入,Vim将实时过滤
    • 类似的,其他的触发命令都可以通过加一个<C-p>来达到通过输入逐步过滤列表的方式
  5. 当前缓冲区补全:根据当前缓冲区的内容生成补全列表 (<C-x><C-n>

  6. 包含文件补全(<C-x><C-i>

    • 对通过包含的方式加载进来的文件内容生成补全列表,如import#include

    • Vim本身就理解C语言包含文件的方式

    • 通过设置 include 选项,我们也可以让它了解其他语言的对应提示符

    • 通常,文件类型(file-type)插件会对该选项进行设置,因此基本不需要手动设置,可以通过:set include查看

  7. 标签文件补全(<C-x><C-]>

    • ctags生成的标签文件中的关键字也可以作为补全列表的内容
  8. 普通关键字补全(<C-n>

    • 综合缓冲区列表、包含文件以及标签文件的单词列表,生成一个补全列表
    • 通过 complete 选项可以定制普通关键字补全时所扫描的位置,缺省为complete=.,w,b,u,t,i
      • 例如:set complete-=i禁止扫描包含文件,:set complete+=k激活拼写字典自动补全功能
      • 详见:h complete
  9. 字典单词自动补全(<C-x><C-k>

    • 在字典中进行查找并插入匹配的单词
    • 需要为Vim提供一份合适的单词列表。最简单的方法就是通过运行 :set spell 来激活 Vim 的拼写检查功能
    • 如果不想激活拼写检查功能,也可以通过 dictionary 选项来指定一个或多个含有单词列表的文件
  10. 整行文本补全

    • <C-x><C-l> 根据当前缓冲区的行进行行补充
  11. 文件名 自动补全

    • 在插入模式下,可以通过<C-x><C-f>自动补全文件名
    • 插入的文件名是相对于当前工作目录的
      • :pwd命令获取当前工作目录
      • 通过:cd {path} 命令可以切换工作目录
        • :cd-将切换到之前的工作目录
  12. 全能补全

    • Vim实现的intellsense 功能,它将提供一份为光标所处的上下文量身定做的补全建议列表

    • 通过<C-x><C-o>命令进行触发

    • 该功能由专用的文件类型插件实现,因此,必须先加载以下配置行

      essential.vim
      set nocompatible
      filetype plugin on
      
    • 必须安装一个为所用语言实现了全能补全功能的插件。Vim的发行版本身就支持十几种语言,包括HTML、CSS、JavaScript、PHP以及SQL。可以通过:h compl-omni-filetypes找到完整的列表。

    • 如果你对基于某个特定语言的全能补全功能不满意,就到官网上淘个新插件,或者干脆自己写一个。要了解如何撰写全能补全插件,你可以查阅:h complete-functions

第 20 章 利用Vim的拼写检查器,查找并更正拼写错误

  1. Vim的拼写检查器可以帮助人们更容易地查找并更正拼写错误

  2. Vim的发行版通常只为英语提供了拼写文件,但是安装其他语言的拼写文件也绝非难事。

  3. :set spell 启用Vim内置的拼写检查器

    • 缺省情况下,Vim 将用包含英文单词的字典进行拼写检查,拼写有误的单词下方会显示一条红色虚线
  4. 我们可以用 [s]s 命令在拼写错误间相应地进行反向及正向跳转

  5. 光标位于某个拼错单词之上时,可以通过z=命令来获取Vim提供的更正建议列表

    • 行号+<CR> 可以更正为建议的项目
    • <Esc>可以退出
    • 1z= 可以直接改正为第一个纠正项
  6. 常用命令

    命令用途
    ]s跳到下一处拼写错误
    [s跳到上一处拼写错误
    z=为当前单词提供更正建议
    zg把当前单词添加到拼写文件中
    zw把当前单词从拼写文件中删除
    zug撤销对当前单词的zgzw命令
  7. 配置 spelllang 选项,可以我们更改缺省的拼写字典

    • ⭐️ spelllang 选项只在本地缓冲区生效。在编辑两个或两个以上的文档时,可以分别采用不同的拼写文件。如果你是用双语进行写作的话,这样做的确很方便
    • 缺省设置en同时接受美式和英式英语,可以通过修改成en_us使得只支持美式拼法
    • 可以到http://ftp.vim.org/vim/runtime/spell/下载对其他语言的拼写检查文件
    • 使用spellfile.vim插件,当试图加载系统中没有的拼写文件时,Vim会自动提醒并下载对应文件
      • 需要set nocompatiblefiletype plugin on
  8. 维护专用词典

    • 任何通过 zg 命令添加的单词都将被保存到某个拼写文件中

    • spellfile 选项可以指定一个文件路径,用于保存由 zgzw命令所添加、删除的单词

    • 可以指定多个拼写文件,这意味着可以维护多份单词列表,例如

      setlocal spelllang=en_us

      setlocal spellfile=~/.vim/spell/en.utf-8.add

      setlocal spellfile+=~/books/practical_vim/jargon.utf-8.add

      就加载了两个拼写字典,之后可以归类保存,如1zg时保存到第一个词典里,2zg是保存到第二个词典里,依次类推

  9. 更正拼写错误

    • ① 普通模式下按[s跳转到上一处出错的位置,用z=进行改正
    • ② 插入模式下按<C-x>s<C-x><C-s>
      • 优点是会自动向前搜索错误的单词,并且生成更正列表,不用手动跳转
      • 只限一行内,不能更正上一行的错误

第 21 章 接下来干什么

  1. 定制自己的vimrc

    • 可以参考的资源
      • 热心网友的分享
      • 随本书代码发布的essential.vim文件可以作为你的vimrc的基础
      • 作者的vim设置:http://github.com/nelstrom/dotfiles
  2. ⭐️ Vim的选项 :h option-list

    • 可以使用:set命令来改变

      • :set {option}是打开某一选项
      • :set no{option}是关闭
      • :set {option}! 是反转选项的行为
      • :set {option}? 是获取该选项当前的状态
      • :set {optino}& 会将选项重置为默认值
    • 有些Vim设置项的参数要用到字符串或者数字

      • 例如:set tabstop=2
    • 可以用一条 set 语句设置多组选项

      • 例如:set ts=2 sts=2 sw=2 et
    • 大多数Vim选项都有其简写形式

      • 例如ignorecase = ic
      • 动态定制Vim时,适合用简写名称;在配置vimrc文件时,出于可读性的考虑,适合用全称。
    • :setlocal 命令所触发的改动,只会影响当前窗口或者缓冲区(除非该选项只能被设置为全局性的)

  3. 我们可以将定制化的选项写入文件,加以保存。此后,我们可以通过 :source{file} 命令,将指定 {file}中的设置项应用于当前的编辑会话

    • 保存在文件里的命令前面可以不加冒号,因为 :source 命令会把文件的每一行都当成Ex命令,让Vim执行。
  4. 为特定类型的文件应用个性化设置

    • 少量的设置可以在vimrc中通过autocmd实现,例如

      if has("autocmd")
      	filetype on
      	autocmd FileType ruby setlocal ts=2 sts=2 sw=2 et
      	autocmd FileType javascript setlocal ts=4 sts=4 sw=4 noet
      	autocmd FileType javascript compiler nodelint
      endif
      
      • autocmd语句的检测机制将指示Vim监听某一类事件,一旦该事件发生,Vim将执行指定的命令。
      • 在本例中,我们将监听FileType事件,它会在Vim检测出当前文件类型时被触发。
    • 大量的设置最好使用**文件类型插件(ftplugin)**来为不同文件类型进行定制。

      • 例如

        customizations/ftplugin/javascript.vim
        
        setlocal ts=4 sts=4 sw=4 noet
        compiler nodelint
        
      • 详见:h ftplugin-name

      • 要保证filetype plugin on是开启的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值