我們新鮮出爐的"grep運算符"工作得很好,但是寫Vimscript的目的,就是要體貼地改善你的用戶的生活。 我們可以額外做兩件事,讓我們的運算符更加符合Vim生態圈的要求。
## 保護寄存器
由于把文本復制到未命名寄存器中,我們破壞了之前在那里的內容。
這并不是我們的用戶想要的,所以讓我們在復制之前先保存寄存器中的內容并于最后重新加載。 修改代碼成這樣:
~~~
nnoremap <leader>g :set operatorfunc=GrepOperator<cr>g@
vnoremap <leader>g :<c-u>call GrepOperator(visualmode())<cr>
function! GrepOperator(type)
let saved_unnamed_register = @@
if a:type ==# 'v'
normal! `<v`>y
elseif a:type ==# 'char'
normal! `[v`]y
else
return
endif
silent execute "grep! -R " . shellescape(@@) . " ."
copen
let @@ = saved_unnamed_register
endfunction
~~~
我們在函數的開頭和結尾加入了兩個`let`語句。 第一個用一個變量保存`@@`中的內容,第二個則重新加載保存的內容。
保存并source文件。測試一下,復制一些文本,接著按下`<leader>giw`來執行運算符, 然后按下`p`來粘貼之前復制的文本。
當寫Vim插件時,你_總是_應該盡量在修改之前保存原來的設置和寄存器值,并在之后加載回去。 這樣你就避免了讓用戶陷入恐慌的可能。
## 命名空間
我們的腳本在全局命名空間中創建了函數`GrepOperator`。 這大概不算什么大問題,但當你寫Vimscript的時候,事前以免萬一遠好過事后萬分歉意。
僅需增加幾行代碼,我們就能避免污染全局命名空間。把代碼修改成這樣:
~~~
nnoremap <leader>g :set operatorfunc=<SID>GrepOperator<cr>g@
vnoremap <leader>g :<c-u>call <SID>GrepOperator(visualmode())<cr>
function! s:GrepOperator(type)
let saved_unnamed_register = @@
if a:type ==# 'v'
normal! `<v`>y
elseif a:type ==# 'char'
normal! `[v`]y
else
return
endif
silent execute "grep! -R " . shellescape(@@) . " ."
copen
let @@ = saved_unnamed_register
endfunction
~~~
腳本的前三行已經被改變了。首先,我們在函數名前增加前綴`s:`,這樣它就會處于當前腳本的命名空間。
我們也修改了映射,在`GrepOperator`前面添上`<SID>`,所以Vim才能找到這個函數。 如果我們不這樣做,Vim會嘗試在全局命名空間查找該函數,這是不可能找到的。
歡呼吧,我們的`grep-operator.vim`腳本不僅非常有用,而且是一個善解人意的Vimscript公民!
## 練習
閱讀`:help <SID>`。
享受一下,吃點零食犒勞自己。
- 前言
- 鳴謝
- 預備知識
- 打印信息
- 設置選項
- 基本映射
- 模式映射
- 精確映射
- Leaders
- 編輯你的Vimrc文件
- Abbreviations
- 更多的Mappings
- 鍛煉你的手指
- 本地緩沖區的選項設置和映射
- 自動命令
- 本地緩沖區縮寫
- 自動命令組
- Operator-Pending映射
- 更多Operator-Pending映射
- 狀態條
- 負責任的編碼
- 變量
- 變量作用域
- 條件語句
- 比較
- 函數
- 函數參數
- 數字
- 字符串
- 字符串函數
- Execute命令
- Normal命令
- 執行normal!
- 基本的正則表達式
- 實例研究:Grep 運算符(Operator),第一部分
- 實例研究:Grep運算符(Operator),第二部分
- 實例研究:Grep運算符(Operator),第三部分
- 列表
- 循環
- 字典
- 切換
- 函數式編程
- 路徑
- 創建一個完整的插件
- 舊社會下的插件配置方式
- 新希望:用Pathogen配置插件
- 檢測文件類型
- 基本語法高亮
- 高級語法高亮
- 更高級的語法高亮
- 基本折疊
- 高級折疊
- 段移動原理
- Potion段移動
- 外部命令
- 自動加載
- 文檔
- 發布
- 還剩下什么?