xml.vim plugin 替代方案
xml.vim(原 vim script 1397)這個 plugin 提供一些小功能,寫 HTML 的時候很實用。
不過檢討一下發現,我只用到其中一兩個 mapping 而已……
最後決定移除,自己重製。
各種功能重現
-
自動關閉 tag
在<div
後面輸入>
時,會自動補上</div>
並把游標放回 tag 中間。
現改為以下 function,按 >> 發動。inoremap <buffer> >> <C-\><C-N>:call <SID>html_close_tag()<CR>
function! s:html_close_tag() " Find < or >, should take action only when < appears first. if search('\v(\<)|(\>)', 'bnpW') == 2 let missing_gt = getline('.')[col('.')-1] == '>' ? '' : '>' execute "normal! a" . missing_gt . "</" . "\<C-X>\<C-O>" . "\<C-\>\<C-N>F<" call feedkeys('i', 'n') else call feedkeys('a>>', 'n') endif endfunction
無論在<div
或<div>
後都能正常運作。 -
將 tag 拆為多行
前述<div>|</div>
再按一次 >(| 為游標位置)的話,tag 會被拆為<div> | </div>
這個我沒做。 但可配合下面的 function 改為按 >> 後再按 ;; 達成。 -
自動建立 tag
輸入div;;
就會展開為<div> | </div>
且如果該 tag 前面已有文字,就不會拆為多行,而是變成單行的<div>|</div>
。
新的實作如下:inoremap <buffer> ;; <C-\><C-N>:call <SID>html_make_tag()<CR>
function! s:html_make_tag() let save_reg = [getreg(), getregtype()] execute "normal! a \<C-\>\<C-N>db" let tag_name = @" call setreg(v:register, save_reg[0], save_reg[1]) " Skip invalid tag_name (non-words) if tag_name =~ '\W' " Special case to break single-line tag into multiline form. (that is, 'make' an existed tag) " e.g.: when input ;; between <div></div> if tag_name == '>' && search('\%#\s*<', 'cnW', line('.')) execute "normal! cl" . tag_name . "\<C-\>\<C-N>a\<CR>" call feedkeys('O', 'n') else execute "normal! cl" . tag_name call feedkeys('a;;', 'n') endif return endif let unaryTagsStack = get(b:, 'unaryTagsStack', "area base br col command embed hr img input keygen link meta param source track wbr") if index(split(unaryTagsStack, '\s'), tag_name, 'ic') >= 0 execute "normal! a<" . tag_name . ">" call feedkeys('a', 'n') else " Don't break tag into multi lines if current line is not empty. if getline('.') =~ '\S' execute "normal! cl<" . tag_name . "></" . tag_name . ">\<C-\>\<C-N>F>" call feedkeys('a', 'n') else execute "normal! cl<" . tag_name . ">\<CR></" . tag_name . ">\<C-\>\<C-N>O" call feedkeys('"_cc', 'n') endif endif endfunction
-
在開/關 tag 之間移動
在<div>
上按 % 就能跳到</div>
的位置,也可來回跳。
這個其實不必裝 xml.vim,啟用 matchit 就能辦到了,見:help matchit
。 -
change 外圍 tag
在<di|v>foobar</div>
按 \c,可以把成對的 div 取代為別的值。
這個也不必裝 xml.vim,改用 surround.vim 比較實在。
按鍵是 cst< (Change Surrounding Tags with Tag...) 就會提示你輸入 tag name。
備註
- 本文的 2 個
inoremap
正確用法是在 filetype 為 html 時才生效。 -
以上實作會依賴一些選項,譬如 auto close tag 是藉由
</
後的 omni-completion 達成,換行部分可能也需要正確的 indent 設定。 - xml.vim 還有一些額外功能,例如處理 HTML comment 什麼的,因為沒在用,我就沒研究了。
有 0 個意見
☂