Vim 系列教程目錄:vim
本節會講一些 Vim 中的高級概念和進階用法, 瞭解了這些以後, 能夠解開不少疑惑, 使用起來也會更駕輕就熟.windows
CWD(Current Working Directory), 當前工做目錄, 這是 Vim 中一個挺重要, 可是卻又常常被忽略的概念. 簡單來講, CWD 是 Vim 和操做系統的文件系統進行交互時的上下文環境.緩存
要查看 Vim 的 CWD, 你可使用 :pwd
命令來查看. 正常來講, 當你點擊桌面上的 gVim 圖標打開 Vim 時, Vim 的 CWD 是用戶目錄, 當你在文件上右鍵->用 Vim 編輯打開 Vim 時, Vim 的 CWD 是文件所在路徑.bash
CWD 有什麼用呢? 如今請你打開 Vim, 而後在命令模式下執行 :e test_vim_cwd.txt
, 你會看到打開了一個名爲 test_vim_cwd.txt 的新文件, 你隨便添加一些文本, 而後保存, 你會發現此次 Vim 再也不提示你沒有文件名, 你能夠直接保存了. 那麼問題來了, 這個文件被存到哪裏了呢?session
我想你應該已經猜到了, 沒錯, 在 Vim 裏新建的文件, 若是不指定路徑, 會被保存到 CWD 裏. 因此說 CWD 是 Vim 和文件系統交互時的上下文環境.編輯器
除此以外, Vim 的不少插件工做時也依賴 CWD, 好比 NERDTree, CtrlP 等等.關於插件咱們之後再講, 如今你先記住, CWD 是會影響一些插件的表現的.佈局
在現階段, 你不須要關心 CWD, 由於咱們如今仍是單文件操做, CWD 是哪都無所謂. 但若是你確實想改一下 CWD, 可以使用 :cd
命令修改 CWD:post
cd d:/xxx/yyy
複製代碼
這和命令行裏切換目錄的方式是同樣.學習
OK, 關於 CWD, 先說到這, 後面還會再說. 另外, 如今你又學會一個新命令: :e
, 這個命令能夠新建一個新文件. 其實, :e
這個命令後面能夠路徑/文件名, 若是給定的路徑文件存在, 則是打開, 若是不存在, 則是新建.測試
好, 咱們再回到 Vim 的操做中, 請打開一個英文文本文件或輸入一些英文, 以便接下來的學習.
以前的複製和刪除都是以字符, 行爲單位, 而 w, e, b的做用是從光標處到下個單詞開頭或本單詞結尾, 因此要想刪除整個單詞, 你得這麼作: bdw
, 這表示先將光標移動到單詞開頭, 而後 dw. 這很麻煩, 有時候不當心看錯了, 光標就移動錯了. 要解決這個問題, 可使用 文本對象.
如今請移動到一個單詞的任意一個字母上, 而後執行指令 daw
, 你會發現整個單詞被刪除了, 神奇吧. 這個指令中的 aw
在 Vim 中表明一個文本對象: a word, 即一個單詞, 執行 daw
就表示刪掉一個單詞, 並且, 不管你在這個單詞的哪一個字母上, 均可以執行此命令刪掉整個單詞.
除了 aw, Vim 還支持下列文本對象:
[]
塊, a[, a] 包括兩邊的 "[]", i[, i] 不包括兩邊的 []a<, a> / i<, i>
: 一個尖括號塊, 細節同上上述文本對象大均可以使用計數器, 例如:
這樣一來, 一次性可操做的文本就大大增長了, 並且不用關心光標的位置, 很是便捷.
咱們以前說過, 剪切(刪除)的文本會進入到 Vim 中的寄存器裏, 那什麼是寄存器呢?
所謂寄存器, 就是存放文本和指令/命令的地方, 例如使用 y, d, c 等命令複製或剪切的文本都會被自動存放在 Vim 的寄存器中, 用戶能夠將文本和指令放在寄存器中, 也能夠從寄存器中讀出來.
Vim 中共有9類寄存器, 具體以下:
類型 | 標識 | 讀寫者 | 是否只讀 | 包含的字符來源 |
---|---|---|---|---|
Unnamed | " | Vim | 否 | 最近一次的複製或刪除操做 (d, c, s, x, y) |
Numbered | 0 到 9 | Vim | 否 | 寄存器 0: 最近一次複製. 寄存器 1: 最近一次刪除. 寄存器 2: 倒數第二次刪除, 以此類推. 每來一次新的刪除和修改, Vim 就把前一次的寄存器 1 的內容複製到寄存器 2, 2 到 3, 依此類推. 而寄存器 9 的內容就丟失了 |
Small delete | 中橫線 - | Vim | 否 | 最近一次行內刪除 |
Named | a 到 z 或 A 到 Z | 用戶 | 否 | 由用戶指定時使用, 用戶可將文本存儲到這些寄存器中. 若是存儲至寄存器 a, 那麼 a 中的文本就會被覆蓋. 若是你存儲至 A, 那麼會將文本添加給寄存器 a,不會覆蓋以前已有的文本 |
Read-only | : 與 . 與 % 和 # | Vim | 是 | : 爲最近一次使用的命令, . 爲最近一次添加的文本, % 爲當前的文件名, # 爲輪換文件名 |
Expression | = | 用戶 | 是 | Vim 存儲表達式的地方, 用戶只可讀 |
Selection/Drop | + 與 * 和 ~ | Vim | 否 | + 和 * 爲 GUI 選擇寄存器, 你能夠理解爲它們就是系統的剪切板, - 爲鼠標拖放的寄存器 |
Black hole | 下劃線 _ | Vim | 否 | 通常稱爲黑洞寄存器, 當把文本寫到這個寄存器中時, 什麼都不會發生, 且不可讀, 這個寄存器可用來刪除文本而不影響其餘寄存器 |
Last search pattern | / | Vim | 否 | 最近一次經過 / 、? 或 :global 等命令調用的匹配條件 |
要查看這些寄存器中到底有什麼, 可使用以下命令:
須要注意的是, 有些寄存器名字爲特殊字符, 須要使用 \ 轉義.
如今你能夠先複製一段文本, 而後執行命令 :reg "
, 查看一下 Unnamed 寄存器中的值.
要訪問寄存器, 須要使用 "
做爲前綴, 例如: "0
, "a
.
接下來咱們作一個測試, 例如將 'hello' 這個單詞存儲到寄存器 a, 先將光標移動到 'hello' 這個單詞上, 而後執行:
"ayiw 複製代碼
上述指令表示: 使用寄存器 a, 而後複製一個單詞. 此時使用命令 :reg a
查看寄存器 a 中的內容, 就能看到 'hello' 了. 須要注意的是, 當使用複製剪切等命令向指定寄存器中寫入內容時, 內容同時也會被寫入到 Unnamed 寄存器.
每次向寄存器中寫入內容, 會將寄存器中已有的內容覆蓋, 若是想要往寄存器中追加內容, 則需使用大寫字母防衛寄存器, 如: "Ayiw
, 這表示將當前單詞追加到 寄存器 a 中.
要讀取寄存器 a 中的內容, 則可以使用以下命令:
"ap 複製代碼
這表示先啓用 寄存器 a, 而後進行粘貼操做, 你就能夠看到, 寄存器 a 中的內容被粘貼出來了.
另外, 在插入模式下也能夠訪問寄存器, 在 插入模式中按 Ctrl-r, 而後再輸入寄存器標識(不用輸入", 直接輸入標識), 就能夠將對應寄存器中的內容輸出.
上面說了, y, d, c, x, s
等命令都是將內容存進了 Unnamed 寄存器中("), Unnamed 寄存器是 Vim 本身的寄存器, 操做系統是訪問不到的, 因此你到別的軟件了使用 Ctrl-v
是是沒法粘貼出來的.
可是 Vim 中有另外兩個寄存器: +
和 *
, 這兩個寄存器能夠理解爲操做系統的剪切板, 因此咱們能夠經過這兩個寄存器對系統的剪切板進行讀寫, 方式以下:
"+y
/ "+d
/ "+c
將內容複製/剪切到系統剪切板"+p
將系統剪切板內容粘貼出來PS. 使用 "+ 和 "* 效果同樣
上節咱們講過 .
這個指令, 能夠重複上次的操做, 咱們也說了, .
本質上是一個"宏", 那麼什麼"宏"呢?
所謂"宏", 其實就是能夠反覆播放的一系列操做的集合. 前面說了, 寄存器不僅是能夠存儲數據, 還能夠存儲指令/命令, Vim 中的宏就是將指令存儲到寄存器中, 而後再讀取出來. 宏的使用步驟以下:
qm
, 表示將宏錄製到 m 寄存器中.@m
播放m寄存器中的宏, 前面能夠加數字表示播放次數@@
表示播放以前播放過那個個宏錄製好宏以後, 能夠經過 reg
查看宏中的內容. 另外, 一樣能夠經過使用大寫字母訪問寄存器, 追加宏命令.
在 Vim 中打開的文件都會被存放在 Vim 的緩衝區中. 緩衝區在內存裏, 當修改了文件還未保存時, 改動就在緩衝區中, 當保存時, Vim 會將緩衝區中的內容寫到文件. 要查看緩衝區中有哪些文件, 可以使用 :buffers
命令, :ls
, :files
命令能夠起到一樣的效果.
運行這個命令後, 你會看到相似的輸出:
1 "Android\AFeed\02_項目基本配置.md" 第 39 行
3 a "[未命名]" 第 0 行
5 "Develop\Editor\Vim_1_基本使用.md" 第 177 行
6 %a "Develop\Editor\Vim_2_高級用法.md" 第 203 行
7 a "\Program Files (x86)\Vim\_vimrc" 第 0 行
8 "Develop\Editor\Vim_3_vimrc.md" 第 86 行
9 "Develop\Editor\Vim_5_經常使用插件(通用).md" 第 117 行
複製代碼
緩衝區列表第一列是其序號, 第二列是標記, 標記的含義以下:
如何操做這些 Buffer 呢? 可以使用以下命令:
:buffer <buffer no>
經過 Buffer 編號切換到指定 Buffer, 簡寫 :b <buffer no>
:buffer <file name>
經過文件名切換到指定 Buffer, 簡寫 :b <file name>
:bnext
, :bprevious
切換到下一個/上一個 Buffer, 簡寫 :bn
, :bp
:bfirst
, :blast
切換到第一個/最後一個 Buffer, 簡寫 :bf
, :bl
:bdelete <buffer no>
刪除指定緩衝區, 簡寫 :bd <buffer no>
關於 Buffer 要注意:
Vim 中一個編輯區域中能夠有多個窗口. 所謂窗口, 其實就是把編輯區分割成不一樣區域, 每一個區域被稱爲一個窗口. 窗口是用來顯示 Buffer 的, 當你打開 Vim 時, 其實同時也打開了一個窗口, 只是這個窗口占滿了整個編輯區域.
使用以下命令, 能夠把當前分割窗口:
:split
: 在當前窗口上邊打開新窗口, 新窗口中依然是當前文件, 簡寫爲 :sp
:split filenpath
: 在當前文件上邊打開新窗口, 新窗口中爲指定文件, 簡寫爲 :sp filepath
:vsplit
: 在當前文件左邊打開新窗口, 新窗口中依然是當前文件, 簡寫爲 :vsp
, 一樣可指定文件名:new
: 在當前文件上邊打開新的空白窗口, 不可指定文件名:vnew
: 在當前文件左邊打開新的空白窗口, 不可指定文件名注意:上述命令均可以在前面加一個數字, 表示新窗口的大小(行數), 如 :3sp a.txt
, 則打開 a.txt 的窗口只有三行. 另外, 能夠反覆使用上述命令, 把窗口分割成更小的窗口.
關於窗口的幾個快捷鍵:
關於窗口的幾個命令:
:close
關閉當前窗口, 其實 q 命令和 ZZ 也是能夠關閉當前窗口的, 只不過 :close
命令能夠保證不會關閉最後一個窗口:only
只保留當前窗口, 關閉其餘窗口, 若是其餘窗口中的文件沒保存, 會有警告:wall
保存全部窗口:qall
退出全部窗口:wqall
保存並退出全部窗口除了窗口功能, Vim 還支持多標籤頁功能. 標籤頁是窗口的合集, 即一個標籤頁中有多個窗口, 而:wall
, :qall
等窗口功能其實只對當前標籤頁中的窗口有效. 使用下列命令, 能夠開啓新的標籤頁:
:tabedit
: 打開新的空白標籤頁, 簡寫: tabe
:tabedit filepath
: 在新的標籤頁中打開指定文件, 簡寫: tabe filepath
:tab split
: 打開新的標籤頁, 其內容是當前標籤頁:tab help
: 在新的標籤頁中打開幫助文檔關於標籤頁的幾個指令/命令:
:tabn
切換到下一個標籤頁:tabp
切換到上一個標籤頁:tabn
數字: 切換到指定位置的標籤頁, 從1開始:tabc
關閉當前標籤頁( tabclose 的簡寫):tabo
只保留當前標籤頁, 關閉其餘標籤頁(tabonly 的簡寫)先引用文檔中的原話(help window):
Summary: SummaryA buffer is the in-memory text of a file. A window is a viewport on a buffer. A tab page is a collection of windows.
個人理解:
一些奇怪現象的解釋:
能夠再看看這些文章:
不少軟件都具備這樣一種功能: 在你下一次啓動該軟件時,它會自動爲你恢復到你上次退出的環境, 恢復窗口布局, 所打開的文件等等. Vim 也有相似的功能, 只是用起來比較麻煩...
當你要退出 Vim 時, 能夠保存一個 Vim Session(會話), Vim 會話存放着所 有跟你的編輯相關的信息. 這包括諸如文件列表, 窗口布局, 全局變量, 選 項, 以及其它信息.
要保存會話信息, 可以使用命令 :mksession sessionname
, 簡寫爲 :mks sessionname
, sessionname 由你指定, 會話信息會保存到名爲 sessionname 的文件中, 默認狀況下, Session 文件是存在用戶目錄下的, 固然你也能夠指定 Session 文件的路徑, 例如: :mksession d:/vim/session1
. 若是 Session 文件已存在, 你須要使用 :mksession! d:/vim/session1
來保存 Session.
下次你打開 Vim, 能夠載入這個 Session 文件, 就能恢復以前的會話信息了, 要載入會話, 可以使用命令 :source sessionname
.
比起其餘編輯器, Vim 的 Session 稍顯難用一些.
摺疊... 怎麼解釋呢, 就是把一段文本顯示爲一行, 就像一張紙, 要把它縮短些, 就摺疊起來. 被摺疊的文本其實還在, 只是顯示方式變了. 摺疊的好處 是, 經過把多行的文本摺疊成帶有摺疊提示的一行, 會使你更好地瞭解對文 本的宏觀結構.
要建立一個摺疊, 可以使用 zf
指令, 你能夠把光標移動到某一個段落內, 而後使用指令 zfap
, 你會發現, 這段文字被摺疊了. 這個指令的含義是: zf
是摺疊指令, ap
是文本對象, 表示一段, zfap
就表示摺疊一段文字.
要展開摺疊的文本, 可將光標移動到摺疊行上, 使用 zo
指令, 摺疊的文字就會展開. 要想再次摺疊, 使用 zc
指令, 此次爲啥不用 zf
了? 由於 zf
是建立摺疊的.
經常使用摺疊指令:
總的來講, 摺疊用的很少, 這裏就很少介紹了.
:r! <cmd>
或者 :r !<cmd>
便可, 注意 <cmd>
指的是你要輸入的系統命令:redir > a.txt
, 此命令意爲將命令輸出到 a.txt 中, 默認會在 pwd 目錄下新建文件, 你也能夠指定文件路徑, 若是文件已存在, 可以使用 redir!
進行覆蓋, 或使用 redir >> a.txt
進行追加.redir END
, 此命令意爲重置命令輸出位置.本節講了一些 Vim 中的進階用法, 可讓你處理文本時更加方面快捷. 另外, 對於 Vim 中的寄存器, Buffer, Window, Tab等概念也有詳細的介紹, 瞭解這些會讓你理解 Vim 的一些行爲. 仍是那句話, 多練習, 在用的過程當中學習, 感悟.