前言
最近看到很多大佬用vim贼溜,高大上,而且编辑和处理文本比编辑器打开文件编辑高效很多,所以工作中也一直有意使用vim编辑,这里记录一下常用快捷命令。
中文文档
以mac环境为例
cd ~/.vim // 如果没有文件夹就自己创建一个
mkdir -p pack/my/start
git clone https://github.com/yianwillis/vimcdoc.git pack/my/start/vimcdoc
Vim 教程支持多语言,可使用命令 vimtutor 来启动。如果启动的教程的语言不是你希望的, 你可以使用环境变量 LANG 来设定希望的语言
LANG=zh_CN.UTF-8 vimtutor
基础命令
移动
- h 左
- l 右
- j 下
- k 上
- w 从关标处移动至下一个单词的起始处
- 2w 移动2个单词
- e 从关标处移动至该单词的末尾
- 3e 使光标向前移动到第三个单词的末尾
- 0 移动光标到行首
- $ 移动光标到行尾
- ( 和 ) 移到上一句和下一句
- { 和 } 移到上一段和下一段
- control-f 向下翻页
- control-b 向上翻页
- control-d 向下翻半页
- control-u 向上翻半页
- control-e 光标不动,向上滚动屏幕
- control-y 光标不动,向下滚动屏幕
- zt 鼠标所在当前行滚到屏幕顶部
- zz 鼠标所在当前行滚到屏幕中部
- zb 鼠标所在当前行滚到屏幕底部
替换
- S 替换行
- s 替换字符
- r 输入 r 和一个字符替换光标所在位置的字符
- R 可连续替换多个字符, R 将进入替换模式,直至按 键回到正常模式
- :s/old/new 可以替换old为new,只改变光标所在行的第一个匹配串
- :s/old/new/g 可以替换old为new,替换全行的匹配串
- :%s/old/new/g 替换整个文件中的每个匹配串
- :%s/old/new/gc 会找到整个文件中的每个匹配串,并且对每个匹配串提示是否进行替换
- :#,#s/old/new/g 替换两行之间出现的每个匹配串,#,#代表行号
添加
- A 在一行后添加文本
- a 光标字符后添加文本
- i 光标字符前添加文本
- o 在光标 下方 打开新的一行,这个命令会使您进入插入模式
- O 在光标 上方 打开新的一行,这个命令会使您进入插入模式
删除
- D 当前行,删除光标以及光标后的
- dd 删除当前行
- d2d 从当前行开始,删除2行
- dw 从关标处删除至下一个单词的起始处
- d2w 删除2个单词
- de 从关标处删除至单词末尾
- d$ 从当前关标删除到行末
- x 删除当前字符
- X 删除关标所在位置的前一个字符
删除实践
if (message == "sesame open")
# 假设关标在sesame的a上
# dw(理解为 delete word) 删除'ame␣'
# diw(理解为 delete inside word) 删除'sesame'
# daw(理解为 delete a word) 删除'sesame␣'
# diW 会删除'"sesame'
# daW 会删除'"sesame␣'
# di" 会删除'sesame open'
# da" 会删除'"sesame open"'
# di( 或 di) 会删除'message == "sesame open"'
# da( 或 da) 会删除'(message == "sesame open")'
跳转定位
- G 跳转到结尾
- gg 跳转到开头
- ctrl-g 显示当前编辑文件中当前光标所在行位置以及文件状态信息
- 5G 定位到第5行
- 5| 定位到第5列
- vim -c 'normal 5G5|' text.txt 直接定位到第5行第5列
修改
- C 则相当于 c$,删除到行尾然后进入插入模式。
- c 加动作来进行修改(cc 修改整行)
选择
- V 选择行
- v 选择字符
撤销
- u 撤销最后执行的命令
- U 撤消在最后一行中所做的改动
- ctrl-r(先按下ctrl键,接着按r键) 撤消掉撤消命令
复制
- 使用操作符 y 复制文本,使用 p 粘贴文本(v选中,y复制,p粘贴)
- y 当作操作符来使用。例如:yw 可以用来复制一个单词
粘贴
- p 最后一次删除的内容置入光标所在行的下一行(比如:先dd,然后输入p,粘贴)
修改
- ce 改变文本直到一个单词的末尾
搜索
- / 输入 / 加上一个字符串可以用以在当前文件中查找该字符串
- n 向下寻找
- N 向上寻找
- ?代替/ 逆向查找,这样n就是向上寻找
- ctrl-o 回退到之前的位置
- ctrl-i 回到较新的位置
- % 可以查找配对的括号 )、]、} 比如光标放在(,然后按%
忽略大小写查找
-
:set ic Ignore Case,忽略大小写
-
:set hls is
- 'ic' 'ignorecase' 查找时忽略字母大小写
- 'is' 'incsearch' 查找短语时显示部分匹配
- 'hls' 'hlsearch' 高亮显示所有的匹配短语
-
在选项前加上 no 可以关闭选项 比如 :set noic 禁用忽略大小写
在vim内执行外部命令
- :!然后紧接着输入一个外部命领,比如:!ls -la
保存文件
- :w FILENAME 将对文件的改动保存到新文件中,以 FILENAMEj 为文件名保存整个文件
- 选择性保存 先按V,上下移动,选中,然后按: 再输入w FILENAME
提取和合并文件
- 光标放置待插入位置,输入: FILENAME(这是文件名),就会把FILENAME中的内容提取到光标处
- 提取外部命令的输出。比如::r !ls 可以读取 ls 命令的输出,并把它放置在光标下面
打开新的一行输入
- o 在光标 下方 打开新的一行,这个命令会使您进入插入模式
- O 在光标 上方 打开新的一行,这个命令会使您进入插入模式
命令补全
- 使用 CTRL-D 和 可以进行命令行补全。 当输入 : 命令时,按 CTRL-D 可以查看可能的补全结果
.vimrc进阶配置
基本配置
set enc=utf-8
set nocompatible # 关闭 vi 兼容模式
source $VIMRUNTIME/vimrc_example.vim
备份和撤消文件
set nobackup
if has('persistent_undo')
set undofile
set undodir=~/.vim/undodir
if !isdirectory(&undodir)
call mkdir(&undodir, 'p', 0700)
endif
endif
鼠标支持
if has('mouse')
if has('gui_running') || (&term =~ 'xterm' && !has('mac'))
set mouse=a
else
set mouse=nvi
endif
endif
中文支持
set fileencodings=ucs-bom,utf-8,gb18030,latin1
字体配置
if has('gui_running')
set guifont=Courier_New:h11:cANSI
set guifontwide=新宋体:h11:cGB2312
endif
只要屏幕能滚动,关标就无法移动到上面的4行和最下面4行
# set scrolloff=5 会导致只要屏幕能滚动,关标就无法移动到上面的4行和最下面4行
set scrolloff=1 # 可以减少干扰
minpac安装
git clone https://github.com/k-takata/minpac.git ~/.vim/pack/minpac/opt/minpac
if exists('*minpac#init')
# Minpac is loaded.
call minpac#init()
call minpac#add('k-takata/minpac', {'type': 'opt'})
# Other plugins
endif
if has('eval')
# Minpac commands
command! PackUpdate packadd minpac | source $MYVIMRC | call minpac#update('', {'do': 'call minpac#status()'})
command! PackClean packadd minpac | source $MYVIMRC | call minpac#clean()
command! PackStatus packadd minpac | source $MYVIMRC | call minpac#status()
endif
最近使用的文件
安装插件,然后执行:PackUpdate
# Other plugins
call minpac#add('yegappan/mru')
if !has('gui_running')
" 设置文本菜单
if has('wildmenu')
set wildmenu
set cpoptions-=<
set wildcharm=<C-Z>
nnoremap <F10> :emenu <C-Z>
inoremap <F10> <C-O>:emenu <C-Z>
endif
endif
输入 :emenu 再按tab就可以看到最近打开的文件
已经存在交换文件
错误提示Swap file "Desktop/logs/.text.txt.swp" already exists!,有两种原因:
- 上次编辑这个文件时,发生了意外崩溃
- 已经在使用另外一个vim会话编辑这个文件了 错误提示 process ID 后面没有"STILL RUNNING"这样的字样,就是情况1,其他就是情况2 针对情况1,可以
vim -r text.txt恢复上次的编辑状态,确认之后,根据提示,删除交换文件。
多文件打开的方式
vim *.txt *.log # 暂时只打开第一个文件
:args 要编辑的多文件列表
:args *.xml 使用xml文件替换参数列表
:next(:n) 打开下一个文件
:Next(:N)或者:previous(:prev) 打开上一个文件
:first 回到列表中的第一个文件
:last 打开列表中的最后一个文件
工作流:
:set autowrite 告诉vim在切换文件时自动存盘
:n|normal ggP 切换到下一个文件并执行正常模式命令ggP,跳转到文件开头并粘贴
:向上箭头 执行上面的命令
缓冲区:
:ls 查看缓冲区列表(当前活跃%a 最近的缓冲区# 缓冲区已被修改+)
:buffer(:b) 编号 跳转到编号对应的缓冲区。比如:b3 如果当前缓冲区已被修改但为保存,会报错,命令后加!会放弃修改,比如b!2
:bdelete(:bd) 编号 删除对应的缓冲区。:bd 8
:bnext(:bn) 下一个
:bprevious(:bp) 上一个
:blast 最后一个
control ^ 最近的两个缓冲区之间来回切换
多窗口编辑
-
水平分割
- :split(:sp) 当前窗口分隔开,当前编辑的文件在两个窗口里都显示
- :split(:sp) 文件名 分割窗口并打开该文件
-
竖直分割
- :vsplit(:vs)
control w w 跳转下一个窗口
:new 或 control w n 打开新窗口
:close 或 control w c 关闭当前窗口,最后一个无效
:quit 或 control w q 退出当前窗口,最后一个则退出vim
:only 或 control w o 只保留当前
control w = 所有窗口大小相等
control w 10_ 设置高度为10
control w 10| 设置宽度为10
control w + 增加窗口高度,默认1
control w - 减少窗口高度
control w > 增加窗口宽度
双窗口比较
- vimdiff .vimrc ~/.vimrc
多标签页
:tabs 展示标签列表
:tabnew 或 :tabedit 打开新的标签页。后跟文件名,新的标签打开这个文件
:tabclose 关闭当前标签
:tabnext 下一个标签页
:tabprevious
:tabfirst
:tablast
:control-w T 当前窗口变成一个新标签页
NERDTree插件
安装
.vimrc文件中增加
call minpac#add('preservim/nerdtree')
然后执行PackUpdate,如果一直失败,也可以直接克隆git clone https://github.com/preservim/nerdtree.git ~/.vim/pack/minpac/start/nerdtree
使用
- NERDTreeToggle 左侧打开文件浏览/管理窗口,也可以关闭
- go 浏览文件,光标不会跳转到文件所在窗口
- i 打开文件到新的水平分割窗口
- s 打开文件到新的竖直分割窗口
- t 打开文件到新的标签页
- m 出现菜单,可以添加、删除、更名
- ? 查看帮助信息
最后
本文主要介绍了vim的一些基本用法以及基本配置,要想记忆深刻还的自己多加练习,刻意使用。使用vim文本编辑器还有很多好处:
- 高度可定制,可以根据自己的需求调整文本编辑器的外观、行为和功能,使其适应你的工作风格
- 强大的编辑,支持多级撤销和重做、自动补全、宏录制、代码折叠、语法高亮等
- 高效的快捷键,Vim 使用模式来管理编辑过程,包括命令模式、插入模式和可视模式
- 跨平台支持,可以在多个操作系统上运行,如 Linux、macOS 和 Windows
- 强大的插件生态系统,根据自己的需求选择和安装各种插件,如语法检查、版本控制集成、代码片段等
- 轻量级和快速启动,启动速度非常快,占用的系统资源也比较少