1. 程式人生 > 其它 >vim 從嫌棄到依賴(9)——命令模式進階

vim 從嫌棄到依賴(9)——命令模式進階

上一篇文章更新還是在51前,最近發生了很多事情了,全國各地的疫情又有蔓延的趨勢,北京朝陽區都已經開始實施居家辦公。各位小夥伴請注意安全,安全平安的度過這個疫情。

廢話不多說了,接著上次的內容往下寫。

在上一個篇章中,我們介紹了命令模式的使用,也通過一些例子理解了在需要大範圍操作文字或者進行游標跳轉的情況下,相比於使用普通模式中的operator + motion 來說,使用範圍加命令的方式更快速而且也更方便。同時也以copymove 操作,介紹了操作文字命令的一搬用法。接下來就要繼續往前走,介紹命令模式的其他用法了。

命令列模式下使用普通模式的命令

當初在第一次介紹. 命令的時候相信各位小夥伴應該有一個遺憾,怎麼沒有介紹.

命令類似數字 + . 以達到重複執行目的的操作呢。如果有這麼一個操作那豈不是如虎添翼。甚至可能有小夥伴自己親自去嘗試過,發現失敗了。vim並沒有提供類似的操作。那麼要完成這件任務該如何來操作呢,之前的例子只有3行,每次使用. 之後使用j 來移動然後再使用. 也沒幾次,這個成本是可以接受的,但是如果是將檔案中所有程式碼行的尾部都加分號,而且這個檔案有上百行甚至上千行程式碼呢。

之前針對這個例子給出了不同的解決方案,在學習. 命令的時候,是使用. 命令,在學習可視模式的時候使用處理列的可視模式。現在再介紹一種新的方式,通過在命令列模式中使用normal 關鍵字來告訴vim,我們將要使用普通模式的命令。

它使用的方式為:range + normal + operator ,它支援範圍操作,表示我們將要針對某個範圍來執行普通模式的操作

針對這個例子,首先要構造一個可以使用.命令的操作,即我們在首行使用A; 在行尾新增分號,接著配合命令模式的範圍,加上2,$normal. 表示我們將要從第二行到尾行來執行. 命令


這個在使用. 的時候,我們相當於在重複執行A; 的普通模式的命令,那麼是不是可以做這樣的猜想,使用:normal 也可以執行 A; 這樣的命令做到同時切換輸入模式並且自動輸入字元,而不僅僅侷限於執行operator呢?我們可以將上述修改使用2u回退,然後針對這個猜想做驗證,輸入:%moral A;

我們發現它確實成功完成了這樣的操作。也就是說normal後是可以跟一些改變當前模式的命令並且可以指定輸入的內容的。

這樣我們在快速刪除一個檔案的所有內容上,又有一種新辦法了:$normal dd 但是相比起 :%d 來說要輸入的字元更多罷了。他們的區別相信看到現在的小夥伴應該很熟悉了。這裡就不再解釋了,感興趣的小夥伴也可以在評論區給出自己的答案。

重複上次的ex命令

在普通模式下. 可以重複上一次的修改,但是某些ex命令並沒有對其進行修改,如果我想重複通過. 來重複上次的ex命令則無能為力了。而且通過實驗也可以發現,它也無法重複由ex命令造成的修改。

可以使用@: 重複上一次的命令。如果執行過 @: 進行重複,那麼可以使用@@ 再次執行上次重複的命令,例如在編寫程式碼時經常會一到的一個問題就是將當前行程式碼下移一行,但是也不是所有的行都會這麼幹,那麼就可以先使用 .m.+1將當前位置的程式碼移動到游標的下一行,然後移動游標,在下一個需要次操作的位置執行 @: ,後面就可以直接使用 @@ 來重複上一次的操作了。這裡就不再針對它來做演示了。各位小夥伴可以自己來嘗試一下

自動補全ex命令

在使用shell 命令的時候,使用tab 可以很方便的進行補全,而在使用命令模式的時候也有這個功能

