From 9d852d120ef0f69695b1751387609b5f65b6acca Mon Sep 17 00:00:00 2001 From: Thiago Sposito Date: Sat, 10 Jan 2026 19:39:34 -0300 Subject: [PATCH] feat: nvim: add Fennel config support via nfnl, treesitter, plugins --- home-manager/nvim/default.nix | 48 +++++++++++++++- home-manager/nvim/extraconfig.fnl | 96 +++++++++++++++++++++++++++++++ 2 files changed, 143 insertions(+), 1 deletion(-) create mode 100644 home-manager/nvim/extraconfig.fnl diff --git a/home-manager/nvim/default.nix b/home-manager/nvim/default.nix index 438e593..112fc78 100644 --- a/home-manager/nvim/default.nix +++ b/home-manager/nvim/default.nix @@ -6,7 +6,24 @@ ]; home.packages = with pkgs; [ ripgrep + gcc ]; + home.file.".config/nvim/extraconfig.fnl" = { + source = ./extraconfig.fnl; + }; + home.file.".config/nvim/.nfnl.fnl" = { + source = ./.nfnl.fnl; + }; + # Compile Fennel to Lua at build time + home.file.".config/nvim/extraconfig.lua" = { + text = builtins.readFile ( + pkgs.runCommand "extraconfig-compiled.lua" { + buildInputs = [ pkgs.luajitPackages.fennel ]; + } '' + ${pkgs.luajitPackages.fennel}/bin/fennel --compile ${./extraconfig.fnl} > $out + '' + ); + }; programs.nixvim = { enable = true; colorschemes.nord.enable = true; @@ -21,6 +38,7 @@ }; plugins = { + conjure.enable = true; avante = { enable = true; }; @@ -47,6 +65,10 @@ lspkind.enable = true; lsp-lines.enable = true; + treesitter = { + enable = true; + }; + none-ls = { enable = true; sources = { @@ -65,6 +87,30 @@ conform-nvim.enable = true; }; - extraConfigLua = builtins.readFile ./extraconfig.lua; + extraPlugins = with pkgs.vimPlugins; [ + nvim-web-devicons + (pkgs.vimUtils.buildVimPlugin { + name = "nfnl"; + src = pkgs.fetchFromGitHub { + owner = "Olical"; + repo = "nfnl"; + rev = "v1.3.0"; + hash = "sha256-ug2vAVI3C99TZxFpXw/+AJLRAc+3FLq92bFVhkZUL7A="; + }; + }) + (pkgs.vimUtils.buildVimPlugin { + name = "vim-fennel-syntax"; + src = pkgs.fetchFromGitHub { + owner = "m15a"; + repo = "vim-fennel-syntax"; + rev = "e7299d5"; #v1.3.0 + hash = "sha256-CL3ooywWpGicmzine9qteHTGajAZ2qnIcK9CByaONvc="; + }; + }) + ]; + extraConfigLua = '' + -- Load compiled Fennel config + dofile(vim.fn.expand("~/.config/nvim/extraconfig.lua")) + ''; }; } diff --git a/home-manager/nvim/extraconfig.fnl b/home-manager/nvim/extraconfig.fnl new file mode 100644 index 0000000..a56bb40 --- /dev/null +++ b/home-manager/nvim/extraconfig.fnl @@ -0,0 +1,96 @@ +(do + (local cmp (require :cmp)) + (local avante (require :avante)) + (local cmp-nvim-lsp (require :cmp_nvim_lsp)) + (local treesitter (require :nvim-treesitter.configs)) + + ;; Configure fennel-ls LSP server using new vim.lsp API + ;; Note: vim-fennel-syntax plugin handles filetype detection automatically + (local base-capabilities (vim.lsp.protocol.make_client_capabilities)) + (local capabilities (cmp-nvim-lsp.default_capabilities base-capabilities)) + + ;; Find fennel-ls in PATH + (local fennel-ls-path (vim.fn.exepath "fennel-ls")) + (local fennel-ls-cmd (if (= fennel-ls-path "") ["fennel-ls"] [fennel-ls-path])) + + ;; Setup fennel-ls using autocmd to start on Fennel files + (vim.api.nvim_create_autocmd "FileType" { + :pattern [:fennel] + :callback (fn [] + (local root (vim.fs.find [".nfnl.fnl" ".git" "fnl"] {:upward true})) + (local root-dir (if root (vim.fs.dirname (. root 1)) (vim.fn.getcwd))) + (vim.lsp.start { + :name :fennel_ls + :cmd fennel-ls-cmd + :root_dir root-dir + :settings { + :fennel { + :extra-globals "vim" + } + } + :capabilities capabilities + })) + }) + + ;; Enable inlay hints for better documentation + (vim.lsp.inlay_hint.enable true {:buftype [""]}) + + ;; Configure Treesitter to ensure Fennel grammar is installed + ;; Use writable directory for parsers (not the read-only nix store) + (local parser_install_dir (.. (vim.fn.stdpath :data) "/treesitter")) + (vim.opt.runtimepath:prepend parser_install_dir) + + (treesitter.setup { + :ensure_installed [:fennel :lua] + :highlight {:enable true} + :indent {:enable true} + :parser_install_dir parser_install_dir + }) + + (cmp.setup { + :mapping { + : (cmp.mapping.complete) + : (cmp.mapping.confirm {:select true}) + : (cmp.mapping.select_next_item) + : (cmp.mapping.select_prev_item) + } + :sources [ + {:name :nvim_lsp} + {:name :buffer} + {:name :path} + ] + }) + + (vim.api.nvim_create_autocmd "LspAttach" { + :callback (fn [args] + (local buf args.buf) + (local opts {:buffer buf}) + + (vim.keymap.set "n" "gd" vim.lsp.buf.definition opts) + (vim.keymap.set "n" "gr" vim.lsp.buf.references opts) + (vim.keymap.set "n" "K" vim.lsp.buf.hover opts) + (vim.keymap.set "n" "rn" vim.lsp.buf.rename opts) + (vim.keymap.set "n" "ca" vim.lsp.buf.code_action opts) + (vim.keymap.set "n" "f" (fn [] + (vim.lsp.buf.format {:async true})) + opts) + + (vim.keymap.set "n" "" ":m .+1==") + (vim.keymap.set "n" "" ":m .-2==")) + }) + + (avante.setup { + :provider "ollama" + :providers { + :ollama { + :endpoint "http://127.0.0.1:11434" + :model "gpt-oss:20b" + :extra_request_body { + :temperature 0 + :num_ctx 8192 + } + } + } + }) + ) +