前言
本文是笔者使用 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删除光标所在的单词;
在你需要对一个单词,句子或者段落进行操作时这个形式的快捷键非常常用。由于 cw,dw 等命令需要在一个单词的开头使用时才能对整个单词进行操作,为了使用这些命令你可能得先通过 b,w 等快捷键移动到开头,而 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.
如果哪里写错了或者有问题欢迎评论或者私聊指出,以上。