vim在使用tab時會自動檢索之前輸入的歷史進行匹配。例如,使用 :%n<tab>。它會匹配到一堆符合要求的命令。多次按下 <tab> 鍵則會依次按從上到下的順序進行匹配。也可以使用 <Ctrl n><Ctrl p> 跳轉到下一次匹配和上一次匹配。同樣的也可以使用 <Shift Tab> 來跳轉到上一次匹配

預設情況下,會按照上述例子中的樣式來展示匹配項,但是你也可以自定義匹配項,使用wildmode 來修改補全行為。但是需要事先開啟 wildmenu 選項。

可以使用 :h wildmode:h wildmenu 來檢視對應的幫助文件。這裡我給出我習慣使用的配置

vim.o.wildmenu = true
vim.o.wildmode="full"
set wildmenu
set wildmode=full

當然你不進行這樣的配置也行,neovim 模式的補全模式就是這種

回溯命令歷史

shell 中,可以使用上下鍵直接輸入上次輸入的命令或者在 bash_history 中記錄了之前執行過的命令,vim也有同樣的設計

按下 : 進入到命令模式之後,可以使用方向鍵向上或者向下查詢歷史命令。

除了使用 方向鍵以外,還可以使用 <Ctrl p><Ctrl n> 來遍歷,但是使用方向鍵有一個好處是他們可以針對之前已經輸入的內容對匹配的內容進行過濾。壞處在於,手指的移動幅度大,我們可以使用對映的方式將<Ctrl p><Ctrl n> 進行對映。這裡我們仍然等到講述快捷鍵對映的時候給出程式碼

執行shell 命令

在vim的命令模式中也可以執行shell命令。只需要在shell命令前面加上 ! 即可,例如執行 :!ls 將會執行ls 這個命令

在vim的命令模式中,% 代表的是當前檔名,在執行某些可以傳入檔名作為引數的命令時,可以使用它,例如我要執行當前的Python程式碼時可以使用 :!python %

我們也可以將vim命令模式中的範圍配合shell命令使用,這個時候範圍中包含的內容將會作為shell命令的輸入, 例如現在有這麼一個檔案,記錄了一個檔案列表,現在我想要按照檔名排序

files:
a.txt
ccc.txt
b.txt
d.txt
z.txt
t.txt

可以配合sort 使用 :2,$!sort,由於第一行是表頭的文字不進行排序,所這裡從第2行開始參與排序

使用 write 和read 命令重定向vim緩衝區內容

在vim配合shell命令使用的時候有時候shell會產生大量是輸入或者需要一定的輸出,那麼就可以使用 write 和 read 來配合shell使用。

  • read:vim從shell產生的輸出中讀取內容寫入緩衝區
  • write: vim將緩衝區的內容寫入到shell中,作為shell的輸入

例如某個檔案中有大量的Python程式碼,但是我只想執行部分,那麼可以配合write使用,例如3,5write !python 執行檔案中3-5行的Python程式碼,或者配合可視模式,執行選中的程式碼

再比如,我現在需要獲取當前目錄下有多少個檔案和目錄,並且按照檔名順序排列,就可以使用 :read !ls|sort

甚至配合鍵繫結,完成ide那種一件自動編譯執行的效果。例如

vim.api.nvim_set_keymap('n', '<F5>', ':write | !python %<CR>', {noremap = true, silent = true})

配合檔案型別識別可以做到一鍵執行其他型別的程式碼,將vim 打造成IDE不是夢想

除了手工填寫範圍配合shell命令之外,vim提供了一種簡便的方式來完成這一工作,可以使用 !{motion} 來快速形成範圍,後面只需要輸入命令即可,針對前面排序檔案的例子,假設游標在檔案的第二行,可以使用在普通模式下輸入!G 來快速選中整行,vim為我們在右下角填充了:.,$! 後面只需要寫上sort 之後就可以了

到此為止,我們已經通過介紹不同的模式,將vim編輯文字的功能大致給展示了一下,相信各位小夥伴看到這裡已經瞭解到了vim在編輯文字的強大。但是這並不是vim的全部,後面將詳細介紹如何通過vim來組織檔案、專案工程等功能。請各位敬請期待