一開始看不上親密接觸後又讓你欲罷不能的 vim

每個程序員都有一款心心念叨的代碼編輯器。而在衆多妖顏魅惑的編輯器偶像團體前,vim 就像個不加粉飾的農村姑娘,咋一看是那樣樸實無華,難有傾心。但只要走近一點,來個親密接觸,又會被她的似水柔情所俘獲。linux

這是青筆親身經歷。公司從騰訊空降技術總監,時不時會分享一些他的開發經驗。其中說到編輯器,他的臉上總會泛起淡淡桃花,「我就喜歡 vim!」 。儘管咱們曾一致向他引薦當下紅極一時集美貌與才華於一身的 vscode 。他卻依然心有所屬,不爲所動。程序員

多少次,我百思不得其解,這個「相貌平平」的 vim 到底有何魔力,能緊緊扣住總監的心絃。在我真正走進她的心裏世界,屢次晝夜相伴以後。我最終也被她的清新脫俗所拜倒。正則表達式

接下來就讓咱們一塊兒來了解這名神祕的「女子」。shell

1. vim 歷史

如下是網上找到一張圖。如對 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

2. 內置教程

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
複製代碼

3. 工做模式

對於習慣了 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 應用得駕輕就熟了。

4. 命令模式

4.1 移動光標

要使用 vim 熟練地進行代碼和文本的編輯,首先須要可以精確快速的將光標定位到要編輯的地方。最基本的就是上下左右移動光標了。這些操做固然可使用鍵盤的四個方向鍵來完成。可是更經常使用的是使用字母輸入區域連續的四個按鍵 h, j, k, l 。事實上,當你按照標準的手勢接觸鍵盤,你右手的食指觸碰的就是 j 鍵(按鍵有個凸起)。所以,在你保持正常輸入的手勢下,順其天然地敲動食指,就能將光標往下移動一行,而緊挨着的中指接觸的是 k 鍵,進行的是和 j 相反的操做,即將光標向上移動一行,你會發現這樣用起來至關順手,這就理解爲何要使用字母按鍵來進行光標移動操做了。固然這是在命令模式下,按下字母鍵不會做爲輸入而改變編輯內容。

  • h: 向左移動一個字符
  • l: 向右移動一個字符
  • j: 向下移動一行
  • k: 向上移動一行

雖然可使用 j, k 左右兩邊的 h 和 l 來實現向左和向右移動光標。這在一次只移動一個字符時,也仍是很方便。可是若是向左或向右移動一個字(word,英文中空格和標點符號隔開的單詞,標點符號也算一個字)時,還使用 h 和 l 就顯得有些笨拙了。向左(向後)和向右(向前)移動一個字的方法以下:

  • w: 向右或向前移動一個字,光標定位在字的首字符
  • b: 向左或向後移動一個字,光標定位在字的首字符

命令模式按下字母w將光標向右移動一個字:

命令模式按下字母b將光標向左移動一個字:

若是想近一步擴大光標單次移動的範圍,就要用到按句子和段落來先後移動來。兩對圓括弧()分別將光標向後和向前移動一個句子,對應兩個花括弧{}分別將光標向後和向前移動一個段落。

  • ( : 向後移動一個句子,光標定位在句子開始
  • ) : 向前移動一個句子,光標定位在句子開始
  • { : 向後移動一個段落,光標定位在段落開始
  • } : 向前移動一個段落,光標定位在段落開始

