如何優雅的使用 Vim(一):基本配置

如何優雅的使用 Vim(一):基本配置

Vim 十年,青春不再

轉眼間,Vim 已用了十年。
從一開始的牴觸、不解,到隨之而來的習慣、喜歡,再到近幾年編輯器層出不窮的盛況下對 Sublime Text 等短暫的嘗試,以及最後即現在的迴歸,這是一個複雜的過程。
目前,我對 Vim 仍停留在配置和使用階段,並沒有爲它開發過任何插件。希望接下來十年,能爲它做一些貢獻。
Vim 是一個難學難上手,即使熟悉了也會讓你痛並快樂着的那種編輯器。要教別人用 Vim,就更是難上加難了。

vim_main

如何評價GitHub準備推出下一代文本編輯器Xray? 一文,可以看到時下不少編輯器的嘗試。軟件行業發展到今天,編輯器遠遠沒有達到一個完美的境界,包括 Vim,這本身就是一件很不可思議的事情。

基礎設置

最最基本的一些設置,位於 vimrc 的開頭。

" 首先設置 mapleader,後面鍵盤映射隨時要用
" 基本上所有自定義的快捷鍵都以這個字符打頭,比如映射`,w`爲`:w`
let mapleader = ","
let g:mapleader = ","

" 不兼容 Vi,最大限度使用新特性
set nocompatible

" 寫入文件時,不做備份
set nobackup
set nowritebackup

" 不用交換文件
set noswapfile

" 保存文件的快捷鍵
nmap <leader>w :w!<CR>

" 移除 Windows 文件結尾的 `^M`
noremap <leader>m :%s/<C-V><C-M>//ge<CR>

" 重新打開文件時,恢復上一次遊標位置
" 通過View可以記住很多設置,比如高亮當前行、折行等等,但是往往比較讓人費解
set viewoptions=cursor  " 只記住遊標
au BufWinLeave ?* mkview
au VimEnter ?* silent loadview

" 檢測文件編碼時,優先考慮 UTF-8
set fileencodings=utf-8,ucs-bom,gbk,gb2312,big5,latin1

" 不同平臺,設置不同的行尾符,即 EOL
" 注意:在 Mac 平臺,也是 unix 優先;自 OS X 始,行尾符與 Unix 一致,
"      都是 `\n` 而不是 `\r`
if has("win32")
    set fileformats=dos,unix,mac
else
    set fileformats=unix,mac,dos
endif

" 在斷行、合併(join)行時,針對多字節字符(比如中文)的優化處理
set formatoptions+=mM

配色方案

目前主要使用 morhetz/gruvbox,本文所有截圖都是 gruvbox 的效果。
配色方案可以通過插件安裝,這裏先跳過,會有另一篇文章專門介紹插件。

set background=dark
syntax enable
colorscheme gruvbox
au BufEnter * :syntax sync fromstart

格式

縮進選項

" 採用 C 風格的縮進,適用於大多數語言
" 細節調整見下面的 `cinoptions`
" 你也可以嘗試 smartindent 和 autoindent
set cindent

" 細節調整,主要爲了適應 Google C++ Style
" t0: 函數返回類型聲明不縮進
" g0: C++ "public:" 等聲明縮進一個字符
" h1: C++ "public:" 等聲明後面的語句縮進一個字符
" N-s: C++ namespace 裏不縮進
" j1: 合理的縮進 Java 或 C++ 的匿名函數,應該也適用於 JS
set cinoptions=t0,g1,h1,N-s,j1

製表符 vs. 空格

讓製表符智能一些。

set smarttab

對程序員來說,用製表符還是用空格,足以引發一場戰爭。
美劇《硅谷》中,Richard 因爲不能接受女友用空格縮進而斷然與之分手。
下面的設置並不優雅,各人需求不一樣,需做相應調整。

" 先設置缺省情況,然後根據不同文件類型再次重新設置
set expandtab | set tabstop=4 | set shiftwidth=4  " Python, CSS, etc.

" 對 C/C++ 等,製表符和縮進都是兩個空格
au FileType c,cpp,html,htmldjango,lua,javascript,nsis
    \ set expandtab | set tabstop=2 | set shiftwidth=2

" Makefile 必須保留製表符,且習慣上佔八個空格
" 不過,這年頭誰還會寫 Makefile?
au FileType make set noexpandtab | set tabstop=8 | set shiftwidth=8

文本寬度

除了縮進,另一個深具爭議的話題就是 80列 限制。

雖然現在顯示器大了很多,有些語言習慣上仍然遵守這一規則。

通過設置 textwidth,Vim 可以幫我們在輸入時或用gq格式化時自動斷行。

我發現,用 gq 格式化註釋特別方便,超長的註釋會自動重新排版,以保證不越過指定的長度。

目前,我僅對 C/C++/Python/Vim 做這種限制。

au FileType c,cpp,python,vim set textwidth=80

