vim-1

vim的安装

这里以Ubuntu的安装vim GTK3版本为例:

1
2
sudo apt update	//先更新apt列表
sudo apt install vim-gtk3 //安装GTK3的vim

vim的简单使用

76910d1a16ed737c42078dd1255124a1.webp

vim的一些命令行指令:

  • “:q!”:退出 Vim
  • “:wq\”:存盘退出
  • “:s”:执行替换
  • “:!”:执行外部命令
  • “:edit”(一般缩写为 “:e”):编辑文件
  • “:w”:写文件
  • “:r”:读文件
  • “:help”:查看帮助

vim的四种模式

正常模式

缺省的编辑模式;如果不加特殊说明,一般提到的命令都直接在正常模式下输入;在任何其他模式中,都可以通过键盘上的 Esc 键回到正常模式。

插入模式

输入文本时使用;比如在正常模式下键入 i(insert)或 a(append)即可进入插入模式。

可视化模式

用于选定文本块;可以用键 v(小写)来按字符选定,Vim 里也提供其他不同的选定方法,包括按行和按列块。

命令行模式

用于执行较长、较复杂的命令;在正常模式下键入冒号(:)即可进入该模式;使用斜杠(/)和问号(?)开始搜索也算作命令行模式。命令行模式下的命令要输入回车键(Enter)才算完成。

Tips: 关于 Vim 的模式,我们重点掌握正常模式就可以了,Vim 里的大部分操作会在正常模式下完成。如果你做编辑工作时有超过几秒的停顿,就应当考虑按下 Esc 键,回到正常模式。记住,正常模式就是正常情况下你应当处于的模式。

vim的键描述体系

下面这些键描述符无需记忆,有需要查看即可

  • <Esc>表示 Esc 键;显示为“⎋”
  • <CR>表示回车键;显示为“↩”
  • <Space>表示空格键;显示为“␣”
  • <Tab>表示 Tab 键;显示为“⇥”
  • <BS>表示退格键;显示为“⌫”
  • <Del>表示删除键;显示为“⌦”
  • <lt>表示 < 键;显示为“<”
  • <Up>表示光标上移键;显示为“⇡”
  • <Down>表示光标下移键;显示为“⇣”
  • <Left>表示光标左移键;显示为“⇠”
  • <Right>表示光标右移键;显示为“⇢”
  • <PageUp>表示 Page Up 键;显示为“⇞”
  • <PageDown>表示 Page Down 键;显示为“⇟”
  • <Home>表示 Home 键;显示为“↖”
  • <End>表示 End 键;显示为“↘”
  • <F1> - <F12>表示功能键 1 到 12;显示为“F1”到“F12”
  • <S-...>Shift 组合键;显示为“⇧”(较少使用,因为我们需要写 ! 而不是 ;和特殊键组合时仍然有用)
  • <C-...>Control 组合键;显示为“⌃”
  • <M-...>Alt 组合键;显示为“⌥”(对于大部分用户,它的原始键名 Meta 应该只具有历史意义)
  • <D-...>Command 组合键;显示为“⌘”(Mac 键盘)

如果我们描述的命令行首是“:”,表示这是一个输入 : 开始的 Vim 命令行模式命令(以回车键结束);

如果行首是“/”或“?”,表示这是一个输入 / 或 ? 开始的搜索命令(以回车键结束);

如果行首是“$”,表示这是一个在 shell 命令行上输入的命令(以回车键结束),“$”(和后面的空格)不是命令的一部分,通常后续行也不是命令的一部分,除非行尾有“\”或“^”字符,或行首有“$”字符。

vim的选项和配置

基本配置

根据 Unix 下的惯例,Vim 的配置文件放在用户的主目录下,文件名通常是 .vimrc;而它在 Windows 下名字是 _vimrc。我们前面给出最基本的配置文件是这个样子的:

1
2
3
4
5
set ts=4	#设置Tab为4个空格
set enc=utf-8 #设置编辑文件的内码是 UTF-8
set nocompatible #设置 Vim 不需要和 vi 兼容
source $VIMRUNTIME/vimrc_example.vim
#导入 Vim 的示例配置(这会打开一些有用的选项,如语法加亮、搜索加亮、命令历史、记住上次的文件位置,等等)

