280 lines
8.7 KiB
Nix
280 lines
8.7 KiB
Nix
{ 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
|
|
coc-sh
|
|
coc-nvim
|
|
coc-json
|
|
coc-yaml
|
|
coc-tsserver
|
|
coc-prettier
|
|
coc-pyright
|
|
coc-diagnostic
|
|
vimtex
|
|
coc-vimtex
|
|
coc-html
|
|
coc-go
|
|
coc-spell-checker
|
|
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 = pkgs.writeTextFile {
|
|
name = "nvim-deps.lua";
|
|
text = ''
|
|
return {
|
|
${concatStringsSep ",\n " (mapAttrsToList (name: path: ''${name}_path = "${path}"'') paths)}
|
|
}
|
|
'';
|
|
};
|
|
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" ];
|
|
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
|
|
{
|
|
nativeBuildInputs = [ makeWrapper ];
|
|
} ''
|
|
makeWrapper ${lsp} $out \
|
|
--prefix PATH : ${lib.makeBinPath sdk}
|
|
'';
|
|
in
|
|
builtins.toJSON {
|
|
python = {
|
|
pythonPath = preferProjectEnv "python3" (pkgs.python3 + "/bin/python3");
|
|
formatting.autopep8Path = "${pkgs.python3Packages.autopep8}/bin/autopep8";
|
|
};
|
|
pyright = {
|
|
enable = true;
|
|
};
|
|
# https://rust-analyzer.github.io/manual.html
|
|
rust-analyzer = {
|
|
cargo = {
|
|
allFeatures = true;
|
|
runBuildScripts = true;
|
|
autoreload = true;
|
|
};
|
|
completion = {
|
|
autoimport.enable = true;
|
|
privateEditable.enable = true;
|
|
fullFunctionSignatures.enable = true; # https://github.com/rust-lang/rust-analyzer/pull/15582
|
|
snippets = {
|
|
"return Err(..)" = {
|
|
postfix = [ "reterr" ];
|
|
body = ''return Err($${receiver});'';
|
|
description = "return expression as Err";
|
|
scope = "expr";
|
|
};
|
|
"format!(..)" = {
|
|
postfix = [ "fmt" ];
|
|
body = ''format!($${receiver})'';
|
|
description = "use receiver as format string";
|
|
scope = "expr";
|
|
|
|
};
|
|
"wrap { .. }" = {
|
|
postfix = [ "brace" "wrap" ];
|
|
body = ''{$${receiver}}'';
|
|
description = "wrap this type in { .. }";
|
|
scope = "expr";
|
|
};
|
|
"async move { .. }" = {
|
|
postfix = [ "asyncm" ];
|
|
body = ''async move {$${receiver}}'';
|
|
description = "wrap this type in async move { .. }";
|
|
scope = "expr";
|
|
};
|
|
"try { .. }" = {
|
|
postfix = [ "try" ];
|
|
body = ''let result: Result<_,_> = try {$${receiver}};'';
|
|
description = "wrap this type in try { .. }";
|
|
scope = "expr";
|
|
};
|
|
"while let Some(item) = { .. } {}" = {
|
|
postfix = [ "letwhile" ];
|
|
body = ''while let Some(item) = $${receiver} {}'';
|
|
description = "wrap this type in while let Some";
|
|
scope = "expr";
|
|
};
|
|
"let $x = $x.clone()" = {
|
|
postfix = [ "cloned" ];
|
|
body = ''let $${receiver} = $${receiver}.clone();'';
|
|
description = "clone a variable into a new binding";
|
|
scope = "expr";
|
|
};
|
|
"let $x = $x.into()" = {
|
|
postfix = [ "into" ];
|
|
body = ''let $${receiver} = $${receiver}.clone();'';
|
|
description = "call into() and create a new binding";
|
|
scope = "expr";
|
|
};
|
|
"assert_eq!($x, .. );" = {
|
|
postfix = [ "asseq" ];
|
|
body = ''assert_eq!($${receiver}, );'';
|
|
description = "create an assertion for the expression";
|
|
scope = "expr";
|
|
};
|
|
};
|
|
};
|
|
procMacro = { enable = true; attributes.enable = true; };
|
|
serverPath = addSDK {
|
|
name = "rust-env";
|
|
lsp = "${rust-analyzer}/bin/rust-analyzer";
|
|
sdk = [ rust-sdk ];
|
|
};
|
|
imports.group.enable = true;
|
|
inlayHints = {
|
|
closureReturnTypeHints.enable = false;
|
|
};
|
|
highlightRelated = {
|
|
yieldPoints.enable = true;
|
|
references.enable = true;
|
|
exitPoints.enable = true;
|
|
breakPoints.enable = true;
|
|
};
|
|
checkOnSave = {
|
|
#https://github.com/rust-lang/rust-clippy/issues/9560
|
|
enable = false;
|
|
allFeatures = true;
|
|
command = "clippy";
|
|
# extraArgs = [ "--message-format=json" ];
|
|
};
|
|
diagnostics = {
|
|
enable = true;
|
|
experimental.enable = true;
|
|
};
|
|
files.excludeDirs = [ "result" "target" ];
|
|
extraEnv = {
|
|
RA_LOG = "debug";
|
|
};
|
|
};
|
|
languageserver = {
|
|
ccls = {
|
|
command = preferProjectEnv "ccls" "${pkgs.ccls}/bin/ccls";
|
|
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" ];
|
|
};
|
|
nix = {
|
|
command = "${pkgs.nil}/bin/nil";
|
|
formatting.command = "${pkgs.nixpkgs-fmt}/bin/nixpkgs-fmt";
|
|
flake = {
|
|
autoArchive = true;
|
|
autoEvalInputs = true;
|
|
};
|
|
maxMemoryMB = 1024 * 4;
|
|
rootPatterns = [ "flake.nix" ];
|
|
filetypes = [ "nix" ];
|
|
};
|
|
diagnostic-languageserver = {
|
|
filetypes = {
|
|
sh = [ "${pkgs.shellcheck}/bin/shellcheck" ];
|
|
};
|
|
};
|
|
cSpell = { diagnosticLevel = "hint"; };
|
|
};
|
|
};
|
|
home.sessionVariables = rec {
|
|
EDITOR = "nvim";
|
|
VISUAL_EDITOR = EDITOR;
|
|
};
|
|
}
|