一般如果設定了寬度限制,最好能畫一條豎線以警示。
設置 colorcolumn 即可。甚至可以設置爲多列,比如 "81,101"。
我是所有文件類型都顯示這麼一條線。

set colorcolumn=81

折行

通常代碼不需折行,前面有些語言設置了寬度限制就更不需要了。
實際操作下來,純文本、Markdown、XML 等比較需要折行,因爲它們常常一行太長了。

au FileType text,markdown,html,xml set wrap

" 折行時,以單詞爲界,以免切斷單詞
set linebreak
" 折行後的後續行,使用與第一行相同的縮進
set breakindent

用戶界面

" 即使在終端,也儘量啓用鼠標
if has("mouse") | set mouse=a | endif

" 顯示輸入中的命令,對 gqq/gcc 這種多個字符的命令特別有用
set showcmd
" 下面幾個不解釋,自行查看幫助
set scrolloff=7
set wildmenu
set wildmode="list:longest"
set ruler
" 命令行高度爲兩行
set cmdheight=2

" 永遠顯示行號
" 另有比較酷的相對行號(`relativenumber`),雖然我用不習慣
set number

set lazyredraw
" 切換緩存時不用保存
set hidden
" 輸入模式下,退格鍵可以退一切字符
set backspace=eol,start,indent
set whichwrap+=<,>,h,l

高亮不想要的空格,比如行尾。

vim_hl_trailing_spaces

" See [http://vim.wikia.com/wiki/Highlight_unwanted_spaces]
" - highlight trailing whitespace in red
" - have this highlighting not appear whilst you are typing in insert mode
" - have the highlighting of whitespace apply when you open new buffers
highlight ExtraWhitespace ctermbg=red guibg=red
match ExtraWhitespace /\s\+$/
autocmd BufWinEnter * match ExtraWhitespace /\s\+$/
autocmd InsertEnter * match ExtraWhitespace /\s\+\%#\@<!$/
autocmd InsertLeave * match ExtraWhitespace /\s\+$/
autocmd BufWinLeave * call clearmatches() " for performance

高亮當前行。

vim_hl_cursorline

set cursorline

不過,我一般不用,因爲閃爍的遊標就已經很清楚了。

搜索

首先,搜索時忽略大小寫(ignorecase)。但是,如果搜索模式裏有大寫字母,就不再忽略大小寫(smartcase)。

set ignorecase
set smartcase

即時顯示匹配結果(incsearch),並高亮所有結果(hlsearch)。

set incsearch
set hlsearch
map <silent> <leader><CR> :nohlsearch<CR>

替換時,缺省啓用g標誌,即,同一行裏的所有匹配都會被替換。

set gdefault

切換窗口

切換窗口的鍵盤映射:

map <C-j> <C-W>j
map <C-k> <C-W>k
map <C-h> <C-W>h
map <C-l> <C-W>l

以及,直接用方向鍵切換緩存的鍵盤映射:

map <right> :bn<CR>
map <left>  :bp<CR>
map <up>    :bf<CR>
map <down>  :bl<CR>

縮寫(Abbreviation)

當前日期、時間、文件名這些內容,用縮寫來輸入是再方便不過了。
當然,縮寫本身的名字不能太常見,下面這些都以 x 打頭,一般不會出現在正常的文本中。

iabbrev xname <YouName>  " 改成你自己的名字
iabbrev xmail <YouEmail> " 改成你自己的電郵
iabbrev xfile <c-r>=expand("%:t")<CR>
if exists("*strftime")
    iabbrev xdate <c-r>=strftime("%Y-%m-%d")<CR>  " 當前日期
    iabbrev xtime <c-r>=strftime("%H:%M:%S")<CR>  " 當前時間
endif

刪除行尾空格

前面用戶界面一節已經提到如何高亮行尾空格,下面設置可以刪除行尾空格。

# 這個函數通過替換命令刪除行尾空格
func! DeleteTrailingWS()
    exec "normal mz"
    %s/\s\+$//ge
    exec "normal `z"
endfunc

" 保存時自動刪除行尾空格
au BufWrite * :call DeleteTrailingWS()
map <leader>W :call DeleteTrailingWS()<CR>

" 移除只包含空格的行裏的空格(有點繞口)
" 貌似有了前面的函數,這個就沒有什麼必要了
map <F3> :%s/\s*$//g<CR>:noh<CR>''<CR>

結語

配置是無窮無盡的,是樂趣也是包袱。
這篇文章,並不是我的 Vim 配置的全部,而我的 Vim 配置,也經常性的在變。
此外,我主要寫 C++ 和 Python,可能並不適合你。但是道理是一樣的,總是免不了折騰。
所以,沒有現成適用於所有人的配置,都是在別人的基礎上不斷收集和改進而成。

爲了避免文章太長,常用插件的介紹就另起一篇吧。

<全文完>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章