Vim 8文本处理实战:教您得心应手地在日常任务中使用Vim

通过阅读本章,读者将能更加得心应手地在日常任务中使用Vim。本章使用一个Python工程作为示例,模拟了一系列日常编码的场景。当然,读者完全可以拿自己手头的项目练手;只不过,本章中的使用场景不一定都适用于读者自己的代码。

本章包括如下主题。

  • 介绍一种粗暴但快捷的Vim插件安装方式。
  • 介绍如何使用缓冲区、窗口、标签页和折叠来处理多个文件或长文件,从而使工作区更为整洁。
  • 介绍插件Netrw、NERDTree、Vinegar和CtrlP,通过这些插件,读者可以在不退出Vim的情况下浏览复杂的文件树。
  • 介绍文件中的高级文本浏览方式、极其高效的光标移动插件EasyMotion以及多种文本对象,介绍通过grepack实现跨文件的搜索。
  • 介绍如何利用寄存器来复制和粘贴。

1 技术要求

本章将介绍如何用Vim在一个Python工程上作业。读者可以在异步社区中找到本章用到的代码。

2 安装插件

本章会介绍几个Vim插件,但暂时不会涉及较为复杂的插件管理,相关的内容参见第3章。

首先,读者必须要做好准备工作。

1.创建一个存储插件的目录,执行下列命令。

$ mkdir -p ~/.vim/pack/plugins/start

 

如果在Windows系统中使用gVim,则需要在用户目录(通常是C:\Users\ <用户名>)下创建vimfiles目录,然后在其中创建子目录pack\ plugins\ start

2.使Vim能够自动加载每个插件的文档(Vim默认不会这么做)。在~/.vimrc文件(在Windows系统中为用户目录下的_vimrc文件)中添加下列代码。

packloadall               " 加载所有插件
silent! helptags ALL      " 为所有插件加载帮助文档

然后,每次安装插件都可按照下列步骤进行。

