# Vim 高級技巧

##### 常用技巧

<table border="1" cellpadding="1" cellspacing="1" id="bkmrk-%E5%91%BD%E4%BB%A4%E5%9F%B7%E8%A1%8C%EF%BC%88%E6%B3%A8%E6%84%8F%E5%A4%A7%E5%B0%8F%E5%AF%AB%E4%B8%8D%E5%90%8C%EF%BC%89-%C2%A0%E4%BD%BF%E7%94%A8%E8%AA%AA%E6%98%8E-" style="height: 1830.26px; width: 121.358%;" width="983"><tbody><tr style="height: 35.8375px;"><td bgcolor="#ccffcc" style="height: 35.8375px; width: 33.3663%;"><span style="background-color: #ccffcc; color: #000000;">**命令執行（注意大小寫不同）**</span></td><td bgcolor="#ccffcc" style="height: 35.8375px; width: 33.3663%;"><span style="background-color: #ccffcc; color: #000000;"> **使用說明**</span></td><td bgcolor="#ccffcc" style="height: 35.8375px; width: 33.3663%;"><span style="background-color: #ccffcc; color: #000000;"> **使用技巧**</span></td></tr><tr style="height: 58.875px;"><td style="height: 58.875px; width: 33.3663%;"> i</td><td style="height: 58.875px; width: 33.3663%;">以插入字元方式進入編輯模式</td><td style="height: 58.875px; width: 33.3663%;">與 a 同為進入編輯模式，兩者差別只有游標的起始位置不同</td></tr><tr style="height: 35.8375px;"><td style="height: 35.8375px; width: 33.3663%;"> a</td><td style="height: 35.8375px; width: 33.3663%;">以附加字元方式進入編輯模式</td><td style="height: 35.8375px; width: 33.3663%;">  
</td></tr><tr><td style="width: 33.3663%;">o</td><td style="width: 33.3663%;">插入一個空白行並編輯</td><td style="width: 33.3663%;">  
</td></tr><tr style="height: 58.875px;"><td style="height: 58.875px; width: 33.3663%;"> h j k l</td><td style="height: 58.875px; width: 33.3663%;">操控游標的移動，h--向左, j--向下, k--向上, l--向右</td><td style="height: 58.875px; width: 33.3663%;">當遇到部份作業系統不支援方向鍵使用時，可用此方式代替</td></tr><tr style="height: 35.8375px;"><td style="height: 35.8375px; width: 33.3663%;">:1  
: 22</td><td style="height: 35.8375px; width: 33.3663%;">游標移到第一行  
游標移到第22行  
</td><td style="height: 35.8375px; width: 33.3663%;">程式除錯找特定行號時會用到</td></tr><tr style="height: 35.8375px;"><td style="height: 35.8375px; width: 33.3663%;"> gg</td><td style="height: 35.8375px; width: 33.3663%;">游標移至檔首 </td><td style="height: 35.8375px; width: 33.3663%;">  
</td></tr><tr style="height: 58.875px;"><td style="height: 58.875px; width: 33.3663%;"> G</td><td style="height: 58.875px; width: 33.3663%;">游標移至檔尾</td><td style="height: 58.875px; width: 33.3663%;">編輯大檔案時要移到檔尾不用一頁一頁捲</td></tr><tr style="height: 35.8375px;"><td style="height: 35.8375px; width: 33.3663%;"> 0 / $</td><td style="height: 35.8375px; width: 33.3663%;">游標移至行首/行尾</td><td style="height: 35.8375px; width: 33.3663%;">  
</td></tr><tr style="height: 35.8375px;"><td style="height: 35.8375px; width: 33.3663%;">w / W  
</td><td style="height: 35.8375px; width: 33.3663%;">游標移至下一個單字/空格  
</td><td style="height: 35.8375px; width: 33.3663%;">游標右移</td></tr><tr style="height: 35.8375px;"><td style="height: 35.8375px; width: 33.3663%;">b / B</td><td style="height: 35.8375px; width: 33.3663%;">游標移至上一個單字/空格  
</td><td style="height: 35.8375px; width: 33.3663%;">游標左移</td></tr><tr><td style="width: 33.3663%;">x</td><td style="width: 33.3663%;">刪除目前字元</td><td style="width: 33.3663%;">  
</td></tr><tr><td style="width: 33.3663%;">J (Shift + j)</td><td style="width: 33.3663%;">移除目前行尾的斷行</td><td style="width: 33.3663%;">上下兩行做合併</td></tr><tr style="height: 35.8375px;"><td style="height: 35.8375px; width: 33.3663%;">{  
</td><td style="height: 35.8375px; width: 33.3663%;">游標移至上一個段落  
</td><td style="height: 35.8375px; width: 33.3663%;">  
</td></tr><tr style="height: 35.8375px;"><td style="height: 35.8375px; width: 33.3663%;">}  
</td><td style="height: 35.8375px; width: 33.3663%;">游標移至下一個段落  
</td><td style="height: 35.8375px; width: 33.3663%;">  
</td></tr><tr style="height: 35.8375px;"><td style="height: 35.8375px; width: 33.3663%;"> :wq</td><td style="height: 35.8375px; width: 33.3663%;">存檔後離開 </td><td style="height: 35.8375px; width: 33.3663%;">  
</td></tr><tr style="height: 35.8375px;"><td style="height: 35.8375px; width: 33.3663%;"> :w new.txt</td><td style="height: 35.8375px; width: 33.3663%;">另存新檔成 new.txt</td><td style="height: 35.8375px; width: 33.3663%;">  
</td></tr><tr style="height: 58.875px;"><td style="height: 58.875px; width: 33.3663%;"> :w !sudo tee %</td><td style="height: 58.875px; width: 33.3663%;">以 sudo 模式存檔</td><td style="height: 58.875px; width: 33.3663%;">如果存檔時遇到權限不足，且有 sudo 的權限時的方法</td></tr><tr style="height: 81.9125px;"><td style="height: 81.9125px; width: 33.3663%;"> :q!</td><td style="height: 81.9125px; width: 33.3663%;">不存檔離開 </td><td style="height: 81.9125px; width: 33.3663%;">如不小心編錯內容，只要沒存檔前就可以用此法離開，保存原始內容</td></tr><tr style="height: 35.8375px;"><td style="height: 35.8375px; width: 33.3663%;">:set nu!  
</td><td style="height: 35.8375px; width: 33.3663%;">行號顯示切換  
</td><td style="height: 35.8375px; width: 33.3663%;">  
</td></tr><tr style="height: 35.8375px;"><td style="height: 35.8375px; width: 33.3663%;">:set hlsearch</td><td style="height: 35.8375px; width: 33.3663%;"> Highlight 搜尋的關鍵字</td><td style="height: 35.8375px; width: 33.3663%;">有些系統預設已經啟用</td></tr><tr style="height: 35.8375px;"><td style="height: 35.8375px; width: 33.3663%;">:set cuc!   
</td><td style="height: 35.8375px; width: 33.3663%;">直欄游標切換  
</td><td style="height: 35.8375px; width: 33.3663%;">編輯 json, yaml 格式</td></tr><tr style="height: 35.8375px;"><td style="height: 35.8375px; width: 33.3663%;"> : syntax on</td><td style="height: 35.8375px; width: 33.3663%;">啟用 Hihjlight 顯示</td><td style="height: 35.8375px; width: 33.3663%;">  
</td></tr><tr style="height: 35.8375px;"><td style="height: 35.8375px; width: 33.3663%;">d   
dd</td><td style="height: 35.8375px; width: 33.3663%;">刪除標記的內容  
刪除目前這一行</td><td style="height: 35.8375px; width: 33.3663%;">  
</td></tr><tr style="height: 35.8375px;"><td style="height: 35.8375px; width: 33.3663%;"> 10dd</td><td style="height: 35.8375px; width: 33.3663%;">刪除目前以下10行(含本列)</td><td style="height: 35.8375px; width: 33.3663%;">  
</td></tr><tr style="height: 35.8375px;"><td style="height: 35.8375px; width: 33.3663%;">y   
yy</td><td style="height: 35.8375px; width: 33.3663%;">複製標記的內容  
複製目前這一行</td><td style="height: 35.8375px; width: 33.3663%;">  
</td></tr><tr style="height: 35.8375px;"><td style="height: 35.8375px; width: 33.3663%;"> 3yy</td><td style="height: 35.8375px; width: 33.3663%;">複製目前以下3行(含本列)</td><td style="height: 35.8375px; width: 33.3663%;">  
</td></tr><tr style="height: 35.8375px;"><td style="height: 35.8375px; width: 33.3663%;"> p</td><td style="height: 35.8375px; width: 33.3663%;">貼上</td><td style="height: 35.8375px; width: 33.3663%;">  
</td></tr><tr><td style="height: 35.8375px; width: 33.3663%;"> /keyword</td><td style="height: 35.8375px; width: 33.3663%;">搜尋文字</td><td style="height: 35.8375px; width: 33.3663%;">  
</td></tr><tr><td style="height: 35.8375px; width: 33.3663%;"> /\\KeyWord</td><td style="height: 35.8375px; width: 33.3663%;">搜尋文字(不分大小寫)</td><td style="height: 35.8375px; width: 33.3663%;">  
</td></tr><tr><td style="height: 35.8375px; width: 33.3663%;">/S\[Uu\]SE  
</td><td style="height: 35.8375px; width: 33.3663%;">搜尋特定字元不分大小寫  
</td><td style="width: 33.3663%;">  
</td></tr><tr><td style="width: 33.3663%;">\*</td><td style="width: 33.3663%;">快速搜尋目前游標的單字</td><td style="width: 33.3663%;">  
</td></tr><tr style="height: 58.875px;"><td style="height: 58.875px; width: 33.3663%;"> :%s/old/new/g

 :%s/old/new/gc

