初识Vim
Vim被称为神一样的编译器,人类历史上最好文本编辑器(^_^)。学习成本很高,学习路线陡峭。下面列举一些入门的教程:
- 慕课网-玩转Vim 从放弃到爱不释手 新手必看
- Vim实用技巧(第2版)
- 精通Vim:用Vim8和Neovim实现高效开发
- vimtutor,在命令行中输入 vimtutor -g zh
- 插件入门,GitHub链接
Vim状态模式
vim中总共有五种模式,分别为:
- 普通模式:执行vim指令,如光标移动,复制、粘贴、撤销等操作。这是vim中的默认模式,在该模式下不能插入文字。
- 插入模式:用于文本输入、编辑。
- 视图模式:又叫选择模式,用于文本的选择。该模式可以执行普通模式下的指令,用于文本选择。
- 末行模式:该模式下可以保存退出vim,进行查找替换,执行外部命令,分屏等操作。
- 替换模式:替换模式下可以对现有文本进行替换。
几种模式关系如下图:
打开Vim
进入vim有两种方式,分别如下:
vim #方法一 vim filename #方法二,指定文件名,在启动vim同时,会打开该文件
通过方法一打开vim,会显示vim的基本信息(版本号、简单用法)。我们可以进入插入模式嵌入文本,后续退出时如果需要保存文件,则需要指定文件名。
方法二在打开vim时,指定了文件名,如果当前目录下存在该文件,则会通过vim打开。如果该文件不存在,vim会暂时打开一个没有任何字符的文件。后续编辑完成后,在保存退出时,无需再指定文件名。
保存文件内容
:w #保存文件,用于在打开vim时指定了文件 :w+未被使用的文件名 #以指定的文件名保存当前vim内容
退出vim
退出vim可以在末行模式下输入q(quit),常用的操作如下:
:q #对于没有改动的文件,用q即可退出 :wq #对于发生过修改的文件,保存并退出 :q! #对于发生过修改的文件,放弃修改并退出, !表示强制的意思 :qa #如果打开了多个窗口,全部退出
vim模式
普通模式
页面操作
zz #将当前行置于页面中间 ctrl+u #向上翻页 Ctrl+f #向下翻页
光标移动与跳转
文本对象
在 Vim 中,文本对象以一对标记字符或关键字来表示。它可以与操作命令结合使用,以便更精确地选择、编辑和处理文本。文本对象可以是字符、单词、句子、段落等等,它们可以在各种命令中使用,比如删除(d)、复制(y)、替换(c)等操作。
常见的文本对象:
- w:单词(word)文本对象。 vw 表示选中光标当前位置到结尾的单词(包括括号)。
- s:句子(sentence)文本对象。 vis 表示选择光标所在位置的句子,但不包括句子末尾的标点符号和空格。
- p:段落(paragraph)文本对象。 vip 表示选择光标所在位置的段落,不包括段落前后的空行。
- t:标签(tag)文本对象。vit 表示选择光标所在位置的标签,包括标签的开始和结尾。
- (、)、[、]、{、}<、>:括号文本对象。 vi( 表示选中括号内的内容。
- "、':引号文本对象。vi" 表示选中双引号内的内容。
例如:
假设文本为:<window>text="C++"</window> vit -> text="C++" 假设文本为:"Hello World!" vi" -> Hello World! 假设文本为:<Hello world> va< -> <Hello world>
光标移动
h #光标左移 j #光标下移 k #光标上移 l #光标右移
在单词之间跳转
w #移动光标到下一个单词的开头 b #移动光标到上一个单词的开头 e #移动光标到单词结尾,如果当前已经在结尾,则移动到下一个单词结尾处 W #移动光标到下一个以空白字符分隔的单词开头 B #移动光标到上一个以空白字符分隔的单词开头 E #移动光标到下一个以空白字符分隔的单词结尾
小写与大写的区别在于:分割单词的分割符不同。对于一个单词,大写只认准空格符 ' ' 作为一个单词的分隔,而小写则以非字母作为分割符。
行间跳转
f+字符 #快速跳转至当前行中该字符位置 t+字符 #快速跳转至当前行中该字符前一个字符位置 F+字符 #反过来搜索 T+字符 #反过来搜索
如果跳转的位置不正确,可以使用分号“;”继续向下搜索,使用逗号“,”向上搜索。
行首与行尾跳转
数字0 #光标移动到行首 ^ #光标移动到行首第一个非空白字符 $ #光标移动到行尾 g_ #光标移动到行尾最后一个非空白字符 % #在成对的括号之间跳转
页面间跳转
gg #跳转至文件开头位置(第一行) G #跳转至文件结尾位置(最后一行) 行号+gg #跳转至指定行号 H #跳转至当前页面开头行 M #跳转至当前页面的中间行 L #跳转至当前页面结尾行’‘ ''(两个单引号) #将光标退回上次所在位置
Jump List-跳转列表
在 Vim 中,Jump List(跳转列表)是一个记录了编辑器中跳转操作的历史记录。Jump List 以栈的形式保存了跳转操作,可以通过命令来回溯和跳转到不同的位置。
Jump List 中保存了以下类型的跳转操作:
- 普通跳转,例如光标移动、gg、w、f等操作。
- 文件跳转,在后面的窗口拆分中介绍
- 查找跳转
可以用一下命令来操作 Jump List 表:
Ctrl+o #回退到上一个跳转 Ctrl+i #前进到下一个跳转 g; #等价于Ctrl+i g, #等价于Ctrl+o :ju #显示 Jump List 表
删除操作
在vim中,删除操作是一种剪切操作,被删除的文本会保存在vim寄存器中。
字母x
小写x #删除光标所在位置字符 大写X #删除光标前一个字符 数字+小写x #删除光标后指定个数的字符 数字+大写X #删除光标前指定个数的字符
字母s
字母 s 是 substitute 的简写,表示代替、替换的意思。相比于字母x,字母 s 在删除文本的同时,会进入插入模式。
小写s #删除光标所在位置字符,并进入插入模式 大写S #删除当前行所有字符,并进入插入模式 数字+小写s #删除光标往后指定个数字符,并进入插入模式 数字+大写S #向下删除指定数字行,并进入插入模式
字母r
字母 r 是 replace 的简写,表示代替、替换的意思。与字母 s 的区别是,字母 r 会进入替换模式。替换模式是在现有文本上进行修改操作,但文本替换完成后,会返回普通模式。
r+单个字符 #将光标位置字符替换成指定字符 数字+r #进入替换模式,可以替换光标位置往后指定个数的字符 R #进入连续替换模式,可以替换多个字符,按Esc退出
字母d
字母 d 是 delete 的简写,表示删除。
选中文本+d #删除选中文本 大写D #s删除光标至本行结尾处所有字符 dd #删除当前行 数字+dd #向下删除指定数字行 d+移动命令 #删除移动范围内的文本 d+文本对象(w) #删除文本对象 daw #完整删除光标所在单词以及空白字符 diw #完整删除光标所在单词,不会删除空白字符 da+配对字符 #删除配对字符内文本,配对字符会被删除 di+配对字符 #删除配对字符内文本,配对字符不会被删除 dt+字符 #在当前行中,删除到指定字符之间的所有字符
dw与daw的区别:
- dw是 delete word 的含义,表示从当前光标位置开始删除一个单词。
- daw是 delete around word 的含义(官方的解释是 delete a word ),around表示环绕,该操作会完整的删除该单词,即使光标不在单词开头。
假设需要删除 HelloWorld 字符串,光标处于 o 的位置 dw -> Hell daw ->
da与di的区别:
- da 表示 delete around,在删除指定文本对象时,会连同文本对象符一起删除。
- di 表示 delete inner,在删除指定文本对象时,只会删除文本对象。
假设需要删除 "Hello World" 字符串,光标处于引号内部 da" -> di" -> ""
字母c
字母 c 是change的意思,表示修改。其功能与字母 d 类似,会将文本删除,并切换至插入模式。
复制粘贴
普通模式下,复制粘贴分别使用y(yank)和p(put)命令,例如:
小写y #复制选中内容(需要配合视图模式使用) 大写Y #复制当前行 yy #复制当前行 数字+yy #向下复制多行 yiw #复制一个单词 yis #复制一个句子 yaw #复制一个单词(包括空格) yas #复制一个句子(包括空格) 小写p #将寄存器中的内容插入到光标之后(粘贴操作) 大写P #将寄存器中的内容插入到光标之前(粘贴操作)
撤销
小写u #撤销最后一次执行的操作 大写U #撤销整行修改 Ctrl+r #反撤销
插入模式
当我们进入插入模式,左下角状态栏中会提示“insert”或“插入”文字,表示当前处于插入模式。
进入插入模式的方法
i #在光标之前进入插入模式 a #在光标之后进行插入模式 I #在光标所在行行首进入插入模式 A #在光标所在行行尾进入插入模式 o #在光标所在行下边插入新行,将光标移动到新行行首并进入插入模式。 O #在光标所在行上边插入新行,将光标移动到新行行首并进入插入模式。 gi #回到上次退出插入模式的位置继续
Ctrl+命令快捷操作
Ctrl+u #删除当前行中光标前所有字符 Ctrl+h #删除光标前一个字符,与Backspace功能相同 Ctrl+w #删除光标前一个单词 Ctrl=[ #退出插入模式切换至普通模式
复制粘贴
Ctrl+r+选项 #根据选项含义粘贴文本 #0:表示最近一次复制的文本 #":表示默认寄存器 #寄存器名:粘贴指定寄存器中的内容 #+:系统剪贴板 Ctrl+Shift+c #将光标选中内容拷贝至剪贴板 Ctrl+Shift+v #将剪贴板中的文本粘贴到光标位置
在粘贴从外部复制的代码时,会导致粘贴后的文本缩进出现问题。原因是我们在vimrc中设置了autoindent。可以用下面方法处理:
:set paste 粘贴文本 set nopaste
这样有点麻烦,我们也可以在粘贴文本后,用下面方式调整缩进:
gg=G
视图模式
进入视图模式
v #进入视图模式,通过移动光标进行选择 V #进入视图模式并选中当前行 Ctrl+v #以矩形块方式选中文本
大小写转换
u #将选中的文本转换为小写 U #将选中的文本转换为大写
末行模式
末行模式又被成为命令模式,主要用于执行命令、插件、查找替换等。
查找
?+待查找字符串+回车 #在当前文件中反向查找该字符串 /+待查找字符串+回车 #在当前文件中正向查找该字符串 n #切换至下一个匹配字符串 N #切换至上一个匹配字符串 * #切换至下一个匹配字符串 # #切换至上一个匹配字符串
n 与 * 的区别是: * 会根据当前光标所在位置,跳转到下一个匹配单词相同的光标位置。
替换
替换格式如下:
:[range] s/{pattern}/{string}/[flags]
- range:表示范围,比如:2,10表示2-10行,%表示全部
- pattern:表示要替换的文本,可以是正则表达式
- string:表示替换后的文本
- flags:表示替换标识
- g:表示全局范围内替换
- c:表示询问是否替换
- n:表示报告匹配到的文本次数,不执行替换。
用法:
:% s/C++/Java/g #将当前文件中所有"C++"字符替换为"Java" #% s/\<printf\>/printf_s/g #将当前文件中所有"printf"字符替换为"printf_s" #2,10 s/C++//n #统计2-10行中"C++"字符出现的次数
文件
在vim中,打开一个文件后会将该文件的内容加载到缓冲区。后续对该文件的修改,都是针对内存中的缓冲区,并不会直接保存到文件中。只有使用":w"命令,文件数据才会写入的磁盘中。Vim支持打开多个文件,并在这些文件间切换。
打开其他文件
:e+文件路径 #打开指定文件(可以使用通配符,用于打开多个文件) :e! #强制重新加载当前文件,丢弃对文件所做的所有更改。 e+文件路径+n #打开指定文件并定位到第 n 行 e+文件路径+/pattern #打开指定文件并进行查找
查看已打开文件
输入":ls"命令列举当前已经打开的文件。例如:
:ls 1 "a.txt" 第 3 行 2 # "b.txt" 第 2 行 3 %a "c.txt" 第 2 行 #第一列表示文件编号,可以使用 :b+编号 切换至不同文件。 #第二列表示缓冲区中的状态,%a表示当前正在编辑的文件,#表示上一个文件 #第三列表示文件名 #第四列表示光标所处行
文件切换
:b+n #跳转至第n个文件 :bpre #根据当前文件编号,跳转至上一个文件 :bnext #根据当前文件编号,跳转至下一个文件 :bfirst #根据当前文件编号,跳转至第一个文件 :blast #根据当前文件编号,跳转至最后一个文件 :b+文件名 #根据文件名跳转
窗口
窗口拆分
Ctrl+w+s #水平分割 :sp #水平分割 Ctrl+w+v #垂直分割 :vs #垂直分割
切换活动窗口
Ctrl+w+w #在窗口之间循环切换 Ctrl+w+h #切换至左边窗口 Ctrl+w+j #在窗口之间循环切换 Ctrl+w+k #在窗口之间循环切换 Ctrl+w+l #在窗口之间循环切换
重排窗口大小
Ctrl+w+= #所有窗口等高等宽 Ctrl+w+_ #最大化活动窗口的高度 Ctrl+w+| #最大化活动窗口的宽度 数字+Ctrl+w+_ #把活动窗口 数字+Ctrl+w+| #所有窗口等高等宽
执行外部命令
在末行模式下,输入 ! 外部命令,可以vim中执行外部shell命令,例如:
:! ls-l
执行外部命令后,Vim 会暂时切换到命令行输出模式,可以查看程序输出。按下任意键或按回车键可以返回 Vim 编辑界面。需要注意的是,执行外部命令可能会导致 Vim 的编辑进程暂时被阻塞,直到命令执行完成。如果命令的执行时间较长,可能会导致 Vim 在这段时间内无响应。
以root身份保存文件
有时候,在编辑系统文件或者受权限保护的文件的时候,可能忘记在命令之前添加sudo,这只会以只读方式打开文件。如果此时已经做了修改,不可能撤销当前修改,然后重新打开。可以用如下命令解决:
:w !sudo tee %
寄存器
在vim中的复制、删除、剪切不是操作的系统剪切板,而是一个“无名寄存器”。使用y、d命令,实际是将文本内容保存到该寄存器中。
除了“无名寄存器”,vim还可以指定有名寄存器。有名寄存器用a-z表示,通过使用引号(")+寄存器名使用,例如:
"ayy #复制当前行到a寄存器 "aiw #复制一个单词到a寄存器 "bdd #剪切当前行剪切到b寄存器 "ap #将a寄存器粘贴到当前行 "%p #将文件名输出当前行
还有一些其他的寄存器:
"" #表示无名寄存器 "0 #复制寄存器 "+ #表示系统剪贴板(需要vim支持clipboard) "% #当前文件名 ". #上次插入的文本
插入内容
:r! echo % #插入当前文件名 :r! echo %:p #插入当前路径 :r 文件名 #将指定文件中的内容插入至光标后 :r !外部命令 #将外部命令的输出结果插入至光标后
Vim其他功能
宏
宏可以看作一系列命令的集合。我们可以使用宏录制一系列操作,然后通过回放将其作用于多行文本上。在vim中,录制的宏是保存在寄存器中的。因此,在录制宏时,需要指定寄存器。下面介绍如何录制一个宏:
- 在普通模式下输入q+寄存器名,此时已经进入录制模式。
- 正常进行操作。
- 按下q结束录制。
- 在视图模式下选中需要作用宏的行。
- 按下:进入末行模式,输入:normal @寄存器名
例如,给下列url加上双引号:
https://www.bilibili.com/ https://www.baidu.com/ https://www.sina.com.cn/ https://www.qq.com/ https://www.1688.com/
具体步骤:
光标定位到第一行 普通模式下输入: qa 此时左下角显示recording @a 按下大写I移动到行首并进入插入模式,输入:" 按下ESC退出插入模式,按下大写A移动到行尾并进入插入模式,输入:" 按下ESC退出插入模式,按下q退出录制 视图模式下选中2-5行 按下: 此时末行模式变为::'<,'> 输入: normal @a 按下回车,应用宏。
完成上面功能,还有一种不使用宏的方法:
光标定位到第一行,按下大写A,选中整行 按下大写G,选中全部文本 按下: 此时末行模式变为: :'<,'> 输入: normal I" 执行1、2步再次选中全文 按下: 此时末行模式变为: :'<,'> ,按下 ctrl+p,打开上一次执行的命令 将 normal I" 替换为 normal A" ,回车
补全功能
vim中开启补全功能有如下方式:
Ctrl+n #普通关键字补全,向后选择item项 Ctrl+p #普通关键字补全,向前选择item项 Ctrl+x+n #当前缓冲区关键字 Ctrl+x+i #包含文件关键字 Ctrl+x+] #标签文件关键字 Ctrl+x+k #字典查找 Ctrl+x+l #整行补全 Ctrl+x+f #文件名补全,在使用open指定文件路径时使用 Ctrl+x+o #全能补全
Vim配置
配色
vim提供了一些自带的配色方案,可以通过下列命令查看和修改:
:colorscheme #显示当前的主题配色,默认是default :colorscheme Ctrl+d #显示所有的配色方案 :colorscheme 配色名 #更换配色
如果对自带的配色不满意,可以从网上下载合适的配色方案:
https://vimcolorschemes.com/
上面网站中提供了很多好看的主题配色,可以从中选取一款,然后在GitHub中下载下来:
git clone https://github.com/morhetz/gruvbox.git #确保当前用户目录下存在colors目录 mkdir -p ~/.vim/colors #将.vim文件拷贝到colors目录下 cp /gruvbox-master/colors/gruvbox.vim ~/.vim/colors/ #在vim中开启配色 :colorscheme gruvbox
配置文件
有两种方式修改vim中配置:
/etc/vim/vimrc #全局配置,所有用户都会生效 ~/.vimrc #仅作用于该用户
vim在打开时,会加载配置文件中的设置并应用,这样就不用每次打开vim时,还需要单独进行配置了。
修改配置文件后,如何让其生效,有两种方式:
- 退出vim再重进
- 再末行模式下输入:source+配置文件
:source ~/.vimrc
vimrc文件中包含:
- 常用设置,比如 :set nu 设置行号。
- 常用vim映射
- 自定义的vimscript函数
- 插件配置
常用设置如下:
#命令 #语义 #缩写 set number 代码显示行号 set nu set nonumber 关闭行号 set nonu syntax on 关键词高亮显示 set cindent c 语法自动缩进 set ci set autoindent 新行自动缩进 set ai set shiftwidth=4 缩进宽度 4 set sw=4 set tabstop=4 tab 键宽度 4 set ts=4 set softtabstop=4 制表符宽度 4 set st=4
映射
vim映射允许你将一个操作映射到一个命令或一系列命令上,从而简化编辑的过程。例如我们可以将F2映射为保存,这样就不需要先按Esc退出编辑模式,在使用:w保存,极大程度上简化了操作。
映射分为两类,递归映射与非递归映射:
- 递归映射:是指将一个新的映射关联到一个已定义的映射上。例如将 "-" 映射为 "dd",又将 "+" 映射为 "-",此时输入 "+"也可以实现"dd"的功能。
- 非递归映射:对于映射的命令,不会进行递归解释。
递归映射存在嵌套的风险,因此不建议使用。
vim中,常用的 normal 、visual 、insert 和 command-line 都可以定义映射。
normal映射
nnoremap {keys} {command} #创建不递归的 normal 模式映射 nmap {keys} {command} #创建递归的 normal 模式映射
案例:
nnoremap <F2> :w<CR> #将 F2 键映射到保存文件的命令。 nmap <F3> dd #将 F3 键映射到删除当前行的命令。
visual映射
vnoremap {keys} {command} #创建不递归的 visual 模式映射 vmap {keys} {command} #创建递归的 visual 模式映射
案例:
vnoremap <C-c> "+y #将 Ctrl + c 键映射到复制选定文本到剪贴板(需要clipboard支持)
insert映射
inoremap {keys} {command} #创建不递归的 insert 模式映射 imap {keys} {command} #创建递归的 insert 模式映射
案例:
inoremap jj <Esc>`^ #按下jj切换至 normal 模式且不改变光标位置
command-line映射
cnoremap {keys} {command} #创建不递归的 command-line 模式映射 cmap {keys} {command} #创建递归的 command-line 模式映射
案例:
cnoremap w!! w !sudo tee % >/dev/null 强制写入
vimscript
推荐一篇教程《笨方法VimScript》
Vim插件
安装插件管理器(Vim-plug)
在Vim-plug的GitHub首页中,提供了官方文档。GitHub链接
在线安装:
curl -fLo ~/.vim/autoload/plug.vim --create-dirs \ https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
其他端安装官方文档中有说明。
离线安装:
下载好 Vim-plug,将 plug.vim 拷贝至 ~/.vim/autoload/ 目录下:
mkdir -p ~/.vim/autoload/ cp plug.vim ~/.vim/autoload/plug.vim #需要根据当前路径调整plug.vim
安装完成后,可以在 ~/.vimrc 文件中添加或删除插件,假设需要安装vim-startify插件,操作如下:
call plug#begin('~/.vim/autoload') Plug 'mhinz/vim-startify' #vim-startify插件 call plug#end()
保存文件,在末行模式下执行:
:source ~/.vimrc #应用配置项 :PlugInstall #安装插件
如果需要卸载,输入:
:PlugClean
如何搜寻插件
vimawesome网站上集成很多vim插件,可以在该网页上寻找满足需求的插件。
版权
本文主要参考 《玩转Vim 从放弃到爱不释手》(感谢作者无私录制免费视频)。文章由本人学习后整理而成。
标签:文本,入门,Ctrl,模式,vim,跳转,放弃,光标,Vim From: https://www.cnblogs.com/BroccoliFighter/p/17998703