diff --git a/completion.lua b/completion.lua index d42ede6..b8f8f68 100644 --- a/completion.lua +++ b/completion.lua @@ -109,3 +109,12 @@ lspconfig.clangd.setup({cmd = {(deps["clang-tools_path"] .. "/bin/clangd")}}) lspconfig.bashls.setup({ cmd = {(deps["bash-language-server_path"] .. "/bin/bash-language-server")} }) +lspconfig.pylsp.setup({ + cmd = { (deps["python-lsp-server_path"] .. "/bin/pylsp") }, +}) +lspconfig.lua_ls.setup({ + cmd = { (deps["lua-lsp_path"] .. "/bin/lua-lsp") }, +}) +lspconfig.yamlls.setup({ + cmd = { (deps["yaml-language-server_path"] .. "/bin/yaml-language-server"), "--stdio" }, +}) diff --git a/default.nix b/default.nix index 0e2ed06..c942331 100644 --- a/default.nix +++ b/default.nix @@ -1,7 +1,18 @@ -{ 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 +{ + 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 = [ @@ -15,16 +26,19 @@ ]) cargo-watch ]; - } else symlinkJoin { name = "nvim-rust"; paths = [ rustc cargo rustfmt clippy cargo-watch ]; }; -in -{ - + } + 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 ]; + extraPackages = with pkgs; [fzf xclip fish]; plugins = with pkgs.vimPlugins; [ vim-fugitive git-blame-nvim @@ -58,7 +72,11 @@ in 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 + ( + 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 @@ -66,59 +84,87 @@ in 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"\]).*/\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"))) // { + extraLuaConfig = let + # tries to compute a package set required to make package resolution in lua + # via deps["pkg"] work + inherit (builtins) head tail hasAttr getAttr; + pkg = parts: pkgs: let + rem = tail parts; + subset = + if hasAttr (head parts) pkgs + then getAttr (head parts) pkgs + else throw "no attr ${name}"; + in + if rem == [] + then subset + else builtins.addErrorContext "${concatStringsSep "." parts}" (pkg rem subset); + getPkg = name: let parts = builtins.split "\\." name; in pkg parts pkgs; + packages = file: let + out = builtins.readFile (pkgs.runCommandLocal "extract-deps" + { + nativeBuildInputs = [pkgs.gnused]; + __contentAddressed = true; + } '' + sed -nr 's/.*(deps\["(.*)_path"\]).*/\2/p' ${file} | uniq > $out + ''); + names = lib.splitString "\n" out; + in + filter (name: name != "") names; + paths = + (listToAttrs (map + (name: { + inherit name; + value = getPkg name; + }) + (packages "${confDir}/*.lua"))) + // { lldb = pkgs.lldb; rust_analyzer = rust-analyzer; typst_lsp = pkgs.typst-lsp; + inherit (pkgs.python3Packages) python-lsp-server; + inherit (pkgs.luajitPackages) lua-lsp; inherit (pkgs.nodePackages) typescript-language-server bash-language-server; }; - pathsLua = pkgs.writeTextFile { - name = "nvim-deps.lua"; - text = '' - deps = {} - ${concatStringsSep "\n " (mapAttrsToList (name: path: ''deps["${name}_path"] = "${path}"'') paths)} - return deps - ''; - }; - confDir = lib.sourceFilesBySuffices ./. [ "lua" "vim" ]; - in + pathsLua = pkgs.writeTextFile { + name = "nvim-deps.lua"; + text = '' + deps = {} + ${concatStringsSep "\n " (mapAttrsToList (name: path: ''deps["${name}_path"] = "${path}"'') paths)} + return deps + ''; + }; + confDir = lib.sourceFilesBySuffices ./. ["lua" "vim"]; + in with lib; '' vim.cmd [[source ${confDir}/init.vim]] - package.path = package.path .. ";${confDir}/?.lua;${pathsLua};" + package.path = package.path .. ";${confDir}/?.lua;${pathsLua};" dofile("${confDir}/init.lua") ''; }; - programs.git.ignores = [ ".nvim_session" ]; - xdg.configFile."nvim/coc-settings.json".text = - let - preferProjectEnv = binName: alternate: pkgs.writeShellScript "${binName}-switcher" '' + programs.git.ignores = [".nvim_session"]; + xdg.configFile."nvim/coc-settings.json".text = let + preferProjectEnv = binName: alternate: + pkgs.writeShellScript "${binName}-switcher" '' if command -v ${binName}; then ${binName} ''${@} else ${alternate} ''${@} fi ''; - addSDK = { name, lsp, sdk }: with pkgs; runCommandLocal name + addSDK = { + name, + lsp, + sdk, + }: + with pkgs; + runCommandLocal name { - nativeBuildInputs = [ makeWrapper ]; + nativeBuildInputs = [makeWrapper]; } '' - makeWrapper ${lsp} $out \ - --prefix PATH : ${lib.makeBinPath sdk} - ''; - in + makeWrapper ${lsp} $out \ + --prefix PATH : ${lib.makeBinPath sdk} + ''; + in builtins.toJSON { python = { pythonPath = preferProjectEnv "python3" (pkgs.python3 + "/bin/python3"); @@ -140,67 +186,69 @@ in fullFunctionSignatures.enable = true; # https://github.com/rust-lang/rust-analyzer/pull/15582 snippets = { "return Err(..)" = { - postfix = [ "reterr" ]; + postfix = ["reterr"]; body = ''return Err($${receiver});''; description = "return expression as Err"; scope = "expr"; }; "format!(..)" = { - postfix = [ "fmt" ]; + postfix = ["fmt"]; body = ''format!($${receiver})''; description = "use receiver as format string"; scope = "expr"; - }; "wrap { .. }" = { - postfix = [ "brace" "wrap" ]; + postfix = ["brace" "wrap"]; body = ''{$${receiver}}''; description = "wrap this type in { .. }"; scope = "expr"; }; "async move { .. }" = { - postfix = [ "asyncm" ]; + postfix = ["asyncm"]; body = ''async move {$${receiver}}''; description = "wrap this type in async move { .. }"; scope = "expr"; }; "try { .. }" = { - postfix = [ "try" ]; + postfix = ["try"]; body = ''let result: Result<_,_> = try {$${receiver}};''; description = "wrap this type in try { .. }"; scope = "expr"; }; "while let Some(item) = { .. } {}" = { - postfix = [ "letwhile" ]; + postfix = ["letwhile"]; body = ''while let Some(item) = $${receiver} {}''; description = "wrap this type in while let Some"; scope = "expr"; }; "let $x = $x.clone()" = { - postfix = [ "cloned" ]; + postfix = ["cloned"]; body = ''let $${receiver} = $${receiver}.clone();''; description = "clone a variable into a new binding"; scope = "expr"; }; "let $x = $x.into()" = { - postfix = [ "into" ]; + postfix = ["into"]; body = ''let $${receiver} = $${receiver}.clone();''; description = "call into() and create a new binding"; scope = "expr"; }; "assert_eq!($x, .. );" = { - postfix = [ "asseq" ]; + postfix = ["asseq"]; body = ''assert_eq!($${receiver}, );''; description = "create an assertion for the expression"; scope = "expr"; }; }; }; - procMacro = { enable = true; attributes.enable = true; }; + procMacro = { + enable = true; + attributes.enable = true; + }; serverPath = addSDK { name = "rust-env"; lsp = "${rust-analyzer}/bin/rust-analyzer"; - sdk = [ rust-sdk ]; + sdk = [rust-sdk]; }; imports.group.enable = true; inlayHints = { @@ -223,7 +271,7 @@ in enable = true; experimental.enable = true; }; - files.excludeDirs = [ "result" "target" ]; + files.excludeDirs = ["result" "target"]; extraEnv = { RA_LOG = "debug"; }; @@ -231,14 +279,14 @@ in languageserver = { ccls = { command = preferProjectEnv "ccls" "${pkgs.ccls}/bin/ccls"; - filetypes = [ "c" "cc" "cpp" "c++" "objc" "objcpp" ]; - rootPatterns = [ ".ccls" "compile_commands.json" ".git/" ".hg/" ]; + filetypes = ["c" "cc" "cpp" "c++" "objc" "objcpp"]; + rootPatterns = [".ccls" "compile_commands.json" ".git/" ".hg/"]; initializationOptions = { cache = { directory = "${config.xdg.cacheHome}/ccls"; }; }; - clang.extraOptions = [ "-std=c++20" ]; + clang.extraOptions = ["-std=c++20"]; }; nix = { command = "${pkgs.nil}/bin/nil"; @@ -248,15 +296,15 @@ in autoEvalInputs = true; }; maxMemoryMB = 1024 * 4; - rootPatterns = [ "flake.nix" ]; - filetypes = [ "nix" ]; + rootPatterns = ["flake.nix"]; + filetypes = ["nix"]; }; diagnostic-languageserver = { filetypes = { - sh = [ "${pkgs.shellcheck}/bin/shellcheck" ]; + sh = ["${pkgs.shellcheck}/bin/shellcheck"]; }; }; - cSpell = { diagnosticLevel = "hint"; }; + cSpell = {diagnosticLevel = "hint";}; }; }; home.sessionVariables = rec { diff --git a/init.lua b/init.lua index ff18581..294d59b 100644 --- a/init.lua +++ b/init.lua @@ -239,3 +239,4 @@ lspconfig.nil_ls.setup { require("lsp-inlayhints").setup() require("completion") +require("rust")