入坑 VIM 一周年总结

2,593 阅读7分钟

前言

本文是笔者使用 VIM 一年后的个人总结,包括接触到 VIM 的故事,入门建议,自己常用的 VIM 快捷键以及 ideavim 的配置分享,希望可以帮助读者更好的入门与使用 VIM。

我与 VIM

第一次接触到 VIM 是在学习 Linux 的过程中,按照教程中的命令使用 VIM 编辑某个文件,当时只觉得这个编辑器反人类,各种奇奇怪怪的模式与命令搞得我头晕眼花。

去年的这个时候,VIM 的作者 Bram Moolenaar 离世,通过一篇偶然看到的文章了解到 Bram Moolenaar 与 VIM 的故事后,我决定学习由这位伟大的程序员创造的编辑器 —— VIM。

一年后的今天,VIM 已经成为了我日常开发中不可或缺的一部分:浏览器,笔记,IDE...

如何入门

很多人都提到 VIM 的学习曲线非常陡峭,但在我自己开始入门的过程中似乎并没有遇到太多难以克服的困难,反而当你逐渐开始实际使用这款编辑器的时候并遇到觉得 ”别扭“ 的点的时候,你就可以通过学习更多的快捷方式与配置,让 VIM 逐渐适配你的个人习惯而不是强制自己使用不习惯的方式。

回到入门,VIM Tutor 是我最开始入门时使用的一种方式,它是一个内置在 VIM 中的经典教程。

如果你使用 VIM 则可以使用以下命令来打开:

vimtutor

如果你使用的是 Neovim 则可以在 Neovim 的 Normal 模式下输入下面的命令来打开:

:Tutor

VIM Tutor 提供了一种交互式的实践教程,大概需要花费你 30 分钟左右的时间,它包含了 VIM 中最常用的快捷键以及模式的使用方式。

当你熟悉并记住了 VIM Tutor 中大部分的内容,我相信你已经可以在 VIM 中 “存活” 下来了,接下来你可以就阅读一些介绍 VIM 使用的博客,这些博客中通常包含一些在 VIM Tutor 以及一些基础教程中不会介绍到但非常实用的快捷键,你可以通过这种方式来积累你自己的快捷键库。

下面是一些在我入门时帮助到我的优秀博客,你可以参考着阅读:

如果你觉得这些博客不够官方,想通过一种更正式的方式来进行学习,那我建议你可以阅读 VIM 的用户手册,它是由 Bram Moolenaar 及社区贡献者编写的,非常的全面与细致,在 VIM 或者 Neovim 的 Normal 模式下运行下面的命令来打开:

:help user-manual

常用快捷键

这个部分主要分享一些我在使用 VIM 时常用的快捷键,希望可以对你有帮助。

  • ci":删除冒号中间的所有内容并进入 Insert 模式;

