vim 成“神“之路 (一)
文章目錄
- 1. 安裝
- 1.1 linux
- 1.2 MacOs的安裝
- 1.3 Windows的安裝
- 1.4 vim中文幫助文檔安裝
- 2. vim基本概念和基礎命令
- 2.1 基本的鍵位映射如下:
- 2.2 vim模式
- 2.3 vim的選項和基本配置
- 2.3.1 備份和跨會話撤銷文件
- 2.3.2 vim中支持鼠標
- 3. vim 常用命令 -- 應對稍復雜任務
- 3.1 光標移動
- 3.2 文本修改
- 3.3 文本對象選擇
- 3.4 文本移動 -- 更快
- 3.5 重復操作
- 4. vim 的簡單定制
- 4.1 vim 的目錄結構
- 4.2 vim 軟件包
- 5. vim 的復制與粘貼
- 6. vim的模式匹配:正則表達式
- 6.1 基本的特殊字符
- 6.2 特殊模式項
- 6.3 一些搜索舉例
- 6.3.1 最長匹配和最短匹配
- 6.3.2 搜索加亮和取消
- 6.3.3 正則表達式替換
- 6.3.4 替換實例
哈哈,有點標題黨的意思,vim帶你成"神"?還是你通過vim成了"神"?還是學習了vim,感覺vim就是"神"? 仔細耐心體驗一下vim的"神跡"。
vim 作為程序員三大美德體現:懶惰,急切,傲慢 的優秀編輯器,已經走過了接近三十個年頭。
從肯·湯普遜 1978年將unix 操作系統傳播開來,到比爾·喬伊 完成第一個版本的全屏編輯器 vi的開發(在此之前有很多基于行的編輯器ed,em,en ,ex),再到布萊姆·穆勒納爾 持續維護了三十年的vi 克隆版本, 最后也就演變成了我們現在使用的vi IMproved – vim。
vim的優點如下:
- vim 是一個完全跨平臺的編輯器
從開始的unix,到 現在最為通用流行的 linux,windows,Macos,再到不經常用的操作系統OS/2, BeOS,甚至ios和android也能找到vim的移植版本。 - vim 是一個高度定制和可擴展的編輯器
通過vim 自身腳本語言(Vim Script)可以擴展vim的功能,如果vim 腳本能力還不足,則可以通過Python ,Perl 等其他通用腳本語言進行擴展。這樣就能夠非常自由得打造屬于自己的專屬環境。 - vim 良好的生態環境
網絡上已有的現成的腳本和插件,能夠直接搭建順手的開發環境。像經常用的語法補全,語法檢查等常用功能,都可以在vim下實現,且能夠通過配置 不需要離開vim 編輯器就能完成從寫代碼、到編譯運行的大部分工作。
有這么多優點,又是無數大佬自己使用的編輯器,那么vim 就需要快速搞起來,來讓自己的工作效率進一步提升,希望這篇成神之路能夠帶給你在vim上足夠多的幫助。
客觀來講,vim的配置確實非常繁瑣,甚至復雜,想要達到現在vscode ,clion的方便程度確實會花費不少時間。但vim的高效是能夠在手指不離開鍵盤的情況下完成任何場景下的編輯工作,手指快速敲擊三個鍵以內就能夠達到一段文本的增刪改查。
當然打造自己的vim 感覺 就像是公元前1500年前后 印歐語系游牧的蠻族潛心打造的青銅器,青銅戰車 ,馬具馬鞍,戴著他們橫掃了整個歐亞大陸的古代文明,從尼羅河的埃及文明到地中海的米諾斯文明,到幼發拉底河和底格里斯河的美索不達米亞文明,到印度河文明和中國的商朝(北方的游牧民族)都被精良高效的戰爭民族所取代,顛覆了整個大陸的格局。
vim所做的就是能夠一統整個ide的大陸,用靈活的插件搭配強大的快捷操作實現 ,我們只需要在這個大陸上專注耕耘,建立自己的的偉大帝國。
先瞅瞅當前我的vim 使用上的一些效果:
- 窗口分割
- 自動補全
- markdown
- 查看文件歷史修改記錄
這上面僅僅是展示很小很小一部分插件的編輯功能,每一種編輯功能都會有很多更加方便的細節配置。
同時 本文也只是提供一條道路,希望大家能夠在這條道路上找到適合自己的編輯模式。
最后vim 當然也能夠支持閱讀源代碼,只不過源代碼顯示上不太舒適,這里使用clion這個老東家也很久了,所以還是不能喜新厭舊呀,用它作為擼源碼的工具 還是很給力,而vim主要用在編輯或者寫代碼之上。
vimrc已經放置在vim-github,不過需要vim版本在8.2以上,或者neovim在0.4.4版本才行。
如果能夠看懂vimrc中的簡單vim script,建議先熟悉一下基本鍵位和操作,熟悉之后會發現編輯查看效率 急速飆升,指尖如飛。
1. 安裝
1.1 linux
-
Redhat 和 Centos
查看是否已經安裝vim
yum list installed |grep vim如果只有如下這樣的輸出,則說明是最小的vim安裝
vim-minimal.x86_64 2:7.4.160-2.el7 @centos7.3-x86_64-base建議使用
sudo yum install vim-enhanced.x86_64安裝增強版的vim。 -
Debian 和 Ubuntu
使用apt進行安裝,同時在這兩種系統下vim有比較多的功能vim vim-athema #適用于老的 X-window 界面 vim-gnome vim-gtk #使用于GTK環境 vim-gtk3 #適用于GTK環境 vim-nox #有比較全面的文本界面vim包 vim-tiny #最小功能的vim包安裝可以遵循如下規則
- 如果系統使用的是GNOME桌面環境時,安裝
vim-gtk3或vim-gnome - 如果使用的是KDE桌面 ,安裝
vim-gtk - 如果使用文本界面,安裝
vim-nox
可以通過
apt list --installed|grep vim查看已經安裝的vim版本安裝:
sudo apt update sudo apt install vim-gtk3手工編譯安裝,至少加上Python 支持和圖形界面的支持:
./configure --enable-pythoninterp \--enable-python3inerp \--enable-gui=auto #auto可以根據需要換成gtk3等其他數值 make -j sudo make install安裝成功之后,通過
vim --version能夠看到一個python版本的支持。
- 如果系統使用的是GNOME桌面環境時,安裝
1.2 MacOs的安裝
直接使用homebrew進行安裝
brew install vim
brew install macvim
參考homebrew進行mac下的homebrew的安裝
1.3 Windows的安裝
通過網址https://www.vim.org/download.php#pc下載windows版本的vim.exe,windows下的vim版本還是以32位為主,基本也滿足正常的開發需求了。
安裝過程中進入如下界面:
需要注意如下幾個選項:
- “安裝批處理文件 (Create .bat files)” 對于使用Vim命令行的開發者來說是剛需,所以需要選擇
- “創建圖標 (Create icons for vim)” 根據個人選擇展開
- “創建默認配置文件” 去掉這一項,可以通過后面會說到的方式創建配置文件
- “安裝多語言支持” 使得vim的菜單可以支持多語言選項
點擊下一步,修改安裝的文件目錄,安裝完成即可。
這個時候會打開一個默認的README文件,輸入:e \_vimrc,輸入如下內容:
set enc=utf-8
set nocompatiable
source $VIMRUNTIME/vimrc_example.vim
按ZZ 退出即可
這里說一下windows和linux下vim的區別
- windos下vim配置文件是_vimrc,unix下一般默認~/.vimrc
- windos下打開的vim文件都成為了_ 開頭,如_viminfo
- 打.開頭的vim配置目錄.vim,也變成了vimfiles
同時windos下vim的插件安裝也是比較費勁的,其實希望成為vim"之神"的同學應該以類unix環境為主,至少一個虛擬機下安裝ubuntu鏡像也并不會消耗太多的時間。
1.4 vim中文幫助文檔安裝
英文版的教程,使用 終端下直接輸入 vimtutor 即可看到,同時一些網友也翻譯了中文版本的vim幫助文檔,這個安裝在vim8中也是非常簡單的。
以類unix環境為例(windows下需要將.vim 改為vimfiles目錄),執行如下命令:
cd ~/.vim
mkdir -p pack/my/start/
git clone https://github.com/yianwillis/vimcdoc.git pack/my/start
cd pack/my/start
./vimdoc.sh -i #安裝help.txt的中文幫助文檔
./vimdoc.sh -u # 如果不想要中文版的help信息,則可以卸載掉
進入vim,輸入:help 之后可以有如下的效果:
一般類unix操作系統,可以通過LANG=zh_CN.UTF-8 vimtutor 來進入一個中文版本的vim教程
PS:因為vim使用ctrl鍵會比較多,建議大家學習的時候將ctrl映射到之前的CAPS(mac下),或者windows CapsLock下
2. vim基本概念和基礎命令
2.1 基本的鍵位映射如下:
建議大家在看完之前的vim 教程之后在來熟悉這一塊,保證上面的基本命令都已經很熟悉了。
以上圖沒有說明vim的命令行命令
:q!– 不保存退出:wq– 保存退出:s– 替換:!– 執行外部unix命令:edit– 一般縮寫為:e,編輯文件:w– 寫入指定文件:r– 讀文件:help查看幫助信息- 使用
Ctrl + D和Tab鍵將命令補全
2.2 vim模式
- 正常模式(普通模式):缺省的編輯模式,如果不加特殊說明,一般提到的特殊命令都直接在正常模式下輸入;任何其他模式都可以通過鍵盤上輸入
ESC回到普通模式 - 插入(insert) 模式:輸入文本時使用,普通模式下鍵入
i(insert)或則a(append)即可進入插入模式 - 可視(visual)模式:用于選定文本塊,可以使用
v鍵來按字符選擇,vim中也提供了按行和塊進行選擇的方法 - 命令行(command-line)模式: 用于執行較長,較復雜的命令。普通模式鍵入
:即可進入該模式。 使用/或者?開始搜索也算作命令行模式。命令行模式下需要輸入回車才算完成。
再次強調,只要按下ESC,無論在哪個模式下,都會回到普通模式。
這里再次說明以下,可以利用好vim命令行下的help幫助文檔,能夠提供非常方便的幫助操作。
2.3 vim的選項和基本配置
隨著持續不斷得使用vim,它的配置會不斷得增加,從而應對自己在不同場景的需求。
接下來看看一些基本的vim配置,之前說過unix系統下的vim配置是.vimrc文件,windows的配置則是_vimrc文件
set enc=utf-8
set nocompatiable
source $VIMRUNTIME/vimrc_example.vim
如之前的一段類似于shell 腳本的 配置如上,三行的基本含義如下:
- 設置編輯文件的編碼格式為utf-8
- 設置Vim和vi不兼容
- 倒入vim的配置示例(示例中包括一些有用的選項:語法高亮,搜索高亮,命令歷史等等)
2.3.1 備份和跨會話撤銷文件
vim支持跨會話的編輯能力,這個在目前的編輯器中還沒有其他的能夠做到的。舉個例子,編輯完word,將word關閉,再重新打開,想要做到撤銷上一次的操作,或者恢復到之前n次操作,這個不可能的,vim能夠支持這樣的功能。
基本配置如下兩個:
set backup
set undofile
- 第一個選項使得我們的每一次編輯都能夠保留上一次的備份文件
- 第二個選項使得vim重新打開一個文件時仍然能夠撤銷之前的編輯(undo),還會保留一個編輯歷史的文件(undofile)
這個時候當前目錄下會出現針對編輯后文件的些~結尾的備份文件和.開頭的undo文件
這里通常只保留撤銷文件的功能,有了跨會話撤銷的能力,基本備份的功能就用不到了,將撤銷的文件放在個人用戶目錄下,保證文件的安全和目錄的干凈。
set nobackup
set undodir=~/.vim/undodirset undodir=~\vimfiles\undodir "windos下的形態,目錄符合和unix有差異
為了保證目錄存在,可以再增加如下判斷:
if !isdirectory(&undodir)call mkdir(&undodir, 'p' , 0700)
endif
&undodir是之前設置的undodir值,mkdir括號內部指定mkdir的命令選項 和 目錄權限
2.3.2 vim中支持鼠標
我們正常使用vim的過程中,看代碼肯定比寫代碼要多, 所以這個時候鼠標還是比較有必要存在的。而且鼠標在非線性跳轉上比鍵盤快很多。
我們在vim中對鼠標的需求是:
- vim內部使用鼠標通過可視模式(visual)選擇內容,且僅在vim內部使用
- 通過將vim內部的可視模式選擇的文本和外部操作系統進行編輯交互(在vim內部鼠標選擇后復制,粘貼到外部系統軟件之中)
所以針對以上兩種的使用需求,vim都需要能夠支持:
if has('mouse')if has('gui_running') || (&term =~ 'xterm' && !has('mac'))set mouse=aelseset mouse=nviendif
endif
3. vim 常用命令 – 應對稍復雜任務
3.1 光標移動
-
基本移動 :上、下、左、右 –
k,j,h,l; 缺陷是這四個鍵不能在插入模式下移動 -
跳轉行首:
0, 跳轉行尾:$, 跳轉到行首到第一個非空白字符: ^ -
一次移動超過一個字符:
b/w,B/W
以上含義分別是:words backward, words forward,用來向后或者向前跳轉一個單詞。大寫跳轉和小寫跳轉的唯一區別就是小寫和編程語言的標識符類似,認為一個單詞的組成是由字母,數字和下劃線組成;而大寫則認為非空格字符都是單詞。 -
根據單個字符進行選擇:
f/t,F/T
以上含義是:找到下一個緊接著輸入的字符(如果輸入f/t,F/T之前加上數字n,那就是下面第n個),比如找到當前行的第二個d字符,輸入f2d即可。兩者的區別是f會包含這個字符,t不包含這個字符。大寫的F/T則是進行反方向的搜索。比如下面字符串
*nc = (struct mg_connection *) data;,光標在括號內的第一個字符s的位置,我想一次刪除括號內所有內容,如果不用f/t的話需要仔細考慮w的匹配規則,最后使用c3w,而現在我們只需要使用ct)直接匹配)就可以。 -
文章內移動:
(和)分別是移動到上一句和下一句;{和}分別是移動到上一段和下一段 -
開頭和結尾跳轉:
ctrl - Home和ctrl - End跳轉到文件的開頭和結尾;gg和G也是分別跳轉到文件到開頭和結尾。
只不過G這里的區別是跳轉到最后一行的第一個字符,不是最后一個字符
3.2 文本修改
Vim的基本教程中我們知道c(change),d(delete),i(insert)都能夠對文本進行修改,vim的原則是常用的功能要盡可能按鍵少。因此很多常用的功能在vim中都會有不同的按鍵,而且大寫鍵也會相應得重載相近但稍不同的含義(最后一個字符的包含與不包含這樣的區別)。
d加動作進行刪除:dd刪除整行,D相當于d$刪除到行尾c加動作進行修改:cc修改整行,C相當于c$刪除到行尾并進行插入s相當于cl,向右刪除一個字符并進入插入模式,S相當于cc,替換整行i在當前字符前進入插入模式;I則相當于^i把光標移動到行首非空白字符,進入插入模式a在當前光標所在字符后面進入插入模式,A相當于$a,把光標移動到末尾,然后進入插入模式o在當前行下方插入一個新行,然后在新行進入插入模式;O在當前行上方插入一個新行,并進入插入模式r替換光標下的字符;R進入替換模式,每次按鍵替換一個字符,直到按下ESC退出替換模式u撤銷最近的一個動作;U撤銷當前行的所有修改
這一些按鍵基本能夠讓大部分的編輯任務在一兩個按鍵就能完成,不過需要長期練習,形成肌肉記憶 。
3.3 文本對象選擇
這個功能非常適合程序中的邏輯塊編輯,方便我們在一般模式下對程序代碼或者文件進行隨意自如的修改。
基礎鍵的命令c,,d 是用來對文本內容進行修改,而像a,i,w 這樣的能鍵能夠附加到基礎操作命令之后,對一段文本進行快速修改操作。
針對文本"coding boy = z_stand" 的修改利用如上鍵可以有如下組合策略。假設光標停在coding 的d上
dwdelete word, 刪除ding,結果是"co boy = z_stand"diwdelete inside word, 刪除coding,結果是" boy = z_stand"dawdelete a word,刪除coding, 還有一個空格。 結果是"boy = z_stand"diW刪除"coding,結果是boy = z_stand"daA刪除"coding還有一個空格。結果是boy = z_stand"di"刪除coding boy = z_stand結果是""da"刪除"coding boy = z_stand",字符串包括雙引號被全部刪除
這個操作后面加"或者其他的字符,比如(,則會刪除與其匹配的)內部所有的內容
以上介紹的是d操作,同樣的基礎鍵還可以用c進行,只不過d是執行完成刪除操作之后vim還是一般模式,而c是執行了之后進入插入模式。
同時像如下的幾個鍵也能夠支持文本對象的選擇,可以像d和c一樣搭配a,i,w,單引號,雙引號,左右括號等
- 搭配
s(sentence)對句子進行操作 – 適合英文文本編輯 - 搭配
p(paragraph) 對段落進行操作 – 適合英文文本編輯,以及帶空行的代碼編輯 - 搭配
t(tag) 對HTML/XML 標簽進行操作 – 適合HTML, XML等代碼編輯 - 搭配`和’,對shell或者python等腳本代碼進行操作
- 搭配
[和]方括號,對括號里面的內容進行操作 - 搭配
{和}大括號,對括號內容進行操作 – 適合C/C++語言 - 搭配
<和>角括號 – 適合C++ 模版操作
再進一步,在a和i之前能夠增加數字,表示操作多少個文本對象,適合針對嵌套文本的操作
比如
3.4 文本移動 – 更快
<C-B>向上翻頁<C-F>向下翻頁<C-U>向上翻半頁<C-D>向下翻半頁5G跳轉到第五行6l跳轉到第六列H,M,L當前屏幕下,分別移動光標到屏幕頂部,中間,底部<C-Y>和<C-E>保持光標不動,滾動屏幕,ctrl-y向上,ctrl-e向下zt將光標所在行滾動到屏幕頂部,zz將光標所在行滾動到屏幕中部,zb將光標所在行滾動到屏幕底部
3.5 重復操作
;重復最近的字符查找f或者t操作,重復最近的字符查找, 反方向n重復最近的字符串查找操作(/和? 查找模式)N重復最近的字符串查找操作(/和?)反方向查找.重復執行最近的修改操作
4. vim 的簡單定制
通過對vim目錄,配置文件,擴展包管理器的一些介紹來讓大家能夠初步配置自己的vim
4.1 vim 的目錄結構
vim的工作環境是通過運行支持的vim插件來設定的,合理得定制自己的vim需要了解vim的目錄構造,知道怎么快捷得找到這一些存放插件的位置。
在vim8.2版本下,不同平臺安裝vim的位置有差異:
- unix 下面
/usr/share/vim/vim82 - mac下的MacVim 運行時軟件位置
/Applications/MacVim.app/Contents/Resources/vim/runtime
能夠看到很多子目錄,如autoload,colors,doc等
最常用的是如下幾個目錄: syntaxvim 的語法加亮文件docvim 的幫助文件colorsvim 主題配色方案pluginvim的插件文件
以syntax目錄 為例,MacVim支持619種語法高亮格式,.vim之前的內容就是支持的語言語法。
在一般模式下可以通過:setfiletype cpp來指定cpp文件的語法高亮。
同時一般模式下輸入:help顯示的幫助信息都在doc目錄之下;通過:colorscheme 加tab鍵能夠看到很多種不同的配色主題,這一些主題配色都會在color目錄之下。
可以在.vimrc配置中加入一行 color desert ,指定每次啟動vim加載的配色方案
接下來重點看一插件plugin目錄,能夠在原生vim下支持無數便捷的插件接入,這也是為什么vim被成為編輯器之神的原因。像我們在clion,vscode,sublime中體驗到的便捷特性(代碼補全,源碼閱讀時的跳轉,代碼調試等)都能夠在vim中通過插件得到配置,而且我們能夠將快捷鍵通過vim script的map減少來進一步加快編輯操作,以上是一些可以擴展的插件,而plugin目錄下的插件則是系統內置的插件,分別具有如下功能:
getscriptPlugin.vim獲得最新的vim腳本插件gzip.vim編輯.gz結尾的壓縮文件,打開時能夠自動解壓縮,保存為.gz結尾的文件時自動壓縮logiPat.vim模式匹配的邏輯運算符,允許以非標準正則表達式來寫模式匹配manpager使用vim來查看man幫助文檔matchparen.vim對括號進行高亮匹配netrwPlugin.vim從網絡上編輯文件和瀏覽目錄(支持多種協議如ftp和scp,可以直接打開目錄來選擇文件)rrhelper.vim支持--remote-wait編輯,vim的多服務器會用到這一個功能spellfile.vim在拼寫文件缺失時自動下載,vim一般只安裝了英文的拼寫軟件tarPlugin.vim支持編輯(壓縮).tar結尾的壓縮文件,這里和.gz不同的是不支持寫入tohtml.vim把語法加亮的結果轉成htmlvimballPlugin.vim創建和解壓.vba文件zipPlugin.vim和.gz類似,支持讀和寫.zip結尾的壓縮文件
這幾個簡單的默認配置插件已經能夠體現出了一部分vim的強大之處,簡單演示部分插件功能如下:
4.2 vim 軟件包
vim 的目錄有點傳統的unix格式,一個功能(插件plugin)會分散在多個不同的目錄下
- 插件的主題通常會在plugin目錄下
- 插件的幫助文檔會在doc目錄下
- 有一些插件只對某一些文件類型有效,會有文件放在ftplugin目錄下
- 有一些插件會有自己的文件類型檢測規則,會有文件放在ftdetect目錄下
- 有一些插件有特殊的語法加亮,會有文件放在sytax目錄下
我再mac上是使用vim-plug作為自己的包管理器,其他的vandle或者minpac都是可以的。
-
下載:
curl -fLo ~/.vim/autoload/plug.vim --create-dirs \ https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim -
使用 plug對插件進行管理
安裝上vim-plug之后就可以在vim的配置文件中增加自己想要的插件,mac下的vim配置在~/.vimrc,windows可以通過打開vim輸入:e \_vimrc打開自己的vim配置文件。插件的安裝設置需要遵循如下語法,在
plug#begin和plug#end之間就是我們要安裝的插件,具體的插件需要通過Plug+ 插件名稱來指定安裝的插件:這里需要注意的是闊行內的內容是插件下載之后的存放目錄,可以自己指定,也可以按照下文中的目錄存放。
call plug#begin('~/.vim/plugged') Plug 'mzlogin/vim-markdown-toc', { 'for': ['gitignore', 'markdown', 'vim-plug'] } Plug 'vimwiki/vimwiki' Plug 'terryma/vim-multiple-cursors' Plug 'junegunn/goyo.vim' " distraction free writing mode call plug#end()然后再保存配置文件,在vim中輸入
:PlugInstall命令就可以直接安裝對應的插件了
當然,還可以直接對插件進行更新,或者清理不需要的插件,這一些命令可以通過:Plug按tab鍵自動補全。整個vim的插件管理就變得非常方便了。
5. vim 的復制與粘貼
對于命令行形式的vim,想要將外界復制的內容粘貼到 vim 的文本之中,需要有如下幾步:
- 使用 vim 打開一個文件,進入 vim 的一般模式下
- 通過一般模式的 跳轉命令,將光標移動到需要粘貼的行以及列處
- 輸入
i或者a等插入命令進入vim的插入模式 - 通過鍵盤
<ctrl-c>,粘貼到當前位置 - ESC回到一般模式,ZZ存盤退出
如果不退出vim的話則還需要通過如下兩步
- 打開vim進入一般模式,通過
:e file打開一個文件;可以使用<C-D>查看有哪一些文件,通過tab選擇文件并自動補全 - 存盤則通過:
:w
但是如果粘貼內容含有縮進,而vim又不夠新的情況,還會出現縮進之間在“打架”的情況,導致整個復制縮進一直基于上一個縮進的基礎上在縮進。這個情況是因為vim分不清用戶是在輸入,還是在粘貼,輸入此時會和粘貼沖突,則會有智能縮進、制表符轉換等功能。
這個可以通過 :set paste 命令來讓vim知道當前文件執行的是粘貼的命令,從而不會被智能縮進和制表符轉換的功能影響。
6. vim的模式匹配:正則表達式
6.1 基本的特殊字符
我們在vim的一般模式中經常需要用到模式匹配或者查找命令,通過/,?或者進入vim的命令模式: 進行匹配操作。
vim中的正則表達式和其他常用正則表達式是有一些區別的,這里先簡單介紹一下vim中的一些正則表達式的基礎,在一個搜索表達式里面有如下字符,., [],*, $,^, ~, \ 都是具有特殊含義的字符
.可以匹配除換行符外的任何字符,如a.可以匹配aa,ab等*表示之前的匹配源可以重復0次到多次,比如aa*可以匹配a,aa,aaa等,a.*可以匹配a,ab,abc等,但是兩者都不能匹配b^匹配一行等開頭,如果出現在模式的開頭的話;如果在模式的其他位置,則表示字符本身$匹配一行的結尾,如果出現在模式的結尾的話;在其他位置則表示字符本身~匹配上一次替換的字符,如果上一次把abc替換為了ate,那么~就匹配ate[...]匹配方括號內任意一個字符;方括號內如果第一個字符是^,表示對結果取反;除開頭之外的-表示范圍:如[A-Za-z]表示任意一個拉丁字母,[^+-*/]表示除了+,-,*,/之外的任意一個字符。\的含義取決于下一個字符,在大部分情況下包括上面的這幾個(.,[,],*,$,^,~,\) ,代表后面這個字符本身;在跟某一些字符時有特殊含義。
除此之外就是普通的字符,并沒有特別的含義;需要注意的是如果想要將搜索字符/作為普通字符來使用,則需要\/ 這樣,否則vim看到的/就會以為模式結束了,導致錯誤發生。
如果模式中使用"/"作為路徑的分隔符,在替換命令中可以使用使用其他模式中沒有的符號作為分隔符。比如想把路徑/path/
全部替換為/paths/ ,建議不要用:%s/\/path\//\/paths\//g ,這種樣子非常容易出錯。而應該使用類似的寫法:%s!/path/!/paths/!g,當然這個只能用于替換命令。如果想要使用/作為搜索命令的話就沒有太好的辦法了,只能使用\/這樣的形態。
6.2 特殊模式項
通過\開始的特殊表達式很多,如果我們想要全部了解的話可以通過help pattern-overview來詳細查看,這里僅僅列舉幾個基本的特殊模式項:
\?表示之前的匹配重復零次 或一次: 如aa\?可以匹配"a", “aa”, 但不能完整匹配"aaa"(可以匹配前兩個字符,后兩個或最后一個字符)\+表示之前的匹配原重復一次或多次:如aa\+可以匹配"aa",“aaa”, 但不能匹配"a"或"b"\{n,m}表示之前的匹配原重復n到m遍之間。如:a\{3}可以匹配3個"a":“aaa”;a\{,3}表示最多匹配3個"a", 支持匹配"", “a”, “aa"和"aaa”;大括號內兩個數字都省略時等價于*, 也就是之前的內容可以匹配0次或多次。\(和\)擴起一個模式, 從而組成單個匹配原:如\(foo\)\?可以表示單詞foo出現零次或一次。\&是分支內多個臨接的分隔符,類似于“與”操作,表示每一項都要匹配成功,然后去最后一項的返回結果:如.*foo.*\&.*bar.*匹配同時出現foo和bar的完整行。\|是多個分支的分隔符,類似于“或”的匹配,表示任意一項匹配成功即可:如foo\|bar可匹配foo或bar兩個單詞之一。
還有13個特殊模式項:
\<匹配單詞的開頭\>匹配單詞的結尾\s匹配空白字符\S匹配非空白字符\d匹配數字,相當于[0-9]\D匹配非數字,相當于[^0-9]\x匹配十六進制數字,相當于[0-9A-Fa-f]\w匹配單詞字符,相當于[^0-9A-Za-z_]W匹配非單詞字符\h單詞首字符:[A-Za-z_]\H非單詞首字符:[^A-Za-z_]\a英文字母字符:[A-Za-z]\A非英文字母字符:[^A-Za-z]\l小寫字符:[a-z]\L非小寫字符:[^a-z]\u大寫字符:[A-Z]\U非大寫字符[^A-Z]\_其中 x 可以是以上任意一個字符: 對應字符類加上換行
6.3 一些搜索舉例
-
想要準確匹配一個函數名:
/ \<function_name\>
或者將光標移動到想要匹配的關鍵字上面,按下*,vim就會自動提取光標下的關鍵字,并自動添加\<和\>進行搜索。 -
如上代碼片段,我想要搜索
ReoportError或者void,那么就想到了上面特殊模式中斷\|字符輸入
/\<ReportError\>\|\<void\>即可
6.3.1 最長匹配和最短匹配
這里有一個問題就是我們想要搜索的內容中有很多特殊字符,整個模式會變得極其復雜。
而像*,\?,\+和\{}都屬于最長匹配(貪婪匹配),即模式 既可以匹配一個較長的字符串,也可以匹配一個較短的字符串的時候結果會是那個比較長的字符串。
相應的也會有一個最短匹配,同時匹配較長和較短字符是會產生較短匹配。在vim里面,最短匹配只有一種形式,{-n,m},起意義和之前說得{n,m}相同( \{n,m} 表示之前的匹配原重復n到m遍之間),但結果是較短而非較長的字符串。
以HTML 標簽匹配為例,使用最短匹配的話,可以把模式寫成/<.\{-1,}>,表示要求模式匹配的結果在一對尖括號里面且至少有一個字符,但越短越好。
6.3.2 搜索加亮和取消
如果也有在做上面但實驗,會發現vim在搜索的過程中默認會將模式匹配的內容高亮,這個對確認自己的搜索結果是否正確非常重要。
但是如果你是用了非原生vim,比如某一個IDE的插件,那么就會發現并不是默認高亮。
而有的時候又覺得高亮太刺眼,想要去掉,這個時候vim就提供了比較方便的指令:nohlsearch或者:nohls
想要恢復高亮,則可以:set hlsearch或者:set hls
如果這兩個取消和恢復高亮的指令使用非常頻繁,則可以設置map鍵
noremap <LEADER><CR> :nohlsearch<CR> 我這里設置的是直接按LEADER鍵,我的LEADER鍵設置的是let mapleader=" "空格
6.3.3 正則表達式替換
替換我們正常理解就是利用之前提到的一些模式匹配特殊字符來完成,將一個字符串替換為另一個字符串。但是很多替換場景還是非常復雜的。
- 可能要保留匹配中的某一些字符,而替換另外一些字符
- 要對匹配出來的內容做大小寫轉換
- 可能需要 “計算” 出替換結果
- 可能要決定一行里面替換單次還是多次,是自動替換還是要 – 確認 ,等等。
接下來看看具體的操作
-
在替換結果中保留匹配出的字符
之前我們說到\(\)特殊模式 除了將一個模式轉變成匹配原之外,還有一個捕捉匹配的內容的作用。
按照\(的出現順序依次編號為1到9,并可以在模式和替換字符串中用\1到\9來訪問。如果要在替換字符串中完整使用匹配內容的話,則可以使用\0或&(字符 “&” 也因此要在替換字符串中寫成\&)如果我想要找出作為函數調用的
WebSocket,那我可以寫成\<WebSocket(,雖然(不是想要匹配的內容,但它是函數名稱的一部分。從替換的角度來看需要多處理一下這個字符;在非匹配的內容比較復雜或者變化的時候,這個過程尤為麻煩。
所以vim 里還有專門匹配開始和結束的匹配原,分別是\zs和\ze對于上面函數調用的這個例子,搜索模式就應該是
\<WebSocket\ze(,當然這個模式也可以匹配為\<WebSocket(\&WebSocket或者\<WebSocket(\&...。 -
大小寫轉換的特殊替換字符串
\U把下面的字符串轉變成大寫,直到\E出現
\u把下一個字符變成大寫
\L把下面的字符變成小寫,直到\E出現
\l把下一個字符變成小寫
\E結束大小寫轉換
\=開始一個返回字符串的表達式,用來計算出一個替換的結果和其他的編程語言一樣,vim的正則表達式中支持
\t,\r,\n等特殊轉義字符,但在替換表達式中,\n插入的是空字符(NULL或\0),而非在模式中正常的行尾符LF。如果想要插入行尾符的話我們需要使用\r。這意味著把一個回車變成兩個,需要通過:s/\n/\r\r/這樣尷尬的方式來實現。
如果我們要插入CR(回車)的話,需要輸入\<C-V><CR>才行。
6.3.4 替換實例
-
刪除行尾注釋
:%s!\s*//.*$!!
把零到多個空白字符后面出現的"//" 直到行尾全部刪除,!這個表示分隔符,是為了簡化模式,否則就需要通過\/來不斷轉義 -
刪除
/**/注釋
這個實現就非常復雜了,首先匹配內容可以跨行;其次,有跟HTML標簽類似的問題(注釋內部可能有多個/**/),需要使用最短匹配。
通過如下來實現
:%s!/\*\_.\{-}\*/!!g因為一行中可能有多個
/**/,結尾通過g表示允許一行內部持續多次替換。
后續會持續分享vim的更高級操作,包括鍵盤宏,vim的插件,以及如何編寫vim script來讓自己的指尖 有效得 飛得更快。
總結
以上是生活随笔為你收集整理的vim 成“神“之路 (一)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 试管婴儿哪个国家做的好啊
- 下一篇: 电影投资靠谱吗