</td><td style="height: 58.875px; width: 33.3663%;">全文內容包含有old字元的都會取代成new字元

gc: 啟用提示

</td><td style="height: 58.875px; width: 33.3663%;">  
</td></tr><tr><td style="width: 33.3663%;">:s#/usr/local/bin#/usr/sbin#g

</td><td style="width: 33.3663%;">以 # 作為分隔符號</td><td style="width: 33.3663%;">  
</td></tr><tr style="height: 35.8375px;"><td style="height: 35.8375px; width: 33.3663%;">:10,30 s/old/new/g  
</td><td style="height: 35.8375px; width: 33.3663%;">第10-30行置換 old 為 new  
</td><td style="height: 35.8375px; width: 33.3663%;">  
</td></tr><tr style="height: 35.8375px;"><td style="height: 35.8375px; width: 33.3663%;">:%s/old1\\|OLD2/new/gc  
</td><td style="height: 35.8375px; width: 33.3663%;">全文置換 old1與OLD2 為 new  
</td><td style="height: 35.8375px; width: 33.3663%;">  
</td></tr><tr style="height: 58.875px;"><td style="height: 58.875px; width: 33.3663%;">:/&lt;table&gt;/,/&lt;\\/table&gt;/g/^$/d</td><td style="height: 58.875px; width: 33.3663%;">包含 &lt;table&gt; ... &lt;/table&gt; 的內容刪除</td><td style="height: 58.875px; width: 33.3663%;">  
</td></tr><tr><td style="width: 33.3663%;">:%s/\\t/ /g</td><td style="width: 33.3663%;">置換 Tab 成4個空白</td><td style="width: 33.3663%;">寫程式時有用</td></tr><tr style="height: 58.875px;"><td style="height: 58.875px; width: 33.3663%;"> /\\s\\+$</td><td style="height: 58.875px; width: 33.3663%;">搜尋行尾的空格字元並 Highlight</td><td style="height: 58.875px; width: 33.3663%;">這可以配合 :set hlsearch 使用, not support AIX</td></tr><tr><td style="height: 35.8375px; width: 33.3663%;"> :%s/\\s\\+$//</td><td style="height: 35.8375px; width: 33.3663%;">移除所有行尾的空格字元</td><td style="height: 35.8375px; width: 33.3663%;">not support AIX</td></tr><tr style="height: 35.8375px;"><td style="height: 35.8375px; width: 33.3663%;"> ~</td><td style="height: 35.8375px; width: 33.3663%;">大小寫互換</td><td style="height: 35.8375px; width: 33.3663%;">  
</td></tr><tr style="height: 35.8375px;"><td style="height: 35.8375px; width: 33.3663%;"> :%s/\[ctrl+V and ctrl+M\]//g</td><td style="height: 35.8375px; width: 33.3663%;">消除斷行符號 ^M</td><td style="height: 35.8375px; width: 33.3663%;">  
</td></tr><tr><td style="width: 33.3663%;">ggVG  
</td><td style="width: 33.3663%;">全選內容  
</td><td style="width: 33.3663%;">類似 Ctrl a  
</td></tr><tr><td style="width: 33.3663%;">dG</td><td style="width: 33.3663%;">清除游標以下所有內容</td><td style="width: 33.3663%;">  
</td></tr><tr><td style="width: 33.3663%;">dgg</td><td style="width: 33.3663%;">刪除游標以上所有內容</td><td style="width: 33.3663%;">  
</td></tr><tr style="height: 35.8375px;"><td style="height: 35.8375px; width: 33.3663%;">:1,$d</td><td style="height: 35.8375px; width: 33.3663%;">清空所有內容</td><td style="height: 35.8375px; width: 33.3663%;">  
</td></tr><tr style="height: 35.8375px;"><td style="height: 35.8375px; width: 33.3663%;">:1,22d</td><td style="height: 35.8375px; width: 33.3663%;">清除 1-22 行</td><td style="height: 35.8375px; width: 33.3663%;">  
</td></tr><tr style="height: 35.8375px;"><td style="height: 35.8375px; width: 33.3663%;">:23,$d</td><td style="height: 35.8375px; width: 33.3663%;">清除 23 行以下所有內容</td><td style="height: 35.8375px; width: 33.3663%;">  
</td></tr><tr style="height: 35.8375px;"><td style="height: 35.8375px; width: 33.3663%;"> :! ls -l</td><td style="height: 35.8375px; width: 33.3663%;">執行外部 SHELL 指令</td><td style="height: 35.8375px; width: 33.3663%;"> :!! 上一個指令</td></tr><tr style="height: 58.875px;"><td style="height: 58.875px; width: 33.3663%;"> :vsplit my.file</td><td style="height: 58.875px; width: 33.3663%;">左右分割視窗且左邊載入 my.file</td><td style="height: 58.875px; width: 33.3663%;"> ctrl + w + w 切換視窗</td></tr><tr style="height: 35.8375px;"><td style="height: 35.8375px; width: 33.3663%;"> :split my.file</td><td style="height: 35.8375px; width: 33.3663%;">上下分割視窗</td><td style="height: 35.8375px; width: 33.3663%;">ctrl + w + w 切換視窗</td></tr><tr><td style="width: 33.3663%;">:sort