当你需要对各种形式的冒号,括号中的内容进行操作时,这种形式的快捷键非常的方便;你还可以使用其他 Operator 来构建这种形式的快捷键,例如:

  • yi(:复制小括号内的所有内容;
  • va':选中单引号以及单引号中的所有内容进入 Visual 模式;
  • di<:删除尖括号内的所有内容;

为了方便理解与记忆,这里的 i 代表 inner,也就是对引号或者括号内的内容进行操作,a 代表 around 也就是对引号或者括号周围的内容进行操作。


  • daw 删除光标所在的单词;

在你需要对一个单词,句子或者段落进行操作时这个形式的快捷键非常常用。由于 cwdw 等命令需要在一个单词的开头使用时才能对整个单词进行操作,为了使用这些命令你可能得先通过 bw 等快捷键移动到开头,而 daw 形式的命令只需要你的光标在这个单词内即可对整个单词进行操作,非常方便。类似形式的快捷键有:

  • caw:删除一个单词及其后面的空格并进入 Insert 模式;
  • das:删除一个句子;
  • cap:删除一个段落并进入 Insert 模式;

  • zz:将当前行滚动到屏幕的中央位置;
  • zt:将当前行滚动到屏幕的顶部位置;
  • zb:会将当前行滚动到屏幕的底部位置;

  • H:将光标移动到屏幕的顶部行;
  • M:将光标移动到屏幕的中间行;
  • L:将光标移动到屏幕的底部行;

  • <C-y>:将当前窗口的内容向上滚动一行,同时保持光标位置不变;

  • <C-e>:用于将当前窗口的内容向下滚动一行,同时保持光标位置不变;


  • <C-w>v:垂直分割当前窗口;
  • <C-w>s:水平分割当前窗口;
  • <C-w>w:在窗口间跳转;
  • <C-w>c:关闭当前窗口;
  • <C-w>h:将焦点切换到左侧的窗口;
  • <C-w>j:将焦点切换到下方的窗口;
  • <C-w>k:将焦点切换到上方的窗口;
  • <C-w>l:将焦点切换到右侧的窗口;

IDEAVIM 配置

由于我是一个 Jetbrains 用户,在学习了 VIM 后通过配置 ideavim 插件让我在 IDE 中同时拥有了 Jetbrains IDE 和 VIM 的便捷,下面是我根据个人习惯配置出的一套 ideavim 的配置,希望可以为你提供一些参考:

你也可以在这里 github.com/justlorain/… 找到它

" vim 模式开关
nmap <leader>vim <Action>(VimPluginToggle)

" --- Basic Configuration ---

" leader key
let mapleader = " "

" 在行首/行尾时按 h/l 可以移动到上一行/下一行
set whichwrap=b,s,<,>,h,l,[,]

"" visual shifting (builtin-repeat)
vnoremap < <gv
vnoremap > >gv

" 上下滚动边距行差
set scrolloff=5

" 搜索
set incsearch
set nohls
set ic
set smartcase
nnoremap <leader>ss :set invhlsearch<CR>

" 映射剪切板
set clipboard+=unnamed

" 显示行号
set number
" 设置相对行号
set relativenumber

" Don't use Ex mode, use Q for formatting.
map Q gq

" --- Plugin Configuration ---

" Highlight copied text
Plug 'machakann/vim-highlightedyank'
" Commentary plugin
Plug 'tpope/vim-commentary'
" vim-surround
set surround
" easymotion
set easymotion
" nerdtree
set NERDTree
nnoremap <leader>nf :NERDTreeFind<CR>
" quickscope
set quickscope
let g:qs_highlight_on_keys = ['f', 'F', 't', 'T']
" which-key
set which-key
set notimeout

" --- Coding Configuration ---

" 显示文件结构
let g:WhichKeyDesc_FileStructure = "<leader>fs FileStructure"
nmap <leader>fs <action>(FileStructurePopup)
let g:WhichKeyDesc_FindFile = "<leader>ff FindFile"
nmap <leader>ff <action>(GotoFile)
" Tab 关闭
let g:WhichKeyDesc_CloseCurrentTab = "<leader>xx CloseCurrentTab"
nmap <leader>xx <action>(CloseContent)
let g:WhichKeyDesc_CloseOtherTabs = "<leader>xo CloseOtherTabs"
nmap <leader>xo <action>(CloseAllEditorsButActive)
let g:WhichKeyDesc_CloseAllTabsOnTheLeft = "<leader>x[ CloseAllTabsOnTheLeft"
nmap <leader>x[ <action>(CloseAllToTheLeft)
let g:WhichKeyDesc_CloseAllTabsOnTheRight = "<leader>x] CloseAllTabsOnTheRight"
nmap <leader>x] <action>(CloseAllToTheRight)
" 页面滚动
let g:WhichKeyDesc_EditorScrollUp = "<C-k> EditorScrollUp"
nmap <C-k> <action>(EditorScrollUp)
let g:WhichKeyDesc_EditorScrollDown = "<C-j> EditorScrollDown"
nmap <C-j> <action>(EditorScrollDown)
" 到定义或引用处
let g:WhichKeyDesc_GotoDeclaration = "gd GotoDeclaration"
nmap gd <action>(GotoDeclaration)
" 到使用处
let g:WhichKeyDesc_FindUsages = "<leader>gr FindUsages"
nmap <leader>gr <action>(FindUsages)
" 到父类
let g:WhichKeyDesc_GotoSuperMethod = "<leader>gs GotoSuperMethod"
nmap <leader>gs <action>(GotoSuperMethod)
" 到实现处
let g:WhichKeyDesc_GotoImplementation = "<leader>gi GotoImplementation"
nmap <leader>gi <action>(GotoImplementation)
" 跳转 method
let g:WhichKeyDesc_MethodUp = "<M-k> MethodUp"
nmap <M-k> <Action>(MethodUp)
let g:WhichKeyDesc_MethodDown = "<M-j> MethodDown"
nmap <M-j> <Action>(MethodDown)
let g:WhichKeyDesc_ExtractMethod = "<leader>em ExtractMethod"
vmap <leader>em <Action>(ExtractMethod)
" 跳转 tab
let g:WhichKeyDesc_PreviousTab = "<M-h> PreviousTab"
nmap <M-h> <action>(PreviousTab)
let g:WhichKeyDesc_NextTab = "<M-l> NextTab"
nmap <M-l> <action>(NextTab)
" 翻译
let g:WhichKeyDesc_EditorTranslate = "<leader>t EditorTranslate"
vmap <leader>t <action>($EditorTranslateAction)
" Cursor back
let g:WhichKeyDesc_Back = "<C-i> Back"
nmap <C-i> <action>(Back)
" Cursor forward
let g:WhichKeyDesc_Forward = "<C-o> Forward"
nmap <C-o> <action>(Forward)
" 打开最近项目
let g:WhichKeyDesc_OpenRecentProject = "<leader>p OpenRecentProject"
nmap <leader>p <action>($LRU)
" 替换
let g:WhichKeyDesc_ReplaceInFile = "<leader>rif ReplaceInFile"
nmap <leader>rif <action>(Replace)
vmap <leader>rif <action>(Replace)
let g:WhichKeyDesc_ReplaceInProject = "<leader>rip ReplaceInProject"
nmap <leader>rip <action>(ReplaceInPath)
vmap <leader>rip <action>(ReplaceInPath)
" 查找
let g:WhichKeyDesc_FindInFile = "<leader>fif FindInFile"
nmap <leader>fif <action>(Find)
vmap <leader>fif <action>(Find)
let g:WhichKeyDesc_FindInProject = "<leader>fip FindInProject"
nmap <leader>fip <action>(FindInPath)
vmap <leader>fip <action>(FindInPath)
" 新建行
let g:WhichKeyDesc_NewLine = "<M-o> NewLine"
nnoremap <M-o> :normal o<CR>
" 打断点
let g:WhichKeyDesc_ToggleLineBreakpoint = "<leader>bb ToggleLineBreakpoint"
nmap <leader>bb <action>(ToggleLineBreakpoint)
" 查看表达式类型
let g:WhichKeyDesc_ExpressionTypeInfo = "<leader>et ExpressionTypeInfo"
nmap <leader>et <action>(ExpressionTypeInfo)
" 查看方法形参
let g:WhichKeyDesc_ParameterInfo = "<leader>et ParameterInfo"
nmap <leader>pp <action>(ParameterInfo)
" 最新文件
let g:WhichKeyDesc_RecentFiles = "<leader>ee RecentFiles"
nmap <leader>ee <action>(RecentFiles)

sethandler <C-j> a:vim i:ide
sethandler <C-k> a:vim i:ide

总结

以上就是本篇文章的所有内容了,希望这个个人总结可以帮助你更好的使用 VIM。

再次感谢 Bram Moolenaar 为我们带来这么棒的软件,R.I.P.

如果哪里写错了或者有问题欢迎评论或者私聊指出,以上。

参考列表