SkillAgentSearch skills...

Tangerine.nvim

🍊 Sweet Fennel integration for Neovim

Install / Use

/learn @udayvir-singh/Tangerine.nvim
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

<!-- -- DEPENDS: -- Install | main -- Setup, FAQ | utils[env] -- Command | vim[cmds] -- API | api -- API | fennel -- Build | make --> <!-- ignore-start --> <div align="center">

:tangerine: Tangerine :tangerine:

Neovim version GNU Neovim in Emacs version

AboutInstallationSetupCommandsAPIDevelopment

<p align="center"> <img width="700" src="https://github.com/udayvir-singh/tangerine.nvim/assets/97400310/10082888-b01e-4dbe-b105-4aa74391bb52"> </p> </div> <!-- ignore-end -->

About

Tangerine provides a painless way to add fennel to your config.

Features

  • :fire: BLAZING fast, compile times in milliseconds
  • :ocean: 100% support for interactive evaluation
  • :bamboo: Control over when and how to compile
  • :ribbon: Natively loads nvim/init.fnl

Comparison to other plugins

<b>HOTPOT :stew:</b>

  • Abstracts too much away from the user.
  • Hooks onto lua package searchers to compile [harder to debug].

<b>ANISEED :herb:</b>

  • Excessively feature rich for use in dotfiles.
  • Blindly compiles all files that it founds, resulting in slow load times.

Installation

  1. Create file plugin/0-tangerine.lua to bootstrap tangerine:

[!IMPORTANT] If you are using lazy.nvim then you should create init.lua instead of plugin/0-tangerine.lua.

Refer to #20 for more information.

-- ~/.config/nvim/plugin/0-tangerine.lua or ~/.config/nvim/init.lua

-- pick your plugin manager
local pack = "tangerine" or "packer" or "paq" or "lazy"

local function bootstrap(url, ref)
    local name = url:gsub(".*/", "")
    local path

    if pack == "lazy" then
        path = vim.fn.stdpath("data") .. "/lazy/" .. name
        vim.opt.rtp:prepend(path)
    else
        path = vim.fn.stdpath("data") .. "/site/pack/".. pack .. "/start/" .. name
    end

    if vim.fn.isdirectory(path) == 0 then
        print(name .. ": installing in data dir...")

        vim.fn.system {"git", "clone", url, path}
        if ref then
            vim.fn.system {"git", "-C", path, "checkout", ref}
        end

        vim.cmd "redraw"
        print(name .. ": finished installing")
    end
end

-- for stable version [recommended]
bootstrap("https://github.com/udayvir-singh/tangerine.nvim", "v2.9")

-- for git head
bootstrap("https://github.com/udayvir-singh/tangerine.nvim")
  1. Call tangerine setup() function, see config for valid options:
-- ~/.config/nvim/plugin/0-tangerine.lua

require "tangerine".setup {}
  1. Invoke :FnlCompile manually or add hooks in setup.
<br>

:tanabata_tree: Now start writing your config in ~/.config/nvim/init.fnl.

:hibiscus: Optionally you can also install hibiscus for macros.

Package Management

Only use a package manager if you haven't used ref option in bootstrap function.

<details> <summary><b>Packer</b></summary><br>
(local packer (require :packer))

(packer.startup (lambda [use]
  (use :udayvir-singh/tangerine.nvim)))

Using hibiscus macros:

(require-macros :hibiscus.packer)

(packer-setup {}) ; bootstraps packer

(packer
  (use! :udayvir-singh/tangerine.nvim))
</details> <details> <summary><b>Paq</b></summary><br>
(local paq (require :paq))

(paq [
  :udayvir-singh/tangerine.nvim
])
</details> <details> <summary><b>Lazy</b></summary><br>
(local lazy (require :lazy))

(lazy.setup [
  :udayvir-singh/tangerine.nvim
])
</details>

Setup

Default config

Tangerine comes with sane defaults so that you can get going without having to add much to your config:

local nvim_dir = vim.fn.stdpath [[config]]