命令模式按下)(向前和向後移動一個句子:

命令模式按下}{向前和向後移動一個段落:

此外你還能夠在屏幕所見範圍內進行快速移動光標。分別使用大寫的HML。可是這三種定位並非很精確,一般用作快速大範圍級定位,而後再使用前面的命令進行更加精確的定位。讀者能夠自行嘗試。

  • H: 將光標定位到屏幕頂部一行的最左端
  • M: 將光標定位到屏幕中間一行
  • L: 將光標定位到屏幕的底部一行

還有一種咱們很是熟悉的應用場景,就是在調試程序拋出異常時,一般會顯示出異常產生的行號,這時就須要根據行號快速將光標定位到指定的位置。這個命令相比前面的命令要複雜一點,它須要先輸入表明行號的一個或多個數字,而後按下大寫字母G來完成。例如將光標定位到文件的第 80 行。須要先在命令模式輸入80,而後快速按下大寫字母G

4.2 刪除/撤銷

將刪除和撤銷兩個操做放在一塊兒講,其中一個緣由是考慮到可能由於還不知道如何撤銷刪除操做,而懼怕嘗試刪除操做的心理(儘管咱們已經事先作了備份,但這應該是一種普通的心理和人性懼怕失去是一樣的道理)。咱們知道能夠撤銷,所以在刪除這件事上就有了「安全感」。也許你不是這麼認爲,可是這樣仍是能幫助咱們更好的練習和記憶(咱們能夠循環往復地練習刪除撤銷)。

和移動光標同樣,刪除也能夠按不一樣粒度進行。如刪除單個字符,字,行,句子,段落以及屏幕首尾。刪除操做由用字母d加上表示刪除範圍的標識符構成。同時刪除具體範圍還受光標當前所在的具體位置決定。例如刪除字使用字母組合dw,若是光標出如今單詞hello的第二個字符e上,此時在命令模式連續按下dw,將刪除從e開始以後的整個字,可是會e前面的h不會刪除,刪除後的結果就是還剩一個字母h。其餘粒度的刪除,也遵循類似的規律。

刪除單個字符

刪除單個字符有二者方法。二者等效,都是刪除光標所在的字符,可是使用x更簡單一些,由於只須要輸入一個字母。

  • x
  • dl

刪除字

  • dw: 從光標所在位置開始,刪除到字的末尾(包含光標所在位置的字符)
  • db: 與dw相反方向刪除,即刪除光標所在位置前面的字符(不包含光標所在位置的字符)

刪除行

  • dd: 刪除光標所在的行
  • 3dd: 刪除從光標開始的3行,固然這是一個例子,能夠更改前面的數字刪除任意數量的行

一次刪除3行:

刪除到行尾

若是你不想刪除整行。而是從光標開始到行尾的字符,能夠直接使用一個大寫D來實現。

使用大寫字母D刪除從光標位置開始到行尾的字符:

從行首刪除

與刪除到行尾對應的是使用d0從行首刪除:

d^與d$

若是對正則表達式熟悉,應該很容易猜到二者的含義。也是刪除行首和行尾,可是與前面的 d0D 所不一樣的是不刪除行首和行尾的空格。

  • d^: 刪除光標前面知道行首的字符,包含行首的空格
  • d$: 刪除從光標開始知道行尾的字符,包含行尾的空格

刪除句子和段落

熟悉了前面的刪除,如下刪除句子和段落也能夠以此類推。惟一區別僅僅在於刪除粒度不一樣。

  • d(: 從句首刪除
  • d): 刪除到句尾
  • d{: 從段首刪除
  • d}: 刪除到段尾

替換:刪除並輸入

說到刪除不得再也不提到替換。由於二者就像兄弟通常,實際替換像刪除的哥哥,只比弟弟刪除多作了一步。就是在刪除後緊接着進入編輯模式,在已刪除的地方進行編輯。這兩個組合動做不就是替換嘛。須要注意的還有,替換會改變當前工做模式,也就是進入下文會講到的編輯模式,所以在完成輸入後,須要按ESC從新回到命令模式。與刪除d對應的替換命令是c。所以將刪除裏講到的全部操做中的d換成c就是對應的替換操做,固然執行後的細節會有些差別。可是這種差別在你親自試事後就很容易理解,所以不做過多論述。讀者能夠自行嘗試。

撤銷操做

撤銷操做很簡單,命令模式下,按下小寫字母u(undo)便可。能夠連續按屢次,以快速撤銷多個歷史操做。

4.3 複製/粘貼

複製 y

複製使用字母y。它的用法和刪除操做d很像,不一樣的是y是複製而不是刪除。

下面以複製行爲例。其餘粒度的複製類比刪除操做d便可。

dd刪除當前行對應的複製當前行操做是yy,固然也能夠複製多行,和刪除多行格式類似。在yy前加上要複製的行數。例如3yy複製從光標所在行開始的三行。

  • yy: 複製光標所在的行
  • 3yy: 複製從光標開始的3行,這裏只是例子,實際能夠是任意行數

粘貼 p

粘貼命令就簡單多了。它沒有沒有那麼多的粒度區分,而只須要將已經複製的內容插入到當前光標以後或者以前的位置。分別使用小寫的p和大寫的P

  • p: 將複製的內容插入到光標以後
  • P: 將複製的內容插入到光標以前

4.4 查找字符串

在命令模式輸入斜槓/(向下查找)或問號?(向上查找),光標定位到終端底部一行,輸入要查找的字符串,再按回車(RETURN),首先定位到一個找到的字符串,接着按小寫的n查找下一個,按大寫的N查找前一個。

5. 進入編輯模式

上面介紹的全部命令都是在命令模式下進行的。若是要開始編寫代碼或其餘文字編輯工做,就須要從命令行模式進入編輯模式,不然輸入的字母(除能進入編輯模式的字母外)都將視做命令,而不會編輯到到文件中。

進入編輯模式有如下6種方式,區別僅在於進入編輯模式後,光標所在的位置的不一樣。

  • i: 在當前光標前插入
  • I: 在行首插入
  • a: 在當前光標後追加
  • A: 在行尾追加
  • o: 在當前光標所在行之添加新行
  • O: 在當前光標所在行之添加新行

6. 命令行模式

在命令模式下,按下冒號:,在終端底部出現輸入行,表示當前是命令行模式。在命令行模式可使用 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 編輯界面。

7. 配置文件

前文已經講到若是想要每次打開 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 這位眉目清新又純潔善良的「姑娘」,而且今後對她有了一份獨有的愛意,算是本文創做的最大收穫所在^^。


本文首發公號

相關文章
相關標籤/搜索