vim 從嫌棄到依賴(12)——開啟及儲存檔案
在前幾篇文章中,我們從vim各種模式的使用著手介紹了vim如何進行文字本身的編輯。也通過緩衝區列表的介紹瞭解到了vim是如何進行開啟檔案的管理。這篇我們將會著眼於檔案的開啟和儲存的基本操作。通過這篇的閱讀,我們可以正式開始嘗試將vim用做程式碼編輯器,而不再是像之前那樣作為普通的文字編輯器。
開始前的準備
先來介紹一下vim的工作目錄的概念。我們知道程序都有自己的工作目錄,後續需要操作某個目錄的時候,可以根據這個工作目錄使用相對路徑。這樣的好處是比較靈活,只要我們的檔案按照一定的規則進行組織,後續可以更換程式可執行檔案所在路徑而不用更新程式碼。
vim自己也有一個工作目錄的概念,可以通過:pwd
為了展示vim是如何進行目錄和檔案管理的,這裡我準備通過我之前在github上託管的自己的vim配置檔案來進行演示,nvim-config 各位小夥伴可以下載進行實驗,以便達到與教程保持相同效果。也可以採用自己的實際專案進行實驗。這裡我多說一句,我並不推薦各位採用這個配置,第一個原因在於這個配置並沒有完全完成,算是一個半成品。第二個原因是這個配置並不能完美的符合各位的工作流和工作習慣。我們學習vim、學習vim的配置主要是為了結合自己的工作習慣和工作流形成一套符合自己習慣的操作方式,並不推薦大家照搬裡面的配置。第三個原因是,在後續我想寫一系列的從0開始配置vim的文章,幫助大家完成自己的配置。
edit命令
開啟一個檔案可以通過:edit {filename}
(或者簡寫為 :e
) 。如果filename採用絕對路徑,那麼開啟的就是絕對路徑所對應的檔案,如果是相對路徑,那麼就可以開啟相對與vim工作目錄的檔案。
例如我們想開啟專案中的基礎配置檔案lua/basic/settings.lua
,就可以執行:edit lua/basic/settings.lua
。根據我們前面所學的內容,vim的命令模式是支援自動補全的,我們可以通過tab來快速補全路徑
假設現在已經打開了這個檔案,我想開啟它同級目錄下的keybinds.lua
來配置快捷鍵的話,我要同樣的輸入:edit lua/basic/keybinds.lua
settings.lua
了,我為了開啟keybinds.lua
要輸入這麼大一堆,如果我能以當前settings.lua
的路徑作為相對路徑就好了。
vim 在命令列中提供了一個%
作為活動緩衝區的完整路徑。我們在直接介紹命令模式的時候,%
是作為範圍表示當前開啟的整個文字。這裡它作為路徑引數的話,表示的是當前開啟文字的完整路徑。
我們可以通過 :edit %<Tab>
來自動顯示整個路徑,然後通過<C-w>
來刪除單詞,直到刪除到當前目錄,然後再輸入keybinds.lua
就可以了
用這種方法是簡單了點,但是最後還要刪除個檔名,上面我們按了3次<C-w>
,也挺麻煩的。有沒有什麼方法可以直接定位到對應的目錄,讓我直接輸入檔名呢?可以通過 在%
的後面加上:h
來自動去掉檔名,即輸入:edit %:h<Tab>
來自動出現對應的目錄。這個功能還是挺有用的,但是需要輸入這麼多內容,為了簡化它你肯定也想到了,要給它配置快捷鍵。這裡還是留到以後再講解它的使用。
find命令
即使:edit
命令有%
這種操作來簡便輸入,但是在開啟其他目錄中的檔案時仍然需要輸入完整的目錄和檔名,這個操作也是挺繁瑣的。
作業系統中,有一個PATH
環境變數,輸入命令的時候,他會在PATH
所指定的目錄中查詢對應命令。vim中也有類似的概念。
vim中可以使用:find
,根據輸入的檔名開啟檔案。但是使用:find
的前提是配置path
變數。它們合作完成開啟檔案的操作,與環境變數的用法類似。
可以輸入:set path+=./**
將當前工作目錄以及它下面的所有子目錄。然後可以直接輸入:find keybinds.lua
開啟這個檔案了。
你可能會問,如果專案中有相同的檔名呢,這個專案裡面沒有同名檔案,這裡我們在lua/basic
目錄中新建一個init.lua
這樣它就與根目錄下的init.lua
相同了。我們輸入:find init.lua
,它會開啟當前檔案所在目錄附近的同名檔案。例如如果當前開啟的檔案在lua/basic
目錄中,那麼它會開啟nvim-config/lua/basic/init.lua
,如果當前開啟檔案在nvim-config
中,它會開啟nvim-config/init.lua
。也可以在輸入完init.lua
之後,按下<Tab>
它會提示所有匹配到的檔案。我們可以指定位置的檔案開啟。
在我們不斷使用tab來匹配會出現3個匹配項:init.lua、./init.lua、./lua/basic/init.lua。他們分別對應著上面所說的那個匹配的檔案,以及其他兩個不同位置的檔案。
vim自帶的目錄管理工具
在一般的ide中,左側或者右側會以樹的形式顯示專案中的目錄。vim中也有這樣的功能。它是vim提供的一個名為netrw
外掛。
我們開啟一個目錄就可以看到,它在視窗中顯示該目錄中的檔案結構。它與普通的緩衝區視窗一樣,可以通過motion
操作來移動游標。也支援命令列模式,但是這個緩衝區是不可修改的,也無法儲存。在該視窗中,隨意選擇一行按下回車,如果選擇的是一個檔案,那麼它會開啟該檔案,如果是目錄那麼視窗中則會進入該目錄並顯示目錄內容。
我們可以像開啟一個普通的文字檔案那樣開啟一個目錄,二者的區別僅僅在於顯示的內容不同,某些行為不同而已。如果當前已經打開了一個檔案,我想再繼續顯示這個目錄呢?相信各位小夥伴已經猜到了,既然可以以開啟普通檔案的方式開啟新的目錄,那麼我使用:edit
命令,在後面加入目錄路徑是不是就可以了。
經過實驗,確實是這樣呢。看到沒,vim就是這樣,一旦理解了它的邏輯,很多東西自己就能猜到。當然vim也提供了:Explore
專門用來顯示目錄結構。它可以簡寫為:E
後面不加任何東西可以開啟當前檔案所在目錄,也可以加上路徑開啟指定目錄。
如果我們想要像普通編輯器那樣將目錄結構放到左邊怎麼辦呢?套用開啟檔案的方式,各位肯定能想到使用:vsplit
加上目錄名。vim也提供了一組命令:Sexplore
和:Vexplore
分別在水平和豎直方向開啟目錄。
vim自帶的這個目錄管理工具最大的問題是我通過回車鍵從裡面選擇一個之後,會在當前視窗開啟一個新的緩衝區,並且把目錄樹給覆蓋了,這個時候我們可以快速按下<Ctrl + Shift>^
來在新開啟的緩衝區和目錄樹之間切換。
除了瀏覽目錄結構以外,也可以利用該外掛進行檔案和目錄的建立、刪除、修改、重新命名等操作,例如,使用%
來建立檔案, d
來建立目錄,R
重新命名或者移動目錄和檔案,使用 D
來刪除一個目錄或者檔案
vim自帶的目錄管理工具雖然提供了各種功能,但是並不是特別好用,我們有眾多的第三方工具可以使用。這個留著等到介紹配置的時候再說。一次性講太多了顯得太雜,而且我想用一個懸念留住各位讀者,也用它來吸引新的讀者,這也算是我一點小小的私心吧。
寫入檔案的一些小技巧
寫入不存在的目錄中
我們在原專案的基礎之上開啟一個新的有不存在目錄的檔案,例如:e random/111/test.txt
。
我們成功的進入了vim的編輯介面,我們也可以進行編輯,但是一旦執行寫命令的時候,發現vim會提示目錄不存在。它儲存檔案需要將檔案儲存到一個已經存在的目錄中。
我們可以退出vim,然後使用mkdir
來新建目錄。這個是下下策,之前輸入的內容全丟失了,再重新來一遍實在是令人惱火,不瞞各位,我之前就是這麼幹的,所以我養成了,新開啟一個檔案就立馬執行:w
的習慣。
還記得之前講過怎麼在vim中執行shell命令嗎,不想退出vim,又想在儲存前建立目錄,可以使用這招, :!mkdir -p random/111
, 然後再執行寫入。或者可以靈活的使用在前面介紹的:%h
來快速補全相對路徑
強制以root使用者寫入檔案
有時候我們使用vim打開了系統檔案,例如打開了/etc/hosts
檔案,但是儲存的時候意識到忘了加sudo
了,導致無法寫入,我以前的辦法是先退出,然後再用root許可權開啟,這樣就導致之前輸入的內容全都丟失了,幸虧我養成了前面說的那個習慣,開啟檔案之後的第一步就是執行:w
,在學習了vim的命令模式之後,估計各位小夥伴已經有思路來解決這個問題了。
我們以當前檔案內容作為命令輸入,配合shell命令,完成。我們知道可以使用tee
來將輸入內容寫入檔案中。那麼我們的命令可以是 :w !sudo tee % > /dev/null
, 我們使用:w
來指定當前緩衝區的內容作為shell命令的輸入。然後配合tee
來將內容寫入到%
也就是當前檔案。
寫入檔案之後vim會檢測到該檔案已經被外部的程式修改了,本例中它被 tee
命令修改了,因此這個時候vim會提示我們檔案已經被外部程式修改,需要重新載入檔案還是使用當前緩衝區的內容。因為這裡我們是將緩衝區內容直接覆蓋到檔案裡面,二者的內容是一樣的,使用哪個都行。由於neovim中該操作可能有問題,會報錯,這裡就不演示了,使用vim的小夥伴可以試試這個方法。後續我們可以使用擴充套件外掛來解決這個問題。