{
    vimrc   = nvim_dir .. "/init.fnl",
    source  = nvim_dir .. "/fnl",
    target  = nvim_dir .. "/lua",
    rtpdirs = {},

    custom = {
        -- list of custom [source target] chunks, for example:
        -- {"~/.config/awesome/fnl", "~/.config/awesome/lua"}
    },

    compiler = {
        float   = true,     -- show output in floating window
        clean   = true,     -- delete stale lua files
        force   = false,    -- disable diffing (not recommended)
        verbose = true,     -- enable messages showing compiled files

        globals = vim.tbl_keys(_G), -- list of alowed globals in fennel code

        -- wrapper function that provides access to underlying fennel compiler
        -- useful if you want to modify fennel API or want to provide your own fennel compiler
        adviser = function (fennel)
            -- for example, adding a custom macro path:
            -- fennel["macro-path"] = fennel["macro-path"] .. ";/custom/path/?.fnl"
            return fennel
        end,

        -- version of fennel to use, [ latest, 1-5-1, 1-5-0, 1-4-2, 1-4-1, 1-4-0, 1-3-1, 1-3-0, 1-2-1, 1-2-0, 1-1-0, 1-0-0 ]
        version = "latest",

        -- hooks for tangerine to compile on:
        -- "onsave" run every time you save fennel file in {source} dir
        -- "onload" run on VimEnter event
        -- "oninit" run before sourcing init.fnl [recommended than onload]
        hooks   = {}
    },

    eval = {
        float  = true,      -- show results in floating window
        luafmt = function() -- function that returns formatter with flags for peeked lua
            -- optionally install lua-format by running `$ luarocks install --local --server=https://luarocks.org/dev luaformatter`
            return {"~/.luarocks/bin/lua-format", "--column-limit", "80"}
        end,

        diagnostic = {
            virtual = true,  -- show errors in virtual text
            timeout = 10     -- how long should the error persist
        }
    },

    keymaps = {
        -- set them to <Nop> if you want to disable them
        eval_buffer = "gE",
        peek_buffer = "gL",
        goto_output = "gO",
        float = {
            next    = "<C-K>",
            prev    = "<C-J>",
            kill    = "<Esc>",
            close   = "<Enter>",
            resizef = "<C-W>=",
            resizeb = "<C-W>-"
        }
    },

    highlight = {
        float   = "Normal",
        success = "String",
        errors  = "DiagnosticError"
    },
}

Example Config

Here is config that I use in my dotfiles:

{
    -- save fnl output in a separate dir, it gets automatically added to package.path
    target = vim.fn.stdpath [[data]] .. "/tangerine",

    -- compile files in &rtp
    rtpdirs = {
        "plugin",
        "colors",
        "$HOME/mydir" -- absolute paths are also supported
    },

    compiler = {
        -- disable popup showing compiled files
        verbose = false,

        -- compile every time you change fennel files or on entering vim
        hooks = {"onsave", "oninit"}
    }
}

Commands

Compiling

<!-- doc=:FnlCompileBuffer -->

:FnlCompileBuffer

Compiles current active fennel buffer.

<!-- doc=:FnlCompile -->

:FnlCompile[!]

Diff compiles all indexed fennel files.

If bang! is present then forcefully compiles all source files.

<!-- doc=:FnlClean -->

:FnlClean[!]

Deletes stale or orphaned lua files in target dir.

If bang! is present then it deletes all compiled lua files.

Evaluation

<!-- doc=:Fnl -->

:Fnl {expr}

Executes and Evalutate {expr} of fennel.

:Fnl (print "Hello World")
  -> Hello World

:Fnl (values some_var)
  -> :return [ 1 2 3 4 ]
<!-- doc=:FnlFile -->

:FnlFile {file}

Evaluates {file} of fennel and outputs the result.

:FnlFile path/source.fnl

:FnlFile % ;; not recommended
<!-- doc=:FnlBuffer -->

:[range]FnlBuffer

Evaluates all lines or [range] in current fennel buffer.

mapped to gE by default.

Peeking

<!-- doc=:FnlPeek -->

:[range]FnlPeek

Peek lua output for [range] in current fennel buffer.

mapped to gL by default.

<!-- doc=:FnlGotoOutput -->

:FnlGotoOutput

Open lua output of current fennel buffer in a new buffer.

mapped to gO by default.

Window

<!-- doc=:FnlWinNext -->

:FnlWinNext [N]

Jump to [N]th next floating window created by tangerine..

mapped to CTRL-K in floats by default.

<!-- doc=:FnlWinPrev -->

:FnlWinPrev [N]

Jump to [N]th previous floating window created by tangerine.

mapped to CTRL-J in floats by default.

<!-- doc=:FnlWinResize -->

:FnlWinResize [N]

Increase or Decrease floating window height by [N] factor.

mapped to CTRL-W = to increase and CTRL-W - decrease by default.

<!-- doc=:FnlWinClose -->

:FnlWinClose

Closes current floating window under cursor.

mapped to ENTER in floats by default.

<!-- doc=:FnlWinKill -->

:FnlWinKill

Closes all floating windows made by tangerine.

mapped to ESC in floats by default.

FAQ

Q: How to make tangerine compile automatically when you open vim

A: add hooks in config:

require [[tangerine]].setup {
    compiler = {
        -- if you want to compile before loading init.fnl (recommended)
        hooks = {"oninit"}

        -- if you want to compile after VimEnter event has fired
        hooks = {"onenter"}
    }
}
<br>

Q: How to tuck away compiled output in a separate directory

A: change target in config:

require [[tangerine]].setup {
    target = "/path/to/your/dir"
}
<br>

Q: How to make impatient work with tangerine

A: bootstrap and require impatient before calling tangerine:

bootstrap "https://github.com/lewis6991/impatient.nvim"

require [[impatient]]

require [[tangerine]].setup {...}
<br>

**Q: How to use lua files interchangeably

View on GitHub
GitHub Stars226
CategoryDevelopment
Updated4mo ago
Forks21

Languages

Fennel

Security Score

97/100

Audited on Nov 4, 2025

No findings