{"id":13412695,"url":"https://github.com/Olical/nfnl","last_synced_at":"2025-03-14T18:31:59.803Z","repository":{"id":179220077,"uuid":"661685396","full_name":"Olical/nfnl","owner":"Olical","description":"Enhance your Neovim with Fennel","archived":false,"fork":false,"pushed_at":"2025-03-06T14:24:46.000Z","size":773,"stargazers_count":271,"open_issues_count":7,"forks_count":9,"subscribers_count":8,"default_branch":"main","last_synced_at":"2025-03-12T22:04:20.258Z","etag":null,"topics":["fennel","lua","neovim","neovim-fennel","neovim-plugin","nvim","nvim-plugin"],"latest_commit_sha":null,"homepage":"","language":"Fennel","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"unlicense","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Olical.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":null,"code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"Olical","ko_fi":"olical"}},"created_at":"2023-07-03T12:22:30.000Z","updated_at":"2025-03-11T14:28:44.000Z","dependencies_parsed_at":"2024-01-20T13:27:01.312Z","dependency_job_id":"f3de026b-cd92-4a80-9185-bb82b03c1216","html_url":"https://github.com/Olical/nfnl","commit_stats":{"total_commits":236,"total_committers":5,"mean_commits":47.2,"dds":0.05508474576271183,"last_synced_commit":"60b2ab7051cf2f631bc03274b56061136d1f9177"},"previous_names":["olical/nfnl"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Olical%2Fnfnl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Olical%2Fnfnl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Olical%2Fnfnl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Olical%2Fnfnl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Olical","download_url":"https://codeload.github.com/Olical/nfnl/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243625161,"owners_count":20321247,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["fennel","lua","neovim","neovim-fennel","neovim-plugin","nvim","nvim-plugin"],"created_at":"2024-07-30T20:01:27.972Z","updated_at":"2025-03-14T18:31:59.795Z","avatar_url":"https://github.com/Olical.png","language":"Fennel","readme":"# nfnl\n\nEnhance your [Neovim][neovim] experience through [Fennel][fennel] with zero\noverhead. Write Fennel, run Lua, nfnl will not load unless you're actively\nmodifying your Neovim configuration or plugin source code\n([nfnl-plugin-example][nfnl-plugin-example]).\n\n- Only loads when working in directories containing a `.nfnl.fnl` configuration\n  file.\n- Automatically compiles `*.fnl` files to `*.lua` when you save your changes.\n- Can be used for your Neovim configuration or [plugins][nfnl-plugin-example]\n  with no special configuration, it just works for both.\n- Includes a Clojure inspired [standard library][apidoc] (based on\n  [Aniseed][aniseed]).\n- Compiles your Fennel code and then steps out of the way leaving you with plain\n  Lua that doesn't require nfnl to load in the future.\n- Displays compilation errors as you save your Fennel code to keep the feedback\n  loop as tight as possible.\n\n## Usage\n\nFirst, you must create the configuration file at the root of your project or\nconfiguration, this can be blank if you wish to rely on the defaults for now.\n\n```bash\necho \"{}\" \u003e .nfnl.fnl\n```\n\nThe first time you open a Fennel file under this directory you'll be prompted to\ntrust this configuration file since it's Fennel code that's executed on your\nbehalf. You can put any Fennel code you want in this file, just be sure to\nreturn a table of configuration at the end.\n\n```fennel\n(print \"Hello, World! From my nfnl configuration!\")\n\n{:fennel-path \"...\"}\n```\n\nBy default, writing to any Fennel file with Neovim under the directory\ncontaining `.nfnl.fnl` will automatically compile it to Lua. If there are\ncompilations errors they'll be displayed using `vim.notify` and the Lua will not\nbe updated.\n\nnfnl will refuse to overwrite any existing Lua at the destination if nfnl was\nnot the one to compile it, this protects you from accidentally overwriting\nexisting Lua with compiled output. To bypass the warning you must delete or move\nthe Lua file residing at the destination yourself.\n\nNow you may use the compiled Lua just like you would any other Lua files with\nNeovim. There's nothing special about it, please refer to the abundant\ndocumentation on the topic of Neovim configuration and plugins in Lua.\n\nYou must commit the Lua into your configuration or plugin so that it can be\nloaded by native Neovim Lua systems, with absolutely no knowledge of the Fennel\nit originated from.\n\n## Configuration\n\nnfnl is configured on a per directory basis using `.nfnl.fnl` files which also\nsignify that the plugin should operate on the files within this directory.\nWithout the file the plugin is inert, meaning even if you don't lazy load it you\nwon't see any performance impact at startup time.\n\nAny configuration you don't provide (an empty file or just `{}` is absolutely\nfine!) will default to these values that should work fine for most people.\n\n```fennel\n{;; Enables verbose notifications from nfnl, including notifications about\n ;; when it starts up and when it compiles successfully. Useful for debugging\n ;; the plugin itself and checking that it's running when you expect it to.\n :verbose false\n\n ;; Passed to fennel.compileString when your code is compiled.\n ;; See https://fennel-lang.org/api for more information.\n :compiler-options {;; Disables ansi escape sequences in compiler output.\n                    :error-pinpoint false}\n\n ;; Warning! In reality these paths are absolute and set to the root directory\n ;; of your project (where your .nfnl.fnl file is). This means even if you\n ;; open a .fnl file from outside your project's cwd the compiler will still\n ;; find your macro files. If you use relative paths like I'm demonstrating here\n ;; then macros will only work if your cwd is in the project you're working on.\n\n ;; They also use OS specific path separators, what you see below is just an example really.\n ;; I'm not including nfnl's directory from your runtimepath, but it would be there by default.\n ;; See :rtp-patterns below for more information on including other plugins in your path.\n\n ;; String to set the compiler's fennel.path to before compilation.\n :fennel-path \"./?.fnl;./?/init.fnl;./fnl/?.fnl;./fnl/?/init.fnl\"\n\n ;; String to set the compiler's fennel.macro-path to before compilation.\n :fennel-macro-path \"./?.fnl;./?/init-macros.fnl;./?/init.fnl;./fnl/?.fnl;./fnl/?/init-macros.fnl;./fnl/?/init.fnl\"\n\n ;; A list of glob patterns (autocmd pattern syntax) of files that\n ;; should be compiled. This is used as configuration for the BufWritePost\n ;; autocmd, so it'll only apply to buffers you're interested in.\n ;; Will use backslashes on Windows.\n ;; Defaults to compiling all .fnl files, you may want to limit it to your fnl/ directory.\n :source-file-patterns [\".*.fnl\" \"*.fnl\" \"**/*.fnl\"]\n\n ;; A function that is given the absolute path of a Fennel file and should return\n ;; the equivalent Lua path, by default this will translate `fnl/foo/bar.fnl` to `lua/foo/bar.lua`.\n ;; See the \"Writing Lua elsewhere\" tip below for an example function that writes to a sub directory.\n :fnl-path-\u003elua-path (fn [fnl-path] ...)}\n```\n\nAs an example, if you only want to compile `.fnl` files under the `fnl/`\ndirectory of your Neovim configuration (so nothing in the root directory) you\ncould use this `.nfnl.fnl` file instead.\n\n```fennel\n{:source-file-patterns [\"fnl/**/*.fnl\"]}\n```\n\nAnd since this is a Fennel file that's executed within Neovim you can actually\nload nfnl's modules to access things like the default config values.\n\n```fennel\n(local core (require :nfnl.core))\n(local config (require :nfnl.config))\n(local default (config.default))\n\n{:source-file-patterns (core.concat default.source-file-patterns [\"custom-dir/*.fnl\"])}\n```\n\n`config.default` accepts a table of arguments ([docs][config-default-doc]) to\nchange how it builds the default configuration. You can call\n`(config.default {...})` on the last line of your `.nfnl.fnl` file in order to\nreturn a modified default configuration table. You also then have the option to\ncall `config.default`, modify that table with extra values and then return that.\n\nBy providing a different `rtp-patterns` value (defaults to `[\"/nfnl$\"]`) we can\ninclude other plugins you have installed in your search paths when requiring Lua\nmodules or macros.\n\n```fennel\n;; Configuration that includes nfnl _and_ your-cool-plugin in the search paths.\n(local config (require :nfnl.config))\n(config.default {:rtp-patterns [\"/nfnl$\" \"/your-cool-plugin$\"]})\n\n;; Configuration that includes ALL of your installed plugins in your search paths.\n;; This might slow down compilation on some machines, so it's not the default.\n(local config (require :nfnl.config))\n(config.default {:rtp-patterns [\".*\"]})\n\n;; Searching all of your plugins _and_ merging in some other custom configuration.\n(local core (require :nfnl.core))\n(local config (require :nfnl.config))\n(core.merge\n  (config.default {:rtp-patterns [\".*\"]})\n  {:source-file-patterns [\"fnl/**/*.fnl\"]})\n```\n\n## Installation\n\n- [Lazy][lazy]: `{ \"Olical/nfnl\", ft = \"fennel\" }`\n- [Plug][plug]: `Plug 'Olical/nfnl'`\n- [Packer][packer]: `use \"Olical/nfnl\"`\n\n[Lazy][lazy] will lazily load the plugin when you enter a Fennel file for the\nfirst time. There is no need to call `require(\"nfnl\").setup()` right now, it's\ncurrently a noop but it may be used eventually. Some plugin managers support\nthis function and will call it automatically.\n\n- Requires Neovim \u003e v0.9.0.\n- Add the dependency to your plugin manager.\n- Add lazy loading rules on the Fennel filetype if you want.\n\n## Standard library\n\nnfnl ships with a standard library used mostly for it's internal implementation,\nbut it can also be used by your own Neovim configuration or plugins. This is\nbased on [Aniseed's][aniseed] standard library but without the module system\nthat prevented you from using it in standard, non-Neovim, Fennel projects.\n\nFull API documentation powered by [fenneldoc][fenneldoc] can be found in the\n[api][apidoc] directory.\n\nThe documentation is regenerated by executing\n`./script/render-api-documentation`. One limitation of using this tool is that\nall top level values in a module should really be functions, if we do work\ninside `(local)` for example we'll end up incurring side effects at\ndocumentation rendering time that we may not want.\n\n## Macros\n\nFennel allows you to write inline macros with the `(macro ...)` form but they're\nrestricted to only being used in that one file. If you wish to have a macro\nmodule shared by the rest of your codebase you need to mark that file as a macro\nmodule by placing `;; [nfnl-macro]` somewhere within the source code. The exact\namount of `;` and whitespace doesn't matter, you just need a comment with\n`[nfnl-macro]` inside of it.\n\nThis marker does two things:\n\n- Instructs the compiler not to attempt to compile this file since it would\n  fail. You can't compile macro modules to Lua, they use features that can only\n  be referred to at compile time and simply do not translate to Lua.\n- Ensures that whenever the file is written to all other non-macro modules get\n  recompiled instead. Ensuring any inter-dependencies between your Fennel and\n  your macro modules stays in sync and you never end up having to find old Lua\n  that was compiled with old versions of your macros.\n\nFor example, here's a simplified macro file from nfnl itself at\n`fnl/nfnl/macros.fnl`.\n\n```fennel\n;; [nfnl-macro]\n\n;; .nfnl.fnl config so you don't need to prefix globals like _G.vim.*\n;; {:compiler-options {:compilerEnv _G}}\n\n(fn time [...]\n  `(let [start# (vim.loop.hrtime)\n         result# (do ,...)\n         end# (vim.loop.hrtime)]\n     (print (.. \"Elapsed time: \" (/ (- end# start#) 1000000) \" msecs\"))\n     result#))\n\n{: time}\n```\n\nWhen writing to this file, no matching `.lua` will be generated _but_ all other\nsource files in the project will be re-compiled against the new version of the\nmacro module.\n\nThis system does not currently use static analysis to work out which files\ndepend on each other, instead we opt for the safe approach of recompiling\neverything. This should still be fast enough for everyone's needs and avoids the\nhorrible subtle bugs that would come with trying to be clever with it.\n\n## Why can't I refer to the vim global in my macros?\n\nBy default, the Fennel compiler employs a compiler sandbox in your macro\nmodules. This means you can't refer to any free global variables such a `vim`.\nYou have to configure the [Fennel compiler API][api-module-doc] with the\n`{:compiler-options {...}}` section of your `.nfnl.fnl` file.\n\nYou can either prefix each of these globals with `_G` like `_G.vim.g.some_var`\nor you can turn off the relevant sandboxing rules. One approach is to set the\ncompiler environment to `_G` instead of Fennel's sanitised environment. You can\ndo that with the following `.nfnl.fnl` file.\n\n```fennel\n{:compiler-options {:compilerEnv _G}}\n```\n\n## OS support\n\nCurrently only developed for and tested on Arch Linux, but this works fine on\nMacOS. You can see another example of creating a plugin and done on MacOS at\n[this blog post](https://russtoku.github.io/posts/nfnl-experience.html). I tried\nmy best to support Windows without actually testing it. So I've ensured it uses\nthe right path separators in all the places I can find.\n\nIf you try this out and it works on MacOS or Windows, please let me know so I\ncan add it here. If you run into issues, please report them with as much detail\nas possible.\n\n## Tips\n\n### Ignoring compiled Lua\n\nCreate a `.ignore` file so your `.lua` files don't show up in\n[Telescope][telescope] when paired with [ripgrep][ripgrep] among many other\ntools that respect this file.\n\n```\nlua/**/*.lua\n```\n\nYou can also add these known directories and files to things like your\n[Neo-tree][neotree] configuration in order to completely hide them.\n\n### GitHub language statistics\n\nCreate a `.gitattributes` file to teach GitHub which of your files are generated\nor vendored. This ensures your \"languages\" section on your repository page\nreflects reality.\n\n```\nlua/**/*.lua linguist-generated\nlua/nfnl/fennel.lua linguist-vendored\nscript/fennel.lua linguist-vendored\n```\n\n### LSP\n\nI highly recommend looking into getting a good LSP setup for\n`fennel-language-server`. I use [AstroNvim][astronvim] since it bundles LSP\nconfigurations and Mason, a way to install dependencies, in one pre-configured\nsystem. My configuration is\n[here in my dotfiles](https://github.com/Olical/dotfiles/blob/b72363f77586ad08ba1581c33ee476b1f02e999f/stowed/.config/nvim/lua/user/plugins/mason.fnl).\n\nWith the Fennel LSP running I get a little autocompletion alongside really\nuseful unused or undeclared symbol linting. It'll also pick up things like\nunbalanced parenthesis _before_ I try to compile the file.\n\nThe same can be done for Lua so you can also check the linting and static\nanalysis of the compiled output in order to help debug some runtime issues.\n\n### Directory local Neovim configuration in Fennel\n\nI wrote [nvim-local-fennel][nvim-local-fennel] to solve this problem years ago\nbut I now recommend combining nfnl with the built in `exrc` option. Simply\n`:set exrc` (see `:help exrc` for more information), create a `.nfnl.fnl` file\nand then edit `.nvim.fnl`.\n\nThis will write Lua to `.nvim.lua` which will be executed whenever your Neovim\nenters this directory tree. Even if you uninstall nfnl the `.lua` file will\ncontinue to work. Colleagues who also use Neovim but don't have nfnl installed\ncan also use the `.nvim.lua` file provided they have `exrc` enabled (even if\nthey can't edit the Fennel to compile new versions of the Lua).\n\nThis solution achieves the same goal as nvim-local-fennel with far less code\n_and_ built in options all Neovim users can lean on.\n\n### Embedding nfnl inside your plugin\n\nIf you want to ship a plugin ([nfnl-plugin-example][nfnl-plugin-example]) that\ndepends on nfnl modules you'll need to embed it inside your project. You can\neither `cp -r lua/nfnl` into `your-project/lua/nfnl` if you don't mind your\nplugin's copy of nfnl colliding with other plugins or you can use\n`script/embed` to copy the files into a lower level directory and modify\nthem to isolate them for your plugin specifically.\n\n```bash\ncp -r nfnl/lua/nfnl my-plugin/lua/nfnl\n```\n\nNow your plugin can always use `(require :nfnl.core)` and know it'll be around,\nbut you might run into issues where another plugin author has done the same and\nis using an older version of nfnl that lacks some feature you require. Lua has a\nglobal module namespace, so collisions are quite easy to accidentally cause. You\nmay use my embedding script (or your own) to avoid this though:\n\n```bash\n# There are more paths and options available, see the script source for more information.\n# This will write to my-project/lua/my-project/nfnl.\n./script/embed-library ../my-project\n```\n\nThis will copy nfnl's Lua code into your project's directory under a namespaced\ndirectory unique to your project. It will then perform a find and replace on the\nLua code to scope the nfnl source to your plugin, avoiding conflicts with any\nother copy of nfnl.\n\nThis script depends upon [fd][fd] and [sd][sd], so make sure you install those\nfirst! Alternatively you could modify or write your own script that works for\nyour OS with your available tools.\n\n### Writing Lua elsewhere\n\nIf you're not happy with the defaults of Lua being written beside your Fennel\nand still disagree with [my justifications for it][lua-in-git-justifications]\nthen you may want to override the `:fnl-path-\u003elua-path` function to perform in a\nway you like. Since you get to define a function, how this behaves is entirely\nup to you. Here's how you could write to a sub-directory rather than just `lua`,\njust include this in your `.nfnl.fnl` configuration file for your project.\n\n```fennel\n(local config (require :nfnl.config))\n(local default (config.default))\n\n{:fnl-path-\u003elua-path (fn [fnl-path]\n                       (let [rel-fnl-path (vim.fn.fnamemodify fnl-path \":.\")]\n                         (default.fnl-path-\u003elua-path (.. \"some-other-dir/\" rel-fnl-path))))}\n```\n\n### Commands\n\nUser commands are defined inside your Fennel buffers when nfnl configuration is\ndetected, they are just thin wrappers around the function found in `nfnl.api`\nwhich you can read about under the next header.\n\n- `:NfnlFile [path]`\n\n  - `path` defaults to `%`\n\n  Run the matching Lua file for this Fennel file from disk. Does not recompile\n  the Lua, you must use nfnl to compile your Fennel to Lua first. Calls\n  nfnl.api/dofile under the hood.\n\n- `:NfnlCompileFile [file]`\n\n  - `file` defaults to the current file\n\n  Executes (nfnl.api/compile-file) which will compile the specified file and write it to the appropriate `.lua` path.\n\n- `:NfnlCompileAllFiles [path]`\n\n  - `path` defaults to `.`\n\n  Executes (nfnl.api/compile-all-files) which will, you guessed it, compile all\n  of your files.\n\n### Options\n\nnfnl's user experience can be configured by `g:nfnl#...` prefixed global variables which can also be set by `.setup()` like so:\n\n```lua\nrequire(\"nfnl\").setup({ compile_on_write = false })\n```\n\nThese options customise general behaviour of the plugin that aren't limited to a specific directory or project.\n\n- `g:nfnl#compile_on_write`\n  Set to `false` to disable the automatic compilation on buffer write. You will then need to use the `:NfnlCompile*` commands to compile your Fennel into Lua.\n\n### API\n\nAlthough you can require any internal nfnl Lua module and call it's functions\n([full index of internal modules and functions][apidoc]) there is a specific\nmodule, `nfnl.api` ([documentation][api-module-doc]), that is designed to be\nhooked up to your own functions, mappings and autocmds.\n\nThe functions within are designed to \"do the right thing\" with little to no\nconfiguration. You shouldn't need them in normal use, but they may come in\nuseful when you need to fit nfnl into an interesting workflow or system.\n\nAs an example, here's how and why you'd use the `compile-all-files` function\nfrom another Fennel file to, you guessed it, compile all of your files.\n\n```fennel\n(local nfnl (require :nfnl.api))\n\n;; Takes an optional directory as an argument, defaults to (vim.fn.getcwd).\n(nfnl.compile-all-files)\n```\n\nIn the case where you're absolutely adamant that you need to `.gitignore` your\ncompiled Lua output, this can be used after you `git pull` to ensure everything\nis compiled. However, I strongly advise committing your Lua for performance\n_and_ stability.\n\nThis project was designed around the principal of compiling early and then never\nneeding to compile again unless you make changes. I thought long and hard about\nthe tradeoffs so you don't have to. These tools are here for when I'm wrong.\n\n## Development\n\nIf you have nfnl installed in Neovim you should be able to just modify Fennel\nfiles and have them get recompiled automatically for you. So nfnl is compiled\nwith nfnl. This does however mean you can perform an Oopsie and break nfnl,\nrendering it useless to recompile itself with fixed code.\n\nIf you run into issues like this, you can execute `script/bootstrap-dev` to run\na file watching Fennel compiler and `script/bootstrap` to compile everything\nwith a one off command. Both of these lean on `script/fennel.bb` which is a\nsmart Fennel compiler wrapper written in [Babashka][babashka]. This wrapper\nrelies on the bundled Fennel compiler at `script/fennel.lua`, so it will ignore\nany Fennel version installed at the system level on the CLI.\n\nSo you'll need the following to use the full development suite:\n\n- A Lua runtime of some kind to execute `script/fennel.lua`.\n- [Babashka][babashka] to execute `script/fennel.bb`.\n- [Entr][entr] if you want to use file watching with `script/bootstrap-dev`.\n\nThe bootstrap tools should only really ever be required during the initial\ndevelopment of this plugin or if something has gone catastrophically wrong and\nnfnl can no longer recompile itself. Normally having nfnl installed and editing\nthe `.fnl` files should be enough.\n\nRemember to rebuild the API documentation and run the tests when making changes.\nThis workflow will be automated and streamlined eventually.\n\n## Testing\n\nTests are written under `fnl/spec/nfnl/**/*_spec.fnl`. They're compiled into the\n`lua/` directory by nfnl itself and executed by [Plenary][plenary], you must\nhave this plugin installed in order to run the test suite within Neovim.\n\nThe project local `.nfnl.fnl` defines the `\u003clocalleader\u003ept` mapping which allows\nyou to execute the test suite from within Neovim using Plenary.\n\nTo run the tests outside of your configuration you can run\n`./script/setup-test-deps` (installs dependencies into this local directory) and\nthen `./script/test` to execute the tests in a headless local Neovim\nconfiguration.\n\n## Unlicensed\n\nFind the full [Unlicense][unlicense] in the `UNLICENSE` file, but here's a\nsnippet.\n\n\u003e This is free and unencumbered software released into the public domain.\n\u003e\n\u003e Anyone is free to copy, modify, publish, use, compile, sell, or distribute\n\u003e this software, either in source code form or as a compiled binary, for any\n\u003e purpose, commercial or non-commercial, and by any means.\n\n`lua/nfnl/fennel.lua` and `script/fennel.lua` are excluded from this licensing,\nthey're downloaded from the [Fennel][fennel] website and retains any license\nused by the original author. We vendor it within this tool to simplify the user\nexperience.\n\n`script/fenneldoc.lua` is also excluded since it's compiled from the\n[fenneldoc][fenneldoc] repository.\n\n[neovim]: https://neovim.io/\n[fennel]: https://fennel-lang.org/\n[aniseed]: https://github.com/Olical/aniseed\n[conjure]: https://github.com/Olical/conjure\n[unlicense]: http://unlicense.org/\n[ripgrep]: https://github.com/BurntSushi/ripgrep\n[babashka]: https://babashka.org/\n[entr]: https://eradman.com/entrproject/\n[plug]: https://github.com/junegunn/vim-plug\n[packer]: https://github.com/wbthomason/packer.nvim\n[lazy]: https://github.com/folke/lazy.nvim\n[fenneldoc]: https://gitlab.com/andreyorst/fenneldoc\n[telescope]: https://github.com/nvim-telescope/telescope.nvim\n[neotree]: https://github.com/nvim-neo-tree/neo-tree.nvim\n[astronvim]: https://astronvim.com/\n[plenary]: https://github.com/nvim-lua/plenary.nvim\n[apidoc]: https://github.com/Olical/nfnl/tree/main/docs/api/nfnl\n[nvim-local-fennel]: https://github.com/Olical/nvim-local-fennel\n[sd]: https://github.com/chmln/sd\n[fd]: https://github.com/sharkdp/fd\n[nfnl-plugin-example]: https://github.com/Olical/nfnl-plugin-example\n[lua-in-git-justifications]: https://github.com/Olical/nfnl/issues/5#issuecomment-1655447175\n[api-module-doc]: https://github.com/Olical/nfnl/blob/main/docs/api/nfnl/api.md\n[config-default-doc]: https://github.com/Olical/nfnl/blob/main/docs/api/nfnl/config.md#default\n","funding_links":["https://github.com/sponsors/Olical","https://ko-fi.com/olical"],"categories":["Fennel","Plugins"],"sub_categories":["Quickfix","Neovim"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FOlical%2Fnfnl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FOlical%2Fnfnl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FOlical%2Fnfnl/lists"}