diff --git a/flake.nix b/flake.nix index ac6957c2..6e4ae51d 100644 --- a/flake.nix +++ b/flake.nix @@ -35,14 +35,53 @@ (system: let pkgs = import nixpkgs { inherit system; }; + extractRustAnalyzer = { stdenv, pkgs }: stdenv.mkDerivation { + pname = "extract_rust_analyzer"; + version = "master"; + + dontUnpack = true; + dontBuild = true; + + buildInputs = [ pkgs.python3 ]; + + installPhase = '' + ls -la + mkdir -p $out/bin + cp ${./helpers/extract_rust_analyzer.py} $out/bin/extract_rust_analyzer.py + ''; + }; + extractRustAnalyzerPkg = pkgs.callPackage extractRustAnalyzer { }; in { - packages.docs = pkgs.callPackage (import ./docs.nix) { - modules = nixvimModules; + packages = { + docs = pkgs.callPackage (import ./docs.nix) { + modules = nixvimModules; + }; + runUpdates = pkgs.callPackage + ({ pkgs, stdenv }: stdenv.mkDerivation { + pname = "run-updates"; + version = pkgs.rust-analyzer.version; + + src = pkgs.rust-analyzer.src; + + nativeBuildInputs = with pkgs; [extractRustAnalyzerPkg alejandra nixpkgs-fmt]; + + buildPhase = '' + extract_rust_analyzer.py editors/code/package.json | + alejandra --quiet | + nixpkgs-fmt > rust-analyzer-config.nix + ''; + + installPhase = '' + mkdir -p $out/share + cp rust-analyzer-config.nix $out/share + ''; + }) + { }; }; legacyPackages = rec { makeNixvimWithModule = import ./wrappers/standalone.nix pkgs modules; - makeNixvim = configuration: makeNixvimWithModule { + makeNixvim = configuration: makeNixvimWithModule { module = { config = configuration; }; diff --git a/helpers/extract_rust_analyzer.py b/helpers/extract_rust_analyzer.py new file mode 100755 index 00000000..4c88826a --- /dev/null +++ b/helpers/extract_rust_analyzer.py @@ -0,0 +1,229 @@ +#!/usr/bin/env python3 + +import sys +import json + +ra_package_json = sys.argv[1] +with open(ra_package_json) as f: + ra_package = json.load(f) + +config = ra_package["contributes"]["configuration"]["properties"] + +config_dict = {} + +in_common_block = False + + +def py_to_nix(obj): + if obj is None: + return "null" + + if obj is False: + return "false" + + if obj is True: + return "true" + + if isinstance(obj, str): + s = f'"{obj}"' + if "${" in s: + s = s.replace("${", "$\\{") + return s + + if isinstance(obj, int): + return f"{obj}" + + if isinstance(obj, dict): + val = "{" + for key in obj: + key_val = py_to_nix(obj[key]) + val += f'"{key}" = {key_val};\n' + val += "}" + + return val + + if isinstance(obj, list): + return "[" + " ".join(py_to_nix(val) for val in obj) + "]" + + print(f"Unhandled value: {obj}") + sys.exit(1) + + +def ty_to_nix(ty): + if ty == "boolean": + return "types.bool" + + if ty == "string": + return "types.str" + + # This is an object without any additional properties + if ty == "object": + return "types.attrsOf types.anything" + + if isinstance(ty, list) and ty[0] == "null": + if len(ty) > 2: + print("Unhandled type", ty) + sys.exit() + + nullable_ty = ty_to_nix(ty[1]) + return f"types.nullOr ({nullable_ty})" + + if isinstance(ty, list): + either_types = (ty_to_nix(t) for t in ty) + either_types = " ".join(f"({t})" for t in either_types) + return f"types.oneOf ([{either_types}])" + + print(f"Unhandled type: {ty}") + sys.exit(1) + + +def prop_ty_to_nix(prop_info): + if "type" in prop_info: + if "enum" in prop_info: + enum = "[" + " ".join(f'"{member}"' for member in prop_info["enum"]) + "]" + if prop_info["type"] == "string": + return f"types.enum {enum}" + + print("TODO: with unknown enum type", prop_info["type"]) + sys.exit() + + if "additionalProperties" in prop_info or "properties" in prop_info: + print("TODO: with (additional)Properties", prop_info) + sys.exit() + + if "minimum" in prop_info or "maximum" in prop_info: + can_be_null = False + if "null" in prop_info["type"]: + can_be_null = True + if len(prop_info["type"]) > 2: + print("Unhandled int type", prop_info["type"]) + sys.exit() + prop_info["type"] = prop_info["type"][1] + + if prop_info["type"] == "number": + int_ty = "types.number" + elif prop_info["type"] == "integer": + int_ty = "types.int" + else: + print("Unhandled int type", prop_info["type"]) + sys.exit() + + if "minimum" in prop_info and "maximum" in prop_info: + min = prop_info["minimum"] + max = prop_info["maximum"] + int_ty = f"{int_ty}s.between {min} {max}" + elif "minimum" in prop_info: + min = prop_info["minimum"] + int_ty = f"types.addCheck {int_ty} (x: x >= {min})" + else: + print("TODO: max number", prop_info) + sys.exit() + + if can_be_null: + return f"types.nullOr ({int_ty})" + else: + return int_ty + + if "array" in prop_info["type"] or prop_info["type"] == "array": + if "items" not in prop_info: + print("Array without items") + sys.exit() + + items_ty = prop_ty_to_nix(prop_info["items"]) + array_ty = f"types.listOf ({items_ty})" + if prop_info["type"] == "array": + return array_ty + elif prop_info["type"] == ["null", "array"]: + return f"types.nullOr ({array_ty})" + else: + print("Unhandled array type", prop_info) + sys.exit() + + return ty_to_nix(prop_info["type"]) + elif "anyOf" in prop_info: + can_be_null = False + if {"type": "null"} in prop_info["anyOf"]: + can_be_null = True + prop_info["anyOf"].remove({"type": "null"}) + + types = (prop_ty_to_nix(prop) for prop in prop_info["anyOf"]) + one_of = " ".join(f"({ty})" for ty in types) + one_of_ty = f"types.oneOf ([{one_of}])" + + if can_be_null: + return f"types.nullOr ({one_of_ty})" + else: + return one_of_ty + else: + print("TODO: no *type*", prop_info) + sys.exit() + + +for opt in config: + if opt.startswith("$"): + in_common_block = True + continue + + if not in_common_block: + continue + + opt_path = opt.split(".") + if opt_path[0] != "rust-analyzer": + print("ERROR: expected all options to start with 'rust-analyzer'") + sys.exit(1) + + path = opt_path[1:-1] + option = opt_path[-1] + + top_dict = config_dict + + for p in path: + if not p in top_dict: + top_dict[p] = {} + top_dict = top_dict[p] + + prop_info = config[opt] + + is_optional = False + + ty = prop_ty_to_nix(prop_info) + + default = py_to_nix(prop_info["default"]) + + if "markdownDescription" in prop_info: + desc = prop_info["markdownDescription"] + else: + desc = prop_info["description"] + + desc += f"\n\ndefault value is: \n```nix\n {default}\n```" + + top_dict[ + option + ] = """ +mkOption {{ +type = types.nullOr ({ty}); +default = null; +description = '' +{desc} +''; +}} + """.format( + ty=ty, default=default, desc=desc + ) + + +def print_dict(d): + print("{") + for key in d: + print(f'"{key}" = ') + if isinstance(d[key], str): + print(d[key]) + else: + print_dict(d[key]) + print(";") + print("}") + + +print("# THIS FILE IS AUTOGENERATED DO NOT EDIT") +print("lib: with lib;") +print_dict(config_dict) diff --git a/lib/helpers.nix b/lib/helpers.nix index 70c85d77..94d4ab08 100644 --- a/lib/helpers.nix +++ b/lib/helpers.nix @@ -14,14 +14,15 @@ rec { else "{" + (concatStringsSep "," (mapAttrsToList - (n: v: if head (stringToCharacters n) == "@" then - toLuaObject v - else "[${toLuaObject n}] = " + (toLuaObject v)) - (filterAttrs (n: v: !isNull v && toLuaObject v != "{}") args))) + "}" + (n: v: + if head (stringToCharacters n) == "@" then + toLuaObject v + else "[${toLuaObject n}] = " + (toLuaObject v)) + (filterAttrs (n: v: !isNull v && toLuaObject v != "{}") args))) + "}" else if builtins.isList args then "{" + concatMapStringsSep "," toLuaObject args + "}" else if builtins.isString args then - # This should be enough! + # This should be enough! builtins.toJSON args else if builtins.isPath args then builtins.toJSON (toString args) @@ -36,28 +37,34 @@ rec { else ""; # Generates maps for a lua config - genMaps = mode: maps: let - normalized = builtins.mapAttrs (key: action: - if builtins.isString action then + genMaps = mode: maps: + let + normalized = builtins.mapAttrs + (key: action: + if builtins.isString action then + { + silent = false; + expr = false; + unique = false; + noremap = true; + script = false; + nowait = false; + action = action; + } + else action) + maps; + in + builtins.attrValues (builtins.mapAttrs + (key: action: { - silent = false; - expr = false; - unique = false; - noremap = true; - script = false; - nowait = false; - action = action; - } - else action) maps; - in builtins.attrValues (builtins.mapAttrs (key: action: - { - action = action.action; - config = lib.filterAttrs (_: v: v) { - inherit (action) silent expr unique noremap script nowait; - }; - key = key; - mode = mode; - }) normalized); + action = action.action; + config = lib.filterAttrs (_: v: v) { + inherit (action) silent expr unique noremap script nowait; + }; + key = key; + mode = mode; + }) + normalized); # Creates an option with a nullable type that defaults to null. mkNullOrOption = type: desc: lib.mkOption { @@ -66,45 +73,66 @@ rec { description = desc; }; - mkPlugin = { config, lib, ... }: { - name, - description, - package ? null, - extraPlugins ? [], - extraPackages ? [], - options ? {}, - ... - }: let - cfg = config.plugins.${name}; - # TODO support nested options! - pluginOptions = mapAttrs (k: v: v.option) options; - globals = mapAttrs' (name: opt: { - name = opt.global; - value = if cfg.${name} != null then opt.value cfg.${name} else null; - }) options; - # does this evaluate package? - packageOption = if package == null then { } else { - package = mkOption { - type = types.package; - default = package; - description = "Plugin to use for ${name}"; - }; - }; - in { - options.plugins.${name} = { - enable = mkEnableOption description; - } // packageOption // pluginOptions; + defaultNullOpts = rec { + mkNullable = type: default: desc: mkNullOrOption type ( + let + defaultDesc = "default: `${default}`"; + in + if desc == "" then defaultDesc else '' + ${desc} - config = mkIf cfg.enable { - inherit extraPackages globals; - # does this evaluate package? it would not be desired to evaluate pacakge if we use another package. - extraPlugins = extraPlugins ++ optional (package != null) cfg.package; - }; + ${defaultDesc} + '' + ); + + mkInt = default: mkNullable lib.types.int (toString default); + mkBool = default: mkNullable lib.types.bool (toString default); + mkStr = default: mkNullable lib.types.str ''"${default}"''; }; - globalVal = val: if builtins.isBool val then - (if val == false then 0 else 1) - else val; + mkPlugin = { config, lib, ... }: { name + , description + , package ? null + , extraPlugins ? [ ] + , extraPackages ? [ ] + , options ? { } + , ... + }: + let + cfg = config.plugins.${name}; + # TODO support nested options! + pluginOptions = mapAttrs (k: v: v.option) options; + globals = mapAttrs' + (name: opt: { + name = opt.global; + value = if cfg.${name} != null then opt.value cfg.${name} else null; + }) + options; + # does this evaluate package? + packageOption = if package == null then { } else { + package = mkOption { + type = types.package; + default = package; + description = "Plugin to use for ${name}"; + }; + }; + in + { + options.plugins.${name} = { + enable = mkEnableOption description; + } // packageOption // pluginOptions; + + config = mkIf cfg.enable { + inherit extraPackages globals; + # does this evaluate package? it would not be desired to evaluate pacakge if we use another package. + extraPlugins = extraPlugins ++ optional (package != null) cfg.package; + }; + }; + + globalVal = val: + if builtins.isBool val then + (if val == false then 0 else 1) + else val; mkDefaultOpt = { type, global, description ? null, example ? null, default ? null, value ? v: (globalVal v), ... }: { option = mkOption { @@ -131,9 +159,9 @@ rec { mkRaw = r: { __raw = r; }; wrapDo = string: '' - do - ${string} - end + do + ${string} + end ''; rawType = types.submodule { diff --git a/modules/highlights.nix b/modules/highlights.nix index 0f5fc1f0..281cb4fb 100644 --- a/modules/highlights.nix +++ b/modules/highlights.nix @@ -15,10 +15,21 @@ with lib; }; ''; }; + + match = mkOption { + type = types.attrsOf types.str; + default = { }; + description = "Define match groups"; + example = '' + match = { + ExtraWhitespace = '\\s\\+$'; + }; + ''; + }; }; - config = mkIf (config.highlight != { }) { - extraConfigLuaPost = '' + config = mkIf (config.highlight != { } || config.match != { }) { + extraConfigLuaPost = (optionalString (config.highlight != { }) '' -- Highlight groups {{ do local highlights = ${helpers.toLuaObject config.highlight} @@ -28,6 +39,18 @@ with lib; end end -- }} - ''; + '') + + (optionalString (config.match != { }) '' + -- Match groups {{ + do + local match = ${helpers.toLuaObject config.match} + + for k,v in pairs(match) do + vim.fn.matchadd(k, v) + end + end + -- }} + ''); }; } + diff --git a/plugins/bufferlines/barbar.nix b/plugins/bufferlines/barbar.nix index 964c60be..7d7e7e48 100644 --- a/plugins/bufferlines/barbar.nix +++ b/plugins/bufferlines/barbar.nix @@ -5,7 +5,7 @@ let in { options.plugins.barbar = { - enable = mkEnableOption "Enable barbar.nvim"; + enable = mkEnableOption "barbar.nvim"; package = mkOption { type = types.package; @@ -32,13 +32,13 @@ in }; icons = mkOption { - type = with types; nullOr (oneOf [bool (enum ["numbers both"])]); + type = with types; nullOr (oneOf [ bool (enum [ "numbers both" ]) ]); default = null; description = "Enable/disable icons"; }; iconCustomColors = mkOption { - type = with types; nullOr (oneOf [bool str]); + type = with types; nullOr (oneOf [ bool str ]); default = null; description = "Sets the icon highlight group"; }; @@ -56,7 +56,8 @@ in config = mkIf cfg.enable { extraPlugins = with pkgs.vimPlugins; [ - cfg.package nvim-web-devicons + cfg.package + nvim-web-devicons ]; # maps = genMaps cfg.keys; diff --git a/plugins/bufferlines/bufferline.nix b/plugins/bufferlines/bufferline.nix index 811cf56c..e8371197 100644 --- a/plugins/bufferlines/bufferline.nix +++ b/plugins/bufferlines/bufferline.nix @@ -33,7 +33,7 @@ in options = { plugins.bufferline = { - enable = mkEnableOption "Enable bufferline"; + enable = mkEnableOption "bufferline"; package = mkOption { type = types.package; description = "Plugin to use for bufferline"; @@ -67,7 +67,7 @@ in # is deprecated, but might still work indicatorIcon = mkOption { type = types.nullOr types.str; - description = "The Icon shown as a indicator for buffer. Changing it is NOT recommended, + description = "The Icon shown as a indicator for buffer. Changing it is NOT recommended, this is intended to be an escape hatch for people who cannot bear it for whatever reason."; default = null; }; diff --git a/plugins/colorschemes/base16.nix b/plugins/colorschemes/base16.nix index 27786072..d7866c11 100644 --- a/plugins/colorschemes/base16.nix +++ b/plugins/colorschemes/base16.nix @@ -7,7 +7,7 @@ in { options = { colorschemes.base16 = { - enable = mkEnableOption "Enable base16"; + enable = mkEnableOption "base16"; package = mkOption { type = types.package; diff --git a/plugins/colorschemes/gruvbox.nix b/plugins/colorschemes/gruvbox.nix index ac6a65fe..cc591b12 100644 --- a/plugins/colorschemes/gruvbox.nix +++ b/plugins/colorschemes/gruvbox.nix @@ -7,7 +7,7 @@ in { options = { colorschemes.gruvbox = { - enable = mkEnableOption "Enable gruvbox"; + enable = mkEnableOption "gruvbox"; package = mkOption { type = types.package; @@ -15,10 +15,10 @@ in description = "Plugin to use for gruvbox"; }; - italics = mkEnableOption "Enable italics"; - bold = mkEnableOption "Enable bold"; - underline = mkEnableOption "Enable underlined text"; - undercurl = mkEnableOption "Enable undercurled text"; + italics = mkEnableOption "italics"; + bold = mkEnableOption "bold"; + underline = mkEnableOption "underlined text"; + undercurl = mkEnableOption "undercurled text"; contrastDark = mkOption { type = types.nullOr (types.enum [ "soft" "medium" "hard" ]); @@ -110,9 +110,9 @@ in description = "Improved warnings"; }; - transparentBg = mkEnableOption "Transparent background"; + transparentBg = mkEnableOption "transparent background"; - trueColor = mkEnableOption "Enable true color support"; + trueColor = mkEnableOption "true color support"; }; }; diff --git a/plugins/colorschemes/nord.nix b/plugins/colorschemes/nord.nix index d6cc1ff5..68926bbd 100644 --- a/plugins/colorschemes/nord.nix +++ b/plugins/colorschemes/nord.nix @@ -6,7 +6,7 @@ in { options = { colorschemes.nord = { - enable = mkEnableOption "Enable nord"; + enable = mkEnableOption "nord"; package = mkOption { type = types.package; diff --git a/plugins/colorschemes/one.nix b/plugins/colorschemes/one.nix index f5e7660f..7ef50559 100644 --- a/plugins/colorschemes/one.nix +++ b/plugins/colorschemes/one.nix @@ -6,7 +6,7 @@ in { options = { colorschemes.one = { - enable = mkEnableOption "Enable vim-one"; + enable = mkEnableOption "vim-one"; package = mkOption { type = types.package; diff --git a/plugins/colorschemes/onedark.nix b/plugins/colorschemes/onedark.nix index b488ea63..e12ed110 100644 --- a/plugins/colorschemes/onedark.nix +++ b/plugins/colorschemes/onedark.nix @@ -6,7 +6,7 @@ in { options = { colorschemes.onedark = { - enable = mkEnableOption "Enable onedark"; + enable = mkEnableOption "onedark"; package = mkOption { type = types.package; diff --git a/plugins/colorschemes/tokyonight.nix b/plugins/colorschemes/tokyonight.nix index aec6415e..1cf99d9c 100644 --- a/plugins/colorschemes/tokyonight.nix +++ b/plugins/colorschemes/tokyonight.nix @@ -8,7 +8,7 @@ in { options = { colorschemes.tokyonight = { - enable = mkEnableOption "Enable tokyonight"; + enable = mkEnableOption "tokyonight"; package = mkOption { type = types.package; default = pkgs.vimPlugins.tokyonight-nvim; @@ -24,8 +24,7 @@ in default = true; description = "Configure the colors used when opening a :terminal in Neovim"; }; - transparent = - mkEnableOption "Enable this to disable setting the background color"; + transparent = mkEnableOption "disable setting the background color"; styles = let mkBackgroundStyle = name: mkOption { diff --git a/plugins/completion/copilot.nix b/plugins/completion/copilot.nix index 62002064..8a30cb51 100644 --- a/plugins/completion/copilot.nix +++ b/plugins/completion/copilot.nix @@ -6,7 +6,7 @@ in { options = { plugins.copilot = { - enable = mkEnableOption "Enable copilot"; + enable = mkEnableOption "copilot"; package = mkOption { type = types.package; description = "The copilot plugin package to use"; diff --git a/plugins/completion/coq.nix b/plugins/completion/coq.nix index e278bdc1..82be1f98 100644 --- a/plugins/completion/coq.nix +++ b/plugins/completion/coq.nix @@ -9,7 +9,7 @@ in { options = { plugins.coq-nvim = { - enable = mkEnableOption "Enable coq-nvim"; + enable = mkEnableOption "coq-nvim"; package = mkOption { type = types.package; diff --git a/plugins/completion/nvim-cmp/default.nix b/plugins/completion/nvim-cmp/default.nix index 65dd2725..39b0dd48 100644 --- a/plugins/completion/nvim-cmp/default.nix +++ b/plugins/completion/nvim-cmp/default.nix @@ -15,7 +15,7 @@ let in { options.plugins.nvim-cmp = { - enable = mkEnableOption "Enable nvim-cmp"; + enable = mkEnableOption "nvim-cmp"; package = mkOption { type = types.package; @@ -215,6 +215,7 @@ in }; auto_enable_sources = mkOption { + type = types.bool; default = true; description = '' Scans the sources array and installs the plugins if they are known to nixvim. diff --git a/plugins/default.nix b/plugins/default.nix index 551a8bd2..a76b39fb 100644 --- a/plugins/default.nix +++ b/plugins/default.nix @@ -24,6 +24,7 @@ ./languages/ledger.nix ./languages/nix.nix ./languages/plantuml-syntax.nix + ./languages/rust.nix ./languages/treesitter.nix ./languages/treesitter-context.nix ./languages/treesitter-refactor.nix @@ -34,6 +35,7 @@ ./nvim-lsp ./nvim-lsp/lspsaga.nix ./nvim-lsp/lsp-lines.nix + ./nvim-lsp/nvim-lightbulb.nix ./nvim-lsp/trouble.nix ./pluginmanagers/packer.nix @@ -56,6 +58,7 @@ ./utils/mark-radar.nix ./utils/notify.nix ./utils/nvim-autopairs.nix + ./utils/nvim-colorizer.nix ./utils/nvim-tree.nix ./utils/project-nvim.nix ./utils/specs.nix diff --git a/plugins/git/gitgutter.nix b/plugins/git/gitgutter.nix index 93da29c4..e860230c 100644 --- a/plugins/git/gitgutter.nix +++ b/plugins/git/gitgutter.nix @@ -7,7 +7,7 @@ in { options = { plugins.gitgutter = { - enable = mkEnableOption "Enable gitgutter"; + enable = mkEnableOption "gitgutter"; package = mkOption { type = types.package; diff --git a/plugins/git/gitsigns.nix b/plugins/git/gitsigns.nix index 0a6f1ad0..bb14efe0 100644 --- a/plugins/git/gitsigns.nix +++ b/plugins/git/gitsigns.nix @@ -1,9 +1,8 @@ -{ - config, - lib, - pkgs, - helpers, - ... +{ config +, lib +, pkgs +, helpers +, ... }: with lib; let signOptions = defaults: @@ -28,7 +27,7 @@ with lib; let description = "Specifies the highlight group to use for the line"; default = defaults.linehl; }; - showCount = mkEnableOption "Enable showing count of hunk, e.g. number of deleted lines"; + showCount = mkEnableOption "showing count of hunk, e.g. number of deleted lines"; }; signSetupOptions = values: { inherit (values) hl text numhl linehl; @@ -41,7 +40,8 @@ with lib; let description = "Lua function definition"; }; }; -in { +in +{ options.plugins.gitsigns = { enable = mkEnableOption "Enable gitsigns plugin"; package = mkOption { @@ -87,18 +87,19 @@ in { linehl = "GitSignsAddLn"; }; }; - worktrees = let - worktreeModule = { - options = { - toplevel = mkOption { - type = types.str; - }; - gitdir = mkOption { - type = types.str; + worktrees = + let + worktreeModule = { + options = { + toplevel = mkOption { + type = types.str; + }; + gitdir = mkOption { + type = types.str; + }; }; }; - }; - in + in mkOption { type = types.nullOr (types.listOf (types.submodule worktreeModule)); default = null; @@ -166,58 +167,59 @@ in { ''; }; numhl = mkEnableOption '' - Enable/disable line number highlights. + line number highlights. When enabled the highlights defined in `signs.*.numhl` are used. If the highlight group does not exist, then it is automatically defined and linked to the corresponding highlight group in `signs.*.hl`. ''; linehl = mkEnableOption '' - Enable/disable line highlights. + line highlights. When enabled the highlights defined in `signs.*.linehl` are used. If the highlight group does not exist, then it is automatically defined and linked to the corresponding highlight group in `signs.*.hl`. ''; showDeleted = mkEnableOption '' - Show the old version of hunks inline in the buffer (via virtual lines). + showing the old version of hunks inline in the buffer (via virtual lines). Note: Virtual lines currently use the highlight `GitSignsDeleteVirtLn`. ''; - diffOpts = let - diffOptModule = { - options = { - algorithm = mkOption { - type = types.enum ["myers" "minimal" "patience" "histogram"]; - default = "myers"; - description = "Diff algorithm to use"; - }; - internal = mkOption { - type = types.bool; - default = false; - description = "Use Neovim's built in xdiff library for running diffs"; - }; - indentHeuristic = mkOption { - type = types.bool; - default = false; - description = "Use the indent heuristic for the internal diff library."; - }; - vertical = mkOption { - type = types.bool; - default = true; - description = "Start diff mode with vertical splits"; - }; - linematch = mkOption { - type = types.nullOr types.int; - default = null; - description = '' - Enable second-stage diff on hunks to align lines. - Requires `internal=true`. - ''; + diffOpts = + let + diffOptModule = { + options = { + algorithm = mkOption { + type = types.enum [ "myers" "minimal" "patience" "histogram" ]; + default = "myers"; + description = "Diff algorithm to use"; + }; + internal = mkOption { + type = types.bool; + default = false; + description = "Use Neovim's built in xdiff library for running diffs"; + }; + indentHeuristic = mkOption { + type = types.bool; + default = false; + description = "Use the indent heuristic for the internal diff library."; + }; + vertical = mkOption { + type = types.bool; + default = true; + description = "Start diff mode with vertical splits"; + }; + linematch = mkOption { + type = types.nullOr types.int; + default = null; + description = '' + Enable second-stage diff on hunks to align lines. + Requires `internal=true`. + ''; + }; }; }; - }; - in + in mkOption { type = types.nullOr (types.submodule diffOptModule); default = null; @@ -307,7 +309,7 @@ in { description = "Whether to show a virtual text blame annotation"; }; virtTextPos = mkOption { - type = types.enum ["eol" "overlay" "right_align"]; + type = types.enum [ "eol" "overlay" "right_align" ]; default = "eol"; description = "Blame annotation position"; }; @@ -352,7 +354,7 @@ in { window. ''; }; - yadm.enable = mkEnableOption "Enable YADM support"; + yadm.enable = mkEnableOption "YADM support"; wordDiff = mkEnableOption '' Highlight intra-line word differences in the buffer. Requires `config.diff_opts.internal = true`. @@ -363,76 +365,84 @@ in { ''; }; - config = let - cfg = config.plugins.gitsigns; - in + config = + let + cfg = config.plugins.gitsigns; + in mkIf cfg.enable { extraPlugins = with pkgs.vimPlugins; [ cfg.package ]; - extraConfigLua = let - luaFnOrStrToObj = val: - if builtins.isString val - then val - else {__raw = val.function;}; - setupOptions = { - inherit (cfg) worktrees signcolumn numhl linehl trouble yadm; - signs = mapAttrs (_: signSetupOptions) cfg.signs; - on_attach = - if cfg.onAttach != null - then {__raw = cfg.onAttach.function;} - else null; - watch_gitdir = { - inherit (cfg.watchGitDir) enable interval; - follow_files = cfg.watchGitDir.followFiles; - }; - sign_priority = cfg.signPriority; - show_deleted = cfg.showDeleted; - diff_opts = - if cfg.diffOpts == null - then null - else { - inherit (cfg.diffOpts) algorithm internal vertical linematch; - indent_heuristic = cfg.diffOpts.indentHeuristic; + extraConfigLua = + let + luaFnOrStrToObj = val: + if builtins.isString val + then val + else { __raw = val.function; }; + setupOptions = { + inherit (cfg) worktrees signcolumn numhl linehl trouble yadm; + signs = mapAttrs (_: signSetupOptions) cfg.signs; + on_attach = + if cfg.onAttach != null + then { __raw = cfg.onAttach.function; } + else null; + watch_gitdir = { + inherit (cfg.watchGitDir) enable interval; + follow_files = cfg.watchGitDir.followFiles; }; - count_chars = let - isStrInt = s: (builtins.match "[0-9]+" s) != null; - in { - __raw = - "{" - + (concatStringsSep "," ( - lib.mapAttrsToList ( - name: value: - if isStrInt name - then "[${name}] = ${helpers.toLuaObject value}" - else "[${helpers.toLuaObject name}] = ${helpers.toLuaObject value}" - ) - cfg.countChars - )) - + "}"; + sign_priority = cfg.signPriority; + show_deleted = cfg.showDeleted; + diff_opts = + if cfg.diffOpts == null + then null + else { + inherit (cfg.diffOpts) algorithm internal vertical linematch; + indent_heuristic = cfg.diffOpts.indentHeuristic; + }; + count_chars = + let + isStrInt = s: (builtins.match "[0-9]+" s) != null; + in + { + __raw = + "{" + + (concatStringsSep "," ( + lib.mapAttrsToList + ( + name: value: + if isStrInt name + then "[${name}] = ${helpers.toLuaObject value}" + else "[${helpers.toLuaObject name}] = ${helpers.toLuaObject value}" + ) + cfg.countChars + )) + + "}"; + }; + status_formatter = { __raw = cfg.statusFormatter.function; }; + max_file_length = cfg.maxFileLength; + preview_config = cfg.previewConfig; + attach_to_untracked = cfg.attachToUntracked; + update_debounce = cfg.updateDebounce; + current_line_blame = cfg.currentLineBlame; + current_line_blame_opts = + let + cfgCl = cfg.currentLineBlameOpts; + in + { + inherit (cfgCl) delay; + virt_text = cfgCl.virtText; + virt_text_pos = cfgCl.virtTextPos; + ignore_whitespace = cfgCl.ignoreWhitespace; + virt_text_priority = cfgCl.virtTextPriority; + }; + current_line_blame_formatter = luaFnOrStrToObj cfg.currentLineBlameFormatter.normal; + current_line_blame_formatter_nc = luaFnOrStrToObj cfg.currentLineBlameFormatter.nonCommitted; + word_diff = cfg.wordDiff; + debug_mode = cfg.debugMode; }; - status_formatter = {__raw = cfg.statusFormatter.function;}; - max_file_length = cfg.maxFileLength; - preview_config = cfg.previewConfig; - attach_to_untracked = cfg.attachToUntracked; - update_debounce = cfg.updateDebounce; - current_line_blame = cfg.currentLineBlame; - current_line_blame_opts = let - cfgCl = cfg.currentLineBlameOpts; - in { - inherit (cfgCl) delay; - virt_text = cfgCl.virtText; - virt_text_pos = cfgCl.virtTextPos; - ignore_whitespace = cfgCl.ignoreWhitespace; - virt_text_priority = cfgCl.virtTextPriority; - }; - current_line_blame_formatter = luaFnOrStrToObj cfg.currentLineBlameFormatter.normal; - current_line_blame_formatter_nc = luaFnOrStrToObj cfg.currentLineBlameFormatter.nonCommitted; - word_diff = cfg.wordDiff; - debug_mode = cfg.debugMode; - }; - in '' - require('gitsigns').setup(${helpers.toLuaObject setupOptions}) - ''; + in + '' + require('gitsigns').setup(${helpers.toLuaObject setupOptions}) + ''; }; } diff --git a/plugins/git/neogit.nix b/plugins/git/neogit.nix index 29aec256..af69c42d 100644 --- a/plugins/git/neogit.nix +++ b/plugins/git/neogit.nix @@ -16,7 +16,7 @@ in { options = { plugins.neogit = { - enable = mkEnableOption "Enable neogit"; + enable = mkEnableOption "neogit"; package = mkOption { type = types.package; diff --git a/plugins/helpers.nix b/plugins/helpers.nix index 9d501be8..a6d36262 100644 --- a/plugins/helpers.nix +++ b/plugins/helpers.nix @@ -1 +1,2 @@ args: import ../lib/helpers.nix args + diff --git a/plugins/languages/plantuml-syntax.nix b/plugins/languages/plantuml-syntax.nix index a4fef1de..8083702d 100644 --- a/plugins/languages/plantuml-syntax.nix +++ b/plugins/languages/plantuml-syntax.nix @@ -1,12 +1,11 @@ -{ - pkgs, - lib, - config, - ... +{ pkgs +, lib +, config +, ... }: with lib; { options.plugins.plantuml-syntax = { - enable = mkEnableOption "Enable plantuml syntax support"; + enable = mkEnableOption "plantuml syntax support"; package = mkOption { type = types.package; @@ -26,9 +25,10 @@ with lib; { }; }; - config = let - cfg = config.plugins.plantuml-syntax; - in + config = + let + cfg = config.plugins.plantuml-syntax; + in mkIf cfg.enable { extraPlugins = [ cfg.package ]; diff --git a/plugins/languages/rust.nix b/plugins/languages/rust.nix new file mode 100644 index 00000000..8229950b --- /dev/null +++ b/plugins/languages/rust.nix @@ -0,0 +1,229 @@ +{ pkgs +, config +, lib +, helpers +, ... +}: +with lib; { + options.plugins.rust-tools = + let + mkNullableOptionWithDefault = + { type + , description + , default + , + }: + mkOption { + type = types.nullOr type; + default = null; + description = '' + ${description} + + default: `${default}` + ''; + }; + + mkNullableBoolDefault = default: description: + mkNullableOptionWithDefault { + inherit description; + type = types.bool; + default = toString default; + }; + + mkNullableStrDefault = default: description: + mkNullableOptionWithDefault { + inherit description; + type = types.str; + default = ''"${default}"''; + }; + + mkNullableIntDefault = default: description: + mkNullableOptionWithDefault { + inherit description; + type = types.int; + default = toString default; + }; + in + { + enable = mkEnableOption "rust tools plugins"; + package = mkOption { + type = types.package; + default = pkgs.vimPlugins.rust-tools-nvim; + description = "Package to use for rust-tools"; + }; + + executor = mkNullableOptionWithDefault { + type = types.enum [ "termopen" "quickfix" ]; + default = ''"termopen"''; + description = "how to execute terminal commands"; + }; + + onIntialized = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + Callback to execute once rust-analyzer is done initializing the workspace + The callback receives one parameter indicating the `health` of the server: + "ok" | "warning" | "error" + ''; + }; + + reloadWorkspaceFromCargoToml = mkNullableBoolDefault true '' + Automatically call RustReloadWorkspace when writing to a Cargo.toml file. + ''; + + inlayHints = { + auto = mkNullableBoolDefault true "automatically set inlay hints (type hints)"; + + onlyCurrentLine = mkNullableBoolDefault false "Only show for current line"; + + showParameterHints = + mkNullableBoolDefault true + "whether to show parameter hints with the inlay hints or not"; + + parameterHintsPrefix = mkNullableStrDefault "<- " "prefix for parameter hints"; + otherHintsPrefix = mkNullableStrDefault "=> " "prefix for all the other hints (type, chaining)"; + + maxLenAlign = + mkNullableBoolDefault false + "whether to align to the length of the longest line in the file"; + + maxLenAlignPadding = mkNullableIntDefault 1 "padding from the left if max_len_align is true"; + + rightAlign = mkNullableBoolDefault false "whether to align to the extreme right or not"; + rightAlignPadding = mkNullableIntDefault 7 "padding from the right if right_align is true"; + + highlight = mkNullableStrDefault "Comment" "The color of the hints"; + }; + + hoverActions = { + border = mkOption { + type = types.nullOr types.anything; + default = null; + description = '' + the border that is used for the hover window. see vim.api.nvim_open_win() + ''; + }; + + maxWidth = mkOption { + type = types.nullOr types.int; + default = null; + description = "Maximal width of the hover window. Nil means no max."; + }; + maxHeight = mkOption { + type = types.nullOr types.int; + default = null; + description = "Maximal height of the hover window. Nil means no max."; + }; + + autoFocus = mkNullableBoolDefault false "whether the hover action window gets automatically focused"; + }; + + crateGraph = { + backend = mkNullableStrDefault "x11" '' + Backend used for displaying the graph + see: https://graphviz.org/docs/outputs/ + ''; + + output = mkOption { + type = types.nullOr types.str; + default = null; + description = "where to store the output, nil for no output stored"; + }; + + full = mkNullableBoolDefault true '' + true for all crates.io and external crates, false only the local crates + ''; + + enabledGraphvizBackends = mkOption { + type = types.nullOr (types.listOf types.str); + default = null; + description = '' + List of backends found on: https://graphviz.org/docs/outputs/ + Is used for input validation and autocompletion + ''; + }; + }; + + server = + { + standalone = mkNullableBoolDefault true '' + standalone file support + setting it to false may improve startup time + ''; + } + // (import ../nvim-lsp/rust-analyzer-config.nix lib); + }; + config = + let + cfg = config.plugins.rust-tools; + in + mkIf cfg.enable { + extraPlugins = with pkgs.vimPlugins; [ nvim-lspconfig cfg.package ]; + + plugins.lsp.postConfig = + let + setupOptions = { + tools = { + executor = + if cfg.executor != null + then { __raw = ''require("rust-tools.executors").${cfg.executor}''; } + else null; + + on_initialized = + if cfg.onIntialized != null + then { __raw = cfg.onIntialized; } + else null; + + reload_workspace_from_cargo_toml = cfg.reloadWorkspaceFromCargoToml; + inlay_hints = + let + cfgIH = cfg.inlayHints; + in + { + auto = cfgIH.auto; + only_current_line = cfgIH.onlyCurrentLine; + show_parameter_hints = cfgIH.showParameterHints; + parameter_hints_prefix = cfgIH.parameterHintsPrefix; + other_hints_prefix = cfgIH.otherHintsPrefix; + max_len_align = cfgIH.maxLenAlign; + max_len_align_padding = cfgIH.maxLenAlignPadding; + right_align = cfgIH.rightAlign; + right_align_padding = cfgIH.rightAlignPadding; + highlight = cfgIH.highlight; + }; + + hover_actions = + let + cfgHA = cfg.hoverActions; + in + { + border = cfgHA.border; + max_width = cfgHA.maxWidth; + max_height = cfgHA.maxHeight; + auto_focus = cfgHA.autoFocus; + }; + + crate_graph = + let + cfgCG = cfg.crateGraph; + in + { + backend = cfgCG.backend; + output = cfgCG.output; + full = cfgCG.full; + enabled_graphviz_backends = cfgCG.enabledGraphvizBackends; + }; + }; + server = { + standalone = cfg.server.standalone; + settings.rust-analyzer = lib.filterAttrs (n: v: n != "standalone") cfg.server; + on_attach = { __raw = "__lspOnAttach"; }; + }; + }; + in + '' + require('rust-tools').setup(${helpers.toLuaObject setupOptions}) + ''; + }; +} diff --git a/plugins/languages/treesitter-context.nix b/plugins/languages/treesitter-context.nix index 00edf647..5c1f48e5 100644 --- a/plugins/languages/treesitter-context.nix +++ b/plugins/languages/treesitter-context.nix @@ -5,7 +5,7 @@ }: with lib; { options.plugins.treesitter-context = { - enable = mkEnableOption "Enable nvim-treesitter-context"; + enable = mkEnableOption "nvim-treesitter-context"; package = mkOption { type = types.package; diff --git a/plugins/languages/treesitter-refactor.nix b/plugins/languages/treesitter-refactor.nix index 94bd986e..d0791808 100644 --- a/plugins/languages/treesitter-refactor.nix +++ b/plugins/languages/treesitter-refactor.nix @@ -15,7 +15,7 @@ with lib; { { enable = mkEnableOption - "Enable treesitter-refactor (requires plugins.treesitter.enable to be true)"; + "treesitter-refactor (requires plugins.treesitter.enable to be true)"; package = mkOption { type = types.package; @@ -39,7 +39,7 @@ with lib; { }; highlightCurrentScope = { inherit disable; - enable = mkEnableOption "Highlights the block from the current scope where the cursor is."; + enable = mkEnableOption "highlights the block from the current scope where the cursor is."; }; smartRename = { inherit disable; diff --git a/plugins/languages/treesitter.nix b/plugins/languages/treesitter.nix index eb3f13c6..5771d656 100644 --- a/plugins/languages/treesitter.nix +++ b/plugins/languages/treesitter.nix @@ -7,7 +7,7 @@ in { options = { plugins.treesitter = { - enable = mkEnableOption "Enable tree-sitter syntax highlighting"; + enable = mkEnableOption "tree-sitter syntax highlighting"; package = mkOption { type = types.package; @@ -66,7 +66,7 @@ in }; in { - enable = mkEnableOption "Incremental selection based on the named nodes from the grammar"; + enable = mkEnableOption "incremental selection based on the named nodes from the grammar"; keymaps = { initSelection = keymap "gnn"; nodeIncremental = keymap "grn"; @@ -75,13 +75,13 @@ in }; }; - indent = mkEnableOption "Enable tree-sitter based indentation"; + indent = mkEnableOption "tree-sitter based indentation"; - folding = mkEnableOption "Enable tree-sitter based folding"; + folding = mkEnableOption "tree-sitter based folding"; grammarPackages = mkOption { type = with types; listOf package; - default = pkgs.tree-sitter.allGrammars; + default = cfg.package.passthru.allGrammars; description = "Grammar packages to install"; }; diff --git a/plugins/null-ls/default.nix b/plugins/null-ls/default.nix index 0f9f0688..e30e0fac 100644 --- a/plugins/null-ls/default.nix +++ b/plugins/null-ls/default.nix @@ -10,7 +10,7 @@ in ]; options.plugins.null-ls = { - enable = mkEnableOption "Enable null-ls"; + enable = mkEnableOption "null-ls"; package = mkOption { type = types.package; diff --git a/plugins/null-ls/helpers.nix b/plugins/null-ls/helpers.nix index 3dc5d6cd..2f6c4fc7 100644 --- a/plugins/null-ls/helpers.nix +++ b/plugins/null-ls/helpers.nix @@ -3,7 +3,7 @@ mkServer = { name , sourceType - , description ? "Enable ${name} source, for null-ls." + , description ? "${name} source, for null-ls." , package ? null , extraPackages ? [ ] , ... diff --git a/plugins/null-ls/servers.nix b/plugins/null-ls/servers.nix index 0a6610f1..02892514 100644 --- a/plugins/null-ls/servers.nix +++ b/plugins/null-ls/servers.nix @@ -4,6 +4,9 @@ let serverData = { code_actions = { gitsigns = { }; + shellcheck = { + package = pkgs.shellcheck; + }; }; completion = { }; diagnostics = { @@ -13,6 +16,12 @@ let shellcheck = { package = pkgs.shellcheck; }; + cppcheck = { + package = pkgs.cppcheck; + }; + gitlint = { + package = pkgs.gitlint; + }; }; formatting = { phpcbf = { @@ -36,6 +45,18 @@ let fnlfmt = { package = pkgs.fnlfmt; }; + stylua = { + package = pkgs.stylua; + }; + cbfmt = { + package = pkgs.cbfmt; + }; + shfmt = { + package = pkgs.shfmt; + }; + taplo = { + package = pkgs.taplo; + }; }; }; # Format the servers to be an array of attrs like the following example diff --git a/plugins/nvim-lsp/basic-servers.nix b/plugins/nvim-lsp/basic-servers.nix index 1f92dc7c..40211dd9 100644 --- a/plugins/nvim-lsp/basic-servers.nix +++ b/plugins/nvim-lsp/basic-servers.nix @@ -3,6 +3,12 @@ with lib; let helpers = import ./helpers.nix args; servers = [ + { + name = "astro"; + description = "Enable astrols, for Astro"; + package = pkgs.nodePackages."@astrojs/language-server"; + cmd = cfg: [ "${cfg.package}/bin/astro-ls" "--stdio" ]; + } { name = "bashls"; description = "Enable bashls, for bash."; @@ -23,12 +29,12 @@ let name = "dartls"; description = "Enable dart language-server, for dart"; package = pkgs.dart; - extraOptions = { + settingsOptions = { analysisExcludedFolders = mkOption { type = types.nullOr (types.listOf types.str); default = null; description = '' - An array of paths (absolute or relative to each workspace folder) that should be + An array of paths (absolute or relative to each workspace folder) that should be excluded from analysis. ''; }; @@ -36,7 +42,7 @@ let type = types.nullOr types.bool; default = null; description = '' - When set to false, prevents registration (or unregisters) the SDK formatter. When set + When set to false, prevents registration (or unregisters) the SDK formatter. When set to true or not supplied, will register/reregister the SDK formatter ''; }; @@ -44,7 +50,7 @@ let type = types.nullOr types.int; default = null; description = '' - The number of characters the formatter should wrap code at. If unspecified, code will + The number of characters the formatter should wrap code at. If unspecified, code will be wrapped at 80 characters. ''; }; @@ -59,7 +65,7 @@ let type = types.nullOr types.bool; default = true; description = '' - Whether to generate diagnostics for TODO comments. If unspecified, diagnostics will not + Whether to generate diagnostics for TODO comments. If unspecified, diagnostics will not be generated. ''; }; @@ -103,7 +109,7 @@ let type = types.nullOr types.bool; default = null; description = '' - Whether to include symbols from dependencies and Dart/Flutter SDKs in Workspace Symbol + Whether to include symbols from dependencies and Dart/Flutter SDKs in Workspace Symbol results. If not set, defaults to true. ''; }; @@ -152,7 +158,7 @@ let name = "nil_ls"; description = "Enable nil, for Nix"; package = pkgs.nil; - extraOptions = { + settingsOptions = { formatting.command = mkOption { type = types.nullOr (types.listOf types.str); default = null; @@ -197,6 +203,9 @@ let name = "rust-analyzer"; description = "Enable rust-analyzer, for Rust."; serverName = "rust_analyzer"; + + settingsOptions = import ./rust-analyzer-config.nix lib; + settings = cfg: { rust-analyzer = cfg; }; } { name = "sumneko-lua"; diff --git a/plugins/nvim-lsp/default.nix b/plugins/nvim-lsp/default.nix index f2f74593..8b50570c 100644 --- a/plugins/nvim-lsp/default.nix +++ b/plugins/nvim-lsp/default.nix @@ -11,7 +11,7 @@ in options = { plugins.lsp = { - enable = mkEnableOption "Enable neovim's built-in LSP"; + enable = mkEnableOption "neovim's built-in LSP"; enabledServers = mkOption { type = with types; listOf (oneOf [ @@ -51,6 +51,12 @@ in description = "Code to be run before loading the LSP. Useful for requiring plugins"; default = ""; }; + + postConfig = mkOption { + type = types.lines; + description = "Code to be run after loading the LSP. This is an internal option"; + default = ""; + }; }; }; @@ -92,6 +98,8 @@ in require('lspconfig')[server.name].setup(options) end end + + ${cfg.postConfig} end -- }}} ''; diff --git a/plugins/nvim-lsp/helpers.nix b/plugins/nvim-lsp/helpers.nix index 42e7dcfd..540369b7 100644 --- a/plugins/nvim-lsp/helpers.nix +++ b/plugins/nvim-lsp/helpers.nix @@ -9,7 +9,7 @@ , extraPackages ? { } , cmd ? (cfg: null) , settings ? (cfg: { }) - , extraOptions ? { } + , settingsOptions ? { } , ... }: # returns a module @@ -30,7 +30,8 @@ options = { plugins.lsp.servers.${name} = { enable = mkEnableOption description; - } // packageOption // extraOptions; + settings = settingsOptions; + } // packageOption; }; config = mkIf cfg.enable @@ -42,7 +43,7 @@ name = serverName; extraOptions = { cmd = cmd cfg; - settings = settings cfg; + settings = settings cfg.settings; }; }]; }; diff --git a/plugins/nvim-lsp/lspsaga.nix b/plugins/nvim-lsp/lspsaga.nix index 055a4b30..f5bf6ecf 100644 --- a/plugins/nvim-lsp/lspsaga.nix +++ b/plugins/nvim-lsp/lspsaga.nix @@ -7,7 +7,7 @@ in { options = { plugins.lspsaga = { - enable = mkEnableOption "Enable lspsava.nvim"; + enable = mkEnableOption "lspsaga.nvim"; package = mkOption { type = types.package; @@ -111,27 +111,29 @@ in description = "Maximum finder preview lines"; }; - keys = let - defaultKeyOpt = desc: mkOption { - description = desc; - type = types.nullOr types.str; - default = null; - }; - in { - finderAction = { - open = defaultKeyOpt "Open from finder"; - vsplit = defaultKeyOpt "Vertical split in finder"; - split = defaultKeyOpt "Horizontal split in finder"; - quit = defaultKeyOpt "Quit finder"; - scrollDown = defaultKeyOpt "Scroll down finder"; - scrollUp = defaultKeyOpt "Scroll up finder"; - }; + keys = + let + defaultKeyOpt = desc: mkOption { + description = desc; + type = types.nullOr types.str; + default = null; + }; + in + { + finderAction = { + open = defaultKeyOpt "Open from finder"; + vsplit = defaultKeyOpt "Vertical split in finder"; + split = defaultKeyOpt "Horizontal split in finder"; + quit = defaultKeyOpt "Quit finder"; + scrollDown = defaultKeyOpt "Scroll down finder"; + scrollUp = defaultKeyOpt "Scroll up finder"; + }; - codeAction = { - quit = defaultKeyOpt "Quit code actions menu"; - exec = defaultKeyOpt "Execute code action"; + codeAction = { + quit = defaultKeyOpt "Quit code actions menu"; + exec = defaultKeyOpt "Execute code action"; + }; }; - }; borderStyle = mkOption { type = types.nullOr (types.enum [ "thin" "rounded" "thick" ]); @@ -147,66 +149,76 @@ in }; }; - config = let - notDefault = default: opt: if (opt != default) then opt else null; - notEmpty = opt: if ((filterAttrs (_: v: v != null) opt) != {}) then opt else null; - notNull = opt: opt; - lspsagaConfig = { - use_saga_diagnostic_sign = notDefault true cfg.signs.use; - error_sign = notNull cfg.signs.error; - warn_sign = notNull cfg.signs.warning; - hint_sign = notNull cfg.signs.hint; - infor_sign = notNull cfg.signs.info; + config = + let + notDefault = default: opt: if (opt != default) then opt else null; + notEmpty = opt: if ((filterAttrs (_: v: v != null) opt) != { }) then opt else null; + notNull = opt: opt; + lspsagaConfig = { + use_saga_diagnostic_sign = notDefault true cfg.signs.use; + error_sign = notNull cfg.signs.error; + warn_sign = notNull cfg.signs.warning; + hint_sign = notNull cfg.signs.hint; + infor_sign = notNull cfg.signs.info; - # TODO Fix this! - # error_header = notNull cfg.headers.error; - # warn_header = notNull cfg.headers.warning; - # hint_header = notNull cfg.headers.hint; - # infor_header = notNull cfg.headers.info; + # TODO Fix this! + # error_header = notNull cfg.headers.error; + # warn_header = notNull cfg.headers.warning; + # hint_header = notNull cfg.headers.hint; + # infor_header = notNull cfg.headers.info; - max_diag_msg_width = notNull cfg.maxDialogWidth; + max_diag_msg_width = notNull cfg.maxDialogWidth; - code_action_icon = notNull cfg.icons.codeAction; - finder_definition_icon = notNull cfg.icons.findDefinition; - finder_reference_icon = notNull cfg.icons.findReference; - definition_preview_icon = notNull cfg.icons.definitionPreview; + code_action_icon = notNull cfg.icons.codeAction; + finder_definition_icon = notNull cfg.icons.findDefinition; + finder_reference_icon = notNull cfg.icons.findReference; + definition_preview_icon = notNull cfg.icons.definitionPreview; - max_finder_preview_lines = notNull cfg.maxFinderPreviewLines; + max_finder_preview_lines = notNull cfg.maxFinderPreviewLines; - rename_prompt_prefix = notNull cfg.renamePromptPrefix; + rename_prompt_prefix = notNull cfg.renamePromptPrefix; - border_style = let - borderStyle = if cfg.borderStyle == "thin" then 1 - else if cfg.borderStyle == "rounded" then 2 - else if cfg.borderStyle == "thick" then 3 - else null; - in borderStyle; + border_style = + let + borderStyle = + if cfg.borderStyle == "thin" then 1 + else if cfg.borderStyle == "rounded" then 2 + else if cfg.borderStyle == "thick" then 3 + else null; + in + borderStyle; - finder_action_keys = let - keys = { - open = notNull cfg.keys.finderAction.open; - vsplit = notNull cfg.keys.finderAction.vsplit; - split = notNull cfg.keys.finderAction.split; - quit = notNull cfg.keys.finderAction.quit; - scroll_down = notNull cfg.keys.finderAction.scrollDown; - scroll_up = notNull cfg.keys.finderAction.scrollUp; - }; - in notEmpty keys; + finder_action_keys = + let + keys = { + open = notNull cfg.keys.finderAction.open; + vsplit = notNull cfg.keys.finderAction.vsplit; + split = notNull cfg.keys.finderAction.split; + quit = notNull cfg.keys.finderAction.quit; + scroll_down = notNull cfg.keys.finderAction.scrollDown; + scroll_up = notNull cfg.keys.finderAction.scrollUp; + }; + in + notEmpty keys; - code_action_keys = let - keys = { - quit = notNull cfg.keys.codeAction.quit; - exec = notNull cfg.keys.codeAction.exec; - }; - in notEmpty keys; + code_action_keys = + let + keys = { + quit = notNull cfg.keys.codeAction.quit; + exec = notNull cfg.keys.codeAction.exec; + }; + in + notEmpty keys; + }; + in + mkIf cfg.enable { + + extraPlugins = [ cfg.package ]; + + extraConfigLua = '' + local saga = require 'lspsaga' + + saga.init_lsp_saga(${helpers.toLuaObject lspsagaConfig}) + ''; }; - in mkIf cfg.enable { - extraPlugins = [ cfg.package ]; - - extraConfigLua = '' - local saga = require 'lspsaga' - - saga.init_lsp_saga(${helpers.toLuaObject lspsagaConfig}) - ''; - }; } diff --git a/plugins/nvim-lsp/nvim-lightbulb.nix b/plugins/nvim-lsp/nvim-lightbulb.nix new file mode 100644 index 00000000..67ec2d08 --- /dev/null +++ b/plugins/nvim-lsp/nvim-lightbulb.nix @@ -0,0 +1,95 @@ +{ pkgs +, lib +, config +, ... +}: +let + helpers = import ../helpers.nix { inherit lib; }; +in +with lib; { + options.plugins.nvim-lightbulb = { + enable = mkEnableOption "nvim-lightbulb, showing available code actions"; + + package = mkOption { + type = types.package; + default = pkgs.vimPlugins.nvim-lightbulb; + description = "Plugin to use for nvim-lightbulb"; + }; + + ignore = helpers.defaultNullOpts.mkNullable (types.listOf types.str) "[]" '' + LSP client names to ignore + ''; + + sign = { + enabled = helpers.defaultNullOpts.mkBool true ""; + priority = helpers.defaultNullOpts.mkInt 10 ""; + }; + + float = { + enabled = helpers.defaultNullOpts.mkBool false ""; + + text = helpers.defaultNullOpts.mkStr "💡" "Text to show in the popup float"; + + winOpts = helpers.defaultNullOpts.mkNullable (types.attrsOf types.anything) "{}" '' + Options for the floating window (see |vim.lsp.util.open_floating_preview| for more information) + ''; + }; + + virtualText = { + enabled = helpers.defaultNullOpts.mkBool false ""; + + text = helpers.defaultNullOpts.mkStr "💡" "Text to show at virtual text"; + + hlMode = helpers.defaultNullOpts.mkStr "replace" '' + highlight mode to use for virtual text (replace, combine, blend), see + :help nvim_buf_set_extmark() for reference + ''; + }; + + statusText = { + enabled = helpers.defaultNullOpts.mkBool false ""; + + text = helpers.defaultNullOpts.mkStr "💡" "Text to provide when code actions are available"; + + textUnavailable = helpers.defaultNullOpts.mkStr "" '' + Text to provide when no actions are available + ''; + }; + + autocmd = { + enabled = helpers.defaultNullOpts.mkBool false ""; + + pattern = helpers.defaultNullOpts.mkNullable (types.listOf types.str) ''["*"]'' ""; + + events = + helpers.defaultNullOpts.mkNullable (types.listOf types.str) + ''["CursorHold" "CursorHoldI"]'' ""; + }; + }; + + config = + let + cfg = config.plugins.nvim-lightbulb; + setupOptions = { + inherit (cfg) ignore sign autocmd; + float = { + inherit (cfg.float) enabled text; + win_opts = cfg.float.winOpts; + }; + virtual_text = { + inherit (cfg.virtualText) enabled text; + hl_mode = cfg.virtualText.hlMode; + }; + status_text = { + inherit (cfg.statusText) enabled text; + text_unavailable = cfg.statusText.textUnavailable; + }; + }; + in + mkIf cfg.enable { + extraPlugins = [ cfg.package ]; + extraConfigLua = '' + require("nvim-lightbulb").setup(${helpers.toLuaObject setupOptions}) + ''; + }; +} diff --git a/plugins/nvim-lsp/rust-analyzer-config.nix b/plugins/nvim-lsp/rust-analyzer-config.nix new file mode 100644 index 00000000..3bf0ee9c --- /dev/null +++ b/plugins/nvim-lsp/rust-analyzer-config.nix @@ -0,0 +1,1560 @@ +# THIS FILE IS AUTOGENERATED DO NOT EDIT +lib: with lib; { + "assist" = { + "expressionFillDefault" = mkOption { + type = types.nullOr (types.enum [ "todo" "default" ]); + default = null; + description = '' + Placeholder expression to use for missing expressions in assists. + + default value is: + ```nix + "todo" + ``` + ''; + }; + }; + "cachePriming" = { + "enable" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Warm up caches on project load. + + default value is: + ```nix + true + ``` + ''; + }; + "numThreads" = mkOption { + type = types.nullOr (types.numbers.between 0 255); + default = null; + description = '' + How many worker threads to handle priming caches. The default `0` means to pick automatically. + + default value is: + ```nix + 0 + ``` + ''; + }; + }; + "cargo" = { + "autoreload" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Automatically refresh project info via `cargo metadata` on + `Cargo.toml` or `.cargo/config.toml` changes. + + default value is: + ```nix + true + ``` + ''; + }; + "buildScripts" = { + "enable" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Run build scripts (`build.rs`) for more precise code analysis. + + default value is: + ```nix + true + ``` + ''; + }; + "overrideCommand" = mkOption { + type = types.nullOr (types.nullOr (types.listOf (types.str))); + default = null; + description = '' + Override the command rust-analyzer uses to run build scripts and + build procedural macros. The command is required to output json + and should therefore include `--message-format=json` or a similar + option. + + By default, a cargo invocation will be constructed for the configured + targets and features, with the following base command line: + + ```bash + cargo check --quiet --workspace --message-format=json --all-targets + ``` + . + + default value is: + ```nix + null + ``` + ''; + }; + "useRustcWrapper" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Use `RUSTC_WRAPPER=rust-analyzer` when running build scripts to + avoid checking unnecessary things. + + default value is: + ```nix + true + ``` + ''; + }; + }; + "features" = mkOption { + type = types.nullOr (types.oneOf [ (types.enum [ "all" ]) (types.listOf (types.str)) ]); + default = null; + description = '' + List of features to activate. + + Set this to `"all"` to pass `--all-features` to cargo. + + default value is: + ```nix + [] + ``` + ''; + }; + "noDefaultFeatures" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Whether to pass `--no-default-features` to cargo. + + default value is: + ```nix + false + ``` + ''; + }; + "noSysroot" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Internal config for debugging, disables loading of sysroot crates. + + default value is: + ```nix + false + ``` + ''; + }; + "target" = mkOption { + type = types.nullOr (types.nullOr (types.str)); + default = null; + description = '' + Compilation target override (target triple). + + default value is: + ```nix + null + ``` + ''; + }; + "unsetTest" = mkOption { + type = types.nullOr (types.listOf (types.str)); + default = null; + description = '' + Unsets `#[cfg(test)]` for the specified crates. + + default value is: + ```nix + ["core"] + ``` + ''; + }; + }; + "checkOnSave" = { + "allTargets" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Check all targets and tests (`--all-targets`). + + default value is: + ```nix + true + ``` + ''; + }; + "command" = mkOption { + type = types.nullOr (types.str); + default = null; + description = '' + Cargo command to use for `cargo check`. + + default value is: + ```nix + "check" + ``` + ''; + }; + "enable" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Run specified `cargo check` command for diagnostics on save. + + default value is: + ```nix + true + ``` + ''; + }; + "extraArgs" = mkOption { + type = types.nullOr (types.listOf (types.str)); + default = null; + description = '' + Extra arguments for `cargo check`. + + default value is: + ```nix + [] + ``` + ''; + }; + "features" = mkOption { + type = types.nullOr (types.nullOr (types.oneOf [ (types.enum [ "all" ]) (types.listOf (types.str)) ])); + default = null; + description = '' + List of features to activate. Defaults to + `#rust-analyzer.cargo.features#`. + + Set to `"all"` to pass `--all-features` to Cargo. + + default value is: + ```nix + null + ``` + ''; + }; + "noDefaultFeatures" = mkOption { + type = types.nullOr (types.nullOr (types.bool)); + default = null; + description = '' + Whether to pass `--no-default-features` to Cargo. Defaults to + `#rust-analyzer.cargo.noDefaultFeatures#`. + + default value is: + ```nix + null + ``` + ''; + }; + "overrideCommand" = mkOption { + type = types.nullOr (types.nullOr (types.listOf (types.str))); + default = null; + description = '' + Override the command rust-analyzer uses instead of `cargo check` for + diagnostics on save. The command is required to output json and + should therefor include `--message-format=json` or a similar option. + + If you're changing this because you're using some tool wrapping + Cargo, you might also want to change + `#rust-analyzer.cargo.buildScripts.overrideCommand#`. + + If there are multiple linked projects, this command is invoked for + each of them, with the working directory being the project root + (i.e., the folder containing the `Cargo.toml`). + + An example command would be: + + ```bash + cargo check --workspace --message-format=json --all-targets + ``` + . + + default value is: + ```nix + null + ``` + ''; + }; + "target" = mkOption { + type = types.nullOr (types.nullOr (types.str)); + default = null; + description = '' + Check for a specific target. Defaults to + `#rust-analyzer.cargo.target#`. + + default value is: + ```nix + null + ``` + ''; + }; + }; + "completion" = { + "autoimport" = { + "enable" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Toggles the additional completions that automatically add imports when completed. + Note that your client must specify the `additionalTextEdits` LSP client capability to truly have this feature enabled. + + default value is: + ```nix + true + ``` + ''; + }; + }; + "autoself" = { + "enable" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Toggles the additional completions that automatically show method calls and field accesses + with `self` prefixed to them when inside a method. + + default value is: + ```nix + true + ``` + ''; + }; + }; + "callable" = { + "snippets" = mkOption { + type = types.nullOr (types.enum [ "fill_arguments" "add_parentheses" "none" ]); + default = null; + description = '' + Whether to add parenthesis and argument snippets when completing function. + + default value is: + ```nix + "fill_arguments" + ``` + ''; + }; + }; + "postfix" = { + "enable" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Whether to show postfix snippets like `dbg`, `if`, `not`, etc. + + default value is: + ```nix + true + ``` + ''; + }; + }; + "privateEditable" = { + "enable" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Enables completions of private items and fields that are defined in the current workspace even if they are not visible at the current position. + + default value is: + ```nix + false + ``` + ''; + }; + }; + "snippets" = { + "custom" = mkOption { + type = types.nullOr (types.attrsOf types.anything); + default = null; + description = '' + Custom completion snippets. + + default value is: + ```nix + {"Arc::new" = {"postfix" = "arc"; + "body" = "Arc::new($\{receiver})"; + "requires" = "std::sync::Arc"; + "description" = "Put the expression into an `Arc`"; + "scope" = "expr"; + }; + "Rc::new" = {"postfix" = "rc"; + "body" = "Rc::new($\{receiver})"; + "requires" = "std::rc::Rc"; + "description" = "Put the expression into an `Rc`"; + "scope" = "expr"; + }; + "Box::pin" = {"postfix" = "pinbox"; + "body" = "Box::pin($\{receiver})"; + "requires" = "std::boxed::Box"; + "description" = "Put the expression into a pinned `Box`"; + "scope" = "expr"; + }; + "Ok" = {"postfix" = "ok"; + "body" = "Ok($\{receiver})"; + "description" = "Wrap the expression in a `Result::Ok`"; + "scope" = "expr"; + }; + "Err" = {"postfix" = "err"; + "body" = "Err($\{receiver})"; + "description" = "Wrap the expression in a `Result::Err`"; + "scope" = "expr"; + }; + "Some" = {"postfix" = "some"; + "body" = "Some($\{receiver})"; + "description" = "Wrap the expression in an `Option::Some`"; + "scope" = "expr"; + }; + } + ``` + ''; + }; + }; + }; + "diagnostics" = { + "disabled" = mkOption { + type = types.nullOr (types.listOf (types.str)); + default = null; + description = '' + List of rust-analyzer diagnostics to disable. + + default value is: + ```nix + [] + ``` + ''; + }; + "enable" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Whether to show native rust-analyzer diagnostics. + + default value is: + ```nix + true + ``` + ''; + }; + "experimental" = { + "enable" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Whether to show experimental rust-analyzer diagnostics that might + have more false positives than usual. + + default value is: + ```nix + false + ``` + ''; + }; + }; + "remapPrefix" = mkOption { + type = types.nullOr (types.attrsOf types.anything); + default = null; + description = '' + Map of prefixes to be substituted when parsing diagnostic file paths. + This should be the reverse mapping of what is passed to `rustc` as `--remap-path-prefix`. + + default value is: + ```nix + {} + ``` + ''; + }; + "warningsAsHint" = mkOption { + type = types.nullOr (types.listOf (types.str)); + default = null; + description = '' + List of warnings that should be displayed with hint severity. + + The warnings will be indicated by faded text or three dots in code + and will not show up in the `Problems Panel`. + + default value is: + ```nix + [] + ``` + ''; + }; + "warningsAsInfo" = mkOption { + type = types.nullOr (types.listOf (types.str)); + default = null; + description = '' + List of warnings that should be displayed with info severity. + + The warnings will be indicated by a blue squiggly underline in code + and a blue icon in the `Problems Panel`. + + default value is: + ```nix + [] + ``` + ''; + }; + }; + "files" = { + "excludeDirs" = mkOption { + type = types.nullOr (types.listOf (types.str)); + default = null; + description = '' + These directories will be ignored by rust-analyzer. They are + relative to the workspace root, and globs are not supported. You may + also need to add the folders to Code's `files.watcherExclude`. + + default value is: + ```nix + [] + ``` + ''; + }; + "watcher" = mkOption { + type = types.nullOr (types.enum [ "client" "server" ]); + default = null; + description = '' + Controls file watching implementation. + + default value is: + ```nix + "client" + ``` + ''; + }; + }; + "highlightRelated" = { + "breakPoints" = { + "enable" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Enables highlighting of related references while the cursor is on `break`, `loop`, `while`, or `for` keywords. + + default value is: + ```nix + true + ``` + ''; + }; + }; + "exitPoints" = { + "enable" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Enables highlighting of all exit points while the cursor is on any `return`, `?`, `fn`, or return type arrow (`->`). + + default value is: + ```nix + true + ``` + ''; + }; + }; + "references" = { + "enable" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Enables highlighting of related references while the cursor is on any identifier. + + default value is: + ```nix + true + ``` + ''; + }; + }; + "yieldPoints" = { + "enable" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Enables highlighting of all break points for a loop or block context while the cursor is on any `async` or `await` keywords. + + default value is: + ```nix + true + ``` + ''; + }; + }; + }; + "hover" = { + "actions" = { + "debug" = { + "enable" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Whether to show `Debug` action. Only applies when + `#rust-analyzer.hover.actions.enable#` is set. + + default value is: + ```nix + true + ``` + ''; + }; + }; + "enable" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Whether to show HoverActions in Rust files. + + default value is: + ```nix + true + ``` + ''; + }; + "gotoTypeDef" = { + "enable" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Whether to show `Go to Type Definition` action. Only applies when + `#rust-analyzer.hover.actions.enable#` is set. + + default value is: + ```nix + true + ``` + ''; + }; + }; + "implementations" = { + "enable" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Whether to show `Implementations` action. Only applies when + `#rust-analyzer.hover.actions.enable#` is set. + + default value is: + ```nix + true + ``` + ''; + }; + }; + "references" = { + "enable" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Whether to show `References` action. Only applies when + `#rust-analyzer.hover.actions.enable#` is set. + + default value is: + ```nix + false + ``` + ''; + }; + }; + "run" = { + "enable" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Whether to show `Run` action. Only applies when + `#rust-analyzer.hover.actions.enable#` is set. + + default value is: + ```nix + true + ``` + ''; + }; + }; + }; + "documentation" = { + "enable" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Whether to show documentation on hover. + + default value is: + ```nix + true + ``` + ''; + }; + "keywords" = { + "enable" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Whether to show keyword hover popups. Only applies when + `#rust-analyzer.hover.documentation.enable#` is set. + + default value is: + ```nix + true + ``` + ''; + }; + }; + }; + "links" = { + "enable" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Use markdown syntax for links in hover. + + default value is: + ```nix + true + ``` + ''; + }; + }; + }; + "imports" = { + "granularity" = { + "enforce" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Whether to enforce the import granularity setting for all files. If set to false rust-analyzer will try to keep import styles consistent per file. + + default value is: + ```nix + false + ``` + ''; + }; + "group" = mkOption { + type = types.nullOr (types.enum [ "preserve" "crate" "module" "item" ]); + default = null; + description = '' + How imports should be grouped into use statements. + + default value is: + ```nix + "crate" + ``` + ''; + }; + }; + "group" = { + "enable" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Group inserted imports by the [following order](https://rust-analyzer.github.io/manual.html#auto-import). Groups are separated by newlines. + + default value is: + ```nix + true + ``` + ''; + }; + }; + "merge" = { + "glob" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Whether to allow import insertion to merge new imports into single path glob imports like `use std::fmt::*;`. + + default value is: + ```nix + true + ``` + ''; + }; + }; + "prefix" = mkOption { + type = types.nullOr (types.enum [ "plain" "self" "crate" ]); + default = null; + description = '' + The path structure for newly inserted paths to use. + + default value is: + ```nix + "plain" + ``` + ''; + }; + }; + "inlayHints" = { + "bindingModeHints" = { + "enable" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Whether to show inlay type hints for binding modes. + + default value is: + ```nix + false + ``` + ''; + }; + }; + "chainingHints" = { + "enable" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Whether to show inlay type hints for method chains. + + default value is: + ```nix + true + ``` + ''; + }; + }; + "closingBraceHints" = { + "enable" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Whether to show inlay hints after a closing `}` to indicate what item it belongs to. + + default value is: + ```nix + true + ``` + ''; + }; + "minLines" = mkOption { + type = types.nullOr (types.addCheck types.int (x: x >= 0)); + default = null; + description = '' + Minimum number of lines required before the `}` until the hint is shown (set to 0 or 1 + to always show them). + + default value is: + ```nix + 25 + ``` + ''; + }; + }; + "closureReturnTypeHints" = { + "enable" = mkOption { + type = types.nullOr (types.enum [ "always" "never" "with_block" ]); + default = null; + description = '' + Whether to show inlay type hints for return types of closures. + + default value is: + ```nix + "never" + ``` + ''; + }; + }; + "lifetimeElisionHints" = { + "enable" = mkOption { + type = types.nullOr (types.enum [ "always" "never" "skip_trivial" ]); + default = null; + description = '' + Whether to show inlay type hints for elided lifetimes in function signatures. + + default value is: + ```nix + "never" + ``` + ''; + }; + "useParameterNames" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Whether to prefer using parameter names as the name for elided lifetime hints if possible. + + default value is: + ```nix + false + ``` + ''; + }; + }; + "maxLength" = mkOption { + type = types.nullOr (types.nullOr (types.addCheck types.int (x: x >= 0))); + default = null; + description = '' + Maximum length for inlay hints. Set to null to have an unlimited length. + + default value is: + ```nix + 25 + ``` + ''; + }; + "parameterHints" = { + "enable" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Whether to show function parameter name inlay hints at the call + site. + + default value is: + ```nix + true + ``` + ''; + }; + }; + "reborrowHints" = { + "enable" = mkOption { + type = types.nullOr (types.enum [ "always" "never" "mutable" ]); + default = null; + description = '' + Whether to show inlay type hints for compiler inserted reborrows. + + default value is: + ```nix + "never" + ``` + ''; + }; + }; + "renderColons" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Whether to render leading colons for type hints, and trailing colons for parameter hints. + + default value is: + ```nix + true + ``` + ''; + }; + "typeHints" = { + "enable" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Whether to show inlay type hints for variables. + + default value is: + ```nix + true + ``` + ''; + }; + "hideClosureInitialization" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Whether to hide inlay type hints for `let` statements that initialize to a closure. + Only applies to closures with blocks, same as `#rust-analyzer.inlayHints.closureReturnTypeHints.enable#`. + + default value is: + ```nix + false + ``` + ''; + }; + "hideNamedConstructor" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Whether to hide inlay type hints for constructors. + + default value is: + ```nix + false + ``` + ''; + }; + }; + }; + "joinLines" = { + "joinAssignments" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Join lines merges consecutive declaration and initialization of an assignment. + + default value is: + ```nix + true + ``` + ''; + }; + "joinElseIf" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Join lines inserts else between consecutive ifs. + + default value is: + ```nix + true + ``` + ''; + }; + "removeTrailingComma" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Join lines removes trailing commas. + + default value is: + ```nix + true + ``` + ''; + }; + "unwrapTrivialBlock" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Join lines unwraps trivial blocks. + + default value is: + ```nix + true + ``` + ''; + }; + }; + "lens" = { + "debug" = { + "enable" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Whether to show `Debug` lens. Only applies when + `#rust-analyzer.lens.enable#` is set. + + default value is: + ```nix + true + ``` + ''; + }; + }; + "enable" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Whether to show CodeLens in Rust files. + + default value is: + ```nix + true + ``` + ''; + }; + "forceCustomCommands" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Internal config: use custom client-side commands even when the + client doesn't set the corresponding capability. + + default value is: + ```nix + true + ``` + ''; + }; + "implementations" = { + "enable" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Whether to show `Implementations` lens. Only applies when + `#rust-analyzer.lens.enable#` is set. + + default value is: + ```nix + true + ``` + ''; + }; + }; + "references" = { + "adt" = { + "enable" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Whether to show `References` lens for Struct, Enum, and Union. + Only applies when `#rust-analyzer.lens.enable#` is set. + + default value is: + ```nix + false + ``` + ''; + }; + }; + "enumVariant" = { + "enable" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Whether to show `References` lens for Enum Variants. + Only applies when `#rust-analyzer.lens.enable#` is set. + + default value is: + ```nix + false + ``` + ''; + }; + }; + "method" = { + "enable" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Whether to show `Method References` lens. Only applies when + `#rust-analyzer.lens.enable#` is set. + + default value is: + ```nix + false + ``` + ''; + }; + }; + "trait" = { + "enable" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Whether to show `References` lens for Trait. + Only applies when `#rust-analyzer.lens.enable#` is set. + + default value is: + ```nix + false + ``` + ''; + }; + }; + }; + "run" = { + "enable" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Whether to show `Run` lens. Only applies when + `#rust-analyzer.lens.enable#` is set. + + default value is: + ```nix + true + ``` + ''; + }; + }; + }; + "linkedProjects" = mkOption { + type = types.nullOr (types.listOf (types.oneOf [ (types.str) (types.attrsOf types.anything) ])); + default = null; + description = '' + Disable project auto-discovery in favor of explicitly specified set + of projects. + + Elements must be paths pointing to `Cargo.toml`, + `rust-project.json`, or JSON objects in `rust-project.json` format. + + default value is: + ```nix + [] + ``` + ''; + }; + "lru" = { + "capacity" = mkOption { + type = types.nullOr (types.nullOr (types.addCheck types.int (x: x >= 0))); + default = null; + description = '' + Number of syntax trees rust-analyzer keeps in memory. Defaults to 128. + + default value is: + ```nix + null + ``` + ''; + }; + }; + "notifications" = { + "cargoTomlNotFound" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Whether to show `can't find Cargo.toml` error message. + + default value is: + ```nix + true + ``` + ''; + }; + }; + "procMacro" = { + "attributes" = { + "enable" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Expand attribute macros. Requires `#rust-analyzer.procMacro.enable#` to be set. + + default value is: + ```nix + true + ``` + ''; + }; + }; + "enable" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Enable support for procedural macros, implies `#rust-analyzer.cargo.buildScripts.enable#`. + + default value is: + ```nix + true + ``` + ''; + }; + "ignored" = mkOption { + type = types.nullOr (types.attrsOf types.anything); + default = null; + description = '' + These proc-macros will be ignored when trying to expand them. + + This config takes a map of crate names with the exported proc-macro names to ignore as values. + + default value is: + ```nix + {} + ``` + ''; + }; + "server" = mkOption { + type = types.nullOr (types.nullOr (types.str)); + default = null; + description = '' + Internal config, path to proc-macro server executable (typically, + this is rust-analyzer itself, but we override this in tests). + + default value is: + ```nix + null + ``` + ''; + }; + }; + "runnables" = { + "command" = mkOption { + type = types.nullOr (types.nullOr (types.str)); + default = null; + description = '' + Command to be executed instead of 'cargo' for runnables. + + default value is: + ```nix + null + ``` + ''; + }; + "extraArgs" = mkOption { + type = types.nullOr (types.listOf (types.str)); + default = null; + description = '' + Additional arguments to be passed to cargo for runnables such as + tests or binaries. For example, it may be `--release`. + + default value is: + ```nix + [] + ``` + ''; + }; + }; + "rustc" = { + "source" = mkOption { + type = types.nullOr (types.nullOr (types.str)); + default = null; + description = '' + Path to the Cargo.toml of the rust compiler workspace, for usage in rustc_private + projects, or "discover" to try to automatically find it if the `rustc-dev` component + is installed. + + Any project which uses rust-analyzer with the rustcPrivate + crates must set `[package.metadata.rust-analyzer] rustc_private=true` to use it. + + This option does not take effect until rust-analyzer is restarted. + + default value is: + ```nix + null + ``` + ''; + }; + }; + "rustfmt" = { + "extraArgs" = mkOption { + type = types.nullOr (types.listOf (types.str)); + default = null; + description = '' + Additional arguments to `rustfmt`. + + default value is: + ```nix + [] + ``` + ''; + }; + "overrideCommand" = mkOption { + type = types.nullOr (types.nullOr (types.listOf (types.str))); + default = null; + description = '' + Advanced option, fully override the command rust-analyzer uses for + formatting. + + default value is: + ```nix + null + ``` + ''; + }; + "rangeFormatting" = { + "enable" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Enables the use of rustfmt's unstable range formatting command for the + `textDocument/rangeFormatting` request. The rustfmt option is unstable and only + available on a nightly build. + + default value is: + ```nix + false + ``` + ''; + }; + }; + }; + "semanticHighlighting" = { + "doc" = { + "comment" = { + "inject" = { + "enable" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Inject additional highlighting into doc comments. + + When enabled, rust-analyzer will highlight rust source in doc comments as well as intra + doc links. + + default value is: + ```nix + true + ``` + ''; + }; + }; + }; + }; + "operator" = { + "enable" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Use semantic tokens for operators. + + When disabled, rust-analyzer will emit semantic tokens only for operator tokens when + they are tagged with modifiers. + + default value is: + ```nix + true + ``` + ''; + }; + "specialization" = { + "enable" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Use specialized semantic tokens for operators. + + When enabled, rust-analyzer will emit special token types for operator tokens instead + of the generic `operator` token type. + + default value is: + ```nix + false + ``` + ''; + }; + }; + }; + "punctuation" = { + "enable" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Use semantic tokens for punctuations. + + When disabled, rust-analyzer will emit semantic tokens only for punctuation tokens when + they are tagged with modifiers or have a special role. + + default value is: + ```nix + false + ``` + ''; + }; + "separate" = { + "macro" = { + "bang" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + When enabled, rust-analyzer will emit a punctuation semantic token for the `!` of macro + calls. + + default value is: + ```nix + false + ``` + ''; + }; + }; + }; + "specialization" = { + "enable" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Use specialized semantic tokens for punctuations. + + When enabled, rust-analyzer will emit special token types for punctuation tokens instead + of the generic `punctuation` token type. + + default value is: + ```nix + false + ``` + ''; + }; + }; + }; + "strings" = { + "enable" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Use semantic tokens for strings. + + In some editors (e.g. vscode) semantic tokens override other highlighting grammars. + By disabling semantic tokens for strings, other grammars can be used to highlight + their contents. + + default value is: + ```nix + true + ``` + ''; + }; + }; + }; + "signatureInfo" = { + "detail" = mkOption { + type = types.nullOr (types.enum [ "full" "parameters" ]); + default = null; + description = '' + Show full signature of the callable. Only shows parameters if disabled. + + default value is: + ```nix + "full" + ``` + ''; + }; + "documentation" = { + "enable" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Show documentation. + + default value is: + ```nix + true + ``` + ''; + }; + }; + }; + "typing" = { + "autoClosingAngleBrackets" = { + "enable" = mkOption { + type = types.nullOr (types.bool); + default = null; + description = '' + Whether to insert closing angle brackets when typing an opening angle bracket of a generic argument list. + + default value is: + ```nix + false + ``` + ''; + }; + }; + }; + "workspace" = { + "symbol" = { + "search" = { + "kind" = mkOption { + type = types.nullOr (types.enum [ "only_types" "all_symbols" ]); + default = null; + description = '' + Workspace symbol search kind. + + default value is: + ```nix + "only_types" + ``` + ''; + }; + "limit" = mkOption { + type = types.nullOr (types.addCheck types.int (x: x >= 0)); + default = null; + description = '' + Limits the number of items returned from a workspace symbol search (Defaults to 128). + Some clients like vs-code issue new searches on result filtering and don't require all results to be returned in the initial search. + Other clients requires all results upfront and might require a higher limit. + + default value is: + ```nix + 128 + ``` + ''; + }; + "scope" = mkOption { + type = types.nullOr (types.enum [ "workspace" "workspace_and_dependencies" ]); + default = null; + description = '' + Workspace symbol search scope. + + default value is: + ```nix + "workspace" + ``` + ''; + }; + }; + }; + }; +} diff --git a/plugins/nvim-lsp/update_ra.md b/plugins/nvim-lsp/update_ra.md new file mode 100644 index 00000000..684a32dd --- /dev/null +++ b/plugins/nvim-lsp/update_ra.md @@ -0,0 +1,13 @@ +# Updating rust-analyzer options + +Because there a large number of rust-analyzer options it's difficult to handle them by hand. + +The options can be fetched from the [rust-analyzer package.json](https://github.com/rust-lang/rust-analyzer/blob/master/editors/code/package.json). + +There is a derivation on the top-level flake that allows to build it easily, you just have to run: + +```bash +nix build .#rustAnalyzerOptions +``` + +You can then copy the `result/share/rust-analyzer-config.nix` to the correct location. diff --git a/plugins/pluginmanagers/packer.nix b/plugins/pluginmanagers/packer.nix index f025b807..e5f96703 100644 --- a/plugins/pluginmanagers/packer.nix +++ b/plugins/pluginmanagers/packer.nix @@ -7,7 +7,7 @@ in { options = { plugins.packer = { - enable = mkEnableOption "Enable packer.nvim"; + enable = mkEnableOption "packer.nvim"; plugins = mkOption { type = types.listOf (types.oneOf [ diff --git a/plugins/snippets/luasnip/default.nix b/plugins/snippets/luasnip/default.nix index ad720437..c8485d0a 100644 --- a/plugins/snippets/luasnip/default.nix +++ b/plugins/snippets/luasnip/default.nix @@ -24,7 +24,7 @@ in } ] # generates: - # + # # require("luasnip.loaders.from_vscode").lazy_load({}) # require("luasnip.loaders.from_vscode").lazy_load({['paths'] = {'/nix/store/.../path/to/snippets'}}) # diff --git a/plugins/statuslines/airline.nix b/plugins/statuslines/airline.nix index d560ed41..56f491d9 100644 --- a/plugins/statuslines/airline.nix +++ b/plugins/statuslines/airline.nix @@ -14,7 +14,7 @@ in { options = { plugins.airline = { - enable = mkEnableOption "Enable airline"; + enable = mkEnableOption "airline"; package = mkOption { type = types.package; diff --git a/plugins/statuslines/lightline.nix b/plugins/statuslines/lightline.nix index 08420fd0..5b53ee1c 100644 --- a/plugins/statuslines/lightline.nix +++ b/plugins/statuslines/lightline.nix @@ -7,7 +7,7 @@ in { options = { plugins.lightline = { - enable = mkEnableOption "Enable lightline"; + enable = mkEnableOption "lightline"; package = mkOption { type = types.package; diff --git a/plugins/statuslines/lualine.nix b/plugins/statuslines/lualine.nix index 578e06a3..67f23b8d 100644 --- a/plugins/statuslines/lualine.nix +++ b/plugins/statuslines/lualine.nix @@ -56,7 +56,7 @@ in { options = { plugins.lualine = { - enable = mkEnableOption "Enable lualine"; + enable = mkEnableOption "lualine"; package = mkOption { type = types.package; diff --git a/plugins/telescope/default.nix b/plugins/telescope/default.nix index 45c65f49..e774fe3b 100644 --- a/plugins/telescope/default.nix +++ b/plugins/telescope/default.nix @@ -16,7 +16,7 @@ in # TODO:add support for aditional filetypes. This requires autocommands! options.plugins.telescope = { - enable = mkEnableOption "Enable telescope.nvim"; + enable = mkEnableOption "telescope.nvim"; package = mkOption { type = types.package; @@ -68,21 +68,23 @@ in let $BAT_THEME = '${cfg.highlightTheme}' ''; - extraConfigLua = let - options = { - extensions = cfg.extensionConfig; - defaults = cfg.defaults; - } // cfg.extraOptions; - in '' - do - local __telescopeExtensions = ${helpers.toLuaObject cfg.enabledExtensions} + extraConfigLua = + let + options = { + extensions = cfg.extensionConfig; + defaults = cfg.defaults; + } // cfg.extraOptions; + in + '' + do + local __telescopeExtensions = ${helpers.toLuaObject cfg.enabledExtensions} - require('telescope').setup(${helpers.toLuaObject options}) + require('telescope').setup(${helpers.toLuaObject options}) - for i, extension in ipairs(__telescopeExtensions) do - require('telescope').load_extension(extension) + for i, extension in ipairs(__telescopeExtensions) do + require('telescope').load_extension(extension) + end end - end - ''; + ''; }; } diff --git a/plugins/telescope/frecency.nix b/plugins/telescope/frecency.nix index 58e93d1c..8d871730 100644 --- a/plugins/telescope/frecency.nix +++ b/plugins/telescope/frecency.nix @@ -1,11 +1,11 @@ { pkgs, config, lib, ... }: with lib; -let +let cfg = config.plugins.telescope.extensions.frecency; in { options.plugins.telescope.extensions.frecency = { - enable = mkEnableOption "Enable frecency"; + enable = mkEnableOption "frecency"; package = mkOption { type = types.package; @@ -50,24 +50,26 @@ in }; }; - config = let - configuration = { - db_root = cfg.dbRoot; - default_workspace = cfg.defaultWorkspace; - ignore_patterns = cfg.ignorePatterns; - show_scores = cfg.showScores; - workspaces = cfg.workspaces; - show_unindexed = cfg.showUnindexed; - devicons_disabled = cfg.deviconsDisabled; - }; - in mkIf cfg.enable { - extraPackages = [ pkgs.sqlite ]; - extraPlugins = with pkgs.vimPlugins; [ - cfg.package - sqlite-lua - ]; + config = + let + configuration = { + db_root = cfg.dbRoot; + default_workspace = cfg.defaultWorkspace; + ignore_patterns = cfg.ignorePatterns; + show_scores = cfg.showScores; + workspaces = cfg.workspaces; + show_unindexed = cfg.showUnindexed; + devicons_disabled = cfg.deviconsDisabled; + }; + in + mkIf cfg.enable { + extraPackages = [ pkgs.sqlite ]; + extraPlugins = with pkgs.vimPlugins; [ + cfg.package + sqlite-lua + ]; - plugins.telescope.enabledExtensions = [ "frecency" ]; - plugins.telescope.extensionConfig."frecency" = configuration; - }; + plugins.telescope.enabledExtensions = [ "frecency" ]; + plugins.telescope.extensionConfig."frecency" = configuration; + }; } diff --git a/plugins/telescope/fzf-native.nix b/plugins/telescope/fzf-native.nix index 0686f8b2..525651dc 100644 --- a/plugins/telescope/fzf-native.nix +++ b/plugins/telescope/fzf-native.nix @@ -1,6 +1,6 @@ { pkgs, config, lib, ... }: with lib; -let +let cfg = config.plugins.telescope.extensions.fzf-native; in { @@ -34,7 +34,7 @@ in }; }; - config = let + config = let configuration = { fuzzy = cfg.fuzzy; override_generic_sorter = cfg.overrideGenericSorter; diff --git a/plugins/telescope/project-nvim.nix b/plugins/telescope/project-nvim.nix index 32f0b771..e8d7d834 100644 --- a/plugins/telescope/project-nvim.nix +++ b/plugins/telescope/project-nvim.nix @@ -1,11 +1,11 @@ -{ pkgs, config, lib, ...}: +{ pkgs, config, lib, ... }: with lib; let cfg = config.plugins.telescope.extensions.project-nvim; in { options.plugins.telescope.extensions.project-nvim = { - enable = mkEnableOption "Enable project-nvim telescope extension"; + enable = mkEnableOption "project-nvim telescope extension"; }; diff --git a/plugins/utils/commentary.nix b/plugins/utils/commentary.nix index 406e130c..cfd428c5 100644 --- a/plugins/utils/commentary.nix +++ b/plugins/utils/commentary.nix @@ -8,11 +8,11 @@ in options = { plugins.commentary = { - enable = mkEnableOption "Enable commentary"; + enable = mkEnableOption "commentary"; package = mkOption { type = types.package; - default = pkgs.vimPlugins.vim-commentary; + default = pkgs.vimPlugins.vim-commentary; description = "Plugin to use for vim-commentary"; }; }; diff --git a/plugins/utils/dashboard.nix b/plugins/utils/dashboard.nix index 7fe28966..311d7b93 100644 --- a/plugins/utils/dashboard.nix +++ b/plugins/utils/dashboard.nix @@ -8,7 +8,7 @@ in { options = { plugins.dashboard = { - enable = mkEnableOption "Enable dashboard"; + enable = mkEnableOption "dashboard"; package = mkOption { type = types.package; diff --git a/plugins/utils/floaterm.nix b/plugins/utils/floaterm.nix index 92c7aeec..cc340ce6 100644 --- a/plugins/utils/floaterm.nix +++ b/plugins/utils/floaterm.nix @@ -7,7 +7,7 @@ in { options = { plugins.floaterm = { - enable = mkEnableOption "Enable floaterm"; + enable = mkEnableOption "floaterm"; package = mkOption { type = types.package; diff --git a/plugins/utils/intellitab.nix b/plugins/utils/intellitab.nix index 9edca5aa..706f9bf8 100644 --- a/plugins/utils/intellitab.nix +++ b/plugins/utils/intellitab.nix @@ -1,7 +1,7 @@ { config, pkgs, lib, ... }: with lib; let - cfg = config.plugins.comment-nvim; + cfg = config.plugins.intellitab; defs = import ../plugin-defs.nix { inherit pkgs; }; in { diff --git a/plugins/utils/magma-nvim.nix b/plugins/utils/magma-nvim.nix index 67fa1358..190a3c5f 100644 --- a/plugins/utils/magma-nvim.nix +++ b/plugins/utils/magma-nvim.nix @@ -73,21 +73,21 @@ in { package = mkOption { type = types.nullOr types.package; default = null; - example = + example = "package = pkgs.fetchFromGitHub { owner = \"WhiteBlackGoose\"; repo = \"magma-nvim-goose\"; rev = version; sha256 = \"sha256-IaslJK1F2BxTvZzKGH9OKOl2RICi4d4rSgjliAIAqK4=\";} "; - + }; }; }; config = mkIf cfg.enable { - extraPlugins = [ ( - if cfg.package != null then plugins.magma-nvim.override {src = cfg.package;} else plugins.magma-nvim + extraPlugins = [ ( + if cfg.package != null then plugins.magma-nvim.override {src = cfg.package;} else plugins.magma-nvim )]; diff --git a/plugins/utils/mark-radar.nix b/plugins/utils/mark-radar.nix index 5b3e147f..deb55ccf 100644 --- a/plugins/utils/mark-radar.nix +++ b/plugins/utils/mark-radar.nix @@ -8,7 +8,7 @@ let in { options.plugins.mark-radar = { - enable = mkEnableOption "Enable mark-radar"; + enable = mkEnableOption "mark-radar"; package = mkOption { type = types.package; diff --git a/plugins/utils/notify.nix b/plugins/utils/notify.nix index 1819c90e..9bd1a416 100644 --- a/plugins/utils/notify.nix +++ b/plugins/utils/notify.nix @@ -10,7 +10,7 @@ let in { options.plugins.notify = { - enable = mkEnableOption "Enable notify"; + enable = mkEnableOption "notify"; package = mkOption { type = types.package; diff --git a/plugins/utils/nvim-autopairs.nix b/plugins/utils/nvim-autopairs.nix index e37503e2..ec330ea1 100644 --- a/plugins/utils/nvim-autopairs.nix +++ b/plugins/utils/nvim-autopairs.nix @@ -6,7 +6,7 @@ let in { options.plugins.nvim-autopairs = { - enable = mkEnableOption "Enable nvim-autopairs"; + enable = mkEnableOption "nvim-autopairs"; package = mkOption { type = types.package; diff --git a/plugins/utils/nvim-colorizer.nix b/plugins/utils/nvim-colorizer.nix new file mode 100644 index 00000000..8c4eaf30 --- /dev/null +++ b/plugins/utils/nvim-colorizer.nix @@ -0,0 +1,161 @@ +{ pkgs, config, lib, ... }: +with lib; +let + + cfg = config.plugins.nvim-colorizer; + helpers = import ../helpers.nix { inherit lib; }; + + colorizer-options = { + RGB = mkOption { + description = "#RGB hex codes"; + type = types.nullOr types.bool; + default = null; + }; + RRGGBB = mkOption { + description = "#RRGGBB hex codes"; + type = types.nullOr types.bool; + default = null; + }; + names = mkOption { + description = "\"Name\" codes like Blue or blue"; + type = types.nullOr types.bool; + default = null; + }; + RRGGBBAA = mkOption { + description = "#RRGGBBAA hex codes"; + type = types.nullOr types.bool; + default = null; + }; + AARRGGBB = mkOption { + description = "0xAARRGGBB hex codes"; + type = types.nullOr types.bool; + default = null; + }; + rgb_fn = mkOption { + description = "CSS rgb() and rgba() functions"; + type = types.nullOr types.bool; + default = null; + }; + hsl_fn = mkOption { + description = "CSS hsl() and hsla() functions"; + type = types.nullOr types.bool; + default = null; + }; + css = mkOption { + description = "Enable all CSS features: rgb_fn, hsl_fn, names, RGB, RRGGBB"; + type = types.nullOr types.bool; + default = null; + }; + css_fn = mkOption { + description = "Enable all CSS *functions*: rgb_fn, hsl_fn"; + type = types.nullOr types.bool; + default = null; + }; + mode = mkOption { + description = "Set the display mode"; + type = types.nullOr (types.enum [ "foreground" "background" "virtualtext" ]); + default = null; + }; + tailwind = mkOption { + description = "Enable tailwind colors"; + type = types.nullOr ( + types.oneOf [ + types.bool + (types.enum [ "normal" "lsp" "both" ]) + ] + ); + default = null; + }; + sass = { + enable = mkOption { + description = "Enable sass colors"; + type = types.nullOr types.bool; + default = null; + }; + parsers = mkOption { + description = "sass parsers settings"; + type = types.nullOr types.attrs; + default = null; + }; + }; + virtualtext = mkOption { + description = "Set the virtualtext character (only used when mode is set to 'virtualtext')"; + type = types.nullOr types.str; + default = null; + }; + }; + +in +{ + options = { + plugins.nvim-colorizer = { + + enable = mkEnableOption "nvim-colorizer"; + + package = mkOption { + type = types.package; + default = pkgs.vimPlugins.nvim-colorizer-lua; + description = "Plugin to use for vim-commentary"; + }; + + fileTypes = mkOption { + description = "Enable and/or configure highlighting for certain filetypes"; + type = types.nullOr ( + types.listOf (types.oneOf [ + types.str + (types.submodule { + options = { + language = mkOption { + type = types.str; + }; + } // colorizer-options; + }) + ]) + ); + default = null; + }; + + userDefaultOptions = mkOption { + description = "Default options"; + type = types.nullOr (types.submodule { + options = colorizer-options; + }); + default = null; + }; + + bufTypes = mkOption { + description = "Buftype value is fetched by vim.bo.buftype"; + type = types.nullOr (types.listOf types.str); + default = null; + }; + }; + }; + + config = mkIf cfg.enable { + extraPlugins = [ cfg.package ]; + + extraConfigLua = let + + filetypes = if (cfg.fileTypes != null) + then ( + let + list = map ( + v: if builtins.isAttrs v + then v.language + " = " + helpers.toLuaObject (builtins.removeAttrs v [ "language" ]) + else "'${v}'" + ) cfg.fileTypes; + in "{" + (concatStringsSep "," list) + "}" + ) + else + "nil" + ; + + in '' + require("colorizer").setup({ + filetypes = ${filetypes}, + user_default_options = ${helpers.toLuaObject cfg.userDefaultOptions}, + buftypes = ${helpers.toLuaObject cfg.bufTypes}, + }) + ''; + }; +} diff --git a/plugins/utils/nvim-tree.nix b/plugins/utils/nvim-tree.nix index 94445999..bf4fb9ac 100644 --- a/plugins/utils/nvim-tree.nix +++ b/plugins/utils/nvim-tree.nix @@ -19,7 +19,7 @@ in ]; options.plugins.nvim-tree = { - enable = mkEnableOption "Enable nvim-tree"; + enable = mkEnableOption "nvim-tree"; package = mkOption { type = types.package; @@ -234,7 +234,6 @@ in hijack_netrw = cfg.hijackNetrw; open_on_setup = cfg.openOnSetup; ignore_ft_on_setup = cfg.ignoreFtOnSetup; - auto_close = cfg.autoClose; open_on_tab = cfg.openOnTab; hijack_cursor = cfg.hijackCursor; sync_root_with_cwd = cfg.syncRootWithCwd; @@ -278,6 +277,14 @@ in nvim-web-devicons ]; + autoCmd = mkIf (cfg.autoClose != null && cfg.autoClose) [ + { + event = "BufEnter"; + command = "if winnr('$') == 1 && bufname() == 'NvimTree_' . tabpagenr() | quit | endif"; + nested = true; + } + ]; + extraConfigLua = '' require('nvim-tree').setup(${helpers.toLuaObject options}) ''; diff --git a/plugins/utils/project-nvim.nix b/plugins/utils/project-nvim.nix index 5d372848..14651295 100644 --- a/plugins/utils/project-nvim.nix +++ b/plugins/utils/project-nvim.nix @@ -6,7 +6,7 @@ let in { options.plugins.project-nvim = helpers.extraOptionsOptions // { - enable = mkEnableOption "Enable project.nvim"; + enable = mkEnableOption "project.nvim"; package = mkOption { type = types.package; diff --git a/plugins/utils/specs.nix b/plugins/utils/specs.nix index ab9e01c4..a8808fa9 100644 --- a/plugins/utils/specs.nix +++ b/plugins/utils/specs.nix @@ -6,7 +6,7 @@ let in { options.plugins.specs = { - enable = mkEnableOption "Enable specs-nvim"; + enable = mkEnableOption "specs-nvim"; package = mkOption { type = types.package; diff --git a/plugins/utils/startify.nix b/plugins/utils/startify.nix index 352ad315..e4d371f6 100644 --- a/plugins/utils/startify.nix +++ b/plugins/utils/startify.nix @@ -182,7 +182,7 @@ mkPlugin args { customHeader = mkDefaultOpt { description = "Define your own header"; - global = "startify_custom_headers"; + global = "startify_custom_header"; type = types.oneOf [ types.str (types.listOf types.str) ]; }; diff --git a/tests/flake.lock b/tests/flake.lock index 1a49f821..1c97a1f1 100644 --- a/tests/flake.lock +++ b/tests/flake.lock @@ -10,11 +10,11 @@ "utils": "utils" }, "locked": { - "lastModified": 1667262410, - "narHash": "sha256-yqqvPvazG/Ci3WpIfPb+o+i2cNuyAYYY19lwJGCmUao=", + "lastModified": 1669854260, + "narHash": "sha256-Z8NAL3g4i5LAhxveNGJhrVDHxIBbUf1lVIy/Thr2RMU=", "owner": "lovesegfault", "repo": "beautysh", - "rev": "a1fdaff999db2dfc5032914630f5052360f4b432", + "rev": "d616eb8d9d05ee4fb33de9c5521d99c3f0695d52", "type": "github" }, "original": { @@ -33,11 +33,11 @@ "utils": "utils_2" }, "locked": { - "lastModified": 1667262410, - "narHash": "sha256-yqqvPvazG/Ci3WpIfPb+o+i2cNuyAYYY19lwJGCmUao=", + "lastModified": 1669854260, + "narHash": "sha256-Z8NAL3g4i5LAhxveNGJhrVDHxIBbUf1lVIy/Thr2RMU=", "owner": "lovesegfault", "repo": "beautysh", - "rev": "a1fdaff999db2dfc5032914630f5052360f4b432", + "rev": "d616eb8d9d05ee4fb33de9c5521d99c3f0695d52", "type": "github" }, "original": { @@ -128,11 +128,11 @@ "gleam": { "flake": false, "locked": { - "lastModified": 1669665314, - "narHash": "sha256-aeho84P91cH13j7uLJwyD/zj8O/peROrpfa41HA/FGo=", + "lastModified": 1672454845, + "narHash": "sha256-h/5SpMD725BasD2+5J0B7OCDzoWlDBGDm7ywTEYmQbk=", "owner": "gleam-lang", "repo": "tree-sitter-gleam", - "rev": "97611918f79643ade377a156f3e4192cd50dc3e6", + "rev": "3eb2e1783f3bf6f85c16cdd150e2f256b2f6844e", "type": "github" }, "original": { @@ -143,12 +143,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1663491030, - "narHash": "sha256-MVsfBhE9US5DvLtBAaTRjwYdv1tLO8xjahM8qLXTgTo=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "767542707d394ff15ac1981e903e005ba69528b5", - "type": "github" + "lastModified": 1671108576, + "narHash": "sha256-6ggOL6KoaELNA1562tnPjtAnQ9SwsKRTgeuaXvPzCwI=", + "path": "/nix/store/iscn1qzhdwvb3mkr5kvsy9gvyhkdnzl3-source", + "rev": "0f5996b524c91677891a432cc99c7567c7c402b1", + "type": "path" }, "original": { "id": "nixpkgs", @@ -157,11 +156,11 @@ }, "nixpkgs-stable": { "locked": { - "lastModified": 1669546925, - "narHash": "sha256-Gvtk9agz88tBgqmCdHl5U7gYttTkiuEd8/Rq1Im0pTg=", + "lastModified": 1672580127, + "narHash": "sha256-3lW3xZslREhJogoOkjeZtlBtvFMyxHku7I/9IVehhT8=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "fecf05d4861f3985e8dee73f08bc82668ef75125", + "rev": "0874168639713f547c05947c76124f78441ea46c", "type": "github" }, "original": { @@ -173,12 +172,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1663491030, - "narHash": "sha256-MVsfBhE9US5DvLtBAaTRjwYdv1tLO8xjahM8qLXTgTo=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "767542707d394ff15ac1981e903e005ba69528b5", - "type": "github" + "lastModified": 1671108576, + "narHash": "sha256-6ggOL6KoaELNA1562tnPjtAnQ9SwsKRTgeuaXvPzCwI=", + "path": "/nix/store/iscn1qzhdwvb3mkr5kvsy9gvyhkdnzl3-source", + "rev": "0f5996b524c91677891a432cc99c7567c7c402b1", + "type": "path" }, "original": { "id": "nixpkgs", @@ -187,11 +185,11 @@ }, "nixpkgs_3": { "locked": { - "lastModified": 1663491030, - "narHash": "sha256-MVsfBhE9US5DvLtBAaTRjwYdv1tLO8xjahM8qLXTgTo=", + "lastModified": 1673606088, + "narHash": "sha256-wdYD41UwNwPhTdMaG0AIe7fE1bAdyHe6bB4HLUqUvck=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "767542707d394ff15ac1981e903e005ba69528b5", + "rev": "37b97ae3dd714de9a17923d004a2c5b5543dfa6d", "type": "github" }, "original": { @@ -207,12 +205,12 @@ }, "locked": { "lastModified": 0, - "narHash": "sha256-008LHsZ1x6jTE46J4+E2jOQTAyexpf7M9fNqSsjQOds=", - "path": "/nix/store/nj5i7q1lcsw9fzch5kha51li3c8w12h6-source", + "narHash": "sha256-7N6OttwH7E7URRmQ79MacpMu4eSzxYlRgW06FOP/lWg=", + "path": "/nix/store/s8ql6s1cwxm1ah1pi4y6h4xv2mz2j4v1-source", "type": "path" }, "original": { - "path": "/nix/store/nj5i7q1lcsw9fzch5kha51li3c8w12h6-source", + "path": "/nix/store/s8ql6s1cwxm1ah1pi4y6h4xv2mz2j4v1-source", "type": "path" } }, @@ -226,12 +224,12 @@ }, "locked": { "lastModified": 0, - "narHash": "sha256-008LHsZ1x6jTE46J4+E2jOQTAyexpf7M9fNqSsjQOds=", - "path": "/nix/store/nj5i7q1lcsw9fzch5kha51li3c8w12h6-source", + "narHash": "sha256-7N6OttwH7E7URRmQ79MacpMu4eSzxYlRgW06FOP/lWg=", + "path": "/nix/store/s8ql6s1cwxm1ah1pi4y6h4xv2mz2j4v1-source", "type": "path" }, "original": { - "path": "/nix/store/nj5i7q1lcsw9fzch5kha51li3c8w12h6-source", + "path": "/nix/store/s8ql6s1cwxm1ah1pi4y6h4xv2mz2j4v1-source", "type": "path" } }, @@ -302,11 +300,11 @@ }, "utils": { "locked": { - "lastModified": 1667077288, - "narHash": "sha256-bdC8sFNDpT0HK74u9fUkpbf1MEzVYJ+ka7NXCdgBoaA=", + "lastModified": 1667395993, + "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=", "owner": "numtide", "repo": "flake-utils", - "rev": "6ee9ebb6b1ee695d2cacc4faa053a7b9baa76817", + "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f", "type": "github" }, "original": { @@ -317,11 +315,11 @@ }, "utils_2": { "locked": { - "lastModified": 1667077288, - "narHash": "sha256-bdC8sFNDpT0HK74u9fUkpbf1MEzVYJ+ka7NXCdgBoaA=", + "lastModified": 1667395993, + "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=", "owner": "numtide", "repo": "flake-utils", - "rev": "6ee9ebb6b1ee695d2cacc4faa053a7b9baa76817", + "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f", "type": "github" }, "original": {