需求
編輯html會有諸多快捷鍵或補全的需求,這裡先列出幾個基本需求來實作
1.限定檔案的括號補全
如打完<
希望能自動補全>
但是希望限定html檔使用
因為其他語言數學式常用到大小於,通常不希望被補全
2.快速打出tag
自訂快捷鍵,快速產生tag
如打出;b 可以快速產生 <b></b>
或 ;p 可以快速產生 <p></p>
3.設定跳躍點
希望在打完tag內容後,可以快速跳到下一行
如
<p>content</p>
+jump+
打完content內容後,可以快速跳躍到外面
4.使用說明
希望在打開html檔後,可以跳出一個說明檔告知如何使用
實作
先看看實作script
"每當打開html檔,自動執行
autocmd FileType html call InitHtml()
"接收使用者輸入的function
function InputTag()
call inputsave()
let g:tag = input("your tag")
call inputrestore()
endfunction
"打開html所需執行的設定函數
function InitHtml()
"自動補全角括號
inoremap < <><Left>
"""
在normal模式按下; 接續輸入會成為tag與跳點
如;p 會生成 <p></p>
跳點
並將光標移回tag中間,同時切換成insert模式
"""
nnoremap ; <ESC>:call InputTag()<CR>i<<C-R>=tag<CR>>OwwOw</<C-R>=tag<CR>><Space><Enter><++><Esc>/OwwOw<CR>5xi
"在插入模式按下;; 會跳至跳點,並切換成normal
inoremap ;; <ESC>/<++><Enter>4x<ESC>
endfunction
結果如下圖
講解
以下是依次講解使用到的script
autocmd
autocmd 事件 匹配 指令
可以在條件滿足時,自動執行後面的指令
1. 事件
常見事件有 讀寫檔案 關閉、離開vim、buffer、window ...並且事件也可以用FileType等指令來依 不同種類檔案來執行不同指令
2. 匹配
匹配特定的檔案,讓autocmd執行在你想要執行的檔案 並且可以使用萬用字元,比如*表示任何檔案- Note: FileType 後的檔案類型本身就已經囊括匹配了
以下是一些例子 (參考:http://vimdoc.sourceforge.net/htmldoc/autocmd.html#{event})
autocmd BufRead * :vs test #開啟任何檔案時自動打開test
autocmd BufRead /tmp/*.py set ts=4 #打開python時自動設定tab長度為4
autocmd BufWrite * :!ls #在儲存檔案時自動ls當前目錄
FilType
檢查當前檔案是甚麼,檢查方式是看檔案的
副檔名。
比如.py , .html , .md …
可以使用指令set filetype? 來查看當前filetype
此外,也可以在~/.vim/after/ftplugin/<FileType>.vim
中為不同副檔名分檔設定
(其中<FileType>
要填入對應的副檔名,比如html.vim)
結合autocmd ,就變成當filetype == 你想要的type才執行後續指令
vim function
1. function 介紹
vim 中的function可以同時進行多個設定比如今天想執行三個設定A B C
autocmd 不需要打三次,直接call function就好
也就是
autocmd FileType html A
autocmd FileType html B
autocmd FileType html C
可以改寫成
function setting()
A
B
C
endfunction
autocmd FileType html call setting()
- Note: 使用時要call 函數名稱()
2. function 結構
結構大概是function 名稱()
// your function
endfunction
注意function範圍是由function ~ endfunction決定
不是縮排,也沒有括號
此外,關於函數參數以後用到會再補上講解
map
1. mapping 介紹
可以讓按鍵進行替換,用途非常多(補全、快捷鍵)基本格式為
[模式][遞迴]map {原按鍵} {替換按鍵}
如將( 替換成 () 就能自然打出括號補全
補全也可以用於打出指令,也有遞迴的補全,此外也可以模擬任何按鍵,以下為介紹
2. mapping 方式
mapping方式可以依 模式區分,並且可以選擇不要遞迴mapping(舉例而言 map A B , map B C ,若遞迴map,按下A就會被映射到C)
可以將模式加在map前面
例如imap, nmap
預設為遞迴,可以將nore加在模式與map之間
如inoremap, nnoremap
還有更多進階用法,以後用到也會介紹(參考:https://vim.fandom.com/wiki/Mapping_keys_in_Vim_-_Tutorial_(Part_1))
3. 按鍵
除了基本英文字母以外,mapping也可以模擬其他按鍵 比如方向鍵<Left> < Right> <Up> <Down>
Enter 鍵、ESC鍵、 空白鍵
<CR>(或<Enter>) <Esc> <Space>
- Note: ESC鍵可以從insert mode 轉換成 normal mode,常用
Control + x
<C-r> #Control+r 以此類推
4. 綜合應用
1.括號補全inoremap { {}<LEFT> #補全後回到括號中間,方便輸入
此例告訴我們可以map任何按鍵,包括用方向鍵移動光標
2.跳點
inoremap <Space> <Esc>/<++><Enter>4xi
按下space後
先利用ESC回到normal
利用/搜尋跳點
按下enter找到跳點
利用4x刪除跳點,完成跳躍
最後切換模式回insert
此例告訴我們甚至可以map normal mode下的指令,以及模式間的切換
input()
input()可以回傳使用者的輸入
例如
let g:name = input(“your name”)
並且裡面的參數可以收字串,告知使用者該輸入甚麼(與python的input用法一樣)
而在使用input()時,為了防止vim的自動補全,通常會在前後加入
inputsave(),inputrestore()
比如
function inPutPattern()
call inputsave()
let g:name = input("your name")
call inputstore()
endfunction
(g表示全域變數,這樣function外部也可以使用到name)
打出變數的方法
用input()紀錄使用者輸入後,可以在insert mode下用Ctrl+r再輸入=變數名打出該變數內容
(注意,若是在normal模式 <c-r>
是回復)
舉例如下gif
實作講解
autocmd FileType html call InitHtml()
當開啟.html時,自動呼叫InitHtml()
function InitHtml()
...
endfunction
定義InitHtml()
inoremap < <><Left>
自動補全角括號
nnoremap ; <ESC>:call InputTag()<CR>i<<C-R> =tag<CR>>OwwOw</<C-R> =tag<CR>><Space><Enter><++><Esc>/OwwOw<CR>5xi
按下;時
切換成normal
呼叫InputTag()
按下確定
切換成insert
完成補全並留下記錄點(OwwOw)
在外面留下跳躍點(<++>
)
切換成normal
跳回OwwOw,並清空(4x)
最後切換成insert
function InputTag()
call inputsave()
let g:tag = input("your tag")
call inputrestore()
endfunction
接收輸入者輸入tag
inoremap ;; <ESC>/<++><Enter>4x
前面解釋過的跳點