备份和撤销文件

1
2
set backup
set undofile

前一个选项使得我们每次编辑会保留上一次的备份文件,后一个选项使得 Vim 在重新打开一个文件时,仍然能够撤销之前的编辑(undo),这就会产生一个保留编辑历史的“撤销文件”(undofile)了。

我的通常做法是,不产生备份文件,但保留跨会话撤销编辑的能力;因为有了撤销文件,备份其实也就没有必要了。同时,把撤销文件放在用户个人的特定目录下,既保证了安全,又免去了其他目录下出现不必要文件的麻烦。要达到这个目的,我在 Linux/macOS 下会这么写:

1
2
set nobackup
set undodir=~/.vim/undodir

我们可以用下面的命令来让 Vim 在启动时自动创建这个目录:

1
2
3
if !isdirectory(&undodir)
call mkdir(&undodir, 'p', 0700)
endif

这样设置之后,<Esc>进入正常模式,u即可回到上一次改变,即undo

通过<C-R>可以实现redo

鼠标支持

1
2
3
4
5
6
7
if has('mouse')
if has('gui_running') || (&term =~ 'xterm' && !has('mac'))
set mouse=a
else
set mouse=nvi
endif
endif

上面代码说的是,如果 Vim 有鼠标支持的话,那在以下任一条件满足时:

  • 图形界面正在运行
  • 终端是 xterm 兼容,并且不是 Mac(Mac 上的终端声称自己是 xterm,但行为并不完全相同)

我们将启用完全的鼠标支持(mouse=a)。特别是,此时鼠标拖拽就会在 Vim 里使用可视模式选择内容(只能在 Vim 里使用)。而当用户按下 Shift 键时,窗口系统接管鼠标事件,用户可以使用鼠标复制 Vim 窗口里的内容供其他应用程序使用。否则(非图形界面的的终端,且终端类型不是 xterm),就只在正常模式(n)、可视模式(v)、插入模式(i)中使用鼠标。这意味着,当用户按下 : 键进入命令行模式时,Vim 将不对鼠标进行响应,这时,用户就可以使用鼠标复制 Vim 窗口里的内容到其他应用程序里去了。

中文支持

按照特定顺序解码文件,避免出现乱码

1
set fileencodings=ucs-bom,utf-8,gb18030,latin1

图形界面的字体配置

注意,Vim 在设置选项时,空格需要用“\”进行转义。比如,如果我们要在 Ubuntu 下把字体设成 10 磅的 DejaVu Sans Mono,就需要写:

1
set guifont=DejaVu\ Sans\ Mono\ 10

此外,宽字符字体(对我们来讲,就是中文字体了)是可以单独配置的。这可能就更是一件仁者见仁、智者见智的事了。对于纯中文的操作系统,这一般反而是不需要配置的;但如果你的语言设定里,中文不是第一选择的话,就有可能在显示中文时出现操作系统误用日文字体的情况。这时你会想要手工选择一个中文字体,比如在 Ubuntu 下,可以用:

1
set guifontwide=Noto\ Sans\ Mono\ CJK\ SC\ 11

文本编辑

一些经常使用的trick

正常模式下:

  • <Home>将光标移到行首,<End>移到行尾,gg跳到文件第一行,G跳到文件最后一行,numG跳转指定行
  • dd删除当前行,dG删除当前行及下面所有行,dw删除一个单词,numdd删除下面的num行,
  • yy复制当前行
  • p粘贴

命令模式下:

  • :begin, end d删除begin-end行

光标移动

Vim 里的基本光标移动是通过 h(左)、j(下)、k(上)、l(右) 四个键实现的

b/B和w/W分别为以单词为单位的向前移动和向后移动

Tip:小写和大写的区别在于小写按标识符的规则识别单词,而大写认为连续非空均为单词

( 和 ) 移到上一句和下一句

{ 和 } 移到上一段和下一段