1.在 GitHub 上找到想要安装的插件。比如,读者想安装scrooloose/ nerdtree(注意,这里的scrooloose/nerdtree为该GitHub仓库的唯一标识,实际地址为https://github.com/scrooloose/nerdtree.git)。假设读者已经安装了Git,则可以找到此Git仓库的克隆地址,然后运行如下命令。

$ git clone https://github.com/scrooloose/nerdtree.git 
~/.vim/pack/plugins/start/nerdtree

 

如果读者没有安装Git,或者在Windows系统中使用gVim,则可以在GitHub页面上找到克隆或下载(Clone or download)按钮,下载ZIP压缩包,然后将其解压到相应的插件目录中,比如在Linux系统中为目录~/.vim/pack/ plugins/start/nerdtree,而在Windows系统中为用户目录下的子目录vimfiles/pack/plugins/start/nerdtree

2.重启Vim之后,即可使用插件进行相关操作。

3 组织工作区

到目前为止,本书还只是用Vim处理单个文件。但是在编写程序时,经常需要同时处理多个文件,涉及来回切换、跨文件编辑或到其他界面查询资料等操作。幸运的是,Vim提供了一个能够处理多个文件的插件。

  • Vim内部用缓冲区来表示文件;通过缓冲区,读者可以在不同文件之间快速切换。
  • Vim用多个窗口在同一屏幕中显示多个文件。
  • Vim用标签页对窗口进行分组。
  • Vim用折叠效果来隐藏或展开一个文件的部分内容,从而让读者可以更容易地浏览文件的内容。

图1中展示了上述要点,解释如下。

图1

  • 多个窗口用于同时打开多个文件(farm.pyanimal/cat.pyanimal_farm.py)。
  • 顶部显示有两个标签页(3 farm.pya/dog.py)。
  • +--开头的行表示折叠,它隐藏了文件的部分内容。

本节将详细介绍窗口、标签页和折叠,通过这些功能,读者可以在工作中同时处理任意多个文件。

3.1 缓冲区

缓冲区是文件的内部表示,每个打开的文件都有一个缓冲区。比如,通过命令行vim animal_farm.py打开一个文件,然后可以用:ls命令看到现有的缓冲区列表。

 

很多命令都有别名或等价命令,:ls也不例外,它和:buffers:files实现的是同样的功能,读者可以从中选择一个最容易记的命令。

图2所示为ls命令的执行结果(最下面的那3行)。

图2

图2中的状态栏显示了已经打开的缓冲区(这里只有一个)的相关信息,这些信息的含义如下。

  • 1为缓冲区编号,在整个Vim会话中,它的值保持不变。
  • % 表示该缓冲区位于当前窗口中。
  • a 表示该缓冲区处于活动状态,即它已被加载并可见。
  • "animal_farm.py"为文件名。
  • line 30表示当前光标位置。

现在,用下列命令打开另一个文件。

:e animals/cat.py

然后,可以看到之前打开的文件已经被当前文件所取代。不过,animal_farm.py仍然存储在某个缓冲区中,读者可以再次用:ls命令将其显示出来。

现在,可以看到两个文件名都被列出来了,如图3所示。

图3

那么怎样才能跳转到之前的文件呢?

Vim通过数字和名称来标识每个缓冲区,在同一个Vim会话中,它们都是唯一的(除非退出Vim)。为了在不同的缓冲区之间切换,可使用:b命令,其参数为缓冲区的编号数字。

:b 1

 

:b 1命令中的空格可以省略,得到简化版的命令:b1

通过一条很简单的命令就可以回到原来的文件。由于缓冲区还可以用文件名来标识,因此读者可以用文件名的一部分来切换缓冲区。下列命令将打开animals/cat.py的缓冲区。

:b cat

不过,如果名称匹配了多个缓冲区,则Vim会报错。比如,用下面的命令查找所有文件名包含py的缓冲区。

:b py

Vim的状态栏中会显示错误,如图4所示。

图4

为解决这个问题,可以使用Tab键补全文件名,从而实现在不同缓冲区之间循环切换。输入:b py(先不要按Enter键),然后按Tab键,在所有匹配的结果之间循环遍历。

读者也可以使用:bn:bnext)和:bp:bprevious)命令循环遍历缓冲区。

当不再需要某缓冲区的时候(如不再需要编辑该文件),可以将其删除。通过如下命令可以将一个缓冲区从打开的缓冲区列表中删除,而无须退出Vim。

:bd

但如果没有保存当前缓冲区,则Vim会报错。因此,在不小心删除缓冲区之前,读者还有一次保存文件的机会。

3.2 插件——unimpaired

