簡(jiǎn)簡(jiǎn)單單的 Vim 就很好
這就是我如何從 35 個(gè) Vim 插件降到只有 6 個(gè)的原因。
當(dāng)你用 ??—clean?
? 選項(xiàng)啟動(dòng) Vim 時(shí),它以 “素” 模式展示
Vim。沒(méi)有插件、沒(méi)有配置,一切回到了最初。多年來(lái),我收集了一堆配置語(yǔ)句,其中一些可以追溯到 MS-DOS 或 Windows 3.1
時(shí)期。我是這樣打算的:從頭開始,只用 Fedora 35
中可用的插件,找到一個(gè)好的配置起點(diǎn)。我可以在一周的編碼生活中生存下來(lái)嗎?我會(huì)找到答案的!
規(guī)則是這樣的:盡可能少的配置語(yǔ)句,并且只使用 Fedora 35+ 中的插件。順便說(shuō)一下,如果你不是 Fedora 用戶,也請(qǐng)繼續(xù)閱讀。你可以隨時(shí)從你的操作系統(tǒng)軟件包管理器手動(dòng)安裝或者使用 Vim 插件管理器安裝這些插件。
在我開始之前,有一個(gè)大問(wèn)題需要解決:用 Vim 還是 Neovim(Vim 的一個(gè)復(fù)刻)。好吧,這由你決定。這篇文章中的所有內(nèi)容應(yīng)該對(duì)兩者都適用。然而,我只用 Vim 測(cè)試過(guò)。當(dāng)你登錄到一個(gè)只有 ??vi?
? 可用的服務(wù)器時(shí),所有的這些技能都會(huì)派上用場(chǎng)。它可以是一個(gè)舊的 UNIX 系統(tǒng)、一個(gè)安裝了最少的軟件以提高安全性的 Linux 服務(wù)器、一個(gè)容器中的交互式 shell,或者一個(gè)空間寶貴的嵌入式系統(tǒng)。
閑話少說(shuō),下面是我提煉出來(lái)的使用 Vim 進(jìn)行編碼的絕對(duì)最低限度的東西:
# dnf install --allowerasing vim-default-editor \
vim-enhanced \
vim-ctrlp \
vim-airline \
vim-trailing-whitespace \
vim-fugitive \
vim-ale \
ctags
不要擔(dān)心 ??—allowerasing?
? 選項(xiàng)。在確認(rèn)之前,只需查看一下安裝的東西。這個(gè)選項(xiàng)的作用是告訴軟件包管理器把現(xiàn)有的 ??nano-default-editor?
? 包替換為 ??vim-default-editor?
?。這是一個(gè)小軟件包,它在 shell 配置文件中將 ??EDITOR?
? 環(huán)境變量設(shè)置為 ??vim?
?,如果你想默認(rèn)使用 Vim(例如,與 ??git?
? 一起使用),這是必須的。這是專門針對(duì) Fedora 的。你不需要在其他發(fā)行版或操作系統(tǒng)上這樣做,只要確保你的 ??EDITOR?
? shell 變量被正確設(shè)置就行。
概覽
簡(jiǎn)單介紹一下我認(rèn)為好的、干凈的插件集:
- CtrlP:盡可能小的模糊查找插件(純 vimscript)
- Fugitive:一個(gè) git 的必備工具
- Trailing-whitespace:顯示并修復(fù)(刪除)尾部的空格
- Airline:一個(gè)改進(jìn)的狀態(tài)行(純 vimscript)
- Ale:在你打字時(shí)高亮顯示錯(cuò)別字或語(yǔ)法錯(cuò)誤
- Ctags:不是 Vim 插件,但卻是一個(gè)非常需要的工具
還有其他的模糊查找插件,如 command-t 或我最喜歡的 ??fzf.vim?
?(非??欤?wèn)題是,??fzf.vim?
? 不在 Fedora 中,而我想要盡可能少的配置。CtrlP 就可以了,而且配置它更容易,因?yàn)樗恍枰裁匆蕾嚒?/p>
如果讓我選擇一個(gè)絕對(duì)最小的配置,那就是:
# cat ~/.vimrc
let mapleader=","
let maplocalleader="_"
filetype plugin indent on
let g:ctrlp_map = '<leader><leader>'
let g:ctrlp_user_command = ['.git/', 'git --git-dir=%s/.git ls-files -oc --exclude-standard']
set exrc
set secure
但這可能太極端了,所以這里是一個(gè)稍大的配置,下面是我的詳細(xì)解釋:
" vim: nowrap sw=2 sts=2 ts=2 et:
" leaders
let mapleader=","
let maplocalleader="_"
" filetype and intent
filetype plugin indent on
" incompatible plugins
if has('syntax') && has('eval')
packadd! matchit
end
" be SSD friendly (can be dangerous!)
"set directory=/tmp
" move backups away from projects
set backupdir=~/.vimbackup
" fuzzy searching
let g:ctrlp_map = '<leader><leader>'
let g:ctrlp_user_command = ['.git/', 'git --git-dir=%s/.git ls-files -oc --exclude-standard']
nnoremap <leader>b :CtrlPBuffer<cr>
nnoremap <leader>t :CtrlPTag<cr>
nnoremap <leader>f :CtrlPBufTag<cr>
nnoremap <leader>q :CtrlPQuickfix<cr>
nnoremap <leader>m :CtrlPMRU<cr>
" buffers and quickfix
function! ToggleQuickFix()
if empty(filter(getwininfo(), 'v:val.quickfix'))
copen
else
cclose
endif
endfunction
nnoremap <leader>w :call ToggleQuickFix()<cr>
nnoremap <leader>d :bd<cr>
" searching ang grepping
nnoremap <leader>g :copen<cr>:Ggrep!<SPACE>
nnoremap K :Ggrep "\b<C-R><C-W>\b"<cr>:cw<cr>
nnoremap <leader>s :set hlsearch! hlsearch?<cr>
" ctags generation
nnoremap <leader>c :!ctags -R .<cr><cr>
" per-project configs
set exrc
set secure
使用逗號(hào)作為引導(dǎo)鍵
我喜歡把我的 ??引導(dǎo)鍵?
? 映射成逗號(hào) ??,?
?,而不是默認(rèn)的反斜杠 ??\?
?。當(dāng)你的手處于書寫位置時(shí),它是 Vim 中最接近的自由鍵。另外,這個(gè)鍵在大多數(shù)鍵盤布局中都是一樣的,而 ??\?
? 在每個(gè)型號(hào)或布局都不一樣。我很少使用 ??本地引導(dǎo)鍵?
?,但下劃線 ??_?
? 看起來(lái)很合適。
文件類型和關(guān)閉語(yǔ)法高亮
接下來(lái)是非常重要的 ??filetype?
? 命令。看,Vim 自帶“內(nèi)置電池”,8.2 版本包含 644 種語(yǔ)言的語(yǔ)法高亮,251 個(gè)文件類型定義(??ftplugins?
?),以及 138 種語(yǔ)言的縮進(jìn)規(guī)則。然而,縮進(jìn)在默認(rèn)情況下是不啟用的,也許是為了給所有人提供一個(gè)一致的編輯體驗(yàn)。我喜歡啟用它。
一個(gè)簡(jiǎn)單的技巧:如果你正在編輯一個(gè)非常大的文件,并且 Vim 感覺(jué)很慢,你可能想禁用語(yǔ)法高亮來(lái)加快速度。只要輸入 ??:syn off?
? 命令即可。
Matchit 插件
Vim 甚至額外帶有使得一些功能不兼容的插件,其中一個(gè)相當(dāng)有用。它就是 ??matchit?
? 插件,它使按下 ??%?
? 鍵可以在某些語(yǔ)言中查找匹配的括號(hào)。通常情況下,你可以找到一個(gè)塊的開始或結(jié)束(開始和結(jié)束括號(hào))或 HTML 匹配標(biāo)簽及類似的。
交換文件
我想從我的舊配置中保留的許多設(shè)置之一是使用 ??/tmp?
? 進(jìn)行交換,并在我的家目錄的一個(gè)單獨(dú)目錄中創(chuàng)建備份,你需要用 ??mkdir ~/.vimbackup?
? 來(lái)創(chuàng)建這個(gè)目錄。重要的是要明白,當(dāng)你開始編輯時(shí),Vim 會(huì)創(chuàng)建一個(gè)名為 “交換文件” 的副本,所有未保存的工作都會(huì)保存在這個(gè)文件中。所以即使停電了,你的交換文件也包含了大部分未保存的工作。我更喜歡使用 ??tmpfs?
?,因?yàn)槲宜械墓P記本電腦和服務(wù)器都有
UPS 保護(hù),而且我經(jīng)常保存。另外,大多數(shù)情況下,你會(huì)使用到交換文件是當(dāng)你的 SSH
連接丟失而不是由于停電時(shí)。對(duì)于大文件來(lái)說(shuō),交換文件可能相當(dāng)大,我很珍視我的固態(tài)硬盤,所以我決定這樣做。如果你不確定,可以刪除這句話,使用 ??/var/tmp?
?,這樣更安全。
模糊尋找插件
現(xiàn)在,模糊查找是一個(gè)我不能沒(méi)有的插件。在服務(wù)器上當(dāng)你每天需要打開 20 個(gè)文件時(shí),使用 ??:Ex?
? 或 ??:e?
? 或 ??:tabe?
? 等命令打開文件是沒(méi)問(wèn)題的。而當(dāng)編碼時(shí),我通常需要打開數(shù)百個(gè)文件。正如我所說(shuō),CtrlP 很好地完成了這項(xiàng)工作。它很小,沒(méi)有依賴性,純 Vim。它用 ??Ctrl + P?
? 組合鍵打開,這對(duì)我來(lái)說(shuō)有點(diǎn)奇怪。我知道一些著名的編輯器(我記得是 VSCode)使用這個(gè)組合鍵。問(wèn)題是,這已經(jīng)是很重要的 Vim 綁定鍵,我不想覆蓋它。所以對(duì)我來(lái)說(shuō),贏家是 ??引導(dǎo)鍵 + 引導(dǎo)鍵?
?(逗號(hào)按兩次)。
??ctrlp_user_command?
? 只是改變了 CtrlP 獲取文件列表的方式。它不使用內(nèi)置的遞歸文件列表(glob),而是使用 ??git ls-files?
?,這通常更好,因?yàn)樗雎粤?nbsp;??.gitignore?
? 中的東西,所以像 ??node_modules?
? 或其他可能拖慢列表的不相關(guān)目錄不會(huì)受到影響。
使用 ??引導(dǎo)鍵?
? + ??B?
?/??T?
?/??F?
?/??Q?
?/??M?
? 來(lái)打開緩沖區(qū)、標(biāo)簽、當(dāng)前文件的標(biāo)簽、快速修復(fù)緩沖區(qū)和最近使用的文件的列表,非常有用。具體來(lái)說(shuō),一旦你用 ??ctags?
? 生成了標(biāo)簽列表,這基本上就是數(shù)百種編程語(yǔ)言的“去……定義處”,而且不需要插件!這都是 Vim 內(nèi)置的?,F(xiàn)在澄清一下,當(dāng)我說(shuō)輸入 ??引導(dǎo)鍵 + B?
? 時(shí),是指按下逗號(hào),然后按 ??B?
? 鍵,而不是像用 ??Control?
? 或 ??Shift?
? 那樣一起按。
緩沖區(qū)管理
雖然現(xiàn)在 Vim 支持標(biāo)簽,但緩沖區(qū)管理是掌握 Vim 的一個(gè)重要技能。我通常會(huì)有很多緩沖區(qū),我需要經(jīng)常做 ??:bdelete?
?。那么,??引導(dǎo)鍵 + D?
? 似乎是一個(gè)不錯(cuò)的選擇,可以更快地完成這個(gè)任務(wù)。我也喜歡關(guān)閉 Quickfix 窗口,所以也有 ??引導(dǎo)鍵 + W?
? 的組合鍵,我在瀏覽搜索結(jié)果時(shí)經(jīng)常使用這個(gè)功能。
Ggrep 和 fugitive 插件
說(shuō)到搜索,它和打開文件一樣重要。我希望能夠?qū)Υa庫(kù)進(jìn)行檢索。為此,有一個(gè)來(lái)自 fugitive 插件的很棒的 ??:Ggrep?
? 命令,它使用 ??git grep?
?,忽略了垃圾文件,只搜索 Git 中的內(nèi)容。由于 ??Shift + K?
? 是 Vim 中的一個(gè)自由鍵,它非常適用于自動(dòng)檢索光標(biāo)位置的詞語(yǔ)。最后,能夠使用 ??引導(dǎo)鍵 + G?
? 輸入任意的搜索模式也很好。注意,這將打開一個(gè)叫做 Quickfix 的窗口,你可以在這里瀏覽結(jié)果、查看下一個(gè)/上一個(gè)/最后一個(gè)/第一個(gè)出現(xiàn)的地方,等等。這個(gè)窗口也用于編譯器或其他工具的輸出,所以要熟悉它。如果你對(duì)此感到陌生,我建議進(jìn)一步閱讀文檔。
用 fugitive 進(jìn)行搜索、檢索
順便說(shuō)一下,用 ??/?
? 鍵搜索是智能和大小寫敏感的,這意味著如果所有的搜索字符都是小寫的,Vim 的搜索會(huì)忽略大小寫。默認(rèn)情況下,它會(huì)高亮顯示結(jié)果,我覺(jué)得我已經(jīng)敲了無(wú)數(shù)次的 ??:noh?
?(來(lái)關(guān)閉高亮顯示)。這就是為什么我有 ??引導(dǎo)鍵 + S?
? 來(lái)切換高亮顯示。我建議以后也多讀讀手冊(cè)中關(guān)于搜索的內(nèi)容。
接下來(lái)是搜索、檢索。fugitive 插件已經(jīng)為你提供了。使用命令 ??:Ggrep pattern?
? 來(lái)進(jìn)行 ??git grep?
?,結(jié)果會(huì)進(jìn)入 Quickfix 窗口。然后簡(jiǎn)單地使用快速修復(fù)命令(??:cn?
?、??:cp?
? 等等)瀏覽結(jié)果,或者簡(jiǎn)單地使用 ??:CtrlPQuickfix?
?(??引導(dǎo)鍵 + Q?
?)來(lái)直觀地滾動(dòng)它們。CtrlP 的快速修復(fù)整合的酷炫之處是,你可以通過(guò)輸入以匹配文件名或內(nèi)容來(lái)進(jìn)一步在搜索結(jié)果中搜索。
Ctags
??引導(dǎo)鍵 + C?
? 可以生成一個(gè) ctags 文件,以便更好地導(dǎo)航,這在處理一個(gè)新的代碼庫(kù)或做一個(gè)有很多跳轉(zhuǎn)的較長(zhǎng)的編碼任務(wù)時(shí)很有用。ctags 支持?jǐn)?shù)百種語(yǔ)言,而 Vim 可以利用所有這些知識(shí)來(lái)導(dǎo)航。后面會(huì)有更多關(guān)于如何配置它的內(nèi)容。注意我已經(jīng)討論過(guò) ??引導(dǎo)鍵 + T?
? 來(lái)打開所有標(biāo)簽的模糊搜索,記得嗎?這兩個(gè)是非常相同的。
按鍵映射
能夠通過(guò)在項(xiàng)目目錄下創(chuàng)建一個(gè) ??.vimrc?
? 文件來(lái)覆蓋該項(xiàng)目中的任何設(shè)置是一個(gè)好主意。只要把它放在(全局的) ??.gitignore?
? 中,以確保你不需要在每個(gè)項(xiàng)目中編輯成千上萬(wàn)的 ??.gitignore?
? 文件。這樣的一個(gè)項(xiàng)目的 ??.vimrc?
? 可以是這樣的(對(duì)于使用 GNU Makefile 的 C/C++ 項(xiàng)目):
" coding style
set tabstop=4
set softtabstop=4
set shiftwidth=4
set noexpandtab
" include and autocomplete path
let &path.="/usr/local/include"
" function keys to build and run the project
nnoremap <F9> :wall!<cr>:make!<cr><cr>
nnoremap <F10> :!LD_LIBRARY_PATH=/usr/local/lib ./project<cr><cr>
正如你所看到的,我通常將 ??F2?
? 到 ??F10?
? 等鍵映射到編譯、運(yùn)行、測(cè)試和類似的操作。用 ??F9?
? 來(lái)調(diào)用 ??make?
?,聽起來(lái)不錯(cuò)。還記得 MS-DOS 上的藍(lán)色 Borland IDE 嗎?
如前所述,在全局范圍內(nèi)忽略 ??.vimrc?
? 和(由 ??ctags?
? 生成的)??tags?
? 是個(gè)好主意,所以不需要每次都更新 ??.gitignore?
?:
# git config --global core.excludesfile ~/.gitignore
# cat ~/.gitignore
/.vimrc
/tags
/TAGS
在我的個(gè)人配置中還有幾條只與那些非美國(guó)鍵盤布局的人有關(guān)(我用捷克語(yǔ))。我需要用“死鍵”來(lái)輸入許多字符(LCTT 譯注:“死鍵”是一種通過(guò)將變音符號(hào)與后面的字母結(jié)合起來(lái)打出重音字符的方法。這種方法在歷史上被用于機(jī)械打字機(jī)),這根本不可能,我寧愿輸入命令而不是按那些難以按下的組合鍵。這里有一個(gè)解決問(wèn)題的辦法:
" CTRL-] is hard on my keyboard layout
map <C-K> <C-]>
" CTRL-^ is hard on my keyboard layout
nnoremap <F1> :b#<cr>
nnoremap <F2> :bp<cr>
nnoremap <F3> :bn<cr>
" I hate entering Ex mode by accident
map Q <Nop>
功能鍵在 Vim 中都是自由的,除了 ??F1?
?,它被綁定在幫助上。我不需要幫助,并不是說(shuō)我已經(jīng)會(huì)對(duì) Vim 了如指掌,并不是。但如果需要的話,我可以簡(jiǎn)單地輸入 ??:help?
?。而 ??F1?
? 是一個(gè)關(guān)鍵的鍵,離 ??Esc?
? 鍵如此之近。我喜歡將它用于緩沖區(qū)交換(??:b#?
?),將 ??F2?
?/??F3?
? 用作下一個(gè)/上一個(gè)。你越是與緩沖區(qū)打交道,你就越需要這個(gè)。如果你沒(méi)有使用過(guò) ??Ctrl + ^?
?,我建議你要習(xí)慣于它。哦,你有沒(méi)有丑陋地輸入 ??:visual?
? 進(jìn)入過(guò) Ex 模式?許多初學(xué)者都不知道如何從該模式下退出 Vim。對(duì)我來(lái)說(shuō),這就是打擾,因?yàn)槲液苌偈褂盟?/p>
現(xiàn)在,熟悉 ??ctags?
? 是成功使用 Vim 的一個(gè)關(guān)鍵因素。這個(gè)工具支持?jǐn)?shù)百種語(yǔ)言,它不小心就為你不想創(chuàng)建標(biāo)簽的文件創(chuàng)建它,因此我建議忽略典型的垃圾目錄:
# cat ~/.ctags.d/local.ctags
--recurse=yes
--exclude=.git
--exclude=build/
--exclude=.svn
--exclude=vendor/*
--exclude=node_modules/*
--exclude=public/webpack/*
--exclude=db/*
--exclude=log/*
--exclude=test/*
--exclude=tests/*
--exclude=\*.min.\*
--exclude=\*.swp
--exclude=\*.bak
--exclude=\*.pyc
--exclude=\*.class
--exclude=\*.cache
Airline 插件
我一定不能忘記 Vim 的 Airline 插件。在 Fedora 的兩個(gè)插件中,這個(gè)插件很輕量級(jí),不需要外部依賴,而且可以開箱即用我所有的字體。你可以定制它,而且還有主題之類的東西。我只是碰巧喜歡它的默認(rèn)設(shè)置。
我必須提到,有兩個(gè)主要的 Ctags 項(xiàng)目:Exuberant Ctags 和 Universal Ctags。后者是一個(gè)更現(xiàn)代的復(fù)刻。如果你的發(fā)行版有,就用它。如果你在 Fedora 35+ 上,你應(yīng)該知道你現(xiàn)在用的是 Universal Ctags。
總結(jié)
作為總結(jié),我的建議是這樣的。盡量保持你的 Vim 配置流暢和干凈。這將在未來(lái)得到回報(bào)。在我轉(zhuǎn)換到新配置之后,我不得不重新學(xué)習(xí)“寫入并退出”的命令,因?yàn)槲铱偸遣恍⌒陌阉虺?nbsp;??:Wq?
?,而我在舊的配置里有一個(gè)“小技巧”,讓它實(shí)際上按我的意思工作。好吧,這個(gè)可能真的很有用,并能入選,我希望你能明白我的意思:
:command Wq wq
:command WQ wq
最后的一個(gè)快速技巧是:你可能需要經(jīng)常改變你的默認(rèn) Vim 配置,來(lái)找到我在這里向你介紹的和你自己口味之間的舒適區(qū)。使用下面的別名,這樣你就不需要一直搜索歷史。相信我,當(dāng)一個(gè) Vim 用戶在命令歷史里搜索 “vim” 時(shí),找不到什么是相關(guān)的內(nèi)容:
alias vim-vimrc='vim ~/.vimrc'
就是這些了。也許這可以幫助你在沒(méi)有大量插件的情況下在 Vim 的豐富世界遨游?!昂?jiǎn)簡(jiǎn)單單” 的 Vim 也很不錯(cuò)!
要嘗試你剛剛讀到的內(nèi)容,請(qǐng)安裝軟件包并檢出這些配置:
test -f ~/.vimrc && mv ~/.vimrc ~/.vimrc.backup
curl -s https://raw.githubusercontent.com/lzap/vim-lzap/master/.vimrc -o ~/.vimrc
mkdir ~/.vimbackup
特別感謝 Marc Deop 和 Melanie Corr 對(duì)本文的審閱。
更新
我已經(jīng)在這種配置下生存下來(lái)了!我唯一的糾結(jié)是 CtrlP 插件的結(jié)果順序不同。文件的模糊算法與 ??fzf.vim?
? 插件不同,所以我以前用各種搜索詞能找到的文件現(xiàn)在找不到了。我最后安裝了 Fedora 的 fzf 包以獲得更相關(guān)的文件搜索,它附帶了一個(gè) vim 函數(shù) ??FZF?
?,可以綁定到引導(dǎo)鍵組合上。請(qǐng)看我的 GitHub 倉(cāng)庫(kù) 中更新后的配置文件。一路走來(lái),我學(xué)到了很多東西。有一些鍵的綁定我已經(jīng)忘記了,這要感謝許多插件。