一开始看不上亲密接触后又让你欲罢不能的 vim

每个程序员都有一款心心念叨的代码编辑器。而在众多妖颜魅惑的编辑器偶像团体前,vim 就像个不加粉饰的农村姑娘,咋一看是那样朴实无华,难有倾心。但只要走近一点,来个亲密接触,又会被她的似水柔情所俘获。linux

这是青笔亲身经历。公司从腾讯空降技术总监,时不时会分享一些他的开发经验。其中说到编辑器,他的脸上总会泛起淡淡桃花,“我就喜欢 vim!” 。尽管咱们曾一致向他引荐当下红极一时集美貌与才华于一身的 vscode 。他却依然心有所属,不为所动。程序员

多少次,我百思不得其解,这个“相貌平平”的 vim 到底有何魔力,能紧紧扣住总监的心弦。在我真正走进她的心里世界,屡次昼夜相伴以后。我最终也被她的清新脱俗所拜倒。正则表达式

接下来就让咱们一块儿来了解这名神秘的“女子”。shell

1. vim 历史

如下是网上找到一张图。如对 vim 发展历史感兴趣能够参考维基百科的词条 Vim (text editor)vim

en.wikipedia.org/wiki/Vim_(t…安全

早期的 UNIX 操做系统上标准的编辑器是 ed ,这是一个面向行的编辑器,只能显示当前编辑的行。1976年,Bill Joy 在 ed 上作了扩展,使之支持了全屏显示和编辑,命名为 ex 。ex 是 ed 的超集,经过在 ex 输入命令 vi 来启动扩展功能。后来这个命令因为常用而被独立出来,也就是如今 Linux (包括 macOS)系统预装的命令行编辑器 vi 。直到 1991 年,Bram Moolenaar 才开发了 vi 的改进版(improvement),命名为 VIM (寓意:Vi IMprovement),同年 11 月 4 日发布了 vim 的第一个版本。下图来自 vim.org 网站首页的一条新闻,也就是去年的11月4日迎来了 vim 的27岁生日。bash

2. 内置教程

vim 自带了一个面向初学者开发的教程。可经过独立的子程序 vimtutor 启动教程。编辑器

若是系统已经安装了 vim (macOS 预装了 vim,部分 linux 发行版可能须要手动安装),能够在直接在终端输入 vimtutor 命令打开教程。学习

vimtutor
复制代码

教程实际也是使用 vim 打开系统上的一个文本文件。文件一般在 /usr/share/vim/vim80/tutor/ 目录下。固然,这个目录下有不少个文件,分别是不一样语言版本的教程。使用 vimtutor 的不一样之处是能自动打开用户所在地的语言版本。网站

上面看到的简体中文版实际就是文件 /usr/share/vim/vim80/tutor/tutor.zh_cn.utf-8

所以,你能够将其复制一份放到当前目录下,再使用 vim 打开,用作练习,随意编辑文件内容。

cp /usr/share/vim/vim80/tutor/tutor.zh_cn.utf-8 ./
vim tutor.zh_cn.utf-8
复制代码

但若是按照教程来练习,我的用起来感受最舒服的方式是:同时打开两个终端,一个使用 vimtutor 打开本地教程用于阅览,另外一个将教程的英文版复制到当前目录,而后使用 vim 在复制的英文版上进行编辑练习(由于咱们实际应用场景大可能是英文环境,包括编辑代码和配置文件)。

复制英文版教程并进行编辑练习:

cp /usr/share/vim/vim80/tutor/tutor ./
vim tutor
复制代码

3. 工做模式

对于习惯了 GUI 编辑器的开发者,刚开始接触 vim ,很容易被 vim 的工做模式搞得一头雾水,并且极可能就此放弃使用 vim 。但若是熟悉了,就以为一切也理所固然。按照维基百科的介绍,vim 一共有 12 种不一样模式,但只有 6 种基本模式,剩下 6 种都是基本模式的变种。但实际咱们最常接触的只有两类模式:命令模式和编辑模式。其中命令模式又细分为,Normal(默认)模式和 Cmdline (底部命令行) 模式。而 Normal 模式是启动 vim 进入的默认模式,而且在任何模式下,按 ESC (键盘左上角)键都将回到这个模式,做用相似于手机的 Home 键。所以,当你开始迷糊本身当前处在什么模式下,最好的办法就是按 ESC 回到 Normal 模式。咱们使用 vim 的绝大多数命令都在 Normal 模式运行,而 Cmdline(命令行)模式一般只在退出和保存时使用,所以,如不特别说明,当咱们在说命令模式时,就是指代 Normal 模式。此外,本文将 Cmdline 统称为命令行模式

下图是三种模式的切换方式:

若是要简单归纳这三种模式的使用场景,那就是:在命令模式中执行光标导航,复制粘贴删除,撤销重作,以及查找替换等操做;在编辑模式下,编写代码或进行创做;在命令行模式模式下,输入 q 退出,输入w保存,输入wq保存并退出。固然这里还不是所有的操做,可是熟悉这些操做,基本就能将 vim 应用得驾轻就熟了。

4. 命令模式

4.1 移动光标

要使用 vim 熟练地进行代码和文本的编辑,首先须要可以精确快速的将光标定位到要编辑的地方。最基本的就是上下左右移动光标了。这些操做固然可使用键盘的四个方向键来完成。可是更经常使用的是使用字母输入区域连续的四个按键 h, j, k, l 。事实上,当你按照标准的手势接触键盘,你右手的食指触碰的就是 j 键(按键有个凸起)。所以,在你保持正常输入的手势下,顺其天然地敲动食指,就能将光标往下移动一行,而紧挨着的中指接触的是 k 键,进行的是和 j 相反的操做,即将光标向上移动一行,你会发现这样用起来至关顺手,这就理解为何要使用字母按键来进行光标移动操做了。固然这是在命令模式下,按下字母键不会做为输入而改变编辑内容。

  • h: 向左移动一个字符
  • l: 向右移动一个字符
  • j: 向下移动一行
  • k: 向上移动一行

虽然可使用 j, k 左右两边的 h 和 l 来实现向左和向右移动光标。这在一次只移动一个字符时,也仍是很方便。可是若是向左或向右移动一个字(word,英文中空格和标点符号隔开的单词,标点符号也算一个字)时,还使用 h 和 l 就显得有些笨拙了。向左(向后)和向右(向前)移动一个字的方法以下:

  • w: 向右或向前移动一个字,光标定位在字的首字符
  • b: 向左或向后移动一个字,光标定位在字的首字符

命令模式按下字母w将光标向右移动一个字:

命令模式按下字母b将光标向左移动一个字:

若是想近一步扩大光标单次移动的范围,就要用到按句子和段落来先后移动来。两对圆括弧()分别将光标向后和向前移动一个句子,对应两个花括弧{}分别将光标向后和向前移动一个段落。

  • ( : 向后移动一个句子,光标定位在句子开始
  • ) : 向前移动一个句子,光标定位在句子开始
  • { : 向后移动一个段落,光标定位在段落开始
  • } : 向前移动一个段落,光标定位在段落开始

命令模式按下)(向前和向后移动一个句子:

命令模式按下}{向前和向后移动一个段落:

此外你还能够在屏幕所见范围内进行快速移动光标。分别使用大写的HML。可是这三种定位并非很精确,一般用作快速大范围级定位,而后再使用前面的命令进行更加精确的定位。读者能够自行尝试。

  • H: 将光标定位到屏幕顶部一行的最左端
  • M: 将光标定位到屏幕中间一行
  • L: 将光标定位到屏幕的底部一行

还有一种咱们很是熟悉的应用场景,就是在调试程序抛出异常时,一般会显示出异常产生的行号,这时就须要根据行号快速将光标定位到指定的位置。这个命令相比前面的命令要复杂一点,它须要先输入表明行号的一个或多个数字,而后按下大写字母G来完成。例如将光标定位到文件的第 80 行。须要先在命令模式输入80,而后快速按下大写字母G

4.2 删除/撤销

将删除和撤销两个操做放在一块儿讲,其中一个缘由是考虑到可能由于还不知道如何撤销删除操做,而惧怕尝试删除操做的心理(尽管咱们已经事先作了备份,但这应该是一种普通的心理和人性惧怕失去是一样的道理)。咱们知道能够撤销,所以在删除这件事上就有了“安全感”。也许你不是这么认为,可是这样仍是能帮助咱们更好的练习和记忆(咱们能够循环往复地练习删除撤销)。

和移动光标同样,删除也能够按不一样粒度进行。如删除单个字符,字,行,句子,段落以及屏幕首尾。删除操做由用字母d加上表示删除范围的标识符构成。同时删除具体范围还受光标当前所在的具体位置决定。例如删除字使用字母组合dw,若是光标出如今单词hello的第二个字符e上,此时在命令模式连续按下dw,将删除从e开始以后的整个字,可是会e前面的h不会删除,删除后的结果就是还剩一个字母h。其余粒度的删除,也遵循类似的规律。

删除单个字符

删除单个字符有二者方法。二者等效,都是删除光标所在的字符,可是使用x更简单一些,由于只须要输入一个字母。

  • x
  • dl

删除字

  • dw: 从光标所在位置开始,删除到字的末尾(包含光标所在位置的字符)
  • db: 与dw相反方向删除,即删除光标所在位置前面的字符(不包含光标所在位置的字符)

删除行

  • dd: 删除光标所在的行
  • 3dd: 删除从光标开始的3行,固然这是一个例子,能够更改前面的数字删除任意数量的行

一次删除3行:

删除到行尾

若是你不想删除整行。而是从光标开始到行尾的字符,能够直接使用一个大写D来实现。

使用大写字母D删除从光标位置开始到行尾的字符:

从行首删除

与删除到行尾对应的是使用d0从行首删除:

d^与d$

若是对正则表达式熟悉,应该很容易猜到二者的含义。也是删除行首和行尾,可是与前面的 d0D 所不一样的是不删除行首和行尾的空格。

  • d^: 删除光标前面知道行首的字符,包含行首的空格
  • d$: 删除从光标开始知道行尾的字符,包含行尾的空格

删除句子和段落

熟悉了前面的删除,如下删除句子和段落也能够以此类推。惟一区别仅仅在于删除粒度不一样。

  • d(: 从句首删除
  • d): 删除到句尾
  • d{: 从段首删除
  • d}: 删除到段尾

替换:删除并输入

说到删除不得再也不提到替换。由于二者就像兄弟通常,实际替换像删除的哥哥,只比弟弟删除多作了一步。就是在删除后紧接着进入编辑模式,在已删除的地方进行编辑。这两个组合动做不就是替换嘛。须要注意的还有,替换会改变当前工做模式,也就是进入下文会讲到的编辑模式,所以在完成输入后,须要按ESC从新回到命令模式。与删除d对应的替换命令是c。所以将删除里讲到的全部操做中的d换成c就是对应的替换操做,固然执行后的细节会有些差别。可是这种差别在你亲自试事后就很容易理解,所以不做过多论述。读者能够自行尝试。

撤销操做

撤销操做很简单,命令模式下,按下小写字母u(undo)便可。能够连续按屡次,以快速撤销多个历史操做。

4.3 复制/粘贴

复制 y

复制使用字母y。它的用法和删除操做d很像,不一样的是y是复制而不是删除。

下面以复制行为例。其余粒度的复制类比删除操做d便可。

dd删除当前行对应的复制当前行操做是yy,固然也能够复制多行,和删除多行格式类似。在yy前加上要复制的行数。例如3yy复制从光标所在行开始的三行。

  • yy: 复制光标所在的行
  • 3yy: 复制从光标开始的3行,这里只是例子,实际能够是任意行数

粘贴 p

粘贴命令就简单多了。它没有没有那么多的粒度区分,而只须要将已经复制的内容插入到当前光标以后或者以前的位置。分别使用小写的p和大写的P

  • p: 将复制的内容插入到光标以后
  • P: 将复制的内容插入到光标以前

4.4 查找字符串

在命令模式输入斜杠/(向下查找)或问号?(向上查找),光标定位到终端底部一行,输入要查找的字符串,再按回车(RETURN),首先定位到一个找到的字符串,接着按小写的n查找下一个,按大写的N查找前一个。

5. 进入编辑模式

上面介绍的全部命令都是在命令模式下进行的。若是要开始编写代码或其余文字编辑工做,就须要从命令行模式进入编辑模式,不然输入的字母(除能进入编辑模式的字母外)都将视做命令,而不会编辑到到文件中。

进入编辑模式有如下6种方式,区别仅在于进入编辑模式后,光标所在的位置的不一样。

  • i: 在当前光标前插入
  • I: 在行首插入
  • a: 在当前光标后追加
  • A: 在行尾追加
  • o: 在当前光标所在行之添加新行
  • O: 在当前光标所在行之添加新行

6. 命令行模式

在命令模式下,按下冒号:,在终端底部出现输入行,表示当前是命令行模式。在命令行模式可使用 vim 自身支持的不少命令。如前文已经谈到的最经常使用用到的就是退出和保存。

  • :q + RETURN: 退出编辑
  • :w + RETURN: 保存不退出
  • :wq + RETURN: 保存并退出

经常使用的还有对 vim 进行设置。如下命令都须要在输入完后按下回车键 RETURN 才能执行(和在终端执行命令方式差很少)。

  • :syntax on: 开启语法高亮
  • :set number: 显示行号
  • :set tabstop=4: 设置 Tab 键宽度
  • :set expandtab: 使用空格替代 Tab
  • :set softtabstop=4: 设置软件 Tab (自动Tab)宽度为 4
  • :set shiftwidth=4: 设置自动缩进宽度为 4
  • :set autoindent: 开启自动缩进,一般用于编写程序

固然以上对 vim 的设置仅仅影响当前打开的 vim 。要想每次打开都使用一样的设置,须要将设置命令统一保存到 vim 的配置文件 ~/.vimrc 中,方法下一节将讲到。

此外,可使用help来获取帮助。例如输入:help user-manual + RETURN 查看用户手册。

若是说以上都是 vim 内部执行命令,那么在命令行模式下,实际也能够调用外部 shell 的命令。方法是以感叹号!开头,标识感叹号!以后的命令是一条外部 shell 的命令。如查看当前目录下的文件,:!ls -l。第一次按下 RETURN 会隐藏当前编辑区域,显示终端界面,第二次按下 RETURN 再次回到 vim 编辑界面。

7. 配置文件

前文已经讲到若是想要每次打开 vim 都使用一样和界面和设置,须要将设置命令统一保存在配置文件中。在 linux 系统(含macOS)推荐保存的路径是 ~/.vimrc。若是历来没有设置过,这个文件可能还不存在。这就须要咱们先建立一个。为了避免覆盖已有的,咱们可使用以下命令:

test -f ~/.vimrc || vim ~/.vimrc
复制代码

这条 shell 命令会先判断 ~/.vimrc 是否存在,不存在就新建一个空白的配置文件,并使用 vim 打开这个新建的配置文件。

可选的方式也能够复制一份系统的上的配置文件,而后在此基础上添加和覆盖默认配置。

test -f ~/.vimrc || cp /usr/share/vim/vimrc ~/.vimrc
复制代码

如下是青笔本身的配置文件参考:

colorscheme default     " 设置颜色主题 syntax on " 语法高亮
filetype on             " 检测文件的类型 set number " 显示行号

set ruler               " 在编辑过程当中,在右下角显示光标位置的状态行 set laststatus=2 " 显示状态栏 (默认值为 1, 没法显示状态栏)
set statusline=\ %<%F[%1*%M%*%n%R%H]%=\ %y\ %0(%{&fileformat}\ %{&encoding}\ %c:%l/%L%)                        " 设置在状态行显示的信息 set tabstop=4 " Tab键的宽度
set expandtab           " 使用空格替换Tab set softtabstop=4 set shiftwidth=4 " 统一缩进为4

set autoindent          " vim使用自动对齐,也就是把当前行的对齐格式应用到下一行(自动缩进) set cindent " (cindent是特别针对 C语言语法自动缩进)
set smartindent         " 依据上面的对齐格式,智能的选择对齐方式,对于相似C语言编写上有用 set scrolloff=3 " 光标移动到buffer的顶部和底部时保持3行距离

set incsearch           " 输入搜索内容时就显示搜索结果 set hlsearch " 搜索时高亮显示被找到的文本

set foldmethod=indent   " 设置缩进折叠 set foldlevel=99 " 设置折叠层数
nnoremap <space> @=((foldclosed(line('.')) < 0) ? 'zc' : 'zo')<CR>
                        " 用空格键来开关折叠 " 自动跳转到上次退出的位置
if has("autocmd")
    au BufReadPost * if line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g'\"" | endif
endif
复制代码

关于配置文件的更多信息,也可经过 vim 内置的帮助手册来查看。与配置相关的手册为 usr_05 。在命令行模式输入:help usr_05(冒号用于进入命令行模式,输入后回车)便可打开该手册。

总结

本文从 vim 的发展历史开始,以具有可以熟练驾驭 vim 编辑器来知足平常代码编写的基本操做为主线,讲解了在 vim 中进行模式切换,光标导航,删除,撤销,替换,复制,粘贴,插入文本,以及配置编辑器外观设置等必要技能。固然,vim 支持的操做和命令还有不少。本文只介绍到基础部分。可是倒是咱们进行代码编辑最经常使用到的功能。熟练掌握后,能够进一步查看手册学习更多的技巧。查看手册方式上文已经给出。即在命令行模式输入::help user-manual 再回车。

若是本文能让你从新认识了 vim 这位眉目清新又纯洁善良的“姑娘”,而且今后对她有了一份独有的爱意,算是本文创做的最大收获所在^^。


本文首发公号

相关文章
相关标签/搜索