一如大多數編程語言,Vimscript支持函數。讓我們看看如何創建函數,然后再討論它們的古怪之處。
執行下面的命令:
~~~
:function meow()
~~~
你可能會認為這將定義函數`meow`。不幸的是,情況不是這樣的,我們已經掉進了Vimscript其中的一個坑。
**沒有作用域限制的Vimscript函數必須以一個大寫字母開頭!**
即使你_真的_給函數限定了作用域(我們待會會談到),你最好也用一個大寫字母開頭。 大多數Vimscript程序猿都是這么做的,所以不要破例。
ok,是時候認真地定義一個函數了。執行下面的命令:
~~~
:function Meow()
: echom "Meow!"
:endfunction
~~~
這次Vim愉快地定義了一個函數。讓我們試試運行它:
~~~
:call Meow()
~~~
不出所料,Vim顯示`Meow!`
讓我們試試令它返回一個值。執行下面的命令:
~~~
:function GetMeow()
: return "Meow String!"
:endfunction
~~~
現在執行這個命令試試:
~~~
:echom GetMeow()
~~~
Vim將調用這個函數并把結果傳遞給`echom`,顯示`Meow String!`。
## 調用函數
我們已經看到,Vimscript里調用函數有兩種不同的方法。
當你想直接調用一個函數時,使用`call`命令。執行下面命令:
~~~
:call Meow()
:call GetMeow()
~~~
第一個函數輸出`Meow!`,然而第二個卻沒有任何輸出。當你使用`call`時,返回值會被丟棄, 所以這種方法僅在函數具有副作用時才有用。
第二種方法是在表達式里調用函數。這次不需要使用`call`,你只需引用函數的名字。 執行下面的命令:
~~~
:echom GetMeow()
~~~
正如我們見過的,這會調用`GetMeow`并把返回值傳遞給`echom`。
## 隱式返回
執行下面的命令:
~~~
:echom Meow()
~~~
這將會顯示兩行:`Meow!`和`0`。第一個顯然來自于`Meow`內部的`echom`。第二個則告訴我們, 如果一個Vimscript函數不返回一個值,它隱式返回`0`。看我們可以利用這一點做什么。執行下面命令:
~~~
:function TextwidthIsTooWide()
: if &l:textwidth ># 80
: return 1
: endif
:endfunction
~~~
這個函數涉及到我們之前學到的許多重要概念:
* `if`語句
* 將選項作為變量
* 訪問特定作用域里的選項變量
* 大小寫敏感的比較
如果你對以上內容感到陌生,最好翻到前幾章溫習一遍。
現在我們已經定義了一個函數,該函數告訴我們當前緩沖區的`textwidth`會不會設得‘太過寬’。 (因為80字符的限制適用于除了HTML之外的任何代碼文件)
現在讓我們使用它。執行下面的命令:
~~~
:set textwidth=80
:if TextwidthIsTooWide()
: echom "WARNING: Wide text!"
:endif
~~~
在這里我們做了什么?
* 一開始我們設置全局的`textwidth`為`80`。
* 接著我們運行一個if語句判斷`TextwidthIsTooWide()`是否為真。
* 由于不滿足條件,`if`語句體(譯注:包括函數內的和函數外的)不會被執行。
因為我們沒有顯式返回一個值,Vim從函數中返回代表'falsy'的`0`。試試改變一下。運行下面的命令:
~~~
:setlocal textwidth=100
:if TextwidthIsTooWide()
: echom "WARNING: Wide text!"
:endif
~~~
這次函數中的`if`執行了它的語句體,返回`1`,并且我們手工輸入的`if`語句也執行了_它_的語句體。
## 練習
閱讀`:help :call`。目前先忽略關于"范圍"的內容。你可以傳遞多少參數給一個函數?感到驚訝不?
閱讀`:help E124`第一自然段并找出你可以用哪些字符來命名函數。可以用下劃線嗎?點(Dashes)呢? 重音符號(Accented characters)?Unicode符號?如果讀了文檔還是搞不清楚,試一下看看。
閱讀`:help return`。這個命令的縮寫("short form")是什么?(我說了你千萬不要用它) 在你的預期之內嗎?如果不是,為什么?
- 前言
- 鳴謝
- 預備知識
- 打印信息
- 設置選項
- 基本映射
- 模式映射
- 精確映射
- Leaders
- 編輯你的Vimrc文件
- Abbreviations
- 更多的Mappings
- 鍛煉你的手指
- 本地緩沖區的選項設置和映射
- 自動命令
- 本地緩沖區縮寫
- 自動命令組
- Operator-Pending映射
- 更多Operator-Pending映射
- 狀態條
- 負責任的編碼
- 變量
- 變量作用域
- 條件語句
- 比較
- 函數
- 函數參數
- 數字
- 字符串
- 字符串函數
- Execute命令
- Normal命令
- 執行normal!
- 基本的正則表達式
- 實例研究:Grep 運算符(Operator),第一部分
- 實例研究:Grep運算符(Operator),第二部分
- 實例研究:Grep運算符(Operator),第三部分
- 列表
- 循環
- 字典
- 切換
- 函數式編程
- 路徑
- 創建一個完整的插件
- 舊社會下的插件配置方式
- 新希望:用Pathogen配置插件
- 檢測文件類型
- 基本語法高亮
- 高級語法高亮
- 更高級的語法高亮
- 基本折疊
- 高級折疊
- 段移動原理
- Potion段移動
- 外部命令
- 自動加載
- 文檔
- 發布
- 還剩下什么?