Trying Fennel
Published Sun Jan 21 2024Fennel is a small lisp-like language that compiles to Lua. I have become very interested in lisp and lisp-like languages, the syntax is simple and has great potential for elegance. Since Neovim is configured with Lua, we can use Fennel to write Neovim config with a lisp syntax!
Getting Started
Since Fennel is not officially supported, I am using nfnl to seamlessly integrate fennel with my config files. The setup here is very quick and easy. Just create a new file named .nfnl.fnl
in your configuration directory and install "Olical/nfnl"
using your plugin manager. From here any Fennel file you create under your configuration directory will be compiled to Lua for use by Neovim.
Translating a Lazy Plugin
Since I am using Lazy I have my plugins separated into modules under /lua/plugins/*.lua
. I’ll use one of these as an example for Fennel’s syntax.
return {
'rose-pine/neovim',
name = 'rose-pine',
lazy = false,
priority = 1000,
dependencies = {
'f-person/auto-dark-mode.nvim',
},
config = function()
require("rose-pine").setup({
dark_variant = "moon"
})
local auto_dark_mode = require('auto-dark-mode')
auto_dark_mode.setup({
update_interval = 1000,
set_dark_mode = function()
vim.api.nvim_set_option('background', 'dark')
vim.cmd('colorscheme rose-pine')
end,
set_light_mode = function()
vim.api.nvim_set_option('background', 'light')
vim.cmd('colorscheme rose-pine')
end,
})
auto_dark_mode.init()
end
}
This is my module for theming, it includes a small configuration function for automatically switching themes when my system preference changes. With some quick refactoring the Fennel equivalent looks like this:
{
1 :rose-pine/neovim
:name "rose-pine"
:lazy false
:priority 1000
:dependencies [:f-person/auto-dark-mode.nvim]
:config (fn []
(let [rose-pine (require :rose-pine)]
(rose-pine.setup { :dark_variant "moon" }))
(let [auto-dark-mode (require :auto-dark-mode)]
(auto-dark-mode.setup {
:update_interval 1000
:set_dark_mode (fn []
(vim.api.nvim_set_option "background" "dark")
(vim.cmd "colorscheme rose-pine")
)
:set_light_mode (fn []
(vim.api.nvim_set_option "background" "light")
(vim.cmd "colorscheme rose-pine")
)
})
(auto-dark-mode.init)
)
)
}
With this example there are a few syntax differences that I enjoy.
First is Fennel’s key/value syntax for tables. You declare pairs with :key-name
followed by a value. This works out great, except when you mix named and unnamed values. In the above you may wonder why 1
appears. This is because the first entry is indexed with no key name. If there is a way to mitigate these numbered keys I’d love to know.
Following with key/value pairs, Fennel has a separate table syntax for sequential tables: []
. These are similar to arrays, in this example :dependencies
has a sequential table for a value containing 1 string f-person/auto-dark-mode.nvim
.
I am still early in my lisp and Fennel adventure, but so far it has been great! Once my configuration is fully Fenneled out I look forward to sitting with it and molding the code to fit Fennel’s style better.