linux · vim · 2015-01-25 · yuex

初学 Vim 时,我们都有这样的经历 ——“ 哇,怎么退出?!”。在尝试了 <Ctrl-C><Esc> 全都没有效果时,才会注意左下角状态栏的小提示:

Type :quit<Enter> to exit Vim

在小心翼翼地键入这个命令完成退出之后,我们欣喜地自认为已经掌握了 Vim 的退出之法。然而,当我们在 Vim 中进行了一番探索、受了一些嘲弄、做了一些不听使唤的修改后,虔诚地键入 :quit,准备结束这次不成功的尝试,舒缓一下心神,重新来过之时,Vim 又会无情地用一行血红色的小字警告你:

E37: No write since last change (add ! to override)

很多人的 Vim 之旅就此便戛然而止。许多年之后,那些并未放弃的人们,早已掌握了 Vim 中的大多数奥妙,但时不时地,仍然会在完成一些快速修改,准备退出进行一下验证或者修改下一个文件的时候,遭遇 Vim 的 E37 嘲弄。Vim 仿佛是在用这种方式训斥你 ——“ 你,图样图森破,上台拿衣服 ”。虽然,无数次地,我们在论坛上、bbs 里,义正言辞地强调 “WYSIWYG,图样图森破;Vim,时尚时尚最时尚 ”,然而在夜深人静的时候,我们扪心自问,深深明白,Vim 还有很多地方不够完美 1

所以,在这篇文章里,我要展示一个我在用的 Vim 配置,可以让我们在退出的时候,不再遭受 E37 的痛苦折磨。闲言少叙,直接上相关代码。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
function SmartQuit()
    if !&modified
        exec "quit"
    else
        redraw
        echohl WarningMsg
        echo "Buffer changed! [^W]w [^S]x [^B^N]q!: "
        echohl None

        let cmd = ""
        let ret = nr2char(getchar())

        if ret == "\<C-b>" || ret == "\<C-n>"
            " BOOM! NUKE!
            let cmd = "q!"
        elseif ret == "\<C-w>"
            let cmd = "w"
        elseif ret == "\<C-s>"
            let cmd = "x"
        endif

        redraw
        if !empty(cmd)
            exec cmd
        endif
    endif
endfunction

nnoremap <unique> <C-c> :call SmartQuit()<CR>

这段代码很简单,我们将 <C-c> 映射到调用 SmartQuit() 函数。而这个函数会检查当前文件是否已经修改过。若没有修改,则直接退出;若有修改,则会提示你进行保存(<C-w>)、保存退出(<C-s>)、强制退出(<C-b> 或者 <C-n>)、或者取消操作(<C-c>)。最后根据选择执行相应的命令。

当然,如果你不喜欢这几个按键,或者不喜欢那个提示语,可以自行修改以适合自己口味。另外,这个函数在编写的过程中参考了 Stackoverflow 上的一个 回答 ,你也可以进行一下对比,选取合适的部分,再加以发挥形成自己的 SmartQuit。

眼尖的读者可能已经发现了,这个配置是要用 <C-c> 来进行退出 Vim。其实我们也可以用这个按键代替 <Esc>2 来退出 Vim 中的各个模式。这在 Vim 中是一个默认设置,大多数情况下两者的行为是一致的。但有一个例外,就是用 <C-v>I 进行多行首插入时。:h i_ctrl-c 中写明 <C-c> 在 insert 模式中不会触发 InsertLeave 事件,因此也就无法完成多行插入了。解决这个问题,也很简单,只要加入如下配置就好了。

1
inoremap <unique> <C-c> <Esc>

另外,以 MacBook Pro 为代表的新一代的笔电设计,愈发地将 <Esc> 缩小,并置于偏离键盘左上角的位置,对于 Vim 的使用造成了一定的不便,所以非常推荐大家用 <C-c> 代替 <Esc>。当然, 前提是要将 <CapsLock> 设置为 <Ctrl>。否则,频繁使用 <C-c> 可能还会更痛苦。不过说到底,这个设置的好与不好,要不要采纳,大家还是要在使用中,根据自己的习惯做出适合自己的选择。

以上。


  1. 目前针对 Vim 有一个名为 Neovim 的改良项目。 

  2. :h esc,Vim 文档中对 <Esc> 的用途进行了详细的描述。