来自wechat python
从 2009 年开始,我就一直把 Vim 当作个人主要(惟一)文本编辑器。在过去的这些年,我学到了不少好用的 Vim 技巧,它们令我感受相见恨晚,由于它们极大地提升了个人文本编辑效率。在这篇博文中,我想与大家分享其中的最精华部分。 git
Vim 新手一般会收到的第一条建议是“使用 h/j/k/l 键代替方向键!”在很长一段时间,我都忽略了这一条建议由于我以为那很荒谬:我究竟为什么非得那么作?然而,有天我仍是决定试一试,而且一试便一发不可收拾了。虽然我花了数日时间才适应了这条建议,但是一旦上手,我才恍然大悟。h/j/k/l 几个键直接处于本位列上,因此你的手不用(像在使用方向键时那样)移动太远的距离。这不只节省了键盘操做时间,提升了效率,并且让个人双手得以更加放松。我相信这是治好我手腕疼的因素之一。另外一个因素是,我在手下面垫了一块腕垫。 vim
若是你想学会使用 h/j/k/l 键代替方向键,那我建议你要么关闭方向键要么把它们重映射为其余更有用的指令。另外一个不使用方向键的好处是,你将会适应更好的移动指令,如 f/F/t/T,w/W/b/B,0/^/$,或者搜索指令。使用这些指令,比起简单地按下方向键或者 h/j/k/l键,你的输入效率会更高。在 Vim 中,单键指令是一种反面模式。 api
像不少用户同样,我也使用绝对行号,好吧,全部用户都使用它。然而,有天我偶然发现了这篇文章,令我陷入思考:万一相对行号更好用呢?我决定用用看。而后,就像 Ben 在这个视频中所言,绝对行号在个人生活中就是一个谎话。Vim的正宗用法是启用相对行号。 浏览器
启用相对行号以前,我建议把下列命令行添加到 .vimrc 文件中:服务器
set number session
set relativenumberapp
这两个命令行一块儿,使 Vim 对当前行显示绝对行号,而对其它行显示相对行号。 frontend
接下来,我要说明相对行号的用处。不少 Vim 命令都有一个数字做为前缀。例如,要移动当前行如下的 10 行,能够用 10j。要移动当前行以上的 4 行,使用 4k。要对当前行及如下 2 行缩进,使用 >2j。明白了吧?有了相对行号,其它行(距离当前行)有多远就一目了然了。若是你使用的是绝对行号,你要知道两行之间相距多少行就必须作口算,把两个行号(可能很大)相减。使用相对行号就能够减小这种数学运算。 ssh
同时,你仍然可使用绝对行号。例如,你编译了一个源文件,而后编译器告知第 943 行有一个语法错误,这时你能够用 943G 或 :943<CR> 定位到这一行。
Vim 的一个很是好的特性是,你能够设置折行功能。不少用户包括我会把 j/k 键重映射为 gj/gk,使得按下它们时,光标按虚拟行而不是按物理行移动。然而,这种重映射影响了前文提到的计数功能。为了弥补这一不足,基于这篇stackoverflow.com的博文,咱们从新进行以下映射:
noremap <silent> <expr> j (v:count == 0 ? 'gj' : 'j')
noremap <silent> <expr> k (v:count == 0 ? 'gk' : 'k')
这样以后,当遇到没有行号的行时,gj/gk 命令会使光标按虚拟行移动,而当遇到有行号的行时,光标则按物理行移动。这与相对行号一块儿,堪称绝配。
在很长一段时间里,我都是使用 GVim,不涉及 Vim 终端。由于它更炫,与窗口环境及集成度更高,等等。后来,我仍是发现了 Tmux,它极大地改善了个人工做流程。简言之,经过它,你能够在一个终端中打开多个独立的会话(session),在每一个会话中又能够打开多个窗口(window),而每一个窗口又能够分为多个窗格(pane)。看看这个截屏感觉一下吧。
Tmux 也让我进退两难:怎么把它跟 GVim 配合使用呢?Tmux 是一款终端应用,而 GVim 则是一款独立的 GUI 应用。幸运的是,经过设置,Vim 几乎能够具有与 GVim 同样的功能。最好用的插件是 CSApprox。它能够令 GVim 专属的配色方案轻松地应用于 Vim 终端上。还有其余不少设置帮助我转移到 Vim 终端上工做,参考个人 .vimrc 文件。
Tmux+Vim 组合的最大优点是,它能够令你在一个终端就能够完成几乎全部的开发工做。例如,你能够经过 ssh 远程登陆到一个服务器并在那里作开发,这样你也能够在不一样地方甚至不一样电脑上无缝对接以前的工做。另外一个好处是,服务器的运行速度一般要比笔记本或台式电脑快。你甚至可能在一台拥有海量核芯与内存的服务器上作开发,这取决于你公司的预算。这样的体验简直会让人流连忘返。
若是你从未用过 Tmux,那我建议你至少试它一试。它真是一个很棒的工具。万事开头难,我在这里详述了 Tmux 的配置过程,给你作个指南。仔细看看,或许你能从中学到一些技巧帮你调整并改善工做流程。例如,在该文中我介绍了一种在 Vim 与 Tmux 之间实现无缝导航的方法。
Vim 的一个独特之处是它能让你能够经过一门语言与之对话。例如,Vim 命令中有相似动词的 d(删除)或 y(复制),相似名词的 b(括号)或 s(句子),以及相似形容词的 i(内部的)或 a(所有的)。你能够把它们自由组合,所以,dib 表明删除括号内的全部文本,yap 表明复制当前的段落。在你学会这门简单语言以后,你不用再思考删除一个段落须要作什么,只需简单地输入 dap。不少人以为 Vim 很难掌握,就是由于他们不习惯用这种方式来看待 Vim。
更难能难得之处是 Vim 语言是可扩展的。事实上,用户能够在 Vim 语法的基础上建立本身的“动词”和“名词”(Vim 语法中的操做和行动/文本对象)。下面介绍一些我平常必备的好用插件。
tcomment-vim——执行代码注释操做:gc。例如,为一个段落注释,能够用 gcap(go comment a paragraph);为当前行及如下 5 行注释,能够用 gc5j(感谢有相对行号!)。
vim-sort-motion——执行排序操做:gs。例如,在 Python 中,对光标所在处的 imports 进行排序,能够用 gsip(go sort inside paragraph)。
ReplaceWithRegister——执行替换操做:gr。执行替换文本操做不会覆盖寄存器的内容。例如,要用默认的寄存器替换当前单词,能够用 griw(go replace inner word )。gr 操做还能够与点号命令配合(.,重复上一次动做),这使它更加高效。它是我最喜欢的操做之一。
targets.vim——添加许多有用的文本对象。例如,daa 用于删除一个函数调用的一个参数(deletes an argument of a function call),ci$ 用于改变美圆符号之间的文本(在 LaTeX 中很是有用)。该插件的另外一个特色是,即便光标未落在所欲编辑的文本对象之处,用户也能够经过该插件使用该文本对象。例如,用 di”(delete inside quotes)能够删除距离光标最近的双引号内的内容。
vim-indent-object——对当前的缩进执行操做。例如,将当前代码块向左移动,能够用 <ii(left-shift inside indent)。这对 Python 来讲颇有用,由于它用空格标识代码块,而不是大括号。
vim-surround——对周围环境操做。例如,cs”‘ 表示用单引号替换周围的双引号,而 dsb 则表示删除周围的括号。
固然,你也能够把在以上插件中说起的操做与行动结合起来使用。例如,在一个 Python 列表中每一项都在单独成行,为了对列表排序,可使用 gsii(go sort inside indent)。
有些简单的文本对象甚至能够不借助插件来定义。例如,对一整个文件进行操做,能够把下列这行代码加入 .vimrc:
onoremap af :<C-u>normal! ggVG<CR>
因而,要复制整个文件的内容(更准确地讲,整个缓冲器),可使用 yaf(yank a file)。
在 Vim 中打开一个文件,能够用 edit 或者 tabnew 命令,分别在当前缓冲器或新标签页中打开该文件。这种方式的一个缺点是,当你打开的是一个内嵌有不少目录及文件的大工程时,就会很是慢。例如,要编辑文件 frontend/scripts/js/view/viewer.js,你就得敲入整个路径。嗯,必需要有更好的方法……
幸运的是,确实有!经过使用模糊查找器,如 Command-T。如今只须要简单地启用查找器(输入 ,t),敲入 fsviewer(f 与 s 是文件路径的一部分),就能够在当前窗口或者新标签页中瞬间打开上述文件。一旦你知道本身工程的路径结构或文件名,使用模糊查找器能够极大地提升文件的打开速度。
咱们常常要列出全部包含给定短语或单词(如一个函数的名称)的文件。在我刚开始使用 Vim 时,我会转到终端而后输入 gvim grep –r FUNC | cut –d: -f1 从而在 GVim 中打开找到的文件。然而,为什么不把这个简单的任务交给 Vim 来作呢?
你既能够用 Vim 内置的 grep 命令,也能够用一款更高级的插件,如 vim-grepper,它能让用户选择一种检索工具(grep,git grep 或 ag)并选择怎样显示结果。例如,用户能够映射 ,/ 来在一个工程中检索全部包含某个单词的文件,或者用 ,∗ 在整个项目范围内检索包含光标所在单词的文件。在检索过程结束后,会弹出一个包含目标文件的窗口,Vim 用户能够直接打开这些文件。
若是你在使用一款文本编辑器,最重要的是尽量常用它。毕竟,当你已经了解 Vim 了,为什么还要去学另外一款编辑器呢?例如网页上的 textarea forms?若是你在工做中到处使用 Vim,甚至还能够把它的优势发挥在以前想像不到的地方。
例如,在火狐浏览器中,有一个插件叫 It’s All Text!,该插件能让用户在 Vim 中编辑 textarea 元素。这为用户使用本身最爱的的编辑器编辑维基网页,写博文,提交 bug 报告等活动提供了便利。对 Vim 用户来讲,这意味着他们能够尽情享受其语法高亮、拼写检查、字典补全、代码片断以及其余功能。
又如,在雷鸟邮件客户端中也有一个 It’s All Text! 插件。比起内置的编辑器,使用该插件可让你写邮件写得更快、更温馨。
不少终端应用也支持把 Vim 做为外部编辑器使用。例如,你能够把 Midnight Commander设置为从 Vim 打开文件。Vim 的另外一个难得之处表如今用版本控制系统,如 Git,写提交说明的时候。你厌倦了排印错误吗?那就在 Vim 中设定拼写检查。你想经过使用 Ctrl+n 让出如今 diff 文件中的单词能自动补全吗?那就与 -verbose 参数一块儿提交吧。它能够把整个 diff 文件复制到 Vim 中,所以你就可使用字典补全功能,就像函数名那样。老板不再用担忧你写提交说明了。
最后,我要提的是另外一款火狐浏览器插件,Vimperator。它能让用户在浏览网页的时候也能够运用 Vim 的原则,使浏览器用起来像 Vim 。例如,不须要动鼠标,你就能够快速地在网页上打开链接、复制文本或者制做书签稍后再返回。Vimperator 甚至能让你在一个相似 .vimrc 的文件中配置火狐浏览器。这个是个人版本。
假设你正在写 Pyhton 代码,而且你要在当前文件中执行单元测试。或者,假设你正在写 Latex 文档,为了查看结果你得进行编译。其中一个办法是打开一个终端,而后执行测试或进行编译。然而,这并非一种高效的办法,由于它形成你工做流程的中断。
一种较好的方式是利用 Vim 能执行外部命令的特性。例如,利用下列的自动命令,你只须要简单的按下 F9 就能够为你的 Python 代码保存并执行当前编辑好的单元测试:
au FileType python nnoremap <buffer> <F9> :wa<CR>:!clear; nosetests %<CR>
在 Tmux 中运行 Vim 的另外一个好处就是,使在 Tmux 窗格或窗口执行外部命令成为可能。例如,你能够将当前的 Tmux 窗口分为两个窗格,其中一个用于编辑文件,另外一个用于执行测试,而不须要在它们之间切换。为了让你体验一下个人工做流程,下面我作个示范。我工做中使用了双显示器,并作了相应设置。对于一个工程,我打开两个终端,分别在其中打开一个 Tmux 控制台,而后令每一个显示器中分别显示一个终端。这时,我能够在第一个 Tmux 控制台上写代码,若是我想执行测试,生成文档,或用 lint 相似的工具检查代码,我只需经过 Vim 发送一条命令到第二个 Tmux 控制台,测试就会在第二个显示器中进行。这样,我就能够在第一个显示器的分割窗口中写代码和测试文档,在第二个显示器中运行 git 命令、执行测试等。我还对 Fluxbox进行设置,从而能够用 Ctrl+Alt+h/l 在两个显示器之间切换。这是个人配置文件。此外,还有更精彩的部分哦!那就是以上介绍的工做流程甚至适用于经过 SSH 登陆到远程服务器运行 Tmux 的状况。
Vim 是高度可扩展的。你能够根据我的喜爱对它进行配置,能够为你常用的动做添加映射和命令。在过去的时光中,我逐渐完善了我本身的 .vimrc 文件,其中包含了不少有用的设置、映射。如下是其中的一部分,不过,我建议大家看完个人整个 .vimrc 文件。
" Quickly select the text that was just pasted. This allows you to, e.g.,
" indent it after pasting.
noremap gV `[v`]
" Stay in visual mode when indenting. You will never have to run gv after
" performing an indentation.
vnoremap < <gv
vnoremap > >gv
" Make Y yank everything from the cursor to the end of the line. This makes Y
" act more like C or D because by default, Y yanks the current line (i.e. the
" same as yy).
noremap Y y$
" Make Ctrl-e jump to the end of the current line in the insert mode. This is
" handy when you are in the middle of a line and would like to go to its end
" without switching to the normal mode.
inoremap <C-e> <C-o>$
" Allows you to easily replace the current word and all its occurrences.
nnoremap <Leader>rc :%s/<<C-r><C-w>>/
vnoremap <Leader>rc y:%s/<C-r>"/
" Allows you to easily change the current word and all occurrences to something
" else. The difference between this and the previous mapping is that the mapping
" below pre-fills the current word for you to change.
nnoremap <Leader>cc :%s/<<C-r><C-w>>/<C-r><C-w>
vnoremap <Leader>cc y:%s/<C-r>"/<C-r>"
" Replace tabs with four spaces. Make sure that there is a tab character between
" the first pair of slashes when you copy this mapping into your .vimrc!
nnoremap <Leader>rts :%s/ / /g<CR>
" Remove ANSI color escape codes for the edited file. This is handy when
" piping colored text into Vim.
nnoremap <Leader>rac :%s/<C-v><Esc>[(d{1,2}(;d{1,2}){0,2})?[m|K]//g<CR>
最后这点也很重要,我要提一下 vim-argwrap 插件。它可让你快速折叠或展开函数参数(表)、列表或字典。例如,你能够用它把下列代码
decompiler = Decompiler(api_url=args.api_url, api_key=args.api_key)
转换为
decompiler = Decompiler(
api_url=args.api_url,
api_key=args.api_key
)
反之亦然,仅须要做一个简单映射。
0 跳到行首,^ (shift 6)跳到行首第一个不是空白的字符上 ,$ 到行尾 ctrl + f (forward) ctrl + b (backward) 分别向下 / 上卷动一屏 crtl + d (down) ctrl + u (up) 分别向下 / 上卷动半屏