對 Vim 十分熟悉的同學,掌握這個插件會很容易的,在他們的手中才會發揮出該款神器應有的價值。
當然基本的hjkl移動光標和幾種常見模式等等基本概念就略過不提了。為了確保只包含常用操作,這裡提到的技巧都沒有從現成文檔裡抄,而是憑記憶列出。
1、切換Vim模擬器狀態
這個插件允許設置一個快捷鍵一鍵開啟或關閉,在切換模式時會同時自動切換keymap,十分方便。默認鍵位是Ctrl+Alt+V,但這個鍵位覆蓋了很常用的“抽取局部變量”功能,建議重設,在setting->keymap中查找VIM Emulator即可。
由於開啟和關閉狀態分別使用兩套keymap,因此兩套都需要設定。可以把兩套keymap下的都設為一樣的鍵,也就是用同一個鍵切換。但個人建議設為不同的鍵,這樣能清楚知道當前處於那種模式中。並且,如果在開啟Vim的插入模式下關閉Vim模擬器,下次進入時仍然是插入模式,比較混亂(因為你關閉模擬器就是為了使用默認keymap輸入大段代碼,重新開啟Vim模擬器就是為了使用普通模式下的命令)。
因此建議把Vim keymap中的Exit Insert Mode設為與另一個keymap的Vim Emulator相同的鍵(也就是進入Vim模擬器的快捷鍵)。
例如,我使用的設定是:
Default keymap -> Vim Emulator : Ctrl+; (用Ctrl+分號開啟Vim模擬器)
Vim keymap -> Vim Emulator : Ctrl+, (用Ctrl+逗號關閉Vim模擬器)
Vim keymap -> Vim Emulator : Ctrl+; (用Ctrl+分號退出插入模式,進入普通模式)
這樣,在任何時候只要連按兩下ctrl+分號,就能保證必定在Vim模擬器的普通模式中。
2、ScrollOff 參數
啟動Intellij後在Vim模擬器下輸入命令 :
<code>set so=5/<code>
可以令屏幕滾動時在光標上下方保留5行預覽代碼(也就是光標會在第5行觸發向上滾動,或者在倒數第5行觸發向下滾動)。
在代碼窗口比較狹小時(例如單步跟蹤調試時)非常方便。可惜僅在Vim模擬器開啟時有效。
3、行號定位
普通模式下輸入 行號G 或 :行號 都能快速定位到某一行。
區別在於前者在輸入行號時屏幕上沒有任何提示,後者則在Vim命令輸入框中可以看到輸入過程。
題外話:Sublime Text 2也是用 :行號 來快速定位到某行,應該是沿用了Vim的習慣。
4、進入修改
進入插入模式的方式有很多,直接選用合適的方式進入插入模式比進入後再用箭頭鍵移動光標要好。常用的有:
o - 在當前行下方插入新行並自動縮進
O - 在當前行上方插入新行並自動縮進 (普通模式下的大寫字母命令用 shift+字母鍵 輸入,下同)
i - 在當前字符左方開始插入字符
a - 在當前字符右方開始插入字符
I - 光標移動到行首並進入插入模式
A - 光標移動到行尾並進入插入模式
s - 刪除光標所在字符並進入插入模式
S - 刪除光標所在行並進入插入模式
c - 刪除光標所在位置周圍某個範圍的文本並進入插入模式。關於範圍請看第5點,常用的組合有:caw - 刪除一個單詞包括它後面的空格並開始插入;ciw - 刪除一個單詞並開始插入;ci" - 刪除一個字符串內部文本並開始插入;c$ - 從光標位置刪除到行尾並開始插入;ct字符 - 從光標位置刪除本行某個字符之前(保留該字符)並開始插入。等等。
C - 刪除光標位置到行尾的內容並進入插入模式 (相當於c$)
r - 修改光標所在字符,然後返回普通模式
R - 進入覆蓋模式
5、範圍操作
某些普通模式的動作命令後面可以追加一些表示範圍的指令,表示該動作將作用在整個範圍上。這類命令常用的有:
d - 刪除一定範圍內的文本
c - 刪除一定範圍內的文本並進入插入模式
y - 將範圍內的文本放入0號和"號註冊欄
v - 選擇範圍內的文本
= - 自動縮進範圍內的文本
gU - 將範圍內的字符轉換為大寫
gu - 將範圍內的字符轉換為小寫
- 將範圍中的內容縮進一格
< - 將範圍中的內容取消縮進一格
常用的範圍指令有:
空格 - 光標所在位置字符。(例如 gU空格 - 將光標位置字符轉為大寫)
重複某些動作命令 - 光標所在行。(例如dd刪除一行,yy複製一行,cc刪除一行文本並開始插入,>> 當前行縮進一格,==自動縮進當前行)
$ - 從光標位置到行尾
^ - 從光標位置到行首,不包含縮進空白
0 - 從光標位置到行首,包含縮進空白
gg - 從光標位置到文件開頭
G - 從光標位置到文件結尾
% - 從光標位置到另一邊匹配的括號
f - 從光標位置到光標右邊某個字符首次出現的位置,包括該字符
F - 從光標位置到光標左邊某個字符首次出現的位置,包括該字符
t - 從光標位置到光標右邊某個字符首次出現的位置,包括該字符
F - 從光標位置到光標左邊某個字符首次出現的位置,包括該字符
/正則表達式 - 從光標位置到下一個匹配正則表達式的位置(跨行)
?正則表達式 - 從光標位置到上一個匹配正則表達式的位置(跨行)
aw - 一個單詞加一個空格 (a可理解為“一個”,下同)
iw - 一個單詞 (i可理解為in,下同)
a" - 一個字符串包括雙引號
i" - 一個字符串內部文本
a< - 一組< >包含的文本,包括< >號本身
同理類推:i
注意:真正vim中的it範圍(一對xml標籤內部)在ideaVim中不生效。
用/或?命令查找時,正則表達式默認大小寫敏感,如果需要不敏感,可以在正則表達式開始處加上\\c標誌。
例如 /\\cabc 可以匹配到 ABC。下面提到的:s命令同樣適用。
6、選擇文本
在Vim中,選擇文本需要進入“可視模式”(Visual Mode),這個名稱比較奇怪,它的來由據說是因為在Vim的前身Vi中,選擇區域是不可見的。
在Vim中選擇區域會高亮顯示,因此稱為“可視模式”。
v - 進入字符選擇模式, V - 進入行選擇模式, Ctrl+v - 進入塊選擇模式。
進入相應模式後移動光標即可選中文本。過程中可按o鍵令光標在選區兩端切換。
在塊選擇模式中選中多行,然後按I或A後輸入文本,再退出插入模式,所輸入的文本將自動加入到每一行的開頭或結尾。
7、複製粘貼
在Vim模式下,複製粘貼並不直接使用系統的剪貼板,而是使用Vim提供的多個“寄存器”,每個寄存器都以一個字符來表示。
關於寄存器的詳細說明可以看這裡 http://blah.blogsome.com/2006/04/27/vim_tut_register/ ,這裡簡單列一些常用的操作技巧
注意,vim使用雙引號”來作為選擇寄存器的命令,因此下文中的雙引號均指在普通模式下按雙引號鍵:
a)用y命令將文本存入寄存器後,如果想在別處替換原有內容,可以先用v命令選中原有內容,然後用p命令粘貼。
但第一次粘貼後,默認的寄存器”將被替換為剛剛刪除的內容。如果要再次粘貼之前複製的內容,需要使用 “0p 命令組合來複制。
也可以進入插入模式後用 Ctrl+r 0 來複制,例如 ciw<ctrl>0 命令組合將用粘貼內容替換光標處的一個單詞,並停留在插入模式。/<ctrl>
b)在Windows下,寄存器 + 和 * 都代表系統剪貼板,可以互換使用,選一個順手的即可。
例如 “+yy 命令組合可將當前行復制到系統剪貼板。ci”<ctrl>* 命令組合則將系統剪貼板的內容替換字符串的內部文本。/<ctrl>
c) 寄存器1至9記錄之前九次的刪除大段文本,每次超過一行的刪除操作都會導致這9個寄存器的內容發生位移,最近刪除的文本會存入寄存器1。
但只有刪除超過1行時才會影響寄存器1至9,行內的刪除內容則會被存入寄存器-(減號)。
如果用q命令錄製宏時不涉及跨行刪除,可以在宏中直接使用這9個寄存器來暫存文本。
(在Vim中,複製內容與錄製宏共享同一套寄存器,因此我習慣把字母寄存器留給宏使用)
d) 普通模式下小寫p把寄存器內容複製到當前位置之後,大寫P把寄存器內容複製到當前位置之前。
e) 使用 :regs 命令可以列出當前所有寄存器的內容
8、一些插入模式下的常用快捷鍵
Ctrl+h - 刪除光標左邊字符
Ctrl+w - 刪除光標左邊的單詞
Ctrl+y - 複製上方的一個字符
Ctrl+e - 複製下方的一個字符
Ctrl+r 0 - 插入前一次用y命令寄存的內容
Ctrl+r * - 插入系統剪貼板的內容
Ctrl+r - 插入指定寄存器的內容
Ctrl+a - 插入前一次插入模式所鍵入的內容
Ctrl+o - 執行一個普通模式下的命令然後返回插入模式。例如 Ctrl+o A 相當於按 End鍵, Ctrl+o I相當於按Home鍵
9、退出插入模式
退出插入模式可以用 ESC 鍵,但鍵位太遠。其實也可以用 Ctrl+[ 鍵退出插入模式 。
當然也可以用第1點自定義的Ctrl+;快捷鍵,但這不是標準vim按鍵,會養成不良習慣,不建議使用。
10、重複操作
普通模式下按. (小數點)可重複上一次的修改操作
& - 重複上一次的:s替換命令
@@ - 重複上一次執行的宏
11、跳轉
Ctrl+] 跳轉到當前標識符的定義位置 (相當於在當前光標位置的單詞上按住ctrl用鼠標點擊)
Ctrl+o 回退一步 (go back)
Ctrl+i 前進一步 (go forward)
`. 跳轉到之前修改位置
`` 在前一次跳轉位置與當前位置間切換
行號G 或 :行號 跳轉到某一行
gg 跳轉到文件開頭
G 跳轉到文件末尾
H 跳轉到屏幕頂端(如果設置了set so=n,則跳轉到第n行)
L 跳轉到屏幕底端(如果設置了set so=n,則跳轉到倒數第n行)
M 跳轉到屏幕中間
f 或 F 跳轉到本行某個字符,小寫f向右查找,大寫F向左查找。用;或,在匹配間切換
t 或 T 跳轉到本行某個字符之前,小寫t向右查找,大寫T向左查找。用;或,在匹配間切換
/正則表達式 跳轉到下一個匹配。用n或N在匹配間切換。
?正則表達式 跳轉到上一個匹配。用n或N在匹配間切換。
結合前面第5點,你也許注意到了,在指定範圍時,使用跳轉命令將指定一個從光標位置到跳轉目標的區域。
12、書籤
在普通模式下按 m 即可定義書籤,按 ` 則可跳轉到某個書籤的精確位置,按 ‘可跳轉到某個書籤所在行的行首(用來錄製宏時比較有用)。
最常用的自然是mm, mn, mj, mk, ml這幾個順手的鍵位。
真正的vim中的全局書籤 m 在目前IdeaVim版本中不生效。需要定義全局書籤可以使用Idea原本的 F11 + 數字 方式。
13 、文本替換
使用 :s/正則表達式/替換文本/ 可在本行內替換首次出現的匹配
使用 :s/正則表達式/替換文本/g 在本行內替換所有出現的匹配
使用 :%s/正則表達式/替換文本/g 在當前文件內替換所有出現的匹配
在可視模式下選中文本後,使用:’s/正則表達式/替換文本/g 命令可在選中區域中替換文本。
其中’部分在可視模式下,按:冒號後自動加入,直接輸入s命令即可。但有效區域只能以行為單位。
真正Vim中的 %V 標誌在IdeaVim中不生效。
14、代碼摺疊
zo - 打開摺疊
zc - 關閉摺疊
15 、宏定義
在IdeaVim中定義宏比Idea自帶的宏功能要輕量許多。
按在普通模式下 q 即可開始把後續按鍵序列錄製到指定寄存器中(寄存器參考前面第7條)。錄製完畢進入普通模式再按q鍵即可停止錄製。
之後用 @ 即可重放。需要注意的是宏和複製粘貼共用一套寄存器,因此在錄製宏時就注意不要把當前宏正在使用的寄存器用來複制了。
寄存器內容是自動保存的,重啟Idea仍然生效。但IdeaVim沒有導出宏獨立保存的功能。因此最好把用來保存宏的寄存器和用來複制粘貼的寄存器分開,不要同一個寄存器有時用來記錄宏,有時用來複制粘貼。我的習慣是鍵盤左手區用來保存一些長期使用的宏(比如說我有一個宏專門用來把pom.xml中的版本號抽取到property區域,原來的位置則改用${property}引用)。
右手區的hjklnm鍵用來保存一些臨時宏。yuiop五個寄存器保留用來複制粘貼。如果錄製的宏不涉及刪除大段代碼,寄存器1至9也可以用來進行復制粘貼。
執行一次宏後,可以用@@命令重複上一次執行的宏。
在Idea中錄製宏時,如果觸發了代碼自動完成,在自動完成列表啟動的狀態輸入的字符不會被記錄。因此最好在Setting -> Code Completion -> Autopopup code completion中把延遲設為500ms以上或乾脆關掉。在錄製宏的過程中避免觸發代碼自動完成功能。
錄製一些長期有效的宏時,開始錄製後,最好先用0,^,T, F, $等命令把光標對齊到行首行末或某個特定起始位置(比如說用 F” 跳轉到字符串的左邊引號),再用一個f或/指令跳轉到操作位置,這樣的宏就不用必須把光標放在某個特定字符才能使用了。
16、一些常用組合技
全選:ggvG
調換兩個字符位置:xp
複製一行:yyp
調換兩行位置:ddp
插入模式下到行尾繼續輸入(相當於End鍵):Ctrl+o A 或 Ctrl+[ A
插入模式下到行首繼續輸入(相當於Home鍵):Ctrl+o I 或 Ctrl+[ I
到類定義位置(適用於正確縮進的public,protected類) :?^p回車
17、一些在目前版本已知沒有實現的一些常用Vim功能
如果對Vim不熟悉可以跳過這節。
a)let命令 (沒有let命令就無法導出/導入寄存器內容,也就是無法導入宏)
b):g命令 (在文本處理中很有用的一個命令,在編程中倒是不那麼常用)
c)!命令 (執行shell命令)
d)大部分正則表達式標記 (例如 %V, \\v 等等)
e) 某些多鍵命令雙擊最後一個字符表示作用於當前行。例如在Vim中gUU可以把當前行轉換為大寫,在IdeaVim中無效,實現同樣功能可以先用V命令選中當前行,再用gU轉換為大寫。
f)關於窗口操作的大部分命令 (Ctrl+w系列命令, :split等)
g)所有Vim腳本插件 (不過大部分可以用Idea自身的功能和插件來補償)
嗯,差點忘了,在普通模式下按u撤銷上一個修改(相當於其他IDE的Ctrl+z),按Ctrl+r重做被撤銷的修改。
閱讀更多 老男孩的成長之路 的文章