SkillAgentSearch skills...

Hotpot.nvim

:stew: Carl Weathers #1 Neovim Plugin.

Install / Use

/learn @rktjmp/Hotpot.nvim
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

<div align="center"> <img src="images/logo.png" style="width: 100%" alt="Hotpot Logo"/> </div>

🍲 Hotpot Github Tag Badge LuaRocks Release Badge

<!-- panvimdoc-ignore-start -->

You take this home, throw it in a pot, add some broth, some neovim... baby, you got a stew going!

~ Fennel Programmers (probably)

<!-- panvimdoc-ignore-end --> <!-- panvimdoc-include-comment ``` dP dP dP dP 88 88 88 88 88aaaaa88a .d8888b. d8888P 88d888b. .d8888b. d8888P 88 88 88' `88 88 88' `88 88' `88 88 88 88 88. .88 88 88. .88 88. .88 88 dP dP `88888P' dP 88Y888P' `88888P' dP 88 dP You take this home, throw it in a pot, add some broth, some neovim... baby, you got a stew going! ~ Fennel Programmers (probably) ``` -->

Hotpot is a Fennel compiler plugin for Neovim. Just (require :my-fennel) and Hotpot does the rest, recompiling your fennel code as needed.

;; ~/.config/nvim/fnl/is_neat.fnl
;; put your fennel code in fnl/
(fn [what] (print what "is neat!"))
-- and require it like normal in your lua file
local neat = require('is_neat') -- compiled & cached on demand
neat("fennel") -- => "fennel is neat!"
<!-- panvimdoc-ignore-start -->

TOC

<!-- panvimdoc-ignore-end -->

Requirements

  • Neovim 0.9.1+
  • ~~Fanatical devotion to parentheses.~~

Install

All you need to do is install Hotpot and call require("hotpot") before you try to run any Fennel code.

<details> <summary>Installing via Lazy.nvim or similar</summary>
-- ~/.config/nvim/init.lua
-- Ensure lazy and hotpot are always installed
local function ensure_installed(plugin, branch)
  local user, repo = string.match(plugin, "(.+)/(.+)")
  local repo_path = vim.fn.stdpath("data") .. "/lazy/" .. repo
  if not (vim.uv or vim.loop).fs_stat(repo_path) then
    vim.notify("Installing " .. plugin .. " " .. branch)
    local repo_url = "https://github.com/" .. plugin .. ".git"
    local out = vim.fn.system({
      "git",
      "clone",
      "--filter=blob:none",
      "--branch=" .. branch,
      repo_url,
      repo_path
    })
    if vim.v.shell_error ~= 0 then
      vim.api.nvim_echo({
        { "Failed to clone " .. plugin .. ":\n", "ErrorMsg" },
        { out, "WarningMsg" },
        { "\nPress any key to exit..." },
      }, true, {})
      vim.fn.getchar()
      os.exit(1)
    end
  end
  return repo_path
end
local lazy_path = ensure_installed("folke/lazy.nvim", "stable")
local hotpot_path = ensure_installed("rktjmp/hotpot.nvim", "v0.14.8")
-- As per Lazy's install instructions, but also include hotpot
vim.opt.runtimepath:prepend({hotpot_path, lazy_path})

-- You must call vim.loader.enable() before requiring hotpot unless you are
-- passing {performance = {cache = false}} to Lazy.
vim.loader.enable()

require("hotpot") -- Optionally you may call require("hotpot").setup(...) here

-- You must include Hotpot in your plugin list for it to function correctly.
-- If you want to use Lazy's "structured" style, see the next code sample.
local plugins = {"rktjmp/hotpot.nvim"}
require("lazy").setup(plugins)

-- Include the rest of your config. Your call to Lazy.setup does not have
-- to be done in init.lua and could be in a required file.
require("say-hello")

The say-hello module would be put in ~/.config/nvim/fnl/say-hello.fnl:

;; ~/.config/nvim/fnl/say-hello.fnl
(print :hello!)

"Structured Setup"

Lazy.nvim allows you to separate your plugin specs into individual files and folders, but to support this it must be able to find the raw lua files.

We can instruct Hotpot to compile your Fennel code ahead of time, into a directory Lazy can find (eg: lua/).

First we must define a .hotpot.lua file at the root of ~/.config/nvim. See the documenation for additional details on "dot-hotpot".

-- ~/.config/nvim/.hotpot.lua

-- By default, the Fennel compiler wont complain if unknown variables are
-- referenced, we can force a compiler error so we don't try to run faulty code.
local allowed_globals = {}
for key, _ in pairs(_G) do
  table.insert(allowed_globals, key)
end

return {
  -- by default, build all fnl/ files into lua/
  build = true,
  -- remove stale lua/ files
  clean = true,
  compiler = {
    modules = {
      -- enforce unknown variable errors
      allowedGlobals = allowed_globals
    }
  }
}

Now open a .fnl file and save it, you should now have a populated lua/ directory and can pass the appropriate module to Lazy.

-- .config/nvim/init.lua

-- ...

-- See Lazy's own documentation for details.
require("lazy").setup({spec = {import = "plugins"}})
<details> <summary>Hiding `lua/` when using `.hotpot.lua`</summary>