文本修改

  • c可以实现修改,可以理解为d(删除)+i(进入插入模式)
  • d 加动作来进行删除(dd 删除整行);D 则相当于 d$,删除到行尾。
  • c 加动作来进行修改(cc 修改整行);C 则相当于 c$,删除到行尾然后进入插入模式。
  • s 相当于 cl,删除一个字符然后进入插入模式;S 相当于 cc,替换整行的内容。
  • i 在当前字符前面进入插入模式;I 则相当于 ^i,把光标移到行首非空白字符上然后进入插入模式。
  • a 在当前字符后面进入插入模式;A 相当于 $a,把光标移到行尾然后进入插入模式。
  • o 在当前行下方插入一个新行,然后在这行进入插入模式;O 在当前行上方插入一个新行,然后在这行进入插入模式。
  • r 替换光标下的字符;R 则进入替换模式,每次按键(直到 )替换一个字符。
  • u 撤销最近的一个修改动作;U 撤销当前行上的所有修改。

Tip:vim提供的操作很多,大多数情况的需求往往一两个字母就能实现

文本对象选择

我们已经看到,通过c, d等命令,后面跟上目标对象,就可以实现对目标对象的操作

下面讲两个附加选对象的动作:a, i

  • a表示后续动作指的完整内容
  • i表示后续动作指向内容的内部

对于句子:

1
if (message == "sesame open")

进行不同操作会产生不同的效果:

  • ‘dw’(理解为 delete word)会删除“ame␣”,结果是“if (message == “sesopen”)”
  • ‘diw’(理解为 delete inside word)会删除“sesame”,结果是“if (message == “ open”)”
  • ‘daw’(理解为 delete a word)会删除“sesame␣”,结果是“if (message == “open”)”
  • ‘diW’会删除“”sesame”,结果是“if (message == open”)”
  • ‘daW’会删除“”sesame␣”,结果是“if (message == open”)”
  • ‘di”’会删除“sesame open”,结果是“if (message == “”)”
  • ‘da”’会删除“”sesame open””,结果是“if (message ==)”
  • ‘di(’或‘di)’会删除“message == “sesame open””,结果是“if ()”
  • ‘da(’或‘da)’会删除“(message == “sesame open”)”,结果是“if␣”

类似的搭配还有很多:

  • 搭配 s(sentence)对句子进行操作——适合西文文本编辑
  • 搭配 p(paragraph) 对段落进行操作——适合西文文本编辑,及带空行的代码编辑
  • 搭配 t(tag)对 HTML/XML 标签进行操作——适合 HTML、XML 等语言的代码编辑
  • 搭配 ` 和 ‘ 对这两种引号里的内容进行操作——适合使用这些引号的代码,如 shell 和 Python
  • 搭配方括号(“[”和“]”)对方括号里的内容进行操作——适合各种语言(大部分都会用到方括号吧)
  • 搭配花括号(“{”和“}”)对花括号里的内容进行操作——适合类 C 的语言
  • 搭配角括号(“<”和“>”)对角括号里的内容进行操作——适合 C++ 的模板代码

而a和i还可以前面加数字,对多层的文本对象进行选择

更快的移动

我们可以使用<PageUp>和<PageDown>来翻页,但 Vim 更传统的用法是<C-B>和<C-F>,分别代表 Backward 和 Forward。除了翻页,Vim 里还能翻半页,有时也许这种方式更方便,需要的键是<C-U>和<C-D>,Up 和 Down。

另外vim默认滚动的off是5,我们可以调为1

1
set scrolloff=1

只要光标还在屏幕上,你也可以滚动屏幕而不移动光标(不像某些其他编辑器,Vim 不允许光标在当前屏幕以外)。需要的按键是<C-E>和<C-Y>。

另外一种可能更实用的滚动屏幕方式是,把当前行“滚动”到屏幕的顶部、中部或底部。Vim 里的对应按键是 zt、zz 和 zb。和上面的几个滚动相关的按键一样,它们同样受选项 scrolloff 的影响。

重复操作

  • ; 重复最近的字符查找(f、t 等)操作

  • , 重复最近的字符查找操作,反方向

  • n 重复最近的字符串查找操作(/ 和 ?)

  • N 重复最近的字符串查找操作(/ 和 ?),反方向

  • . 重复执行最近的修改操作