:sort!

:sort u

:sort i

:sort n

</td><td style="width: 33.3663%;">排序

反向排序

排序並移除重複行

忽略大小寫的排序

以數字排序

</td><td style="width: 33.3663%;">  
</td></tr><tr><td style="width: 33.3663%;">u  
Ctrl + r

</td><td style="width: 33.3663%;">Undo  
Redo

</td><td style="width: 33.3663%;">  
</td></tr><tr><td style="width: 33.3663%;">:g/^$/d

:4,100g/^$/d

:g/pattern/d

:!g/pattern/d

</td><td style="width: 33.3663%;">全文移除空白行

第4-100行移除空白行

移除符合 pattern 的行

移除不符合 pattern 的行

</td><td style="width: 33.3663%;">\[range\]g/pattern/cmd</td></tr></tbody></table>

其他技巧：

- 跳到上次編輯的行號：`'.`
- 開啟指令視窗：`:terminal`
    - `:below terminal` , `:bel term`
    - `:vertical terminal` , `:vert term`
    - 切換視窗: Ctrl + `w` + `w`
    - 編輯模式: Ctrl + `w` + `N` （切換回指令列: `hi`）
- 搜尋檔案並開啟：`:find your-script.sh` （可用 tab 自動補全與 `*` 符號） 
    - `:find *.sh`

