每個程序員都有一款心心念叨的代碼編輯器。而在衆多妖顏魅惑的編輯器偶像團體前,vim 就像個不加粉飾的農村姑娘,咋一看是那樣樸實無華,難有傾心。但只要走近一點,來個親密接觸,又會被她的似水柔情所俘獲。linux
這是青筆親身經歷。公司從騰訊空降技術總監,時不時會分享一些他的開發經驗。其中說到編輯器,他的臉上總會泛起淡淡桃花,「我就喜歡 vim!」 。儘管咱們曾一致向他引薦當下紅極一時集美貌與才華於一身的 vscode 。他卻依然心有所屬,不爲所動。程序員
多少次,我百思不得其解,這個「相貌平平」的 vim 到底有何魔力,能緊緊扣住總監的心絃。在我真正走進她的心裏世界,屢次晝夜相伴以後。我最終也被她的清新脫俗所拜倒。正則表達式
接下來就讓咱們一塊兒來了解這名神祕的「女子」。shell
如下是網上找到一張圖。如對 vim 發展歷史感興趣能夠參考維基百科的詞條 Vim (text editor)
。vim
en.wikipedia.org/wiki/Vim_(t…安全
早期的 UNIX 操做系統上標準的編輯器是 ed ,這是一個面向行的編輯器,只能顯示當前編輯的行。1976年,Bill Joy 在 ed 上作了擴展,使之支持了全屏顯示和編輯,命名爲 ex 。ex 是 ed 的超集,經過在 ex 輸入命令 vi 來啓動擴展功能。後來這個命令因爲常用而被獨立出來,也就是如今 Linux (包括 macOS)系統預裝的命令行編輯器 vi 。直到 1991 年,Bram Moolenaar 纔開發了 vi 的改進版(improvement),命名爲 VIM (寓意:Vi IMprovement),同年 11 月 4 日發佈了 vim 的第一個版本。下圖來自 vim.org 網站首頁的一條新聞,也就是去年的11月4日迎來了 vim 的27歲生日。bash
vim 自帶了一個面向初學者開發的教程。可經過獨立的子程序 vimtutor
啓動教程。markdown
若是系統已經安裝了 vim (macOS 預裝了 vim,部分 linux 發行版可能須要手動安裝),能夠在直接在終端輸入 vimtutor
命令打開教程。編輯器
vimtutor
複製代碼
教程實際也是使用 vim 打開系統上的一個文本文件。文件一般在 /usr/share/vim/vim80/tutor/
目錄下。固然,這個目錄下有不少個文件,分別是不一樣語言版本的教程。使用 vimtutor
的不一樣之處是能自動打開用戶所在地的語言版本。oop
上面看到的簡體中文版實際就是文件 /usr/share/vim/vim80/tutor/tutor.zh_cn.utf-8
。
所以,你能夠將其複製一份放到當前目錄下,再使用 vim 打開,用作練習,隨意編輯文件內容。
cp /usr/share/vim/vim80/tutor/tutor.zh_cn.utf-8 ./
vim tutor.zh_cn.utf-8
複製代碼
但若是按照教程來練習,我的用起來感受最舒服的方式是:同時打開兩個終端,一個使用 vimtutor 打開本地教程用於閱覽,另外一個將教程的英文版複製到當前目錄,而後使用 vim 在複製的英文版上進行編輯練習(由於咱們實際應用場景大可能是英文環境,包括編輯代碼和配置文件)。
複製英文版教程並進行編輯練習:
cp /usr/share/vim/vim80/tutor/tutor ./
vim tutor
複製代碼
對於習慣了 GUI 編輯器的開發者,剛開始接觸 vim ,很容易被 vim 的工做模式搞得一頭霧水,並且極可能就此放棄使用 vim 。但若是熟悉了,就以爲一切也理所固然。按照維基百科的介紹,vim 一共有 12 種不一樣模式,但只有 6 種基本模式,剩下 6 種都是基本模式的變種。但實際咱們最常接觸的只有兩類模式:命令模式和編輯模式。其中命令模式又細分爲,Normal(默認)模式和 Cmdline (底部命令行) 模式。而 Normal 模式是啓動 vim 進入的默認模式,而且在任何模式下,按 ESC
(鍵盤左上角)鍵都將回到這個模式,做用相似於手機的 Home 鍵。所以,當你開始迷糊本身當前處在什麼模式下,最好的辦法就是按 ESC
回到 Normal 模式。咱們使用 vim 的絕大多數命令都在 Normal 模式運行,而 Cmdline(命令行)模式一般只在退出和保存時使用,所以,如不特別說明,當咱們在說命令模式時,就是指代 Normal 模式。此外,本文將 Cmdline 統稱爲命令行模式。
下圖是三種模式的切換方式:
若是要簡單歸納這三種模式的使用場景,那就是:在命令模式中執行光標導航,複製粘貼刪除,撤銷重作,以及查找替換等操做;在編輯模式下,編寫代碼或進行創做;在命令行模式模式下,輸入 q
退出,輸入w
保存,輸入wq
保存並退出。固然這裏還不是所有的操做,可是熟悉這些操做,基本就能將 vim 應用得駕輕就熟了。
要使用 vim 熟練地進行代碼和文本的編輯,首先須要可以精確快速的將光標定位到要編輯的地方。最基本的就是上下左右移動光標了。這些操做固然可使用鍵盤的四個方向鍵來完成。可是更經常使用的是使用字母輸入區域連續的四個按鍵 h, j, k, l 。事實上,當你按照標準的手勢接觸鍵盤,你右手的食指觸碰的就是 j 鍵(按鍵有個凸起)。所以,在你保持正常輸入的手勢下,順其天然地敲動食指,就能將光標往下移動一行,而緊挨着的中指接觸的是 k 鍵,進行的是和 j 相反的操做,即將光標向上移動一行,你會發現這樣用起來至關順手,這就理解爲何要使用字母按鍵來進行光標移動操做了。固然這是在命令模式下,按下字母鍵不會做爲輸入而改變編輯內容。
h
: 向左移動一個字符l
: 向右移動一個字符j
: 向下移動一行k
: 向上移動一行雖然可使用 j, k 左右兩邊的 h 和 l 來實現向左和向右移動光標。這在一次只移動一個字符時,也仍是很方便。可是若是向左或向右移動一個字(word,英文中空格和標點符號隔開的單詞,標點符號也算一個字)時,還使用 h 和 l 就顯得有些笨拙了。向左(向後)和向右(向前)移動一個字的方法以下:
w
: 向右或向前移動一個字,光標定位在字的首字符b
: 向左或向後移動一個字,光標定位在字的首字符命令模式按下字母w
將光標向右移動一個字:
命令模式按下字母b
將光標向左移動一個字:
若是想近一步擴大光標單次移動的範圍,就要用到按句子和段落來先後移動來。兩對圓括弧(
和)
分別將光標向後和向前移動一個句子,對應兩個花括弧{
和}
分別將光標向後和向前移動一個段落。
(
: 向後移動一個句子,光標定位在句子開始)
: 向前移動一個句子,光標定位在句子開始{
: 向後移動一個段落,光標定位在段落開始}
: 向前移動一個段落,光標定位在段落開始命令模式按下)
和(
向前和向後移動一個句子:
命令模式按下}
和{
向前和向後移動一個段落:
此外你還能夠在屏幕所見範圍內進行快速移動光標。分別使用大寫的H
,M
,L
。可是這三種定位並非很精確,一般用作快速大範圍級定位,而後再使用前面的命令進行更加精確的定位。讀者能夠自行嘗試。
H
: 將光標定位到屏幕頂部一行的最左端M
: 將光標定位到屏幕中間一行L
: 將光標定位到屏幕的底部一行還有一種咱們很是熟悉的應用場景,就是在調試程序拋出異常時,一般會顯示出異常產生的行號,這時就須要根據行號快速將光標定位到指定的位置。這個命令相比前面的命令要複雜一點,它須要先輸入表明行號的一個或多個數字,而後按下大寫字母G
來完成。例如將光標定位到文件的第 80 行。須要先在命令模式輸入80,而後快速按下大寫字母G
。
將刪除和撤銷兩個操做放在一塊兒講,其中一個緣由是考慮到可能由於還不知道如何撤銷刪除操做,而懼怕嘗試刪除操做的心理(儘管咱們已經事先作了備份,但這應該是一種普通的心理和人性懼怕失去是一樣的道理)。咱們知道能夠撤銷,所以在刪除這件事上就有了「安全感」。也許你不是這麼認爲,可是這樣仍是能幫助咱們更好的練習和記憶(咱們能夠循環往復地練習刪除撤銷)。
和移動光標同樣,刪除也能夠按不一樣粒度進行。如刪除單個字符,字,行,句子,段落以及屏幕首尾。刪除操做由用字母d
加上表示刪除範圍的標識符構成。同時刪除具體範圍還受光標當前所在的具體位置決定。例如刪除字使用字母組合dw
,若是光標出如今單詞hello
的第二個字符e
上,此時在命令模式連續按下d
和w
,將刪除從e
開始以後的整個字,可是會e
前面的h
不會刪除,刪除後的結果就是還剩一個字母h
。其餘粒度的刪除,也遵循類似的規律。
刪除單個字符
刪除單個字符有二者方法。二者等效,都是刪除光標所在的字符,可是使用x
更簡單一些,由於只須要輸入一個字母。
x
dl
刪除字
dw
: 從光標所在位置開始,刪除到字的末尾(包含光標所在位置的字符)db
: 與dw
相反方向刪除,即刪除光標所在位置前面的字符(不包含光標所在位置的字符)刪除行
dd
: 刪除光標所在的行3dd
: 刪除從光標開始的3行,固然這是一個例子,能夠更改前面的數字刪除任意數量的行一次刪除3行:
刪除到行尾
若是你不想刪除整行。而是從光標開始到行尾的字符,能夠直接使用一個大寫D
來實現。
使用大寫字母D
刪除從光標位置開始到行尾的字符:
從行首刪除
與刪除到行尾對應的是使用d0
從行首刪除:
d^與d$
若是對正則表達式熟悉,應該很容易猜到二者的含義。也是刪除行首和行尾,可是與前面的 d0
與 D
所不一樣的是不刪除行首和行尾的空格。
d^
: 刪除光標前面知道行首的字符,不包含行首的空格d$
: 刪除從光標開始知道行尾的字符,不包含行尾的空格刪除句子和段落
熟悉了前面的刪除,如下刪除句子和段落也能夠以此類推。惟一區別僅僅在於刪除粒度不一樣。
d(
: 從句首刪除d)
: 刪除到句尾d{
: 從段首刪除d}
: 刪除到段尾替換:刪除並輸入
說到刪除不得再也不提到替換。由於二者就像兄弟通常,實際替換像刪除的哥哥,只比弟弟刪除多作了一步。就是在刪除後緊接着進入編輯模式,在已刪除的地方進行編輯。這兩個組合動做不就是替換嘛。須要注意的還有,替換會改變當前工做模式,也就是進入下文會講到的編輯模式,所以在完成輸入後,須要按ESC
從新回到命令模式。與刪除d
對應的替換命令是c
。所以將刪除裏講到的全部操做中的d
換成c
就是對應的替換操做,固然執行後的細節會有些差別。可是這種差別在你親自試事後就很容易理解,所以不做過多論述。讀者能夠自行嘗試。
撤銷操做
撤銷操做很簡單,命令模式下,按下小寫字母u
(undo)便可。能夠連續按屢次,以快速撤銷多個歷史操做。
複製 y
複製使用字母y
。它的用法和刪除操做d
很像,不一樣的是y
是複製而不是刪除。
下面以複製行爲例。其餘粒度的複製類比刪除操做d
便可。
與dd
刪除當前行對應的複製當前行操做是yy
,固然也能夠複製多行,和刪除多行格式類似。在yy
前加上要複製的行數。例如3yy
複製從光標所在行開始的三行。
yy
: 複製光標所在的行3yy
: 複製從光標開始的3行,這裏只是例子,實際能夠是任意行數粘貼 p
粘貼命令就簡單多了。它沒有沒有那麼多的粒度區分,而只須要將已經複製的內容插入到當前光標以後或者以前的位置。分別使用小寫的p
和大寫的P
。
p
: 將複製的內容插入到光標以後P
: 將複製的內容插入到光標以前在命令模式輸入斜槓/
(向下查找)或問號?
(向上查找),光標定位到終端底部一行,輸入要查找的字符串,再按回車(RETURN),首先定位到一個找到的字符串,接着按小寫的n
查找下一個,按大寫的N
查找前一個。
上面介紹的全部命令都是在命令模式下進行的。若是要開始編寫代碼或其餘文字編輯工做,就須要從命令行模式進入編輯模式,不然輸入的字母(除能進入編輯模式的字母外)都將視做命令,而不會編輯到到文件中。
進入編輯模式有如下6種方式,區別僅在於進入編輯模式後,光標所在的位置的不一樣。
i
: 在當前光標前插入I
: 在行首插入a
: 在當前光標後追加A
: 在行尾追加o
: 在當前光標所在行之後添加新行O
: 在當前光標所在行之前添加新行在命令模式下,按下冒號:
,在終端底部出現輸入行,表示當前是命令行模式。在命令行模式可使用 vim 自身支持的不少命令。如前文已經談到的最經常使用用到的就是退出和保存。
:q
+ RETURN: 退出編輯:w
+ RETURN: 保存不退出:wq
+ RETURN: 保存並退出經常使用的還有對 vim 進行設置。如下命令都須要在輸入完後按下回車鍵 RETURN 才能執行(和在終端執行命令方式差很少)。
:syntax on
: 開啓語法高亮:set number
: 顯示行號:set tabstop=4
: 設置 Tab 鍵寬度:set expandtab
: 使用空格替代 Tab:set softtabstop=4
: 設置軟件 Tab (自動Tab)寬度爲 4:set shiftwidth=4
: 設置自動縮進寬度爲 4:set autoindent
: 開啓自動縮進,一般用於編寫程序固然以上對 vim 的設置僅僅影響當前打開的 vim 。要想每次打開都使用一樣的設置,須要將設置命令統一保存到 vim 的配置文件 ~/.vimrc
中,方法下一節將講到。
此外,可使用help
來獲取幫助。例如輸入:help user-manual
+ RETURN 查看用戶手冊。
若是說以上都是 vim 內部執行命令,那麼在命令行模式下,實際也能夠調用外部 shell 的命令。方法是以感嘆號!
開頭,標識感嘆號!
以後的命令是一條外部 shell 的命令。如查看當前目錄下的文件,:!ls -l
。第一次按下 RETURN 會隱藏當前編輯區域,顯示終端界面,第二次按下 RETURN 再次回到 vim 編輯界面。
前文已經講到若是想要每次打開 vim 都使用一樣和界面和設置,須要將設置命令統一保存在配置文件中。在 linux 系統(含macOS)推薦保存的路徑是 ~/.vimrc
。若是歷來沒有設置過,這個文件可能還不存在。這就須要咱們先建立一個。爲了避免覆蓋已有的,咱們可使用以下命令:
test -f ~/.vimrc || vim ~/.vimrc 複製代碼
這條 shell 命令會先判斷 ~/.vimrc
是否存在,不存在就新建一個空白的配置文件,並使用 vim 打開這個新建的配置文件。
可選的方式也能夠複製一份系統的上的配置文件,而後在此基礎上添加和覆蓋默認配置。
test -f ~/.vimrc || cp /usr/share/vim/vimrc ~/.vimrc 複製代碼
如下是青筆本身的配置文件參考:
colorscheme default " 設置顏色主題 syntax on " 語法高亮 filetype on " 檢測文件的類型 set number " 顯示行號 set ruler " 在編輯過程當中,在右下角顯示光標位置的狀態行 set laststatus=2 " 顯示狀態欄 (默認值爲 1, 沒法顯示狀態欄) set statusline=\ %<%F[%1*%M%*%n%R%H]%=\ %y\ %0(%{&fileformat}\ %{&encoding}\ %c:%l/%L%) " 設置在狀態行顯示的信息 set tabstop=4 " Tab鍵的寬度 set expandtab " 使用空格替換Tab set softtabstop=4 set shiftwidth=4 " 統一縮進爲4 set autoindent " vim使用自動對齊,也就是把當前行的對齊格式應用到下一行(自動縮進) set cindent " (cindent是特別針對 C語言語法自動縮進) set smartindent " 依據上面的對齊格式,智能的選擇對齊方式,對於相似C語言編寫上有用 set scrolloff=3 " 光標移動到buffer的頂部和底部時保持3行距離 set incsearch " 輸入搜索內容時就顯示搜索結果 set hlsearch " 搜索時高亮顯示被找到的文本 set foldmethod=indent " 設置縮進摺疊 set foldlevel=99 " 設置摺疊層數 nnoremap <space> @=((foldclosed(line('.')) < 0) ? 'zc' : 'zo')<CR> " 用空格鍵來開關摺疊 " 自動跳轉到上次退出的位置 if has("autocmd") au BufReadPost * if line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g'\"" | endif endif 複製代碼
關於配置文件的更多信息,也可經過 vim 內置的幫助手冊來查看。與配置相關的手冊爲 usr_05
。在命令行模式輸入:help usr_05
(冒號用於進入命令行模式,輸入後回車)便可打開該手冊。
本文從 vim 的發展歷史開始,以具有可以熟練駕馭 vim 編輯器來知足平常代碼編寫的基本操做爲主線,講解了在 vim 中進行模式切換,光標導航,刪除,撤銷,替換,複製,粘貼,插入文本,以及配置編輯器外觀設置等必要技能。固然,vim 支持的操做和命令還有不少。本文只介紹到基礎部分。可是倒是咱們進行代碼編輯最經常使用到的功能。熟練掌握後,能夠進一步查看手冊學習更多的技巧。查看手冊方式上文已經給出。即在命令行模式輸入::help user-manual
再回車。
若是本文能讓你從新認識了 vim 這位眉目清新又純潔善良的「姑娘」,而且今後對她有了一份獨有的愛意,算是本文創做的最大收穫所在^^。
本文首發公號