We can compile our lua to a hidden directory, and then add that directory to Neovims RTP via Lazy's configuration.

-- ~/.config/nvim/.hotpot.lua
local allowed_globals = {}
for key, _ in pairs(_G) do
  table.insert(allowed_globals, key)
end

return {
  build = {
    {atomic = true, verbose = true},
    {"fnl/**/*macro*.fnl", false},
    -- put all lua files inside `.compiled/lua`, note we must still name the
    -- final directory lua/, due to how nvims RTP works.
    {"fnl/**/*.fnl", function(path)
      -- ~/.config/nvim/fnl/hello/there.fnl -> ~/.config/nvim/.compiled/lua/hello/there.lua
      return string.gsub(path, "/fnl/", "/.compiled/lua/")
    end},
    -- You may also compile a init.fnl file to init.lua
    {"init.fnl", true}
  },
  clean = {{".compiled/lua/**/*.lua", true}},
  compiler = {
    modules = {
      allowedGlobals = allowed_globals
    }
  }
}
;; When calling Lazy setup, pass the hidden directory as an additional RTP patho
;; Note that the path here *does not* include `/lua`!
(setup {:performance {:rtp {:paths [(.. (vim.fn.stdpath :config) "/.compiled")}}
        :spec { ... }})
</details> </details> <details> <summary>Installing via MiniDeps</summary>
-- ~/.config/nvim/init.lua
local path_package = vim.fn.stdpath('data') .. '/site/'
local function ensure_installed(plugin, branch)
  local user, repo = string.match(plugin, "(.+)/(.+)")
  local repo_path = path_package .. 'pack/deps/start/' .. repo
  if not (vim.uv or vim.loop).fs_stat(repo_path) then
    vim.notify("Installing " .. plugin .. " " .. branch)
    local repo_url = "https://github.com/" .. plugin
    local out = vim.fn.system({
      "git",
      "clone",
      "--filter=blob:none",
      "--branch=" .. branch,
      repo_url,
      repo_path
    })
    if vim.v.shell_error ~= 0 then
      vim.api.nvim_echo({
        { "Failed to clone " .. plugin .. ":\n", "ErrorMsg" },
        { out, "WarningMsg" },
        { "\nPress any key to exit..." },
      }, true, {})
      vim.fn.getchar()
      os.exit(1)
    end
    vim.cmd('packadd ' .. repo .. ' | helptags ALL')
    vim.cmd('echo "Installed `' .. repo ..'`" | redraw')
  end
end

ensure_installed("echasnovski/mini.nvim", "stable")
ensure_installed("rktjmp/hotpot.nvim", "v0.14.8")

require("hotpot") -- Optionally you may call require("hotpot").setup(...) here

require("mini.deps").setup({path = {package = path_package}})
MiniDeps.add({source = "echasnovski/mini.nvim", checkout = "stable"})
MiniDeps.add({source = "rktjmp/hotpot.nvim", checkout = "v0.14.8"})

-- Include the rest of your config
require("say-hello")

The say-hello module would be put in ~/.config/nvim/fnl/say-hello.fnl:

;; ~/.config/nvim/fnl/say-hello.fnl
(print :hello!)
</details> <details> <summary>Installing via Rocks.nvim</summary>

Install via the Rocks command or editing rocks.toml.

:Rocks install hotpot.nvim

Now update your init.lua file to call require("hotpot") and include the rest of your config.

-- ~/.config/nvim/init.lua
-- Likely you will have some code to ensure Rocks.nvim is installed here
-- ...

require("hotpot") -- optionally you may call require("hotpot").setup(...) here

-- Include the rest of your config
require("say-hello")

The say-hello module would be put in ~/.config/nvim/fnl/say-hello.fnl:

;; ~/.config/nvim/fnl/say-hello.fnl
(print :hello!)
</details>

Usage

Place all your fennel files under a fnl dir, as you would place lua files under lua. This practice extends to other folders outside of your config directory, such as plugins you may write or install.

With your file in the correct location, you only need to require it like you would any normal lua module.

;; ~/.config/nvim/fnl/is_neat.fnl
;; some kind of fennel code
(fn [what]
  (print what "is neat!"))
-- and in ~/.config/nvim/init.lua
local neat = require('is_neat')
neat("fennel") -- => "fennel is neat!"

Hotpot will keep an internal cache of lua code, so you won't see files cluttering the lua/ directory.

<!-- panvimdoc-ignore-start -->

You can may want to read the cookbook or see more options in setup.

<!-- panvimdoc-ignore-end --> <!-- panvimdoc-include-comment You can may want to read the `:h hotpot-cookbook` or see more options in [setup](#setup). -->

Setup

The setup() function may optionally be called. setup() provides access to Fennels configuration options as described on fennel-lang.org as well as some configuration of hotpot itself.

You do not have to call setup unless you are altering a default option.

require("hotpot").setup({
  enable_hotpot_diagnostics = true,
  com
View on GitHub
GitHub Stars389
CategoryDevelopment
Updated1d ago
Forks13

Languages

Fennel

Security Score

100/100

Audited on Mar 26, 2026

No findings