{ config, pkgs, lib, ... }: with lib; let rust-analyzer = if (pkgs ? rust-analyzer-nightly && config.class ? dev) then pkgs.rust-analyzer-nightly else pkgs.rust-analyzer; rust-sdk = with pkgs; if config.class ? dev then symlinkJoin { name = "nvim-fenix"; paths = [ (fenix.latest.withComponents [ "cargo" "clippy-preview" "rust-src" "rust-std" "rustc" "rustfmt-preview" ]) cargo-watch ]; } else symlinkJoin { name = "nvim-rust"; paths = [ rustc cargo rustfmt clippy cargo-watch ]; }; in { programs.neovim = { # https://github.com/nix-community/home-manager/blob/master/modules/programs/neovim.nix enable = true; vimAlias = true; withNodeJs = true; extraPackages = with pkgs; [ fzf xclip fish ]; plugins = with pkgs.vimPlugins; [ vim-fugitive neogit diffview-nvim vim-airline zephyr-nvim vim-toml elm-vim vim-markdown vim-mergetool split-term-vim # vim-grammarous markdown-preview-nvim rainbow nvim-web-devicons fzf-vim editorconfig-nvim vim-vsnip # tmuxline-vim nvim-dap nvim-dap-ui nvim-notify nvim-cmp cmp-nvim-lsp cmp-nvim-lua cmp-buffer cmp-path cmp-spell cmp-vsnip cmp-conventionalcommits cmp-calc cmp-cmdline rustaceanvim (if config.programs.neovim.package.version == "0.10.0" then throw "lsp-inlayhints-nvim may be removed" else lsp-inlayhints-nvim) # https://github.com/mrcjkb/rustaceanvim/discussions/46#discussioncomment-7620822 plenary-nvim crates-nvim nvim-lspconfig telescope-nvim telescope-undo-nvim oil-nvim ]; extraLuaConfig = let # tries to compute a package set required to make package resolution in lua # via deps["pkg"] work packages = file: let out = builtins.readFile (pkgs.runCommandLocal "extract-deps" { nativeBuildInputs = [ pkgs.gnused ]; __contentAddressed = true; } '' sed -nr 's/.*(deps\.(.*)_path|deps\["(.*)"\]).*/\2/p' ${file} | uniq > $out ''); names = lib.splitString "\n" out; in filter (name: name != "") names; paths = (listToAttrs (map (name: { inherit name; value = builtins.getAttr name pkgs; }) (packages "${confDir}/*.lua"))) // { lldb = pkgs.lldb; rust_analyzer = rust-analyzer; typst_lsp = pkgs.typst-lsp; }; pathsLua = let name = "nvim-deps.lua"; in (pkgs.writeTextDir "/${name}" '' deps = {} ${concatStringsSep "\n" (mapAttrsToList (name: path: ''deps["${name}_path"] = "${path}"'') paths)} return deps '') + "/${name}"; confDir = lib.sourceFilesBySuffices ./. [ "lua" "vim" ]; in with lib; '' vim.cmd [[source ${confDir}/init.vim]] package.path = package.path .. ";${confDir}/?.lua;${pathsLua};" dofile("${confDir}/init.lua") ''; }; programs.git.ignores = [ ".nvim_session" ]; home.sessionVariables = rec { EDITOR = "nvim"; VISUAL_EDITOR = EDITOR; }; }