Tim Pope的vim-unimpaired是一个Vim插件,它为很多内置命令(以及一些新的命令)添加映射。本书作者每天都会使用这个插件,因为它提供了更为直观的映射,比如]b[b用于循环遍历缓冲区,]f[f用于遍历目录中的文件。该插件可以在GitHub仓库tpope/vim-unimpaired中找到(安装方法参见本章2.2节)。

下面是vim-unimpaired提供的部分映射。

  • ]b[b循环遍历缓冲区。
  • ]f[f循环遍历同一目录中的文件,并打开为当前缓冲区。
  • ]l[l遍历位置列表(参见第5章)。
  • ]q[q遍历快速修复列表(参见第5章)。
  • ]t[t遍历标签列表(参见第4章)。

此插件还支持用少数几次按键来切换某些选项,比如yos切换拼写检查,或yoc切换光标行高亮显示。更多功能参见:help unimpaired中vim-unimpaired所提供的完整映射和功能清单。

3.3 窗口

Vim将缓冲区加载到窗口中。一个屏幕上可以同时显示多个窗口,它们将屏幕分割成几块。

1.窗口的创建、删除和跳转

本节将介绍Vim窗口的使用方式。首先,打开animal_farm.py文件(在命令行中执行$ vim animal_farm.py或从Vim中执行:e animal_farm.py)。

然后,使用如下命令将窗口分割成两个,其中一个显示新的文件。

:split animals/cat.py

 

:split命令可以简化为:sp

可以看到animals/cat.py被打开,显示在原文件上方的窗口中,而且光标也出现在里面,如图5所示。

图5

也可以使用下面的命令按水平方向分割窗口。

:vsplit farm.py

如图6所示,当前窗口又水平分隔出一个新的窗口(光标也随之移动到左边的新窗口中)。

图6

 

:vs:vsplit的简化版。

通过组合:split:vsplit,可以生成任意多个窗口。

目前本书提到的所有命令都适用于窗口,包括切换缓冲区。为了使光标能在不同窗口间移动,先按Ctrl + w组合键,然后输入一个方向键:h、j、k、l中的一个或键盘方向键。

Ctrl + h组合键,之后再按Ctrl + j组合键(Ctrl键可以不松开,记为Ctrl + w,j组合键),光标会进入下面的窗口,而使用Ctrl + w,k组合键则进入上面的窗口。

 

如果经常使用窗口,读者可以按照如下配置绑定快捷键。

" 使用<Ctrl> + hjkl快速在窗口间跳转
noremap <c-h> <c-w><c-h>
noremap <c-j> <c-w><c-j>
noremap <c-k> <c-w><c-k>
noremap <c-l> <c-w><c-l>

然后,就可以用Ctrl + h组合键跳到左边的窗口,用Ctrl + j组合键跳到底部的窗口,依此类推。

读者可以用下列方式来关闭窗口。

  • 使用Ctrl + w,q组合键关闭当前窗口。
  • 使用:q命令关闭窗口并卸载缓冲区;不过,当只有一个窗口打开的时候,这会导致退出Vim。
  • 使用:bd命令删除当前缓冲区,并关闭当前窗口。
  • 使用Ctrl + w,o组合键(或:only,或:on命令)关闭除当前窗口之外的所有窗口。

 当打开了多个窗口时,可通过:qa命令关闭所有窗口并退出。也可以结合:w命令,即:wqa,它会先保存所有打开的文件,再退出Vim。

如果只想关闭缓冲区,而保留它所在的窗口,则可以在.vimrc文件中加入如下配置。

" 关闭缓冲区而不关闭窗口
command! Bd :bp | :sp | :bn | :bd

然后,读者就可以使用:Bd来关闭缓冲区,而保留分割窗口。

2.窗口的移动

窗口也可以移动、交换或改变大小。因为Vim中没有鼠标拖曳的功能,所以只能记住一些命令了。

 

读者并不需要记住所有这些命令,只要知道Vim支持哪些窗口操作,剩下的操作可以通过查看文档。使用:help window-moving:help window- resize打开Vim手册中相应的条目,即可找到所有相关的快捷键。

窗口命令的快捷键都要先按Ctrl + w组合键,后面跟一个大写的方向键(H、J、KL中的一个),当前窗口会被移动到相应的位置。

  • 使用Ctrl + w,H组合键将当前窗口移动到屏幕的最左边。
  • 使用Ctrl + w,J组合键将当前窗口移动到屏幕的底部。
  • 使用Ctrl + w,K组合键将当前窗口移动到屏幕的顶部。
  • 使用Ctrl + w,L组合键将当前窗口移动到屏幕的最右边。

比如图 7 所示的窗口布局(先打开animal_farm.py,然后再依次运行:sp animals/cat.py:vs farm.py,可得到这个布局)。

图7

注意,图7中光标位于animals/cat.py文件所在的窗口中。通过前面介绍的几个快捷键,可以让这个窗口朝不同的方向移动。

  • 使用Ctrl + w,H组合键将animals/cat.py移动到最左边,如图8(a)所示。
  • 使用Ctrl + w,J组合键将animals/cat.py移动到底部,而且左右分割变成了上下分割,如图8(b)所示。
  • 使用Ctrl + w,K组合键将animals/cat.py移动到顶部,如图8(c)所示。
  • 使用Ctrl + w,L组合键将animals/cat.py移动到最右边,如图8(d)所示。

(a)

(b)

(c)

(d)

图8

若想修改一个窗口的内容,则只需要跳转到这个窗口,然后用:b命令来选择所需的缓冲区。不过,也有一些快捷键可以用于交换两个窗口的内容。

  • 使用Ctrl + w,r组合键将当前行或当前列(行优先于列)中的每个窗口的内容向右或向下移动。使用Ctrl + w,R组合键则以相反的方向执行类似的操作。
  • 使用Ctrl + w,x组合键将当前窗口与下一个窗口的内容交换(如果当前窗口是最后一个,则与前一个交换)。 

Vim内部用数字来标识窗口。不过,与缓冲区不同,窗口的编号是随着布局变化而改变的,而且并没有直接的方法来修改窗口编号。有些窗口管理命令以窗口编号为参数,但本书不会涉及这部分内容。有一条原则仅供参考,窗口编号顺序为由上至下、由左至右递增。

3.改变窗口的大小

Vim窗口默认的宽高比为50/50,这可能并不满足读者的需求,因此窗口的大小可以通过一些方法来改变。

快捷键Ctrl + w,=(按Ctrl+w后再按=键)能够将所有打开窗口的宽和高调整为一致。如果不恰当地调整了窗口大小,这个命令将非常有用。

:resize命令会增加或减少当前窗口的高度,而:vertical resize将调整窗口的宽度。读者还可以使用如下命令。

  • :resize +N用于将当前窗口的高度增加N行。
  • :resize -N用于将当前窗口的高度减少N行。
  • :vertical resize +N用于将当前窗口的宽度增加N列。
  • :vertical resize -N用于将当前窗口的宽度减少N列。 

:resize:vertical resize可分别简写为:res:vert res。另外,还有将窗口高度和宽度改变一行/列的快捷键:Ctrl + w,-Ctrl + w,+用于调整高度,而Ctrl+w,>Ctrl + w,<用于调整宽度。

两种命令都可以将宽度/高度设置为具体的行数/列数。

  • :resize N用于将窗口高度设置为N
  • :vertical resize N用于将窗口宽度设置为N

3.4 标签页

在很多现代编辑器中,标签页(Tabs)用于表示不同的文件。在Vim中自然也是如此,但读者需要考虑其原始目的。

Vim用标签页来组织一个窗口的集合,进而支持在不同的窗口集合之间切换,这让用户方便地拥有了多个工作区。标签页通常用来在同一个Vim会话中区分不同的问题或者文件集合。标签页功能不一定是一个频繁使用的功能,但如果希望在不同项目或同一项目的不同上下文之间切换,那么标签页将是一个不错的选择。 

用户愿意使用标签页的另一个原因可能与Vim的diff功能有关,因为diff作用于一个标签页内。更多详情请参考第5章中关于vimdiff的介绍。

在一个新标签页中打开一个空缓冲区的命令如下。

:tabnew 

在新标签页中打开一个已有文件的命令为:tabnew <文件名>

本文截选自《Vim 8文本处理实战》

Vim 8ææ¬å¤çå®æ

  • Vim8文本处理技术指南,vim实用技巧
  • 文本编辑器书籍
  • 程序员编程开发技能,python语言结合

作为全面介绍Vim使用方法的教程,本书介绍了各种常用的文本编辑方法和程序设计中的实用操作,深入Vim内部的数据结构和VimScript脚本编程,内容详实。本书基于Vim 8平台,介绍了前沿分支Neovim,还推荐了更先进的Oni编辑器,兼容并包,集Vim社区典型使用经验和发展趋势于一体。 


本书面向的读者群体是所有使用Vim的程序员,书中的示例文本为Python代码,并详细介绍了Git和正则表达式。读者需要对操作系统和程序设计有基本的了解,特别是需要了解Linux操作系统的基本使用。虽然本书尝试兼顾三大操作系统,但毫无疑问书中内容以Linux为主。本书可以帮助读者完善Vim技能,增加程序设计的知识储备。

发布了496 篇原创文章 · 获赞 280 · 访问量 87万+

猜你喜欢

转载自blog.csdn.net/epubit17/article/details/104141542
Vim