##### Visual mode

- 切換至字元模式: `V`
- 切換至行模式: Shift + `V`  
    
    - 整行文字: Shift + `V`
    - 文字起始點至結束點: `V`
- 切換至區塊模式: Ctrl + `V`
    - 區塊左邊插入文字: `I`
    - 區塊右邊插入文字: `A`
    - 選擇區塊內至行尾的文字: `$`
- 選擇與操作 
    - 游標: 上/下鍵
    - 下一個單字: `w`
    - 下一個單字頭是點: `f .`
    - 下一個段落: `}`
- 取消選擇: `Esc`
- 複製選擇區文字: `y`
- 貼上文字: `p`
- 刪除選擇區的文字: `d` \*(Delete)\*
- 移動選擇區的文字: `d` &gt; Move to target line &gt; `p`
- 取代選擇區的文字: `r` \*(Replace)\*
- 變更選擇區的文字: `c` \*(Change)\*
- 復原最近刪除文字: `u` \*(Undo)\*
- 快速選擇目前引號("或')內的文字: `i` + `"` 或 `'`

##### 快速移動游標技巧

- 搜尋 MyKeyWord： `/MyKeyWord`
- 往下移動至相同文字的位置：`*`
- 標示關鍵字：`:set hlsearch`
- 輸入即顯示關鍵字：`:set incsearch`
- 段落`{},[]()`的結束符號：`%`
- 返回目前位置的段落起始符號`{`：`[{`
- 移動游標的的顯示位置（行號不變）：`zt` (Top), `zz` (Middle), `zb` (Bottom)
- 移動游標至畫面上其他行：`H` (Top), `M` (Middle), `L` (Last Line)
- 整頁移動：`Ctrl+b` (上一頁), `Ctrl+f` (下一頁)
- 整行移動：`Ctrl+y` (向上), `Ctrl+e` (向下)

##### 取代文字技巧

- 逐一取代：搜尋文字 `/old` -&gt; `cw` -&gt; 輸入取代文字 new -&gt; 離開編輯模式 `Esc` -&gt; 下一個搜尋 `n` -&gt; 重複上次變更 `.`
- 選擇多行取代： 
    1. 行模式：shift + `v`
    2. 選擇多行
    3. 取代關鍵字：`:s/old/new/g` (*反斜線也可以用井字取代*)

##### 複製整行

```
# 複製指定的行號，然後移到要貼上的行，輸入 p 貼上
:<行號>yank

# 複製指定的行號，貼上至目前行的下方. 使用 copy 或 t
:<行號>copy.
:<行號>t.

# 複製目前行下方第 10 行文字，並貼上至目前行
:+10t.

# 複製目前行上方第 10 行文字，並貼上至目前行
:-10t.

# 複製連續多行文字(33 ~ 44)至目前位置
:33,44t.
```

##### 在文字區段的每行行首插入多個空白字元

1. Ctrl + `v`
2. 移到第一行的開頭處
3. 往下移最後行
4. Shift + `I`
5. 輸入要插入的空白
6. Esc 跳離後完成

##### 在文字區段的每行行尾插入`;`

1. 移到第一行的中間處
2. Ctrl + `v`
3. 往下移至最後行
4. Shift + `$`
5. Shift + `A`
6. 輸入要插入的文字 `;`
7. Esc 跳離後完成

##### 快速註解

1. Shift + `v`
2. 選取多行
3. `:norm i#` (加上註解符號)
4. `:norm x` (移除註解符號)

##### 選取文字另存新檔

1. Shift + `v` (Visually Seleting)
2. 選取多行
3. `:w /path/to/newfile` (Save as newfile)
4. `gv` (reselect the last visual selection)
5. `d` (delete that selection)

##### 檔名自動補全 (auto-complete)

1. 進入編輯模式
2. 輸入 /etc/profile（任意路徑）
3. Ctrl + `x` -&gt; Ctrl `f`

##### Buffers

同時編輯多個檔案

- `vim aa.txt bb.txt cc.txt` : 開啟多個檔案
- `:buffers` : 列出目前已開啟的檔案清單
- `:bn[ext]` : 切換至下一個檔案
- `:bp[revious]` : 切換至上一個檔案
- `:e filename` : 開啟檔案
- `:b filename` : 切換至檔案 (檔名不用完整)
- `:b#` : 切換至檔案編號

##### Tutorials

- [Youtube Channel - Vim (TheFrugalComputerGuy)](https://www.youtube.com/watch?v=1lzXr-MztOU&list=PLy7Kah3WzqrEjsuvhT46fr28Q11oa5ZoI)
- [VIM Colors Online](https://vimcolors.com/)
- [VimTricks](https://vimtricks.com/)