Linux:Vim文本编辑器

Vim的各种模式和命令操作

Posted by BlackDn on October 13, 2023

“乱了盛夏蓝了海,伤了初冬白了城。”

Linux:Vim 文本编辑器

前言

因为自己的 Linux 没有装图形界面(装的 Linux Server),所以只能用命令行
这种情况下 Vim 就显得非常重要了
之前只会那么几个快捷键,撤回是哪个按键都还要去查
一不做二不休,干脆自己来总结一下

文本编辑器

Linux 有许多文本编辑器,有的使用简单,有的功能强大,而且不出意外的话还有人在源源不断地开发新的编辑器。总之,大家比较耳熟能详的编辑器有这些:

  • Nano:适合新手用户的命令行文本编辑器,命令行界面相对友好,通常会在底部显示可用的快捷键。
  • Vi/VimVim(Vi Improved)Vi的改进版,功能强大,基本上已经内置在各个 Linux 发行版中了。编辑文本非常高效但是门槛较高,主要是一堆快捷键和各种输入模式。
  • Sublime Text:跨平台文本编辑器软件,和 ObsidianNotion 等软件类似,支持 Markdown 语法,插件生态丰富。主要是它支持 Linux,一般软件都只跨 IOS 和 Windows。
  • Atom:GitHub 开源的文本编辑器,支持 Git 集成、多窗口编辑等功能,适用于编程和协作开发。

许多开发人员热爱 Vim 的快速、键盘驱动(据说熟悉 Vim 后编辑文本就完全不需要鼠标了)的工作流程,本着 “可以不用但多少得会一点” 的原则,我们来看看 Vim 的使用。

这里推荐一个 Vim 游戏:Vim Advantures,在游戏中学习 Vim 的各种模式、指令、用法等。不过后面要收费,前面只能玩一玩移动、删除相关的指令=。=

Vim 简介

Vim的前身Vi 编辑器由 Bill Joy 于 1976 年创建,最早应用于 BSD Unix 操作系统中。1991 年,Bram Moolenaar 对 Vi 进行改进和扩展,以增强 Vi 的功能,同时保持其基本的操作方式,于是就有了Vim
Vim 第一次亮相时,提供了多级撤销、语法高亮、多窗口编辑等 Vi 所不具备的功能,而一直以来 Vim 都在持续改进,造就了如今庞大的用户和开发者社区、数千个插件和脚本。
VS Code类似,Vim 本身是一个轻量级文本编辑器,但是丰富的插件使得其不仅可以高效地编辑文本,还可以进行各种语言的编程。
此外,还有许多 Vim 的衍生版本,如NeovimSpaceVim等,它们在 Vim 的基础上进行了进一步的扩展和改进,以适应现代开发需求。

安装

通常情况下Vi/Vim是预装在各个 Linux 发行版中的,但如果真没安装,或者装的 Linux 版本比较偏门,那还得自己安装,以 Ubuntu 为例:

sudo apt-get update # 更新源
sudo apt-get install vim # 安装Vim

安装完成后启动 Vim,以验证安装成功:

vim # 进入vim命令模式
:wq # 保存修改并退出,或者:
:q! # 不保存,强制退出

工作模式

硬要说的话 Vim 有很多模式,但是最主要的还是这三种(名字翻译可能会有差异):

  • 普通模式(Normal Mode):用于导航(光标移动)、复制粘贴等操作
  • 插入模式(Insert Mode):用于编辑文本,输入内容
  • 命令行模式(Command-Line Mode):也称底线命令模式,用于执行各种命令,如保存文件、退出 Vim 等

菜鸟好像吧把普通模式说成是命令模式(Command Mode),问题不大

此外,在普通模式下,我们可以进入三种可视模式,用于选取文本,以便后续的复制、替换等操作(按Ese退出可视模式):

  • 可视模式(Visual Mode):按v进入,使用光标选择文本。(按下 v 相当于按住鼠标,然后拖动光标来选择内容)
  • 可视行模式(Visual Line Mode):按V进入,以行为单位选择文本
  • 可视块模式(Visual Block Mode):按ctrl+v,进入,以矩形块为单位选择文本,常用于对齐文本、编辑代码块等

vim mode

普通模式命令

