# `vi` —— 終端中的編輯器python
## 目標程序員
* `vi` 簡介
* 打開和新建文件
* 三種工做模式
* 經常使用命令
* 分屏命令
* 經常使用命令速查圖編程
## 01. `vi` 簡介vim
### 1.1 學習 `vi` 的目的瀏覽器
* 在工做中,要對 **服務器** 上的文件進行 **簡單** 的修改,可使用 `ssh` 遠程登陸到服務器上,而且使用 `vi` 進行快速的編輯便可
* 常見須要修改的文件包括:
* **源程序**
* **配置文件**,例如 `ssh` 的配置文件 `~/.ssh/config`
> * 在沒有圖形界面的環境下,要編輯文件,`vi` 是最佳選擇!
> * 每個要使用 Linux 的程序員,都應該或多或少的學習一些 `vi` 的經常使用命令bash
### 1.2 vi 和 vim服務器
* 在不少 `Linux` 發行版中,直接把 `vi` 作成 `vim` 的軟鏈接app
#### vissh
* `vi` 是 `Visual interface` 的簡稱,是 `Linux` 中 **最經典** 的文本編輯器
* `vi` 的核心設計思想 —— **讓程序員的手指始終保持在鍵盤的核心區域,就能完成全部的編輯操做**編輯器
* `vi` 的特色:
* **沒有圖形界面** 的 **功能強大** 的編輯器
* 只能是編輯 **文本內容**,不能對字體、段落進行排版
* **不支持鼠標操做**
* **沒有菜單**
* **只有命令**
* `vi` 編輯器在 **系統管理**、**服務器管理** 編輯文件時,**其功能永遠不是圖形界面的編輯器能比擬的**
#### `vim`
**vim = vi improved**
* `vim` 是從 `vi` 發展出來的一個文本編輯器,支持 **代碼補全**、**編譯** 及 **錯誤跳轉** 等方便編程的功能特別豐富,在程序員中被普遍使用,被稱爲 **編輯器之神**
#### 查詢軟鏈接命令(知道)
* 在不少 `Linux` 發行版中直接把 `vi` 作成 `vim` 的軟鏈接
```bash
# 查找 vi 的運行文件
$ which vi
$ ls -l /usr/bin/vi
$ ls -l /etc/alternatives/vi
$ ls -l /usr/bin/vim.basic
# 查找 vim 的運行文件
$ which vim
$ ls -l /usr/bin/vim
$ ls -l /etc/alternatives/vim
$ ls -l /usr/bin/vim.basic
```
## 02. 打開和新建文件
* 在終端中輸入 `vi` **在後面跟上文件名** 便可
```bash
$ vi 文件名
```
* 若是文件已經存在,會直接打開該文件
* 若是文件不存在,會新建一個文件
### 2.1 打開文件而且定位行
* 在平常工做中,有可能會遇到 **打開一個文件,並定位到指定行** 的狀況
* 例如:在開發時,**知道某一行代碼有錯誤**,能夠 **快速定位** 到出錯代碼的位置
* 這個時候,可使用如下命令打開文件
```bash
$ vi 文件名 +行數
```
> 提示:若是隻帶上 `+` 而不指定行號,會直接定位到文件末尾
### 2.2 異常處理
* 若是 `vi` 異常退出,在磁盤上可能會保存有 **交換文件**
* 下次再使用 `vi` 編輯該文件時,會看到如下屏幕信息,按下字母 `d` 能夠 **刪除交換文件** 便可
> 提示:按下鍵盤時,注意關閉輸入法
## 03. 三種工做模式
* `vi` 有三種基本工做模式:
1. **命令模式**
* **打開文件首先進入命令模式**,是使用 `vi` 的 **入口**
* 經過 **命令** 對文件進行常規的編輯操做,例如:**定位**、**翻頁**、**複製**、**粘貼**、**刪除**……
* 在其餘圖形編輯器下,經過 **快捷鍵** 或者 **鼠標** 實現的操做,都在 **命令模式** 下實現
2. **末行模式** —— 執行 **保存**、**退出** 等操做
* 要退出 `vi` 返回到控制檯,須要在末行模式下輸入命令
* **末行模式** 是 `vi` 的 **出口**
3. **編輯模式** —— 正常的編輯文字
> 提示:在 `Touch Bar` 的 Mac 電腦上 ,按 `ESC` 不方便,可使用 `CTRL + [` 替代
### 末行模式命令
| 命令 | 英文 | 功能 |
| :---: | :---: | --- |
| w | write | 保存 |
| q | quit | 退出,若是沒有保存,不容許退出 |
| q! | quit | 強行退出,不保存退出 |
| wq | write & quit | 保存並退出 |
| x | | 保存並退出 |
## 04. 經常使用命令
### 命令線路圖
0. 重複次數
* 在命令模式下,**先輸入一個數字**,**再跟上一個命令**,可讓該命令 **重複執行指定次數**
1. 移動和選擇(**多練**)
* `vi` 之因此快,關鍵在於 **可以快速定位到要編輯的代碼行**
* **移動命令** 可以 和 **編輯操做** 命令 **組合使用**
2. 編輯操做
* **刪除**、**複製**、**粘貼**、**替換**、**縮排**
3. 撤銷和重複
4. 查找替換
5. 編輯
#### 學習提示
1. `vi` 的命令較多,**不要指望一會兒所有記住**,個別命令忘記了,只是會影響編輯速度而已
2. 在使用 `vi` 命令時,注意 **關閉中文輸入法**
### 4.1 移動(基本)
* 要熟練使用 `vi`,首先應該學會怎麼在 **命令模式** 下樣快速移動光標
* **編輯操做命令**,可以和 **移動命令** 結合在一塊兒使用
#### 1) 上、下、左、右
| 命令 | 功能 | 手指 |
| :---: | --- | :---: |
| h | 向左 | 食指 |
| j | 向下 | 食指 |
| k | 向上 | 中指 |
| l | 向右 | 無名指 |
#### 2) 行內移動
| 命令 | 英文 | 功能 |
| :---: | :---: | --- |
| w | word | 向後移動一個單詞 |
| b | back | 向前移動一個單詞 |
| 0 | | 行首 |
| ^ | | 行首,第一個不是空白字符的位置 |
| $ | | 行尾 |
#### 3) 行數移動
| 命令 | 英文 | 功能 |
| :---: | :---: | --- |
| gg | go | 文件頂部 |
| G | go | 文件末尾 |
| 數字gg | go | 移動到 數字 對應行數 |
| 數字G | go | 移動到 數字 對應行數 |
| :數字 | | 移動到 數字 對應行數 |
#### 4) 屏幕移動
| 命令 | 英文 | 功能 |
| :---: | :---: | --- |
| Ctrl + b | back | 向上翻頁 |
| Ctrl + f | forward | 向下翻頁 |
| H | Head | 屏幕頂部 |
| M | Middle | 屏幕中間 |
| L | Low | 屏幕底部 |
### 4.2 移動(程序)
#### 1) 段落移動
* `vi` 中使用 空行 來區分段落
* 在程序開發時,一般 **一段功能相關的代碼會寫在一塊兒** —— 之間沒有空行
| 命令 | 功能 |
| :---: | --- |
| { | 上一段 |
| } | 下一段 |
#### 2) 括號切換
* 在程序世界中,`()`、`[]`、`{}` 使用頻率很高,並且 **都是成對出現的**
| 命令 | 功能 |
| :---: | --- |
| % | 括號匹配及切換 |
#### 3) 標記
* 在開發時,某一塊代碼可能**須要稍後處理**,例如:編輯、查看
* 此時先使用 `m` 增長一個標記,這樣能夠 **在須要時快速地跳轉回來** 或者 **執行其餘編輯操做**
* **標記名稱** 能夠是 `a~z` 或者 `A~Z` 之間的任意 **一個** 字母
* 添加了標記的 **行若是被刪除**,**標記同時被刪除**
* 若是 **在其餘行添加了相同名稱的標記**,**以前添加的標記也會被替換掉**
| 命令 | 英文 | 功能 |
| :---: | :---: | --- |
| mx | mark | 添加標記 x,x 是 a~z 或者 A~Z 之間的任意一個字母 |
| 'x | | 直接定位到標記 x 所在位置 |
### 4.3 選中文本(可視模式)
* 學習 `複製` 命令前,應該先學會 **怎麼樣選中 要複製的代碼**
* 在 `vi` 中要選擇文本,須要先使用 `Visual` 命令切換到 **可視模式**
* `vi` 中提供了 **三種** 可視模式,能夠方便程序員選擇 **選中文本的方式**
* 按 `ESC` 能夠放棄選中,返回到 **命令模式**
| 命令 | 模式 | 功能 |
| :---: | --- | --- |
| v | 可視模式 | 從光標位置開始按照正常模式選擇文本 |
| V | 可視行模式 | 選中光標通過的完整行 |
| Ctrl + v | 可視塊模式 | 垂直方向選中文本 |
* **可視模式**下,能夠和 **移動命令** 連用,例如:`ggVG` 可以選中全部內容
### 4.4 撤銷和恢復撤銷
* 在學習編輯命令以前,先要知道怎樣撤銷以前一次 **錯誤的** 編輯動做!
| 命令 | 英文 | 功能 |
| :---: | :---: | --- |
| u | undo | 撤銷上次命令 |
| CTRL + r | redo | 恢復撤銷的命令 |
### 4.5 刪除文本
| 命令 | 英文 | 功能 |
| :---: | :---: | --- |
| x | cut | 刪除光標所在字符,或者選中文字 |
| d(移動命令) | delete | 刪除移動命令對應的內容 |
| dd | delete | 刪除光標所在行,能夠 ndd 複製多行 |
| D | delete | 刪除至行尾 |
> 提示:若是使用 **可視模式** 已經選中了一段文本,那麼不管使用 `d` 仍是 `x`,均可以刪除選中文本
* 刪除命令能夠和 **移動命令** 連用,如下是常見的組合命令:
```
* dw # 從光標位置刪除到單詞末尾
* d0 # 從光標位置刪除到一行的起始位置
* d} # 從光標位置刪除到段落結尾
* ndd # 從光標位置向下連續刪除 n 行
* d代碼行G # 從光標所在行 刪除到 指定代碼行 之間的全部代碼
* d'a # 從光標所在行 刪除到 標記a 之間的全部代碼
```
### 4.6 複製、粘貼
* `vi` 中提供有一個 **被複制文本的緩衝區**
* **複製** 命令會將選中的文字保存在緩衝區
* **刪除** 命令刪除的文字會被保存在緩衝區
* 在須要的位置,使用 **粘貼** 命令能夠將緩衝區的文字插入到光標所在位置
| 命令 | 英文 | 功能 |
| :---: | :---: | --- |
| y(移動命令) | copy | 複製 |
| yy | copy | 複製一行,能夠 nyy 複製多行 |
| p | paste | 粘貼 |
**提示**
* 命令 `d`、`x` 相似於圖形界面的 **剪切操做** —— `CTRL + X`
* 命令 `y` 相似於圖形界面的 **複製操做** —— `CTRL + C`
* 命令 `p` 相似於圖形界面的 **粘貼操做** —— `CTRL + V`
* `vi` 中的 **文本緩衝區一樣只有一個**,若是後續作過 **複製、剪切** 操做,以前緩衝區中的內容會被替換
**注意**
* `vi` 中的 **文本緩衝區** 和系統的 **剪貼板** 不是同一個
* 因此在其餘軟件中使用 `CTRL + C` 複製的內容,不能在 `vi` 中經過 `P` 命令粘貼
* 能夠在 **編輯模式** 下使用 **鼠標右鍵粘貼**
### 4.7 替換
| 命令 | 英文 | 功能 | 工做模式 |
| :---: | :---: | --- | --- |
| r | replace | 替換當前字符 | 命令模式 |
| R | replace | 替換當前行光標後的字符 | 替換模式 |
* `R` 命令能夠進入 **替換模式**,替換完成後,按下 `ESC` 能夠回到 **命令模式**
* **替換命令** 的做用就是不用進入 **編輯模式**,對文件進行 **輕量級的修改**
### 4.8 縮排和重複執行
| 命令 | 功能 |
| :---: | --- |
| >> | 向右增長縮進 |
| << | 向左減小縮進 |
| . | 重複上次命令 |
* **縮排命令** 在開發程序時,**統一增長代碼的縮進** 比較有用!
* 一次性 **在選中代碼前增長 4 個空格**,就叫作 **增長縮進**
* 一次性 **在選中代碼前刪除 4 個空格**,就叫作 **減小縮進**
* 在 **可視模式** 下,縮排命令只須要使用 **一個** `>` 或者 `<`
> 在程序中,**縮進** 一般用來表示代碼的歸屬關係
>
> * 前面空格越少,代碼的級別越高
> * 前面空格越多,代碼的級別越低
### 4.9 查找
#### 常規查找
| 命令 | 功能 |
| :---: | --- |
| /str | 查找 str |
* 查找到指定內容以後,使用 `Next` 查找下一個出現的位置:
* `n`: 查找下一個
* `N`: 查找上一個
* 若是不想看到高亮顯示,能夠隨便查找一個文件中不存在的內容便可
#### 單詞快速匹配
| 命令 | 功能 |
| :---: | --- |
| * | 向後查找當前光標所在單詞 |
| # | 向前查找當前光標所在單詞 |
* 在開發中,經過單詞快速匹配,能夠快速看到這個單詞在其餘什麼位置使用過
### 4.10 查找並替換
* 在 `vi` 中查找和替換命令須要在 **末行模式** 下執行
* 記憶命令格式:
```
:%s///g
```
#### 1) 全局替換
* **一次性**替換文件中的 **全部出現的舊文本**
* 命令格式以下:
```
:%s/舊文本/新文本/g
```
#### 2) 可視區域替換
* **先選中** 要替換文字的 **範圍**
* 命令格式以下:
```
:s/舊文本/新文本/g
```
#### 3) 確認替換
* 若是把末尾的 `g` 改爲 `gc` 在替換的時候,會有提示!**推薦使用!**
```
:%s/舊文本/新文本/gc
```
1. `y` - `yes` 替換
2. `n` - `no` 不替換
3. `a` - `all` 替換全部
4. `q` - `quit` 退出替換
5. `l` - `last` 最後一個,並把光標移動到行首
6. `^E` 向下滾屏
7. `^Y` 向上滾屏
### 4.11 插入命令
* 在 `vi` 中除了經常使用的 `i` 進入 **編輯模式** 外,還提供瞭如下命令一樣能夠進入編輯模式:
| 命令 | 英文 | 功能 | 經常使用 |
| :---: | :---: | --- | :---: |
| i | insert | 在當前字符前插入文本 | 經常使用 |
| I | insert | 在行首插入文本 | 較經常使用 |
| a | append | 在當前字符後添加文本 | |
| A | append | 在行末添加文本 | 較經常使用 |
| o | | 在當前行後面插入一空行 | 經常使用 |
| O | | 在當前行前面插入一空行 | 經常使用 |
#### 演練 1 —— 編輯命令和數字連用
* 在開發中,可能會遇到連續輸入 `N` 個一樣的字符
> 在 `Python` 中有簡單的方法,可是其餘語言中一般須要本身輸入
* 例如:`**********` 連續 10 個星號
要實現這個效果能夠在 **命令模式** 下
1. 輸入 `10`,表示要重複 10 次
2. 輸入 `i` 進入 **編輯模式**
3. 輸入 `*` 也就是重複的文字
4. 按下 `ESC` 返回到 **命令模式**,返回以後 `vi` 就會把第 `二、3` 兩步的操做重複 `10` 次
> 提示:正常開發時,在 **進入編輯模式以前,不要按數字**
#### 演練 2 —— 利用 可視塊 給多行代碼增長註釋
* 在開發中,可能會遇到一次性給多行代碼 **增長註釋** 的狀況
> 在 `Python` 中,要給代碼增長註釋,能夠在代碼前增長一個 `# `
要實現這個效果能夠在 **命令模式** 下
1. 移動到要添加註釋的 **第 1 行代碼**,按 `^` 來到行首
2. 按 `CTRL + v` 進入 **可視塊** 模式
3. 使用 `j` 向下連續選中要添加的代碼行
4. 輸入 `I` 進入 **編輯模式**,並在 **行首插入**,注意:必定要使用 **I**
5. 輸入 `# ` 也就是註釋符號
6. 按下 `ESC` 返回到 **命令模式**,返回以後 `vi` 會在以前選中的每一行代碼 **前** 插入 `# `
## 05. 分屏命令
* 屬於 `vi` 的高級命令 —— 能夠 **同時編輯和查看多個文件**
### 5.1 末行命令擴展
**末行命令** 主要是針對文件進行操做的:**保存**、**退出**、**保存&退出**、**搜索&替換**、**另存**、**新建**、**瀏覽文件**
| 命令 | 英文 | 功能 |
| :---: | :---: | --- |
| :e . | edit | 會打開內置的文件瀏覽器,瀏覽要當前目錄下的文件 |
| :n 文件名 | new | 新建文件 |
| :w 文件名 | write | 另存爲,可是仍然編輯當前文件,並不會切換文件 |
> 提示:切換文件以前,必須保證當前這個文件已經被保存!
* 已經學習過的 **末行命令**:
| 命令 | 英文 | 功能 |
| :---: | :---: | --- |
| :w | write | 保存 |
| :q | quit | 退出,若是沒有保存,不容許退出 |
| :q! | quit | 強行退出,不保存退出 |
| :wq | write & quit | 保存並退出 |
| :x | | 保存並退出 |
| :%s///gc | | 確認搜索並替換 |
> 在實際開發中,可使用 `w` 命令 **階段性的備份代碼**
### 5.2 分屏命令
* 使用 **分屏命令**,能夠 **同時編輯和查看多個文件**
| 命令 | 英文 | 功能 |
| :---: | :---: | --- |
| :sp [文件名] | split | 橫向增長分屏 |
| :vsp [文件名] | vertical split | 縱向增長分屏 |
#### 1) 切換分屏窗口
> 分屏窗口都是基於 `CTRL + W` 這個快捷鍵的,`w` 對應的英文單詞是 `window`
| 命令 | 英文 | 功能 |
| :---: | :---: | --- |
| w | window | 切換到下一個窗口 |
| r | reverse | 互換窗口 |
| c | close | 關閉當前窗口,可是不能關閉最後一個窗口 |
| q | quit | 退出當前窗口,若是是最後一個窗口,則關閉 vi |
| o | other | 關閉其餘窗口 |
#### 2) 調整窗口大小
> 分屏窗口都是基於 `CTRL + W` 這個快捷鍵的,`w` 對應的英文單詞是 `window`
| 命令 | 英文 | 功能 |
| :---: | :---: | --- |
| + | | 增長窗口高度 |
| - | | 減小窗口高度 |
| > | | 增長窗口寬度 |
| < | | 減小窗口寬度 |
| = | | 等分窗口大小 |
> 調整窗口寬高的命令能夠和數字連用,例如:`5 CTRL + W +` 連續 5 次增長高度
## 06. 經常使用命令速查圖
### vimrc
* `vimrc` 是 `vim` 的配置文件,能夠設置 vim 的配置,包括:**熱鍵**、**配色**、**語法高亮**、**插件** 等
* `Linux` 中 `vimrc` 有兩個位置,**家目錄下的配置文件優先級更高**
```
/etc/vim/vimrc
~/.vimrc
```
* 經常使用的插件有: * 代碼補全 * 代碼摺疊 * 搜索 * Git 集成 * ……* 網上有不少高手已經配置好的針對 `python` 開發的 `vimrc` 文件,能夠下載過來直接使用,或者等你們多 `Linux` 比較熟悉後,再行學習!