掌握 Vim:提高编辑效率的必备技巧

462 阅读6分钟

前言

最近看到很多大佬用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!,有两种原因:

  1. 上次编辑这个文件时,发生了意外崩溃
  2. 已经在使用另外一个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
  • 强大的插件生态系统,根据自己的需求选择和安装各种插件,如语法检查、版本控制集成、代码片段等
  • 轻量级和快速启动,启动速度非常快,占用的系统资源也比较少