在介绍命令前,我们先定义一下 Vim 中的wordWORD,其实他们都是由一系列单词、数字或标点组成的字串,但是有什么区别呢?word除下划线以外的标点视为单独的元素,和其左右的字符互为不同的wordWORD则将两个空格之间的全部内容视为一个元素。
举个例子,我们有一句判断条件:if (next_line !== "The END!")

  • word分隔:if ( next_line !== " The END !") 共 8 个元素
  • WORD分隔:if (next_line !== "The END!")共 4 个元素

默认情况下,我们通过vim命令首先进入的是普通模式 ,其常用命令如下:

光标移动相关

  • h:左移光标(同左方向键)
  • j:下移光标(同下方向键)
  • k:上移光标(同上方向键)
  • l:右移光标(同右方向键)
  • 数字+移动光标:向指定方向移动指定行,比如3 + j,表示光标向下移动 3 行(按下 3 后右下角应该会显示这个 3,表示等待进一步操作)
  • 数字 + 空格:向右移动指定行
  • 数字 + 回车:向下移动指定行

  • home/end:移动光标到行首/行尾(Mac 上是fn + 左方向fn + 右方向
  • pageUp/pageDown:向上/向下翻页(Mac 上是fn + 上方向fn + 下方向
  • 0:数字 0,等同于home,移动到行首
  • $:等同于end,移动到行尾
  • ctrl + f:向下翻页,相当于pageDown
  • ctrl + d:向下翻半页
  • ctrl + b:向上翻页,相当于pageUp
  • ctrl + b:向上翻半页,相当于pageUp

  • H:定位到当前屏幕第一行
  • M:定位到当前屏幕中间行
  • L:定位到当前屏幕最后一行
  • G:定位到当前文件最后一行
  • 数字 + G:定位到当前文件的指定行
  • gg:定位到当前文件第一行(相当于1G

  • w/W:定位到下一个word/WORD
  • e/E:定位到当前word/WORD尾(如果已在头部则跳到下一个尾)
  • b/B:定位到当前word/WORD头(如果已在尾部则跳到下一个头)

删除、复制粘贴相关

之所以把删除复制粘贴放一起,是因为他们的命令有许多类似的地方

  • x/X:删除当前光标/光标前一个字符
  • 数字 + x/X:连续删除指定数量字符
  • dd:删除当前行
  • 数字 + dd:连续删除指定数量的行
  • dG:删除当前行到最后一行的内容
  • d0:删除光标所在处到当前行首的内容
  • d$:删除光标所在处到当前行尾的内容
  • d数字G:删除光标所在行到指定行的内容(可以向上删除)

  • yy:复制当前行
  • 数字 + yy:复制当前及接下来指定行,比如5yy表示复制当前行及下面 4 行的内容
  • yG:复制当前行到最后一行的内容
  • y1G:复制当前行到第一行的内容
  • y0:复制光标所在处到当前行首的内容
  • y$:复制光标所在处到当前行尾的内容
  • p/P:将复制的内容粘贴到下一行/上一行

  • J:将下一行接在当前行的行尾
  • .:小数点,表示重复上一个命令

查找替换相关

  • /查找内容:左下角会出现输入内容,按回车进行查找,从光标处开始向下查找(大小写敏感)
  • ?查找内容:同上,只不过从光标开始向上查找
  • n:查找成功后按n表示 “下一个” ,光标会定位到第一个字符
  • N:同上,表示 “上一个”

替换有一个自己的结构,大致如下([]里的内容表示可选,可以不填):

:起始行号,结束行号s/查找内容/替换内容/[gc]
or
:%s/查找内容/替换内容/[gc]

最简单的用法就是::%s/hello/world/%表示查找整个文件,将每行的第一个hello,并替换为world,如果想要把全部的hello都进行替换,需要在最后加个g:%s/hello/world/g
此外,如果想在每次替换前进行确认,可以再加个c:%s/hello/world/gc
在指定行号的时候,我们可以用$来表示行尾,比如将第 5 行到末尾的hello进行替换::5,$s/hello/world/g
当然,我们可以不写替换内容,以此达到删除的效果::%s/hello//g

不论是查找还是替换,都支持正则表达式,不过正则符号要用反斜杠转译一下,不然会被识别成查找内容::/colou\?r表示搜索colorcolour(正则符号?表示零次或一次出现),:%s/colou\?r/color/g表示全局将colour替换为color

考虑到文本中也可能出现很多  / ,为了避免这种情况下频繁地转义,我们可以用其他字符代替表示分隔的斜杠  /: :%s,pattern,replace,g:%s#pattern#replace#g

模式转换相关

  • i:进入插入模式,光标位置不变
  • I:进入插入模式,光标移动到当前行第一个非空格字符位置(如果行首不是空格,那就是移动到行首)
  • a:进入插入模式,光标后移一个位置(泪目,明明i+右方向键能好,偏要给你个快捷键)
  • A:进入插入模式,光标移动到行尾
  • o/O:在下一行/上一行添加一个空行,并进入插入模式
  • ::进入命令行模式,会看到界面底下出现冒号:
  • r:进入替换模式(Replace mode),相当于按了Insert 键,新输入的文字会替换光标所在位置的文字,但只会替换一次,之后就是正常的插入模式编辑
  • R:进入替换模式且一直保持替换

其他

  • u:撤销
  • ctrl + r:回退(u的逆操作)
  • :set nu:显示行号
  • :set nonu:取消行号显示
  • ZZ:保存并退出,相当于命令行模式的:wq
  • ZQ:不保存,强制退出,相当于命令模式的:q!

插入模式命令

在普通模式通过i / o / a等命令进入插入模式
插入模式其实就是我们熟悉的编辑文本操作,输入文本,回车换行、删除啥的都一样
值得一提的是,我们仍可以通过home/end键来快速定位到行首/行尾,通过pageUp/pageDown上下翻页。此外,insert键可以切换光标为输入/替换模式,光标将变成竖线/下划线(但是 Mac 好像没有这个键,只能进入替换模式操作) 最后按Esc退出插入模式,回到普通模式

命令行模式

在普通模式按冒号:进入命令行模式,界面底下出现冒号:,等待我们输入命令,回车执行
因为基本不能对文件内容进行修改,所以通常是对整个文件进行的操作
常用的命令如下(为了区分,保留前面的冒号):

  • :w:保存修改
  • :q:退出 vim(如果有修改未保存会退出失败)
  • :wq:保存修改并退出
  • :q!:不保存,强制退出

修改配置

很多时候我们想要在进入 vim 的时候初始化一些内容,或进行一些偏好配置,比如默认显示行号
这个时候需要在用户主目录下的.vimrc文件中进行配置,如果没有这个文件就先创建一个:

blackdn@root:~$ vim .vimrc

然后在第一行输入set nu就行了(因为是新建的所以整个文件就这一行)
我们可以理解为每次打开 vim,都会先执行一遍.vimrc里的命令就行
之后再使 Vim,默认就会显示行号了

此外还有很多设置参数可以配置在.vimrc中:

  • set number:显示行号。
  • set relativenumber:显示相对行号,便于导航。
  • set cursorline:突出显示当前行。(加了条下划线)
  • set cursorcolumn:突出显示当前列。
  • set ruler:显示光标位置。
  • set encoding=utf-8:使用 UTF-8 编码。
  • set fileformat=unix:设置文件格式为 Unix 风格(LF 换行符)。
  • set fileformat=dos:设置文件格式为 DOS 风格(CRLF 换行符)。
  • set tabstop=4:设置制表符宽度为 4 个空格。
  • set softtabstop=4:设置在编辑时插入的空格数量。
  • set shiftwidth=4:设置自动缩进的宽度。
  • set expandtab:使用空格代替制表符。
  • set ignorecase:忽略搜索时的大小写(默认大小写敏感的)。
  • set smartcase:仅在搜索中包含大写字母时区分大小写。
  • set incsearch:在输入搜索模式时动态显示匹配项。
  • colorscheme <主题>:更改 Vim 的颜色主题。
  • syntax enable:启用语法高亮。
  • filetype plugin on:启用文件类型检测和插件。

此外,如果使用了一些插件管理器(Vundle、Pathogen、Vim-Plug 等)安装了插件,这些插件也是在这个文件中进行配置。

参考

  1. Vim - the ubiquitous text editor
  2. Linux vi/vim
  3. How To: Vim show line numbers by default on Linux
  4. 感谢 ChatGPT