vim 让人爱不释手的编辑器之神
VIM
基本介绍
vim诞生已有20多年,它常被人称之为编辑器之神,vim的操作理念可以说是独具一格而又出类拔萃,使用vim能极大的提升文本处理效率,因此熟练掌握vim应该是每个程序员都应该做到的事情。
vim目前有3个较常见的版本:
- vi:只保留了一些基础功能,在绝大多数Linux发行版中都内置了vi
- vim:相较于vi功能更加完善,是标准的版本,但是在某些Linux发行版中需要手动安装
- neovim:目前最火热的一个vim分支,它在vim原本的基础上做了一些改进,使其更加的优秀
安装nvim
由于neovim是今后的主流,所以我们选择安装neovim,可参阅官方文档查阅安装方法,我这里是以MAC平台为例。
1)下载neovim的安装包:
$ wget https://github.com/neovim/neovim/releases/download/stable/nvim-macos.tar.gz
2)解压到指定的目录:
$ tar xzf ./nvim-macos.tar.gz -C /usr/local/application/
$ mv /usr/local/application/nvim-osx64/ /usr/local/application/nvim
3)将neovim添加到系统环境变量,并将nvim alias 为 vim:
$ vim /etc/profile
alias vim='nvim'
PATH=/usr/local/application/nvim/bin:$PATH
$ source /etc/profile
4)输入vim后能够看到neovim的字样则代表安装成功:
模式介绍
vim有4种模式,分别是:
- NORMAL:普通模式、使用ESC进入
- INSERT:插入模式、使用i、a、o、I、A、O、s、S、c进入,使用ESC退出
- COMMAND:命令模式、使用 : 进入,输入命令后要回车才会生效,使用ESC退出
- VISUAL:可视模式、使用v、V进入,使用ESC或者v、V退出
首先当我们进入vim后,它会处于普通模式中,普通模式是vim最强大的也最常用的模式。
普通模式
光标移动
普通模式下光标移动命令如下:
命令 | 描述 |
---|---|
h | 光标向左移动一个字符 |
l | 光标向右移动一个字符 |
j | 光标向下移动一行 |
k | 光标向上移动一行 |
w | 向后移动一个单词,光标位于单词首部 |
W | 向后移动一组单词,光标位于单词首部,如class-name就会被认为是一组单词 |
b | 向前移动一个单词,光标位于单词首部 |
B | 向前移动一组单词,光标位于单词首部,如class-name就会被认为是一组单词 |
e | 向后移动一个单词,光标位于单词尾部 |
E | 向后移动一组单词,光标位于单词尾部,如class-name就会被认为是一组单词 |
f | 向后查询一个字符,并将光标跳转到目标处 |
F | 向前查询一个字符,并将光标跳转到目标处 |
t | 向后查询一个字符,并将光标跳转到目标前一个位置 |
T | 向前查询一个字符,并将光标跳转到目标后一个位置 |
; | 重复上一次的f、F、t、T查询 |
0 | 光标移动到本行的起始位置 |
$ | 光标移动到本行的结束位置 |
^ | 光标移动到本行的第一个非空白字符处 |
$_ | 光标移动到本行的最后一个非空白字符处 |
G | 光标移动到文件的开头 |
gg | 光标移动到文件的末尾 |
注意w、b、e如果光标正位于当前单词的中间,那么它将会先把光标移动到当前单词的首部或者尾部。
文档浏览
普通模式下文档浏览命令如下:
命令 | 描述 |
---|---|
H | 光标移动到当前屏幕展示内容区域第一行的第一个字符 |
M | 光标移动到当前屏幕展示内容区域中间行的第一个字符 |
L | 光标移动到当前屏幕展示内容区域最后一行的第一个字符 |
zt | 将光标所在行设为屏幕展示区域的首行 |
zz | 将光标所在行设为屏幕展示区域的中心 |
zb | 将光标所在行设为屏幕展示区域的尾行 |
ctrl + e | 将页面移动一个光标 |
ctrl + u | 查看上半页内容 |
ctrl + d | 查看下半页内容 |
ctrl + b | 查看上一页内容 |
ctrl + f | 查看下一页内容 |
ctrl + o | back 到之前的位置 |
ctrl + i | foward 到之前的位置 |
[ 与 ] | 跳转到上一句、下一句 |
跳转到上一段、下一段 | |
gt | 切换下一个标签栏 |
gT | 切换上一个标签栏 |
gf | 当处于一个 文档链接 上时,可以直接在新的标签页打开该文件 |
注意,当打开新的 vim 时(无内容),可以按下 ctrl + o 打开上次的文件。
文档插入
普通模式下文档插入命令如下,若想从编辑模式回到普通模式,只需要按下ESC键即可:
命令 | 描述 |
---|---|
a | 光标后进行插入,进入编辑模式 |
i | 光标前进行插入,进入编辑模式 |
o | 下一行进行插入,进入编辑模式 |
A | 当前行尾插入,进入编辑模式 |
I | 当前行首插入,进入编辑模式 |
O | 上一行进行插入,进入编辑模式 |
s | 删除当前光标下的内容,并进入编辑模式 |
S | 删除当前行的内容,并进入编辑模式 |
cc | 删除当前行的内容,并进入编辑模式 |
复制粘贴
普通模式下复制命令如下:
命令 | 描述 |
---|---|
y | 复制当前光标下的内容 |
yy | 复制当前行中的内容 |
p | 将内容粘贴至下一行 |
P | 将内容粘贴至上一行 |
删除替换
普通模式下删除替换命令如下:
命令 | 描述 |
---|---|
dd | 删除当前行的内容 |
cc | 删除当前行的内容,并进入编辑模式 |
r | 替换当前光标下的内容 |
R | 替换当前光标后的内容,按ESC键回到普通模式 |
s | 删除当前光标下的内容,并进入编辑模式 |
S | 删除当前行的内容,并进入编辑模式 |
xp | 交互当前字符和下一个字符的位置 |
注意,dd命令删除其实是剪切的意思,你可以通过p或者P来进行粘贴。
字符查找
普通模式下字符查找命令如下:
命令 | 描述 |
---|---|
/ | 正向查找字符串,通过n或者N进行光标的上下跳转 |
? | 反向查找字符串,通过n或者N进行光标的上下跳转 |
# | 向前查找光标所在处的单词 |
* | 向后查找光标所在处的单词 |
撤销重做
普通模式下撤销重做命令如下:
命令 | 描述 |
---|---|
u | 撤销 |
ctrl + r | 重做 |
数字加减
普通模式下数字加减命令如下:
命令 | 描述 |
---|---|
ctrl + a | 数字自加1 |
ctrl + x | 数字自减1 |
字符转换
普通模式下字符转换命令如下:
命令 | 描述 |
---|---|
~ | 将光标下的字母切换大小写 |
g ~~ | 将当前行的字母切换大小写 |
gUU | 将当前行的字母改成大写 |
guu | 将当前行的字母改成小写 |
gUaw | 将当前单词改成大写 |
guaw | 将当前单词改成小写 |
缩进重复
普通模式下缩进重复命令如下:
命令 | 描述 |
---|---|
>> | 进行缩进,默认为8个空格 |
<< | 进行反缩进 |
== | 自动缩进当前行 |
. | 重复上一次的动作 |
指令动作
vim里分为指令和动作,我们可以通过它们的组合定义出一系列的动作链进行执行。
比如,向右移动3个字符:
3l
再比如,向后查询第二个以f开头的字符:
2ff
删除全文:
dG
dgg
令数字自增或者自减n个值:
100 ctrl+a
100 ctrl+x
在文档操作中,有一类操作很常见,比如删除下面Array的内容:
[1, 2, 3, 4, 5]
我们可以将光标移动到该数组上,输入以下命令即可,其中i代表inner,即不包含[]自身:
ci[
# change inner []
如果你想连同[]也一起删除,可以输入以下命令,其中a代表all,即包含[]自身:
ca[
# change all []
同理,[]、()、{}以及""和''都支持这样操作。
在HTML文档操作中,删除一个标签的内容可能会经常常用,对此你可以直接在将被删除的标签上使用cit命令即可:
cit
# change inner to
同理,若要连标签一起删除,可以使用cat命令:
cat
# change all to
常用组合
以下的n均代表数字。
文档插入:
命令 | 描述 |
---|---|
:n | 跳转到指定的行数 |
nh、nl、nj、nk | 向左右移动n个字符、向上下移动n行 |
nw、nb | 向前或后移动n个单词 |
nf{char}、nF | 向前或后查询第n个字符,并将光标跳转到此处 |
0、^、$_、$ | 光标移动到本行的起始或结束位置 |
G、gg | 光标移动到文件的开头或者末尾 |
复制粘贴:
命令 | 描述 |
---|---|
nyw | 复制n个词语 |
yy | 复制一整行 |
nyy | 复制n行 |
yi" | 复制本行的""中的内容 |
ya" | 复制本行的"" |
p、P | 将内容粘贴至下一行或上一行 |
删除文本:
命令 | 描述 |
---|---|
r | 替换当前光标下的内容 |
R | 替换当前光标后的内容,按ESC键回到普通模式 |
ndw | 删除n个单词,也可以使用dnw |
ndd | 删除n行,也可以使用dnd |
dG | 从文本开头删到文本结束 |
dgg | 从文本结束删到文本开头 |
df | 删除本行中f之前的内容 |
di" | 删除本行的""中的内容 |
da" | 删除本行的"" |
dit | 删除HTML标签中的内容 |
dat | 删除HTML标签 |
cat | 删除HTML标签,并且进入编辑模式,通常情况下c要比d更常用 |
ciw | 删除当前单词、不包含后面的空格 |
caw | 删除当期单词、包含后面的空格 |
数字加减:
命令 | 描述 |
---|---|
ctrl + a | 数字自加1 |
ctrl + x | 数字自减1 |
n ctrl + a | 数字自加n |
n ctrl + x | 数字自减n |
缩进重复:
命令 | 描述 |
---|---|
>> | 进行缩进,默认为8个空格 |
<< | 进行反缩进 |
. | 重复上一次的动作 |
命令模式
文件开关
命令模式下文件开关命令如下:
命令 | 描述 |
---|---|
:w 与 :w! | 保存当前文件但不退出、加!是强制保存 |
:wa 与 :wa! | 保存所有文件但不退出、加!是强制退出 |
:q 与 :q! | 退出当前文件但不保存、加!是强制退出 |
:qa 与 :qa! | 退出所有文件但不保存、加!是强制退出 |
:x 与 :x! | 退出当前文件并保存、加!是强制退出并保存 |
:wq 与 :wq! | 退出当前文件并保存、加!是强制退出并保存 |
:xa 与 :xa! | 退出所有文件并保存、加!是强制退出并保存 |
:wqa与:wqa! | 退出所有文件并保存、加!是强制退出并保存 |
:saveas file | 将文件另存为 |
:tabnew file | 在标签栏中打开另一个文件 |
:tabn 与 :tabp | 切换下一个或上一个标签栏 |
:tabc 与 :tabo | 关闭当前或其他标签栏 |
:e | 将文件以buffer的形式打开 |
:bn 与 :bp | 打开上一次或下一次浏览的buffer |
:source nvim配置文件 | 刷新配置文件 |
行号相关
命令模式下行号相关命令如下:
命令 | 描述 |
---|---|
:set nu | 显示行号 |
:set nonu | 隐藏行号 |
:set rnu | 设置相对行号 |
:set nornu | 关闭相对行号 |
:n | 定位到n行 |
拼写检查
命令模式下拼写检查相关命令如下:
命令 | 描述 |
---|---|
:set spell | 打开拼写检查 |
:set nospell | 关闭拼写检查 |
:set spell! | 打开或关闭拼写检查 |
:set spelllang=en_us,cjk | 设置拼写检查语言(忽略中文) |
[s | 移动到上一个拼写错误处 |
]s | 移动到下一个拼写错误处 |
z= | 给出正确拼写的建议 |
zg | 添加到用户拼写中(标识为正确) |
zw | 从用户平写中删除(取消标识) |
字符替换
命令模式下查找替换命令如下:
命令 | 描述 |
---|---|
:{range}s/{target}/{replace}/ | 查找并替换字符串 |
:noh | 取消搜索高亮 |
查找并替换字符串里其中range是范围,不写代表当前行、%代表全文。
而mode是查找模式,如i是大小写不敏感、I是大小写敏感、g是行模式等、c代表是否弹出 确认替换:
:s/http/https/gi # 将当前行的http替换为https
:%s/http/https/gi # 将全文的http替换为https
:2,10s/http/https/gi # 将第2到第10行的http替换为https
:2,+3s/http/https/gi # 将第2到后3行的http替换为https
:2,-3s/http/https/gi # 将第2到前3行的http替换为https
粘贴模式
有的时候我们复制一部分文本在vim中粘贴时可能会发生格式错乱的问题。
此时你只需要打开粘贴模式然后再p即可:
命令 | 描述 |
---|---|
:set paste | 打开粘贴模式 |
:set nopaste | 退出粘贴模式 |
ab替换
有些单词可能很长,如Elasticsearch,我们希望今后在输入es的时候vim会自动将它替换为Elasticsearch,为此我们可以定义一条ab规则:
:ab es Elasticsearch
代码折叠
vim的代码折叠方式共有6种,每次只能使用一种:
- manual:手动通过zf定义折叠
- indent:利用缩进自动定义折叠
- expr:利用表达式自动定义折叠
- syntax:利用语法高亮自动定义折叠
- diff:对没有更改的文本进行折叠
- marker:对文中的标准进行折叠
设置默认的折叠方式,你可以将它设置到配置文件中:
" 自动按照缩进进行代码折叠
set foldmethod=indent
以下是一些常见的代码折叠相关操作:
- zf:创建折叠
- zo:打开折叠
- zc:关闭折叠
- zR:打开所有
- zM:关闭所有
- zj:移动到下一个折叠
- zk:移动到上一个折叠
执行命令
在打开vim脚本时我们希望再到终端中执行某些命令:
:! command # 如 :! ls
将命令的结果输入到当前文件中:
:r !command # 如 :r !ls
使用以下命令查看 vim
打开终端
在vim中打开终端只需要输入以下命令即可:
:term
它会创建一个新的内置终端,该终端也遵循vim相关操作。
若要退出终端,可输入 <C-\><C-n>
可视模式
基本概述
可视模式相当于多选操作,类似于鼠标左键一直摁住选择一块区域。
- v:进入字符可视化模式,按v或者ESC键可退回到普通模式
- V:进入行可视化模式,按V或者ESC键可退回到普通模式
- ctrl + v : 进入块可视化模式,按ctrl + v或者ESC键可退回到普通模式
在可视模式下,一些按键被赋予了特殊的意义:
- y:复制选择区域
- d:删除选择区域
- p:粘贴选择区域
- >:进行缩进
- <:进行反缩进
- vi":选择"之中的内容,不包括""
- va":选择"的内容,包括""
一个很常用的操作:
V移动n行选择一片区域
:s/http/https/gi
# 将一片区域中的http替换成https
另一个操作:
V移动n行选择一片区域
:normal A 123
# 在所有选择行的最后面添加123
换句话说,可视模式搭配其他 2 种模式可以做出很多高效操作。
高级操作
分屏
我们可以在打开文件的时候进行分屏浏览:
$ vim -on file1, filen ... filen # 注意!小写on代表上下分屏
$ vim -On file1, filen ... filen # 注意!大写On代表左右分屏
若想在打开文件后进行分屏操作,则需要:
ctrl + w s # 按照当前文件新拆分一个上下分屏
:sp file # 按照指定文件新拆分一个上下分屏
ctrl + w v # 按照当前文件新拆分一个左右分屏
:vsp file # 按照指定文件新拆分一个左右分屏
移动上下分屏的位置:
ctrl + w H # 将当前光标定位的分屏向左移
ctrl + w L # 将当前光标定位的分屏向右移
ctrl + w J # 将当前光标定位的分屏向下移
ctrl + w K # 将当前光标定位的分屏向上移
切换左右分屏的光标:
ctrl + w h # 将当前光标定位到左边分屏
ctrl + w l # 将当前光标定位到右边分屏
ctrl + w j # 将当前光标定位到下边分屏
ctrl + w k # 将当前光标定位到上边分屏
关闭当前分屏的命令:
ctrl + w c # 关闭当前分屏
ctrl + w q # 关闭当前分屏,如果是最后一个分屏将退出vim
宏录制
在很多情况下我们希望重复一个动作,此时就可以使用宏录制功能。
在普通模式下进行操作:
- 按q启动宏录制
- 为你的宏取一个名字,如t
- 开始录制你的操作
- 录制完成之后按q结束录制
- 按下@t执行宏
如我想生成一个从1到10的数字自增列:
i 1 ESC # 进入插入模式,输入1,然后退到普通模式
q t yy p ctrl+a q # 录制1次宏
8@t # 启动8次宏
配置文件
vim和neovim的配置文件存放地方有些不一样:
- vim:~/.vimrc文件
- neovim:~/.config/nvim/init.vim文件
如下是常用设置,其中"是注释:
"使用系统寄存器(剪切板)
set clipboard=unnamed
" 显示行号
set number
" 设置相对行号
set relativenumber
" 设置行宽
set textwidth=80
" 设置自动这行
set wrap
" 是否显示状态栏
set laststatus=2
" 语法高亮
syntax on
" 支持鼠标
set mouse=a
" 设置编码格式
set encoding=utf-8
" 启用256色
set t_Co=256
" 开启文件类型检查
filetype indent on
" 设置自动缩进
set autoindent
" 设置tab缩进数量
set tabstop=4
" 设置>>与<<的缩进数量
set shiftwidth=4
" 将缩进转换为空格
set expandtab
" 自动高亮匹配符号
set showmatch
" 自动高亮匹配搜索结果
set hlsearch
" 边搜索边高亮
set incsearch
" 开启类型检查
" set spell spelllang=en_us
" 开启命令补全
set wildmenu
" 不创建备份文件
set nobackup
" 不创建交换文件
set noswapfile
" 多窗口下光标移动到其他窗口时自动切换工作目录
set autochdir
" 忽略大小写
set ignorecase
" 智能大小写
set smartcase
更多的情况下我们会替换掉一些默认普通模式下的vim快捷键,在配置前我们需要了解一些概念:
- leader:前导键,类似于Thinkpad的小红点,它是vim的一个功能键
- map:会递归的映射方式、a映射b、c映射a、那么按c其实就等于按了b
- noremap:不会递归的映射方式
- nnoremap:只会在普通模式下生效的映射方式
- inoremap:只会在插入模式下生效的映射方式
- vnoremap:只会在可视模式下生效的映射方式
- cnoremap:只会在命令模式下生效的映射方式
配置文件如下,其中<cr>代表回车键:
" 配置vim的前导键
let mapleader = "\<space>"
" 简化分屏模式快捷键
noremap <C-j> <C-W>j
noremap <C-k> <C-W>k
noremap <C-h> <C-W>h
noremap <C-l> <C-W>l
" 修改标签栏操作,取消e和E的跳词
nnoremap e gt
nnoremap E gT
" 修改回到普通模式的按键
inoremap jj <Esc>
" 修改^以及$的映射方式
nnoremap H ^
nnoremap L $
插件安装
vim的强大之处就在于它可以支持各种各样的插件。
在vim中,我们要想管理插件,就必须依赖另一款插件vim-plug。
下载vim-plug(需要上梯):
$ sh -c 'curl -fLo "${XDG_DATA_HOME:-$HOME/.local/share}"/nvim/site/autoload/plug.vim --create-dirs \
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
# 国内可访问
$ curl -fLo ~/.local/share/nvim/site/autoload/plug.vim --create-dirs \
https://gitee.com/c4pr1c3/vim-plug/raw/master/plug.vim
将下面2行加入到~/.config/nvim/init.vim中,后续我们的插件都放在这2行中间:
" begin指定插件存放目录
" 如果是vim,则指定到~/.vim/autoload/中
call plug#begin('~/.config/nvim/autoload/')
" 插件放在这里
call plug#end()
到github上寻找你要安装的插件,我们以配色插件举例,将它添加到init.vim文件中:
call plug#begin('~/.config/nvim/autoload/')
" 加载配色插件
Plug 'theniceboy/vim-deus'
call plug#end()
然后只需要进入vim在命令模式下输入以下命令即可完成以添加的插件安装,按q退出即可:
:PlugInstall
如果想更新以安装的插件,可以在vim命令模式下输入以下命令:
:PlugUpdate
查看已安装的所有插件状态,按q退出:
:PlugStatus
当需要卸载插件时,你只需要在init.vim文件中将加载的插件行进行删除或注释即可,这样vim下次启动时就不会加载该插件了:
" 注释该插件
" Plug 'vim-plug'
# Ps:若想删除该插件则可使用:PlugClean即可
vim也提供了懒加载机制,只有在特定条件下该插件才会被加载,如下所示:
" 只有在打开php、html、javascript类型文件时才加载该插件
Plug 'vim-plug', { 'for': ['php', 'html', 'javascript'] }
有些vim插件可能在安装后需要做一些额外的操作,你可以在这些插件的自述文档中找到这些说明,比如在安装完成后执行一段脚本:
Plug 'vim-plug', { 'do': './install.sh' }
推荐在init.vim文件首行添加上这样一段代码,它的作用在于每次启动vim前都会检查是否安装了vim-plug插件,如果没有安装它将自动尝试安装且运行:PlugInstall命令:
if empty(glob('~/.config/nvim/autoload/plug.vim'))
silent !curl -fLo ~/.config/nvim/autoload/plug.vim --create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
autocmd VimEnter * PlugInstall --sync | source $MYVIMRC
endif
443问题
在安装vim-plug时curl:433这个问题一直困扰我很久,我尝试了各种办法如挂代理、修改hosts文件等都没得到有效解决。
最后我在chrome中打开了vim-plug的url:
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
将里面的内容copy下来后到~/.config/nvim/autoload中touch了一个vim-plug文件,并将内容粘贴进去得到了解决。