W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
在開(kāi)頭前幾章我們?cè)v過(guò)怎么在Vim里設(shè)置選項(xiàng)。 對(duì)于布爾選項(xiàng),我們可以使用set someoption!
來(lái)"切換"選項(xiàng)。 如果我們能給這個(gè)命令創(chuàng)建一個(gè)映射,那就再好不過(guò)了。
執(zhí)行下面的命令:
:nnoremap <leader>N :setlocal number!<cr>
在normal模式中按下<leader>N
看看。Vim將會(huì)在開(kāi)啟和關(guān)閉行號(hào)顯示之間切換。 像這樣的"切換"映射是十分方便的,因此我們就不需要兩個(gè)獨(dú)立的鍵來(lái)開(kāi)/關(guān)。
不幸的是,這只對(duì)布爾選項(xiàng)起作用。如果我們想要切換一個(gè)非布爾選項(xiàng),還需要做更多的工作。
從創(chuàng)建一個(gè)可以切換選項(xiàng)的函數(shù),以及調(diào)用該函數(shù)的映射開(kāi)始吧。 把下面的代碼加入到你的~/.vimrc
(或一個(gè)~/.vim/plugin/
中的獨(dú)立文件,如果你想要的話):
nnoremap <leader>f :call FoldColumnToggle()<cr>
function! FoldColumnToggle()
echom &foldcolumn
endfunction
保存并source文件,然后按下<leader>f
試試看。Vim顯示當(dāng)前foldcolumn
選項(xiàng)的值。 如果你不熟悉這個(gè)選項(xiàng),閱讀:help foldcolumn
再繼續(xù)。
讓我們添加真正的切換功能。修改代碼成這樣:
nnoremap <leader>f :call FoldColumnToggle()<cr>
function! FoldColumnToggle()
if &foldcolumn
setlocal foldcolumn=0
else
setlocal foldcolumn=4
endif
endfunction
保存并source文件,然后試試看。每次你按下它Vim將顯示或隱藏折疊狀態(tài)條(fold column)。
if
語(yǔ)句判斷&foldcolumn
是否為真(記住Vim把0看作假而其他數(shù)字為真)。 如果是,把它設(shè)成0(隱藏它)。否則就設(shè)置它為4。就是這么簡(jiǎn)單。
你可以使用一個(gè)簡(jiǎn)單的函數(shù)像這樣來(lái)切換任何以0
代表關(guān),以其他數(shù)字代表開(kāi)的選項(xiàng)。
我們的夢(mèng)想不應(yīng)止于切換選項(xiàng)。還有一個(gè)我們想切換的東西是quickfix窗口。 依然以之前的骨架代碼作為起點(diǎn)。加入下面的代碼到你的文件:
nnoremap <leader>q :call QuickfixToggle()<cr>
function! QuickfixToggle()
return
endfunction
這個(gè)映射暫時(shí)什么都不干。讓我們把它轉(zhuǎn)變成其他稍微有點(diǎn)用的東西(不過(guò)還沒(méi)有徹底完成)。 把代碼改成這樣:
nnoremap <leader>q :call QuickfixToggle()<cr>
function! QuickfixToggle()
copen
endfunction
保存并source文件。如果現(xiàn)在你試一下這個(gè)映射,你就會(huì)看到一個(gè)空蕩蕩的quickfix窗口。
為了達(dá)到實(shí)現(xiàn)切換功能的目的,我們將選擇一個(gè)既快捷又骯臟的手段:全局變量。 把代碼改成這樣:
nnoremap <leader>q :call QuickfixToggle()<cr>
function! QuickfixToggle()
if g:quickfix_is_open
cclose
let g:quickfix_is_open = 0
else
copen
let g:quickfix_is_open = 1
endif
endfunction
我們干的事情十分簡(jiǎn)單 —— 每次調(diào)用函數(shù)時(shí),我們用一個(gè)全局變量來(lái)儲(chǔ)存quickfix窗口的開(kāi)關(guān)狀態(tài)。
保存并source文件,接著執(zhí)行映射試試看。Vim將抱怨變量尚未定義!那么我們先把變量初始化吧。
nnoremap <leader>q :call QuickfixToggle()<cr>
let g:quickfix_is_open = 0
function! QuickfixToggle()
if g:quickfix_is_open
cclose
let g:quickfix_is_open = 0
else
copen
let g:quickfix_is_open = 1
endif
endfunction
保存并source文件,接著試一下映射。成功了!
我們的切換函數(shù)可以工作,但還留有一些問(wèn)題。
第一個(gè)問(wèn)題是,假設(shè)用戶用:copen
或:cclose
手動(dòng)開(kāi)關(guān)窗口,我們的全局變量將不會(huì)刷新。 實(shí)際上這不會(huì)是個(gè)大問(wèn)題,因?yàn)榇蠖鄶?shù)情況下用戶會(huì)用這個(gè)映射開(kāi)關(guān)窗口,萬(wàn)一沒(méi)有打開(kāi),他們也會(huì)再按一次。
這又是關(guān)于寫(xiě)Vimscript代碼的重要經(jīng)驗(yàn):如果你試圖處理每一個(gè)邊際條件,你將陷在里面,而且不會(huì)有任何進(jìn)展。
在大多數(shù)情況下,先推出可工作(而且即使不能工作也不會(huì)造成破壞)的代碼然后回過(guò)頭改善, 要比耗費(fèi)許多小時(shí)苛求完美好得多。除外你正在開(kāi)發(fā)一個(gè)很可能有很多人用到的插件。 在這種情況下它才值得耗費(fèi)時(shí)日來(lái)達(dá)到無(wú)懈可擊的程度,讓用戶滿意并減少bug報(bào)告。
我們的函數(shù)的另外一個(gè)問(wèn)題是,當(dāng)用戶已經(jīng)打開(kāi)了quickfix窗口,并執(zhí)行這個(gè)映射時(shí), Vim關(guān)閉了窗口,接著把他們彈到上一個(gè)分割中,而不是送他們回之前的地方。 如果你僅僅想快速查看一下quickfix窗口然后繼續(xù)工作,發(fā)生這種事是讓人惱怒的。
為了解決這個(gè)問(wèn)題,我們將引入一種寫(xiě)Vim插件時(shí)非常有用的慣用法。把你的代碼改成這樣:
nnoremap <leader>q :call QuickfixToggle()<cr>
let g:quickfix_is_open = 0
function! QuickfixToggle()
if g:quickfix_is_open
cclose
let g:quickfix_is_open = 0
execute g:quickfix_return_to_window . "wincmd w"
else
let g:quickfix_return_to_window = winnr()
copen
let g:quickfix_is_open = 1
endif
endfunction
我們?cè)谟成渲屑尤肓诵碌膬尚?。其中一?在else
分支)設(shè)置了另一個(gè)全局變量,來(lái)保存執(zhí)行:copen
時(shí)的當(dāng)前窗口序號(hào)。
另一行(在if
分支)執(zhí)行以那個(gè)序號(hào)作前綴的wincmd w
,來(lái)告訴Vim跳轉(zhuǎn)到對(duì)應(yīng)窗口。
我們的解決方法又一次不是無(wú)懈可擊的,用戶可能在兩次執(zhí)行映射之間打開(kāi)或關(guān)閉新的分割。 即使這樣,它還是適合于大多數(shù)場(chǎng)合,所以目前這已經(jīng)夠好的了。
在大多數(shù)程序中,這種手工保存全局狀態(tài)的伎倆會(huì)遭到譴責(zé),但對(duì)于一個(gè)非常短小的Vimscript函數(shù)而言, 它既快捷又骯臟,卻能不辱使命,完成重任。
閱讀:help foldcolumn
.
閱讀:help winnr()
閱讀:help ctrl-w_w
.
閱讀:help wincmd
.
在需要的地方加上s:
和<SID>
來(lái)把函數(shù)限定在獨(dú)自的命名空間中。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: