[Vim] Terminal Vim
TL;DR
包含在terminal使用vim時的一些其他功能。不一定可以完美對應vsc上的vim。
參考資料
本篇有些圖片取自高見龍老師在IT幫的鐵人賽文章中。
僅供紀錄學習用途,如有不妥麻煩告知。
相關連結
Buffer/Window/Tab的差異
如果使用:h window
去查詢會得到下面的回覆
buffer可能比較難理解,代表一個儲存在記憶體中的文字檔案
window就是顯示一個檔案的視窗(也就是上面的分割畫面)
而tab是window的集合,也就是一個tab裡面可以有很多個windows(當然只有一個window也沒有問題)
- buffer用來保存資料的
- window用來展示資料
- Tab 用來排版佈局
buffer編號
如果要觀看buffer裡面的檔案可以使用:ls
來觀看,%a
的地方代表目前所在的分頁的位置,且左邊會有buffer的編號。
a代表其他分頁中目前停留的地方,所以如果使用gt
切換tab的話,buffer1的位置就會變成%a
。
目前buffer3旁邊有一個#代表上一個開啟的buffer,可以使用:b <buffer number>
來切換buffer(eg: :b1
)
而ctrl+^
可以快速在%a與#中間切換!
:b <部分檔名>
也可以開啟已經存在ls中的buffer檔案(只要配對到唯一一個輸入部分檔名也可以開啟)
:bn
可以切換到下一個buffer(next的意思),:bp
可以切換到前一個buffer(previous)
:bl
可以跳到最後一個buffer(last),:bf
可以跳到第一個buffer(front)
:bdelete
可以關掉buffer,或簡稱:bd
:tab ball
(all的意思),可以一口氣展開全部目前開啟的buffer成tab,也可以簡寫成:tab ba
雖然感覺還是使用tab比較直覺,但是buffer用習慣也很好用,看個人使用習慣囉~
key mapping
vim另一個強大的地方是他的輸入映射,可以將目前輸入的內容替換成其他內容(或是指令)
mapping所使用主要有四種常見的 指令
命令 | Normal Mode | Visual Mode | Insert Mode |
---|---|---|---|
map | V | V | |
nmap | V | ||
vmap | V | ||
imap | V |
可以看到不同的指令分別對應到的模式也不同,可以根據想使用的狀況去選用
這邊很常會用到的一個資源是 :h key-notation
key-notation
可以查詢各種對應的鍵
舉例來說,輸入:vmap <C-c> y
代表會設定在visual模式之下,將<C-c>(利用key-notation查詢到代表這是ctrl+c的意思)替換成y,也就是說,如果已經選取了,使用ctrl+c(如同我們平常在其他軟體所使用的)可以複製所選的內容!
並且在其他模式會沒有效果,僅在visual模式下才會有效(詳見上表格)
又或者是想在輸入模式下,輸入jj就會跳回一般模式(雖然並不推薦)。這邊使用的指令是:imap jj <Esc>
使用:map
可以查詢到目前所有的mapping,裡面可能會有許多plugin所增加的內容,可能不是我們自己增加的
如果要取消目前的mapping,可以使用:unmap <欲清除map>、nunmap <..>、vunmap <..>、iunmap <..> 來清除已存在的mapping,或是使用:mapclear清除所有自己設定的mapping(不包含plugin的)
為了讓自己使用vim的時候可以減少手指離開鍵盤,可以關掉上下左右的所有功能,這時候就可以使用mapping來關閉
noremap <UP> <NOP>
noremap <DOWN> <NOP>
noremap <LEFT> <NOP>
noremap <RIGHT> <NOP>
inoremap <UP> <NOP>
inoremap <DOWN> <NOP>
inoremap <LEFT> <NOP>
inoremap <RIGHT> <NOP>
可以注意到這邊使用的都是noremap而不是map,nore代表的是no recursive,代表不會循環參照。
避免造成a map到b,b map到c,c又map到a 形成回圈的狀況。
所以只要是需要映射都使用noremap,當然如果要指定模式只要在前面加上n/v/i即可(eg::inoremap X X
)
noremap、nnoremap、vnoremap、inoremap
如果想要的功能已經被使用了,可以在前面加一個<leader>
,<leader>
預設是\
,可以透過設 定來將<leader>
更改成,
設定的方式參考這裡
例如:nnoremap <leader>h j
可以將,h變成j(向下),其實效果等同於:nnoremap ,h j
,但是也有使用<leader>
的好處的
使用<leader>
的好處在於,如果之後想要將leader改成別的按鍵可以一次將所有mapping更改完成(有點像是變數的概念
Auto Command (Autocmd)
Autocmd類似JS中的事件監聽(EventListener),可以預先註冊某個自動命令,當符合註冊的情境的時候,會執行後面的內容。
如果要查詢有哪些事件(例如進入window,離開buffer等),可以使用:h autocmd-events
以下利用三個範例來了解自動命令
- 切換視窗的時候顯示cursorline
- 刪除每行最後多餘的空白
- 按下f5之後執行程式
-
切換視窗的時候顯示cursorline
平常我們如果使用vnew開啟一個新的window的時候,通常兩個window都會有cursorline
如果我們想要只在目前所在的window才顯示cursorline,可以做以下設定
:autocmd WinEnter * setlocal cursorline
:autocmd WinLeave * setlocal cursorline第一行意思是指說,在進到一個新的視窗(WinEnter)事件發生時,做後面的事情。也就是設定有cursorline。 另外一行是設定離開Window的時候,將目前這個Window的cursorline給取消。
tipsetlocal跟set的用法是一樣的,只是差別在setlocal只會在目前所在的window,而不會在其他的window中套用。
-
刪除每行最後多餘的空白
這邊需要搭配正規表達式(Regex)來達到功能
輸入以下設定即可
:autocmd BufWritePre * :%s/\s\+$//e
BufWritePre事件,代表在寫入Buffer之前要做後面的事情。
-
按下f5之後執行程式
自訂設定
- 按下f5之後重新整理目前的排版
nnoremap <f5> migg<S-v>G='i
設定檔案(~/.vimrc)
設定檔預設會存在在~/.vimrc
中。這樣只要之後使用vim的時候會自動去讀取這個.vimrc
設定檔案
如果想要讀取其他的設定檔案,可以使用:source <設定檔路徑>
這個指令。
在vim設定檔中,如果需要註解,則需使用”
符號。且在設定檔案中不需使用:
例如需要設定行號只要在.vimrc檔案中加入一行set nu
即可
基礎設定
設定行號
開啟行號:
set number
set nu
關閉行號:
set nonumber
set nonu
設定剪貼簿共用
vim使用的是暫存器,如果要將外部程式剪下的剪貼簿貼在vim編輯器中,需要特別設定共用指令 如果想瞭解更多可以
:h clipboard
set clipboard=unnamed
設定游標所在處顯示底線
set cursorline
設定不要自動產生swap檔案
有時候程式會意外中斷,vim為了避免這種狀況導致檔案丟失,會自動生成一個swap檔案。這時候回去開啟意外中斷的檔案時,vim會發現有一個swap檔,這時候就會詢問你是不是要利用這個swap檔案回覆內容。 雖然這個功能目的是為了解決檔案意外丟失的問題,但是不利於版本控制,可能需要將swap產生的檔案丟到ignore中,如果不小心忽略了這個動作,導致將swap檔案一起丟到網路上,可能 會有風險(使用cat指令可以看到swap檔案內容中仍有資訊) 所以這邊選擇關閉swap自動生成檔案
set noswapfile
搜尋設定
設定搜尋的時候會有highlight
set hlsearch
設定搜尋的時候忽略大小寫差異
set ignorecase
設定漸進式搜尋(increase search)
我們平常在搜尋的時候,需要使用
/ <欲搜尋的字>
或是? <欲搜尋的字>
來搜尋,但是需要等到輸入完指令才會出現 如果我們開啟漸進式搜尋,只要每多打一個字,就會重新根據目前已經輸入的內容搜尋
set incsearch
有開啟漸進式搜尋的話,可以每鍵入一個字就會動態顯示目前搜尋的內容 :set incsearch
沒有開啟漸進式搜尋的搜尋狀況,需要完整輸入完enter之後才會顯示
:set noincsearch
縮排設定
縮排是在寫程式很重要的一個功能,<tab>
與空白鍵
雖然都可以縮排,但是兩者的內容其實不一樣。我們可以透過設定,來更改每次輸入tab會轉換變成空白鍵的數量(還是空白比較統一啦~),或是可以更改>>
& <<
縮排以及取消縮排的距離(也是空白數量)
設定每次使用>>
,<<
所會縮排的距離(visual模式中只需要輸入一次>
,<
)即可
這邊設定距離為兩個空白的家離
set shiftwidth=2
設定輸入tab會轉化的空白數量
只要開啟此功能,tab就會自動轉化成空白,如果需要輸入真正的tab,則需使用ctrl+V<tab> 這邊設定轉換成2個空白
set softtabstop=2
設定將目前的tab都軟化成對應數量的空白
如果已經有設定
softtabstop
好像就不用再設定這個了,不過不確定還是設定一下比較好,設定完之後需要搭配:retab
來將目前已存在的tab重新規劃(成空 白)
set expandtab
分割視窗設定以及分頁設定
分割視窗設定
設定新的分割視窗預設位置 如果沒有設定,預設
:new
會分割出新視窗在上方,:vnew
會分割出新視窗在左邊 需要加上以下設定來將預設的視窗設定在下方以及右邊
set splitbelow
set splitright
分頁設定
如果只有一個分頁,則預設是不會顯示分頁視窗。如果在僅有一個分頁(tab)的狀態下也要顯示分頁,就需要設定 可以使用
:h showtabline
來查詢
set showtabline=2
開啟顏色設定&語言辨識縮排外掛等設定
在vim編輯器中編輯不同的語言的時候,有時候會需要讓他偵測不同的語言,這個跟syntax以及filetype有關
打開語法偵測
syntax on
colorscheme <C-d>
來去選擇目前有的顏色風格 (<C-d>代表ctrl+d)
有可能在設定colorscheme的時候,不一定每台電腦都有該顏色設定 這時候就可以使用try…catch…endcatch來設定例外狀況
try
colorscheme desert
catch
colorscheme default
endtry
這樣如果電腦有desert這個顏色設定,就會套用。但是當沒有的時候會套用到default這個顏色設定。 (不一定只能設定顏色??? 待查證)
開啟filetype辨識語言
需要另外開啟filetype,否則vim無法辨識目前寫的是哪種語言 可以查詢
:h filetype
偵測檔案類型
filetype on
根據目前檔案類型進行縮排
filetype indent on
自動使用常用外掛
filetype plugin on
其他設定
更改預設的<leader>
let mapleader = ",”
設定Vi模式
Vi跟Vim其實是不同的,可以設定變成只有Vi的模式
- 設定成Vim模式(預設):
set nocompatible
- 設定成Vi模式:
set compatible
觀看目前所有自訂的設定檔案
:set
觀看所有vim有的設定檔
:set all
設定座標(目前所在位置)
set ruler
自動換行
預設是會自動換行的(但是仍是在同一個行號)
set nowrap
取消自動換行set linebreak
可以根據文字長度自動摺行(避免同一個word被拆成兩行顯示)
顯示目前模式
預設是顯示的,也可以關掉
set noshowmode
顯示目前指令
預設應該也是顯示的,可以手動關閉
set noshowcmd
智慧搜尋嚴格模式
設定搜尋時只要有混合大小寫,強制一定要完全相同(即使已經開啟ignorecase了也是)
set smartcase
預先滾動緩衝
設定滾動時不會到最後一行才滾動,會有一小段距離就開始滾動(以3行為例)
set scrolloff=3
顯示隱藏字元(e.g:換行符)
set list
(開啟看到隱藏字)set nolist
(關閉看到隱藏字)
設定檔整理
雖然也可以只用~/.vimrc 一個檔案來放設定檔,但是會不好維護。
最簡單的方式是根據內容分別創建好幾個設定檔,接著再在
$HOME/.vimrc
這支檔案中使用source
引入,但是有更好的方式所以這邊只是簡單介紹 e.g:先在$HOME
創建一個settings.vim
,並在裡面寫上set number
等設定 接著再在.vimrc
內加入一行source $HOME/settings.vim
,則當vim開啟去讀取.vimrc
這支設定檔的時候 一行一行讀取,讀到source $HOME/settings.vim
這行的時候會去路徑上尋找settings.vim
中的內容,並載入.vimrc
中 (有點類似css使用link的感覺)
另一種方式是使用vim官方推薦的分類方式!也是我們主要要使用的方式!!
例如說這邊先建立一個colors的資料夾 mkdir colors,接著創建一個mycolor的檔案,雖然以我們目前的能力可能要自己做一個color theme有點困難,但是這邊是要示範只要按照vim所建議的資料夾去規劃,就可以很輕鬆做到管理。
接著進到vim環境中,使用:colorscheme <C-d>就可以看到裡面有一個myColors的配色。
或是建立一個plugin的資料夾mkdir plugin,在這裡面建立一個mySettings.vim的檔案。這樣雖然沒有在.vimrc中引入這個檔案,但是vim預設會去抓取.vim/plugin下的設定。所以這邊的 設定仍然會生效。
像是這邊我在mySettings.vim中寫了一個key mapping,就算.vimrc中沒有source到這個檔案,仍然會生效
如果建立一個ftplugin的資料夾mkdir ftplugin
,根據文件,這個資料內的檔案會根據目前的檔案是哪種語言去執行對應的內容
如果建立一個myType.vim
的話,只要之後檔案類型是myType這種語言(當然這邊是亂打的,沒有這種檔案類型。通常檔案類型會是js,C等等),他會自動執行myType.vim裡面的內容
myType.vim檔案中只有一行,echo代表要回覆後面的文字(類似console.log?)
如果沒辦法判斷是哪個filetype,可以使用:set filetype=xxx
來設定檔案類型。
使用上面指令確定完filetype之後,就會顯示myType.vim中設定的內容,也就是回覆指定文字
在ftplugin檔案中建立一個vim.vim檔案,前面的vim代表之後只要副檔名或是檔案類型是vim檔的話,就會執行 以下內容
內容中輸入:
接著只要存擋,重新進入vim.vim(vim vim.vim)檔案之後,因為這個檔案的副檔名也是vim,所以就會自動執行剛剛設定的內容
我們還可以使用套件管理工具來協助我們管理套件
以前在使用套件的時候很麻煩,需要將檔案一個一個放到正確的位置。
但是現在我們可以使用套件管理的套件!!這樣管理套件的時候就很簡單了。
這邊推薦三種外掛管理工具
- VimPlug
https://github.com/junegunn/vim-plug
- Pathogen
https://github.com/tpope/vim-pathogen
- Vundle
https://github.com/VundleVim/Vundle.vim
❗我們以下使用VimPlug來操作
套件整理
可以參考Vimawesome這個網站,裡面根據不同用途有很多套件可以參考
VimPlug
首先先在terminal上輸入以下指令(根據官網資料)
curl -fLo ~/.vim/autoload/plug.vim --create-dirs \
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
跑完之後可以看到以下資訊,代表安裝完成
可以再去check看看,發現多了一個autoload的資料夾。並且裡面有一個已經寫好的plug.vim
檔案
(可以在這邊先上傳一個git版本)
接著只要在~/.vim/.vimrc檔案中新增一塊區域,內容照著規定的方式寫。就可以使用:PlugInstall的指令來安裝.vimrc中所有寫的套件
call plug#begin()
//要安裝的套件放這邊
//Plug 'github上從github.com/的後面這邊都要複製'
//e.g: Plug 'ap/vim-css-color'
call plug#end()
接著打開一個新的css檔案(好像預設只有.css會顯示)
可以看到已經有剛剛那個css-color套件的功能了!
也可以看到在.vim下面有一個plugged的資料夾。裡面會有所有已經安裝的套件。
vim-airline
Vim-airline是一個可以下方快速顯示功能區的套件
因為已經有下方的狀態列了,所以我們可以將原本的showmode給關掉
第一行將showmode改成noshowmode 第二行則是將下方自行改成有尖角 第五行將上方tab改成有尖角
相關設定可以參考Github頁面內說明
這邊我們統一在.vim/plugin/
裡面創建一個該套件名稱的設定檔案
(e.g:如果是vim-airline套件,設定檔名稱就會是vim-airline.vim
)
因為是在plugin資料夾內,所以設定檔案會自動生效。
nerdtree
nerdtree可以讓我們在目前的頁面旁邊顯示一個檔案系統,並且可以在裡面新增檔案或更改檔案名稱等等。也可以利用nerdtree創建一個資料夾。是一個必裝的套件!
我們在.vim/plugin/nerdtree.vim
設定檔案中,新增上圖右邊的內容
平常我們如果要設定打開nerdtree,需要輸入:NERDTreeToggle
的指令,我們設定在normal模式下,使用f2
就可以輸入指令並送出,這樣就可以使用f2切換nerdtree的開關了
接著使用官方的方式(第二、三行),當目前的頁面是最後一個的時候,:q離開會連同nerdtree一起關閉
最後一行是設定nerdtree顯示欄位的最精簡模式(避免上方出現一些其他的提示)
nerdtree有其他相關的指令,例如
- 使用
m
可以在下方叫出選單 如果輸入m可以在這邊修改檔案名稱,或是輸入a可以新增一個檔案,f可以在finder中顯示,d可以刪除等等 I
可以顯示隱藏的資料o
可以展開資料夾內容u
可以退到上一層(也就是cd ..
),C
可以進到資料夾中
ctrlp
- ctrlp Github
顧名思義使用的時候就是使用
<C-p>
,其用途為快速搜尋目前目錄下的檔案,並且快速切換。
這邊需要加上一些設定,讓使用上更符合我們需求
一樣在.vim/plugin/
新增一個ctrlp.vim
設定檔案,接著在裡面輸入
let g:ctrlp_by_filename = 1
let g:ctrlp_custom_ignore = {
\ 'dir': '\v[\/]\.(git|hg|svn)$|tmp$',
\ 'file': '\v\.(exe|so|dll)$',
\ 'link': 'some_bad_symbolic_links',
\ }
if executable('ag')
set grepprg=ag\ --nogroup\ --nocolor
let g:ctrlp_user_command = 'ag %s -l --nocolor -g ""'
let g:ctrlp_use_caching = 0
endif
第一行是設定,為了讓我們搜尋出來的目錄依照nerdtree指向的地方為基準,避免搜尋到外面我們不需要的資訊
接著設定忽略掉的資訊(例如dir中我們不需要tmp$ //$代表結尾)的資料夾出現在搜尋畫面中
最後一個設定是可以使用更快的搜尋方式(Silver Searcher)
如果需要使用Silver Searcher則需另外安裝
- 使用
ctrl+d
可以搜尋到file name only取代full path search ctrl+p
可以呼叫出ctrlp的視窗
官方文件基本操作
emmet
- vim emmet Github 自動補全的一個套件,在VS Code是內建的功能,但是在vim上面需要額外再安裝
因為最常使用的地方是在html,css當中,如果是在撰寫其他的語言的時候,反而會不希望他自動補全
官方有給出一個建議的設定如下(這邊我們一樣在.vim/plugin/
創建一個emmet.vim
)
Enable just for html/css
// 官方提供的建議
let g:user_emmet_install_global = 0
autocmd FileType html,css EmmetInstall
我們這邊多加了一些設定。除了css以外,我們很常在編輯css以前會有一個scss檔案,這邊也一起加入
並且我們將平常需要輸入指令的方式映射到tab上,讓我們可以利用tab直接展開emmet(原本預設是ctrl+y+,
)
let g:user_emmet_install_global = 0
autocmd FileType html,css,scss,sass EmmetInstall
autocmd Filetype html,css,scss,sass imap <silent> <expr> <tab> emmet#expandAbbrIntelligent("\<tab>")
我們所做的設定
vim-surround
可以快速的在所選範圍外插入或是修改”
,’
,tag
等等
這邊需要記幾個指令
先進入visual模式之後,使用S+想要在左右加上的東西
,即可自動增加,例如viw+S*
如果不想要先選取,也可以使用ys
當作動詞,例如ysiw"
如果已經有符號了,可以使用cs<原符號><欲改符號>
來修改,將符號改成新的符號,例如cs”*
可以將”
改成*
當然也可以使用tag
如果需要知道更多可以參考官網,這個套件真的很好用!!
如果要使用.來重複上一個操作,則需安裝另一個套件
vim-snipmate
可以利用少少的指定文字,創建出已經預先設定好的內容。
如果原本內預設的內容不夠,也可以自己新增(例如在使用bootstrap的時候,可以將需要的內容先儲存起來
之後就可以利用bs前綴詞,生出需要的元件等等。
預設儲存的檔案內容會位於plugged/vim-snippets/snippets
內,會依照filetype
去分類
自己新增的方式是在.vim/
下面新增一個snippets
的資料夾,並且在裡面根據filetype來設定檔案名稱。
例如想要設定的是html的話,就需要建立一個.vim/snippets/html.snippets
檔案,並且在裡面撰寫
撰寫格式如下
snippet <簡寫>
<real-Tab>想要生成的文字
e.g:
snippet justtest
justtest=${1:yaaya},${2:haha},${4:i'm 4th},${3:i'm 3th}
這邊的${1:yaya}
代表預設這會是第一個跳到的位置,且預設詞(placeholder)會是yaya,接著會跳到${2}
的位置,再來會跳到最後面的${3}
,最後才是回到第三個的${4}
當在insert模式的時候,可以使用<C-r><Tab>
來查看有哪些snippets可以使用
並且使用<C-n>
&<C-p>
來切換
i進入insert mode,type ab,ctrl+r+tab叫出視窗顯示有哪些snippets可以使用,ctrl+n下一個,ctrl+p上一個,shift+n設定展開snippets,再按一次shift+n跳到下一個placeholder的位置
tagbar
- tagbar Github 可以快速查看目前可以使用的方法(不太會用…之後再看看)
寫了一個tagbar.vim
的設定檔案,並將f3
映射到開啟tagbar功能
ack
可以快速查詢目前檔案的內容(支援ag)
在ack.vim設定檔案中,設定了如果可以使用ag查詢就用ag查詢
並且設定一個mapping讓我們可以使用FF開啟ack搜尋
vim-indent-guide
生成輔助線,讓我們可以方便看html的層級
手動設定顏色(關閉自動顏色設定)let g:indent_guides_auto_colors = 0
既然已經設定關閉自動顏色設定,就要手動自己指定。在裡面新增以下內容
autocmd VimEnter,Colorscheme * :hi IndentGuidesOdd ctermbg=176
autocmd VimEnter,Colorscheme * :hi IndentGuidesEven ctermbg=56
將indent guides設定成預設打開let g:indent_guides_enable_on_vim_startup = 1
做一個key mapping讓我們可以使用f2就切換是否打開功能nnoremap <f1> :IndentGuidesToggle<Enter>
設定寬度為一個字元let g:indent_guides_guide_size = 1
其他設定可以使用:h indent-guide
查詢
改變自訂顏色
先提供三個別人已經設定好的顏色設定檔案,需要將檔案加入到.vim/colors的資料夾內
- molokai-https://github.com/tomasr/molokai
- gruvbox-https://github.com/morhetz/gruvbox
- wombat256-https://github.com/vim-scripts/wombat256.vim
也可以自己手動去更改顏色,如下影片
高見龍老師的影片