使用經驗小結,持續更新於vim無插件使用
目錄
vim的四種模式
- 一般模式:normal模式。可以移動光標,刪除字符或整行,也可複製、粘貼文件數據。打開vim就是進入這個模式,3個模式的切換也是在這裏中轉。
編輯模式:一般模式下按下
i
I
o
O
a
A
r
R
s
S
任何一個進入該模式。可以編輯文件內容,按Esc回到一般模式。i
I
是insert(在光標所在字符前和行首)o
O
是open新行(在光標所在行的下面另起一新行和在光標所在行的上面另起一行開始插入a
A
是append(在在光標所在字符後和在光標所在你行的行尾)s
S
是刪除(光標所在的字符並開始插入和光標所在行並開始插入),即substitute替換。r
R
是replace光標所在的字符和變成替換模式
- 命令行模式:一般模式下按下
:
/
?
任何一個進入該模式(下文會介紹這些符號的含義)。可以查找數據操作,讀取、保存、大量替換字符、離開vim、顯示行號等操作,按Esc回到一般模式。 - 可視模式:一般模式下按下
v
V
ctr+v
進入可視模式,相當於高亮選取文本後的普通模式,即在該模式下進行任意選擇特定區域且被選擇的區域高亮顯示,v
選擇單位:一個字符;V
又稱爲可視行模式,選擇單位:行;ctr+v
又稱爲可視塊模式,選擇的單位:方塊;這三者都有用,詳細看下文。
移動
normal模式下:
w
→ 到下一個單詞的開頭 e
→ 到下一個單詞的結尾 (單詞默認是以空格分隔的)
W
→ 到下一個字符串的開頭 E
→ 到下一個字符串的結尾 (字符串指的是數字、字母、下劃線組成的字符串)
B
→ 到前一個字符串的首字符上 b
→ “命令則將光標移動到前一個word的首字符上。
默認上來說,一個單詞由字母,數字和下劃線組成
如果你認爲單詞是由blank字符分隔符,那麼你需要使用大寫的E和W(陳皓: 注)
0
→ 數字零,到行頭
^
→ 到本行第一個不是blank字符的位置(所謂blank字符就是空格,tab,換行,回車等)
$
→ 到本行行尾
g_
→ 到本行最後一個不是blank字符的位置
%
→ 到光標所在這對括號的另外一個
gg
→ 首行
G
→ 最後一行
h
j
k
l
(強例推薦使用其移動光標,但不必需) →你也可以使用光標鍵 (←↓↑→). 注: j 向下伸,k是向上伸
- 高頻使用場景1: 修改行中某個變量名 先移把光標移動:
w
andb
、W
andB
(或者如果本行太長可用下文的搜索功能)到目的單詞 - 高頻使用場景2: 修改縮進,跳到行頭
^
- 高頻使用場景3: 查看函數或類的完整或者變量作用域
%
- 高頻使用場景4: 切分屏幕之後,跳轉不同窗口:
ctrl+w+(h or j or k or l)
- 高頻使用場景5: 左下上右移動
(h、j、k、l)
- 高頻使用場景6: 刪除到末尾:
d$
刪除到開頭:d^
標記
簡記:標記是爲了更好地查找,normal模式下:
mx
mean: mark x, x is mark name;
'x
mean: go to the position of x mark
- 高頻使用場景1: 在函數中看到調用其他函數,你想去看怎麼定義的,你看完之後要回來,那麼先標記一下,然後在跳回來。
語法相關的跳轉
normal模式下:
gd
意思: go to definition- 先按
[
再按ctrl+d
跳轉到#define處 語言支持不太良好 - 先按
[
再按ctrl+i
跳轉到函數、變量和#define 語言支持不太良好
快速翻頁
normal模式下:
夥伴1 | 夥伴2 |
---|---|
ctr + d page down |
ctr + u page up |
ctr + f page former |
ctr + b page back |
動作操作指令
normal模式下:
夥伴1 | 夥伴2 |
---|---|
d **d**elete a character and copy to paste board |
D 從光標所在位置一直刪除到行尾 |
y **c**opy to paste board |
Y 複製一行(=yy ) |
s **s**ubstitue a character |
S 替換光標所在行 |
r **r**eplace a character |
R 不常用,表示進入替換模式 |
c **c**hange a character |
C 不常用,表示修改光標所在位置一直到行尾,與S 呈現效果一樣 |
p **p**aste after the cursor |
P 黏貼在光標位置之前(如果是黏貼一整行,則黏貼到上一行) |
u **u**ndo a operation |
U 一次性撤銷對一整行的所有操作 |
x cut a character |
X 不常用, 向左剪切,即退格:刪除光標的左邊那個字符 |
* 向下搜索當前光標所在的單詞,找到就跳到下一個單詞 |
# 向上搜索當前光標所在的單詞,找到就跳到上一個單詞 |
/word 向下全文搜索單詞word,跳到匹配的第一個單詞,如果多個,繼續向下查找按n鍵(順着命令本來方向),向上找按N鍵。 |
?word 向上全文搜索單詞word,跳到匹配的第一個單詞,如果多個,繼續向上查找按n鍵(順着命令本來方向),向下找按N鍵。 |
a **a**ppend after the cursor |
A 是附加在光標所在行的行尾) |
i **i**nsert before the cursor |
I 插入在光標所在行的行首 |
o 在光標所在行的下面另起一新行,open the new world? |
O 在光標所在行的上面另起一行開始插入 |
v 進入**v**isual模式,用來選擇區域(可跨行),用來配合後續的其他操作(增刪改查) |
v 進入visual行模式,用來選擇一些行,用來配合後續的其他操作(增刪改查) |
f **f**ind a character after the cursor |
F 向光標位置之前查找一個字符 |
t **t**ill a character tx和fx相同,區別是跳到字符x前 |
T Tx 和Fx相同,區別是跳到字符x後 |
單獨成型
.
重複剛纔的操作
~
轉換大小寫
- 可以對變量首字母改變大小寫
- 可以結合下文提供的命令的選擇一個字符串(變量),然後再改變整個字符串(變量)的大小寫。比如:宏定義
=
自動格式化
- 對當前行用
==
(連按=兩次), 或對多行用n==
(n是自然數)表示自動縮進從當前行起的下面n行 - 或者進入可視行模式選擇一些行後再
=
進行格式化,相當於一般IDE裏的code format。 - 使用
gg=G
可對整篇代碼進行排版。
撤銷和恢復
u
undo撤銷上一步的操作,命令可以組合,例如Nu
N是任意一個整數,表示撤銷N步操作,以下類同。U
恢復當前行(即一次撤銷對當前行的全部操作)ctr+r
control+redo 恢復上一步被撤銷的操作CTRL-R
回退前一個命令
文本替換
normal 模式下輸入替換命令: :[range]s/pattern/string/[flags]
- pattern 就是要被替換掉的字串,可以用 regexp 來表示。
- string 將 pattern 由 string 所取代。
- [range] 有以下一些取值:
[range] | 含義 |
---|---|
無 | 默認爲光標所在的行 |
. | 光標所在當前的行 |
N | 第N行 |
$ | 最後一行 |
‘a | 標記a所在的行(之前要使用ma做過標記) |
.+1 | 當前光標所在行的下面一行 |
$-1 | 倒數第二行,可以對某一行加減某個數值來確定取得相對的行 |
22,33 | 第22~33行 |
1,$ | 第1行 到 最後一行 |
1,. | 第1行 到 當前行 |
.,$ | 當前行 到 最後一行 |
‘a,’b | 標記a所在的行 到 標記b所在的行(之前要使用ma和mb做過標記) |
% | 所有行(與 1,$ 等價) |
?str? | 從當前位置向上搜索,找到的第一個str所在的行 (其中str可以是任何字符串或者正則表達式) |
/str/ | 從當前位置向下搜索,找到的第一個str所在的行(其中str可以是任何字符串或者正則表達式) |
注意,上面的所有用於range的表示方法都可以通過 +、- 操作來設置相對偏移量。
- [flags]有以下一些取值:
flags | 含義 |
---|---|
g | 對指定範圍內的所有匹配項(global)進行替換 |
c | 在替換前請求用戶確認(confirm) |
e | 忽略執行過程中的錯誤 |
i | ignore 不分大小寫 |
無 | 只對指定範圍內的第一個匹配項進行替換 |
注意:上面的所有flags都可以組合起來使用,比如 gc 表示對指定範圍內的 所有匹配項進行替換,並且在每一次替換之前都會請用戶確認。
例子
替換某些行的內容
:10,20s/from/to/g
對第10行到第20行的內容進行替換。:1,$s/from/to/g
對第一行到最後一行的內容進行替換(即全部文本):1,.s/from/to/g
對第一行到當前行的內容進行替換。:.,$s/from/to/g
對當前行到最後一行的內容進行替換。:'a,'bs/from/to/g
對標記a和b之間的行(含a和b所在的行)進行替換,其中a和b是之前用m命令所做的標記。
替換所有行的內容::%s/from/to/g
動作的重複
normal模式下,任意一個動作都可以重複
注:N是數字
- 數字:
Nyy
從當前行算起向下拷貝N行、Ndd
從當前行算起向下刪除N行、Ngg
跳到第N行、dNw
刪除從當前光標開始到第N個單詞前(不包含空白,即刪除N-1個單詞)、yNe
拷貝從當前光標到第N個單詞末尾(注意:yy
=1yy
dd
=1dd
)、d$
刪除到本行末尾 - 重複前一個命令:
.N
(N表示重複的次數)
區塊選擇
注:中括號內容爲可選項
normal模式下:[ctr + ] v + (h or j or k or l)
- 高頻使用場景1:
[ctr + ] v
選中某些行的行頭之後 再按=
效果:代碼格式自動調整 - 高頻使用場景2:
[ctr + ] v
選中某些行的行頭之後 再按I
再按註釋的符號(比如://
)最後按ESC
效果:選中的這些行全部註釋了 多行快速註釋 - 高頻使用場景3:
[ctr + ] v
選中某些行的行頭之後 再按A
再按註釋的內容 最後按ESC
(比如://這是測試代碼
) 效果:選中的這些行的行尾全部註釋上//這是測試代碼
多行快速註釋 - 高頻使用場景4:
[ctr + ] v
選中某些行的行頭的註釋(比如://
)之後 再按d
最後按ESC
效果:選中的這些行全部註釋刪除了 多行快速刪除註釋 - 高頻使用場景5:
[ctr + ] v
選中某些區塊之後,再按上文動作的按鍵實現區域操作
組合的強大
操作光標所在的一個單詞
normal模式下:
動作 + 移動 [+重複次數]
前面已經已經大量使用組合,這裏繼續:
動作操作指令+範圍 | 效果 |
---|---|
cw or c1 or c1w | change from current cursor to word end |
caw | change whole word including current cursor |
dw or d1 or d1w | delete from current cursor to word end |
daw | delete whole word including current cursor |
yw or y1 or y1w | copy from current cursor to word end |
yaw | copy whole word including current cursor |
範圍+動作操作指令 | 效果 |
---|---|
bve 或 BvE + c/d/y |
操作一個變量或字符串 |
上表都是高頻使用場景
自動補全
在insert模式下直接按: 最常用的補全
ctrl + n
ctrl + p
智能補全
ctrl + x //進入補全模式
- 整行補全
CTRL-X
CTRL-L
- 根據當前文件裏關鍵字補全
CTRL-X
CTRL-N
- 根據字典補全
CTRL-X
CTRL-K
- 根據同義詞字典補全
CTRL-X
CTRL-T
- 根據頭文件內關鍵字補全
CTRL-X
CTRL-I
- 根據標籤補全
CTRL-X
CTRL-]
- 補全文件名
CTRL-X
CTRL-F
- 補全宏定義
CTRL-X
CTRL-D
- 補全vim命令
CTRL-X
CTRL-V
- 用戶自定義補全方式
CTRL-X
CTRL-U
- 拼寫建議
CTRL-X
CTRL-S
//例如:一個英文單詞
摺疊
normal模式下:
zo (折+open)
zi (折+indent)
zc (折+close)
切分屏幕
切分命令,normal模式下,輸入
vs
(說明:vertically split 縱向切分屏幕)sp
(說明:split 橫向切分屏幕,即默認的切分方式)
屏幕相互跳轉
ctr + w
再按h
或j
或k
或l
- 解釋:
h
: left ,j
: down ,k
: up,l
: right
調整切分窗口的大小
ctrl+w
在按+
或-
或=
,當然在按+
或-
或=
之前先按一個數字,改變窗口高度,=
是均分的意思。。- 在normal模式下 輸入
:resize -N
或:resize +N
明確指定窗口減少或增加N行 ctrl+w
在按<
或>
或=
,當然在按<
或>
或=
之前先按一個數字,改變窗口寬度,=
是均分的意思。- 有時候預覽大文件,感覺切分的屏幕太小,
ctrl+w
+T
移動當前窗口至新的標籤頁。
tab窗口
vim 從 vim7 開始加入了多標籤切換的功能, 相當於多窗口. 之前的版本雖然也有多文件編輯功能, 但是總之不如這個方便啦。 用法normal模式下:
:tabnew
[++opt選項] [+cmd] 文件 建立對指定文件新的tab:tabc
關閉當前的tab or:q
:tabo
關閉其他的tab:tabs
查看所有打開的tab:tabp
前一個previous tab window:tabn
後一個next tab window
標準模式下: gt
, gT
可以直接在tab之間切換。 還有很多他命令, :help table 吧。
目錄
normal模式下:
:Te
以tab窗口形式顯示當前目錄 然後可進行切換目錄、打開某個文件:!ls
這種是vim調用shell命令的方式:!ls + shell_command
,但不是以tab窗口的形式顯示當前目錄。
成對符號的內容操作
以下命令可以對標點內的內容進行操作:
ci'
ci"
ci(
ci[
ci{
ci<
分別change這些配對標點符號中的文本內容di'
di"
di(
或dib
di[
di{
或diB
di<
分別刪除這些配對標點符號中的文本內容yi'
yi"
yi(
yi[
yi{
yi<
分別複製這些配對標點符號中的文本內容vi'
vi"
vi(
vi[
vi{
vi<
分別選中這些配對標點符號中的文本內容cit
dit
yit
vit
分別操作一對標籤之間的內容,編輯html很好用
另外如果把上面的 i
改成 a
可以同時操作配對標點和配對標點內的內容,舉個例子:
比如要操作的文本:111”222”333,將光標移到”222”的任何一個字符處輸入命令
- di” ,文本會變成: 111”“333
- 若輸入命令 da” ,文本會變成: 111333
剪貼板
1. 簡單複製和粘貼
vim提供12個剪貼板,它們的名字分別爲vim有11個粘貼板,分別是0、1、2、…、9、a、“。如果開啓了系統剪貼板,則會另外多出兩個+和*。使用:reg命令,可以查看各個粘貼板裏的內容。
在vim中簡單用y
只是複製到 "
的粘貼板裏,同樣用p
粘貼的也是這個粘貼板裏的內容。
2. 複製和粘貼到指定剪貼板
要將vim的內容複製到某個粘貼板,進入正常模式後,選擇要複製的內容,然後按 "Ny
完成複製,其中N爲粘貼板號(注意是按一下雙引號然後按粘貼板號最後按y),例如要把內容複製到粘貼板a,選中內容後按”ay就可以了。
要將vim某個粘貼板裏的內容粘貼進來,需要退出編輯模式,在正常模式按"Np
,其中N爲粘貼板號。比如,可以按"5p
將5號粘貼板裏的內容粘貼進來,也可以按"+p
將系統全局粘貼板裏的內容粘貼進來。
3. 系統剪貼板
查看vim支持的剪切板,normal模式下輸入:reg
和系統剪貼板的交互又應該怎麼用呢?遇到問題一般第一個尋找的是幫助文檔,剪切板即是 Clipboard。通過:h clipboard
查看幫助
星號和加號+粘貼板是系統粘貼板。在windows系統下, 和 + 剪貼板是相同的。對於 X11 系統, * 剪貼板存放選中或者高亮的內容, + 剪貼板存放複製或剪貼的內容。打開clipboard選項,可以訪問 + 剪貼板;打開xterm_clipboard,可以訪問 * 剪貼板。 * 剪貼板的一個作用是,在vim的一個窗口選中的內容,可以在vim的另一個窗口取出。
複製到系統剪貼板
example:
"*y
"+y
"+Nyy
複製N行到系統剪切板
解釋:
命令 | 含義 |
---|---|
{Visual}”+y | copy the selected text into the system clipboard |
“+y{motion} | copy the text specified by {motion} into the system clipboard |
:[range]yank+ | copy the text specified by [range] into the system clipboard |
剪切到系統剪貼板
example:
“+dd
從系統剪貼板粘貼到vim
normal模式下:
"*p
"+p
:put+
含義: Ex command puts contents of system clipboard on a new line
插入模式下:
<C-r>+
含義: From insert mode (or commandline mode)
“+p比 Ctrl-v 命令更好,它可以更快更可靠地處理大塊文本的粘貼,也能夠避免粘貼大量文本時,發生每行行首的自動縮進累積,因爲Ctrl-v是通過系統緩存的stream處理,一行一行地處理粘貼的文本。
vim編碼
Vim 可以很好的編輯各種字符編碼的文件,這當然包括UCS-2、UTF-8 等流行的 Unicode 編碼方式。
四個字符編碼選項,encoding、fileencoding、fileencodings、termencoding (這些選項可能的取值請參考 Vim 在線幫助 :help encoding-names,它們的意義如下:
- encoding: Vim 內部使用的字符編碼方式
包括 Vim 的 buffer (緩衝區)、菜單文本、消息文本等。默認是根據你的locale選擇.用戶手冊上建議只在 .vimrc 中改變它的值,事實上似乎也只有在.vimrc 中改變它的值纔有意義。你可以用另外一種編碼來編輯和保存文件,如你的vim的encoding爲utf-8,所編輯的文件採用cp936編碼,vim會自動將讀入的文件轉成utf-8(vim的能讀懂的方式),而當你寫入文件時,又會自動轉回成cp936(文件的保存編碼).
- fileencoding: Vim 中當前編輯的文件的字符編碼方式
Vim 保存文件時也會將文件保存爲這種字符編碼方式 (不管是否新文件都如此)。
- fileencodings: Vim會自動探測編碼設置項
啓動時會按照它所列出的字符編碼方式逐一探測即將打開的文件的字符編碼方式,並且將 fileencoding 設置爲最終探測到的字符編碼方式。因此最好將Unicode 編碼方式放到這個列表的最前面,將拉丁語系編碼方式 latin1 放到最後面。
- termencoding: Vim 所工作的終端 (或者 Windows 的 Console 窗口) 的字符編碼方式
如果vim所在的term與vim編碼相同,則無需設置。如其不然,你可以用vim的termencoding選項將自動轉換成term的編碼.這個選項在 Windows 下對我們常用的 GUI 模式的 gVim 無效,而對 Console 模式的Vim 而言就是 Windows 控制檯的代碼頁,並且通常我們不需要改變它。 好了,解釋完了這一堆容易讓新手犯糊塗的參數,我們來看看 Vim 的多字符編碼方式支持是如何工作的。
- Vim 啓動,根據 .vimrc 中設置的 encoding 的值來設置 buffer、菜單文本、消息文的字符編碼方式。
- 讀取需要編輯的文件,根據 fileencodings 中列出的字符編碼方式逐一探測該文件編碼方式。並設置 fileencoding 爲探測到的,看起來是正確的 (注1) 字符編碼方式。
- 對比 fileencoding 和 encoding 的值,若不同則調用 iconv 將文件內容轉換爲encoding 所描述的字符編碼方式,並且把轉換後的內容放到爲此文件開闢的 buffer 裏,此時我們就可以開始編輯這個文件了。注意,完成這一步動作需要調用外部的 iconv.dll(注2),你需要保證這個文件存在於 $VIMRUNTIME 或者其他列在 PATH 環境變量中的目錄裏。
- 編輯完成後保存文件時,再次對比 fileencoding 和 encoding 的值。若不同,再次調用 iconv 將即將保存的 buffer 中的文本轉換爲 fileencoding 所描述的字符編碼方式,並保存到指定的文件中。同樣,這需要調用 iconv.dll由於 Unicode 能夠包含幾乎所有的語言的字符,而且 Unicode 的 UTF-8 編碼方式又是非常具有性價比的編碼方式 (空間消耗比 UCS-2 小),因此建議 encoding 的值設置爲utf-8。這麼做的另一個理由是 encoding 設置爲 utf-8 時,Vim 自動探測文件的編碼方式會更準確 (或許這個理由纔是主要的 ;)。我們在中文 Windows 裏編輯的文件,爲了兼顧與其他軟件的兼容性,文件編碼還是設置爲 GB2312/GBK 比較合適,因此 fileencoding 建議設置爲 chinese (chinese 是個別名,在 Unix 裏表示 gb2312,在 Windows 裏表示cp936,也就是 GBK 的代碼頁)。
對於fedora來說,vim的設置一般放在/etc/vimrc文件中,不過,建議不要修改它。可以修改~/.vimrc文件(默認不存在,可以自己新建一個),寫入所希望的設置。
我的.vimrc文件如下:
:set encoding=utf-8
:set fileencodings=ucs-bom,utf-8,cp936
:set fileencoding=gb2312
:set termencoding=utf-8
其中,fileencoding配置可以設置utf-8,但是我的mp3好像不支持utf-8編碼,所以乾脆,我就設置爲gb2312了。現在搞定了,不管是vi中還是mp3上都可以顯示無亂碼的.txt文件了。
常見設置
set number;display number
set mouse=a; setting smart mouse
set hlsearch ;high light search
set tabstop=4 ; setting tab width 4 letters
set shiftwidth=4; setting new line incident width
set noexpandtab; tab doesn't expand to space
;set list ;display manipulator, example: \n \t \r ......
set encoding=utf-8
set fileencodings=ucs-bom,utf-8,cp936
set fileencoding=gb2312
set termencoding=utf-8
前進和後退功能
流行的文本編輯器通常都有前進和後退功能,可以在文件中曾經瀏覽過的位置之間來回移動(聯想到瀏覽器),在 vim 中使用 Ctrl-O
執行後退,使用 Ctrl-I
執行前進,相關幫助: :help CTRL-O
:help CTRL-I
:help jump-motions
vim命令行的保存、離開等命令:
:w
將編輯的數據寫入硬盤文件中。:w!
若文件屬性爲“只讀”,強制寫入該文件。但能否寫入還由對該文件的文件權限有關。:q
保存後離開。若爲“:wq!”則強制保存後離開。:w[文件名]
將編輯的數據保存爲另一個文件。:r[文件名]
在編輯的數據中讀入另一個文件的內容加到光標所在行後面。:n1,n2 w[文件名]
將n1行到n2行的內容保存到另一個文件。:!command
暫時離開vi到命令行模式下執行command的顯示結果。ZZ
若文件未改動,則直接離開;若已改動則保存後離開。set num/nonum
顯示/取消行號。
VIM的宏
宏的使用非常強大,前往vim 中,宏的使用
完整版命令
本文只提供個人使用過程中積累的高頻場景,完整版請點擊此處,或查閱 vim manual
玩遊戲來熟能生巧
用進廢退,所以多用纔是王道,這裏推薦一個遊戲:通過鍵盤輸入控制人物角色冒險的遊戲,玩遊戲的過程中熟悉VIM命令: vim-adventures