學 Vim 時但願早點知道的建議

來自wechat python

從 2009 年開始,我就一直把 Vim 當作個人主要(惟一)文本編輯器。在過去的這些年,我學到了不少好用的 Vim 技巧,它們令我感受相見恨晚,由於它們極大地提升了個人文本編輯效率。在這篇博文中,我想與大家分享其中的最精華部分。 git

HJKL

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 命令會使光標按虛擬行移動,而當遇到有行號的行時,光標則按物理行移動。這與相對行號一塊兒,堪稱絕配。

Vim and Tmux

在很長一段時間裏,我都是使用 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

若是你在使用一款文本編輯器,最重要的是儘量常用它。畢竟,當你已經瞭解 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) 分別向下 / 上捲動半屏
相關文章
相關標籤/搜索