iT邦幫忙

2025 iThome 鐵人賽

DAY 16
0

之前的文章探討了 Fennel、Lisp、函數式編程等概念。從現在開始,我們要開始那些將那些概念應用在 Neovim 的插件開發了。首先,先談一個失敗的學習經驗。

過去,我本來以為開發 Vim 的插件只有 VimScript 與 Lua 兩個選項,發現了 Fennel 之後,就興奮地開始研究。

一開始我發現 Conjure 可以應用 Fennel 的開發,但是,關鍵的跳轉定義不管用。接著,我試著訂出一個看似簡單一點的目標,並且嘗試前進。很快地我發現,遇到問題時,我常常想不出來該怎麼處理。然後,我就把這件事放一邊了。

為何學習失敗

如果分析一下 Neovim 插件開發需要哪些知識的話,除了 Neovim 編輯器操作的基礎之外,至少還有以下四類型的知識:

  1. Conjure 相關的開發環境設置
  2. Fennel 與 Lua
  3. Neovim Runtime
  4. Neovim API

我之前犯下的錯誤是:由於身為 Clojure programmer ,本來就持有 Conjure 相關的開發環境知識,我以為自己掌握了這一項之後,就算是掌握了 50% 的知識,所以就直接開始挑戰做專案。然而,實際上,我掌握的必要知識只有 25% 不到。

在知識如此缺乏的前提之下要前進,自然是困難重重。

相對合理的學習策略

比較合理的學習策略應該是:

  1. 好好地設置開發環境,包含 Conjure,語法高亮度等等。
  2. 將 Fennel 語言的介紹仔細讀過大半。就算記不住也要先讀過。
  3. 對 Neovim Runtime 有一些初步的研究。
  4. 在前述三項知識備齊後,再開始設定小題目,邊做邊學。

這邊讀者可能會覺得有點疑問,Neovim Runtime 與 API ,有什麼不同嗎?這邊我談的 Runtime 知識主要在以下幾個方面:

  • Lua 的編譯
  • 路徑
  • 基本的除錯

這些是必須的知識,而 Neovim API 則包羅萬象,有一些比方說 Tree sitter API 的知識,如果你根本沒有要用到 Tree sitter ,其實也大可以先跳過。

Neovim Runtime

當我們在做一般的網頁應用程式 (Web Application) 開發時,我們通常會先開發軟體,然後單元測試,之後則是搭配資料庫與 Http 伺服器的整合測試

之前的互動式開發,可以視為相當於單元測試,因為我們可以很快地驗証單一 Fennel 函數的運作。那整合測試的部分呢?我們寫的 Fennel 程式要怎麼與 Neovim 一起運作?

兩個挑戰:看不懂、找不到

讓 Fennel 程式與 Neovim 一起運作,主要克服兩個挑戰:

  1. Neovim 其實看不懂 Fennel ,因為它只有內建 Lua 的 Runtime 而已。所以我們必須將 Fennel 編譯成 Lua 。
  2. Neovim 內部有一個變數叫 runtimepath,它會利用該變數裡的路徑來尋找 Lua 檔來載入執行。精確一點來講,我們必須將 Lua 程式碼放在 runtimepath 變數所指向的資料夾之下的 /lua 子目錄,我們的程式碼才有可能被 Neovim 找到。

編譯插件 nfnl

為了編譯方便,我們需要再安裝一個插件:nfnl

安裝方式:

  • 開啟檔案 ~/.config/nvim/init.vim
  • 找到檔案裡被 plug#beginplug#end 夾住的區段,加入 nfnl 的安裝指令
call plug#begin(stdpath('data') . '/plugged')
...
" === Fennel (Config) Support ===
Plug 'Olical/nfnl'
...
call plug#end()
  • 接著,在 Neovim 的 Normal Mode 裡,執行以下的指令:
:source %
:PlugInstall
  • 此外,由於自動編譯插件的指令,會跟 fnlfmt 有點衝突,我們必須在 ~/.config/nvim/init.vim 裡,修改 FennelOnSave 的設置。改成下方:
augroup FennelOnSave
  " Format and compile after save
  autocmd!
  autocmd BufWritePost *.fnl call Fnlfmt() | NfnlCompileFile
augroup END

在安裝、設置了這個 nfnl 插件之後,如果我們日後在編輯完 $path/fnl/some_file.fnl 並且存檔,該插件就會自動生成一個對應的 $path/lua/some_file.lua 檔。

讓 Lua 檔可以被找到

首先,我們可以用以下的 Neovim Ex 指令,看到 runtimepath

set runtimepath?

可以得到:

runtimepath=~/.config/nvim, ... 

所以,我們可以得知,Lua 檔放在 ~/.config/nvim/lua 資料夾下,就可以被 Neovim 讀取到。

回顧一下,之前在 day06 時,我們安裝 LuaRocks 時,也是把我們手寫的 luarocks.lua 放在 ~/.config/nvim/lua 資料夾下。

再思考一個很關鍵的問題:「如果被編譯完成的 Lua 檔應該要放在 ~/.config/nvim/lua 資料夾下,那對應的 Fennel 檔呢?」自然是要放在 ~/.config/nvim/fnl 資料夾裡了。

小結

本篇探討 Neovim 插件學習策略,與進行開發插件時的必要 Neovim Runtime 知識。


上一篇
深入淺出函數式編程 (FP)—進階議題
下一篇
Neovim 插件開發—Hello World
系列文
在 Neovim 中探索 Fennel 與函數式編程19
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言