diff --git a/plugins/default.nix b/plugins/default.nix index b954e310..643b839d 100644 --- a/plugins/default.nix +++ b/plugins/default.nix @@ -44,7 +44,7 @@ ./git/gitgutter.nix ./git/gitlinker.nix ./git/gitmessenger.nix - ./git/gitsigns.nix + ./git/gitsigns ./git/neogit ./languages/clangd-extensions.nix diff --git a/plugins/git/gitsigns.nix b/plugins/git/gitsigns.nix deleted file mode 100644 index 13d36cca..00000000 --- a/plugins/git/gitsigns.nix +++ /dev/null @@ -1,409 +0,0 @@ -{ - lib, - helpers, - config, - pkgs, - ... -}: -with lib; let - signOptions = defaults: { - hl = - helpers.defaultNullOpts.mkStr defaults.hl - "Specifies the highlight group to use for the sign"; - text = - helpers.defaultNullOpts.mkStr defaults.text - "Specifies the character to use for the sign"; - numhl = - helpers.defaultNullOpts.mkStr defaults.numhl - "Specifies the highlight group to use for the number column"; - linehl = - helpers.defaultNullOpts.mkStr defaults.linehl - "Specifies the highlight group to use for the line"; - showCount = - helpers.defaultNullOpts.mkBool false - "showing count of hunk, e.g. number of deleted lines"; - }; - signSetupOptions = values: { - inherit (values) hl text numhl linehl; - show_count = values.showCount; - }; - - luaFunction = types.submodule { - options.function = mkOption { - type = types.str; - description = "Lua function definition"; - }; - }; -in { - options.plugins.gitsigns = { - enable = mkEnableOption "gitsigns plugin"; - - package = helpers.mkPackageOption "gitsigns" pkgs.vimPlugins.gitsigns-nvim; - - gitPackage = mkOption { - type = with types; nullOr package; - default = pkgs.git; - description = "Which package to use for git."; - }; - - signs = { - add = signOptions { - hl = "GitSignsAdd"; - text = "┃"; - numhl = "GitSignsAddNr"; - linehl = "GitSignsAddLn"; - }; - change = signOptions { - hl = "GitSignsChange"; - text = "┃"; - numhl = "GitSignsChangeNr"; - linehl = "GitSignsChangeLn"; - }; - delete = signOptions { - hl = "GitSignsDelete"; - text = "▁"; - numhl = "GitSignsDeleteNr"; - linehl = "GitSignsDeleteLn"; - }; - topdelete = signOptions { - hl = "GitSignsDelete"; - text = "▔"; - numhl = "GitSignsDeleteNr"; - linehl = "GitSignsDeleteLn"; - }; - changedelete = signOptions { - hl = "GitSignsChange"; - text = "~"; - numhl = "GitSignsChangeNr"; - linehl = "GitSignsChangeLn"; - }; - untracked = signOptions { - hl = "GitSignsAdd"; - text = "┆"; - numhl = "GitSignsAddNr"; - linehl = "GitSignsAddLn"; - }; - }; - worktrees = let - worktreeModule = { - options = { - toplevel = mkOption { - type = types.str; - }; - gitdir = mkOption { - type = types.str; - }; - }; - }; - in - mkOption { - type = types.nullOr (types.listOf (types.submodule worktreeModule)); - default = null; - description = '' - Detached working trees. - If normal attaching fails, then each entry in the table is attempted with the work tree - details set. - ''; - }; - onAttach = mkOption { - type = types.nullOr luaFunction; - default = null; - description = '' - Callback called when attaching to a buffer. Mainly used to setup keymaps - when `config.keymaps` is empty. The buffer number is passed as the first - argument. - - This callback can return `false` to prevent attaching to the buffer. - ''; - example = '' - { - function = \'\' - function(bufnr) - if vim.api.nvim_buf_get_name(bufnr):match() then - -- Don't attach to specific buffers whose name matches a pattern - return false - end - -- Setup keymaps - vim.api.nvim_buf_set_keymap(bufnr, 'n', 'hs', 'lua require"gitsigns".stage_hunk()', {}) - ... -- More keymaps - end - \'\' - } - ''; - }; - - watchGitDir = { - enable = - helpers.defaultNullOpts.mkBool true - "Whether the watcher is enabled"; - interval = - helpers.defaultNullOpts.mkInt 1000 - "Interval the watcher waits between polls of the gitdir in milliseconds"; - followFiles = - helpers.defaultNullOpts.mkBool true - "If a file is moved with `git mv`, switch the buffer to the new location"; - }; - signPriority = - helpers.defaultNullOpts.mkInt 6 - "Priority to use for signs"; - signcolumn = - helpers.defaultNullOpts.mkBool true - '' - Enable/disable symbols in the sign column. - - When enabled the highlights defined in `signs.*.hl` and symbols defined - in `signs.*.text` are used. - ''; - numhl = helpers.defaultNullOpts.mkBool false '' - 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 = helpers.defaultNullOpts.mkBool false '' - 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 = helpers.defaultNullOpts.mkBool false '' - 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 = - helpers.defaultNullOpts.mkEnumFirstDefault ["myers" "minimal" "patience" "histogram"] - "Diff algorithm to use"; - internal = - helpers.defaultNullOpts.mkBool false - "Use Neovim's built in xdiff library for running diffs"; - indentHeuristic = - helpers.defaultNullOpts.mkBool false - "Use the indent heuristic for the internal diff library."; - vertical = - helpers.defaultNullOpts.mkBool true - "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 - mkOption { - type = types.nullOr (types.submodule diffOptModule); - default = null; - description = "Diff options. If set to null they are derived from the vim diffopt"; - }; - base = mkOption { - type = types.nullOr types.str; - default = null; - description = "The object/revision to diff against. Default to 'index'"; - }; - countChars = - helpers.defaultNullOpts.mkNullable (types.attrsOf types.str) '' - { - "1" = "1"; - "2" = "2"; - "3" = "3"; - "4" = "4"; - "5" = "5"; - "6" = "6"; - "7" = "7"; - "8" = "8"; - "9" = "9"; - "+" = ">"; - } - '' '' - The count characters used when `signs.*.show_count` is enabled. The - `+` entry is used as a fallback. With the default, any count outside - of 1-9 uses the `>` character in the sign. - - Possible use cases for this field: - • to specify unicode characters for the counts instead of 1-9. - • to define characters to be used for counts greater than 9. - ''; - statusFormatter = helpers.defaultNullOpts.mkNullable luaFunction '' - { - function = \'\' - function(status) - local added, changed, removed = status.added, status.changed, status.removed - local status_txt = {} - if added and added > 0 then table.insert(status_txt, '+'..added ) end - if changed and changed > 0 then table.insert(status_txt, '~'..changed) end - if removed and removed > 0 then table.insert(status_txt, '-'..removed) end - return table.concat(status_txt, ' ') - end - \'\'; - } - '' "Function used to format `b:gitsigns_status`"; - maxFileLength = - helpers.defaultNullOpts.mkInt 40000 - "Max file length (in lines) to attach to"; - previewConfig = - helpers.defaultNullOpts.mkNullable (types.attrsOf types.anything) '' - { - border = "single"; - style = "minimal"; - relative = "cursor"; - row = 0; - col = 1; - } - '' '' - Option overrides for the Gitsigns preview window. - Table is passed directly to `nvim_open_win`. - ''; - attachToUntracked = - helpers.defaultNullOpts.mkBool true - "Attach to untracked files."; - updateDebounce = - helpers.defaultNullOpts.mkInt 100 - "Debounce time for updates (in milliseconds)."; - currentLineBlame = helpers.defaultNullOpts.mkBool false '' - Adds an unobtrusive and customisable blame annotation at the end of the current line. - ''; - currentLineBlameOpts = { - virtText = - helpers.defaultNullOpts.mkBool true - "Whether to show a virtual text blame annotation"; - virtTextPos = - helpers.defaultNullOpts.mkEnumFirstDefault ["eol" "overlay" "right_align"] - "Blame annotation position"; - delay = - helpers.defaultNullOpts.mkInt 1000 - "Sets the delay (in milliseconds) before blame virtual text is displayed"; - ignoreWhitespace = - helpers.defaultNullOpts.mkBool false - "Ignore whitespace when running blame"; - virtTextPriority = - helpers.defaultNullOpts.mkInt 100 - "Priority of virtual text"; - }; - currentLineBlameFormatter = { - normal = - helpers.defaultNullOpts.mkNullable (types.either types.str luaFunction) - ''" , - "'' '' - String or function used to format the virtual text of - |gitsigns-config-current_line_blame|. - - See |gitsigns-config-current_line_blame_formatter| for more details. - ''; - - nonCommitted = - helpers.defaultNullOpts.mkNullable (types.either types.str luaFunction) - ''" "'' '' - String or function used to format the virtual text of - |gitsigns-config-current_line_blame| for lines that aren't committed. - ''; - }; - trouble = mkOption { - type = types.nullOr types.bool; - default = null; - description = '' - When using setqflist() or setloclist(), open Trouble instead of the quickfix/location list - window. - ''; - }; - yadm.enable = helpers.defaultNullOpts.mkBool false "YADM support"; - wordDiff = helpers.defaultNullOpts.mkBool false '' - Highlight intra-line word differences in the buffer. - Requires `config.diff_opts.internal = true`. - ''; - debugMode = helpers.defaultNullOpts.mkBool false '' - Enables debug logging and makes the following functions available: `dump_cache`, - `debug_messages`, `clear_debug`. - ''; - }; - - config = let - cfg = config.plugins.gitsigns; - in - mkIf cfg.enable { - extraPlugins = [cfg.package]; - - extraPackages = optional (cfg.gitPackage != null) cfg.gitPackage; - - extraConfigLua = let - luaFnOrStrToObj = val: - if val == null - then null - else if builtins.isString val - then val - else {__raw = val.function;}; - setupOptions = { - inherit (cfg) worktrees signcolumn numhl linehl trouble yadm base; - 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; - }; - count_chars = let - isStrInt = s: (builtins.match "[0-9]+" s) != null; - in - if cfg.countChars != null - then { - __raw = - "{" - + (concatStringsSep "," ( - lib.mapAttrsToList - ( - name: value: - if isStrInt name - then "[${name}] = ${helpers.toLuaObject value}" - else "[${helpers.toLuaObject name}] = ${helpers.toLuaObject value}" - ) - cfg.countChars - )) - + "}"; - } - else null; - status_formatter = - if cfg.statusFormatter != null - then {__raw = cfg.statusFormatter.function;} - else null; - 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}) - ''; - }; -} diff --git a/plugins/git/gitsigns/default.nix b/plugins/git/gitsigns/default.nix new file mode 100644 index 00000000..4d44ce53 --- /dev/null +++ b/plugins/git/gitsigns/default.nix @@ -0,0 +1,155 @@ +{ + lib, + helpers, + config, + pkgs, + ... +}: +with lib; + helpers.neovim-plugin.mkNeovimPlugin config { + name = "gitsigns"; + originalName = "gitsigns.nvim"; + defaultPackage = pkgs.vimPlugins.gitsigns-nvim; + + maintainers = [maintainers.GaetanLepage]; + + # TODO: introduced 2024-03-12, remove on 2024-05-12 + deprecateExtraOptions = true; + optionsRenamedToSettings = [ + ["signs" "add" "hl"] + ["signs" "add" "text"] + ["signs" "add" "numhl"] + ["signs" "add" "linehl"] + ["signs" "add" "showCount"] + ["signs" "change" "hl"] + ["signs" "change" "text"] + ["signs" "change" "numhl"] + ["signs" "change" "linehl"] + ["signs" "change" "showCount"] + ["signs" "topdelete" "hl"] + ["signs" "topdelete" "text"] + ["signs" "topdelete" "numhl"] + ["signs" "topdelete" "linehl"] + ["signs" "topdelete" "showCount"] + ["signs" "changedelete" "hl"] + ["signs" "changedelete" "text"] + ["signs" "changedelete" "numhl"] + ["signs" "changedelete" "linehl"] + ["signs" "changedelete" "showCount"] + ["signs" "untracked" "hl"] + ["signs" "untracked" "text"] + ["signs" "untracked" "numhl"] + ["signs" "untracked" "linehl"] + ["signs" "untracked" "showCount"] + "worktrees" + "signPriority" + "signcolumn" + "numhl" + "linehl" + "showDeleted" + ["diffOpts" "algorithm"] + ["diffOpts" "internal"] + ["diffOpts" "indentHeuristic"] + ["diffOpts" "vertical"] + ["diffOpts" "linematch"] + "base" + "countChars" + "maxFileLength" + "previewConfig" + "attachToUntracked" + "updateDebounce" + "currentLineBlame" + ["currentLineBlameOpts" "virtText"] + ["currentLineBlameOpts" "virtTextPos"] + ["currentLineBlameOpts" "delay"] + ["currentLineBlameOpts" "ignoreWhitespace"] + ["currentLineBlameOpts" "virtTextPriority"] + "trouble" + ["yadm" "enable"] + "wordDiff" + "debugMode" + ]; + imports = let + basePluginPaths = ["plugins" "gitsigns"]; + settingsPath = basePluginPaths ++ ["settings"]; + in [ + ( + mkRenamedOptionModule + (basePluginPaths ++ ["onAttach" "function"]) + (settingsPath ++ ["on_attach"]) + ) + ( + mkRenamedOptionModule + (basePluginPaths ++ ["watchGitDir" "enable"]) + (settingsPath ++ ["watch_gitdir" "enable"]) + ) + ( + mkRemovedOptionModule + (basePluginPaths ++ ["watchGitDir" "interval"]) + "The option has been removed from upstream." + ) + ( + mkRenamedOptionModule + (basePluginPaths ++ ["watchGitDir" "followFiles"]) + (settingsPath ++ ["watch_gitdir" "follow_files"]) + ) + ( + mkRenamedOptionModule + (basePluginPaths ++ ["statusFormatter" "function"]) + (settingsPath ++ ["status_formatter"]) + ) + ( + mkRenamedOptionModule + (basePluginPaths ++ ["currentLineBlameFormatter" "normal"]) + (settingsPath ++ ["current_line_blame_formatter"]) + ) + ( + mkRenamedOptionModule + (basePluginPaths ++ ["currentLineBlameFormatter" "nonCommitted"]) + (settingsPath ++ ["current_line_blame_formatter_nc"]) + ) + ]; + + extraOptions = { + gitPackage = mkOption { + type = with types; nullOr package; + default = pkgs.git; + description = '' + Which package to use for `git`. + Set to `null` to prevent the installation. + ''; + }; + }; + + settingsOptions = import ./options.nix {inherit lib helpers;}; + + settingsExample = { + signs = { + add.text = "│"; + change.text = "│"; + delete.text = "_"; + topdelete.text = "‾"; + changedelete.text = "~"; + untracked.text = "┆"; + }; + signcolumn = true; + watch_gitdir.follow_files = true; + current_line_blame = false; + current_line_blame_opts = { + virt_text = true; + virt_text_pos = "eol"; + }; + }; + + extraConfig = cfg: { + warnings = + optional + ((isBool cfg.settings.trouble && cfg.settings.trouble) && !config.plugins.trouble.enable) + '' + Nixvim (plugins.gitsigns): You have enabled `plugins.gitsigns.settings.trouble` but + `plugins.trouble.enable` is `false`. + You should maybe enable the `trouble` plugin. + ''; + extraPackages = optional (cfg.gitPackage != null) cfg.gitPackage; + }; + } diff --git a/plugins/git/gitsigns/options.nix b/plugins/git/gitsigns/options.nix new file mode 100644 index 00000000..0951495b --- /dev/null +++ b/plugins/git/gitsigns/options.nix @@ -0,0 +1,430 @@ +{ + lib, + helpers, +}: +with lib; { + signs = let + signOptions = defaults: { + hl = helpers.defaultNullOpts.mkStr defaults.hl '' + Specifies the highlight group to use for the sign. + ''; + + text = helpers.defaultNullOpts.mkStr defaults.text '' + Specifies the character to use for the sign. + ''; + + numhl = helpers.defaultNullOpts.mkStr defaults.numhl '' + Specifies the highlight group to use for the number column. + ''; + + linehl = helpers.defaultNullOpts.mkStr defaults.linehl '' + Specifies the highlight group to use for the line. + ''; + + show_count = helpers.defaultNullOpts.mkBool false '' + Showing count of hunk, e.g. number of deleted lines. + ''; + }; + in { + add = signOptions { + hl = "GitSignsAdd"; + text = "┃"; + numhl = "GitSignsAddNr"; + linehl = "GitSignsAddLn"; + }; + change = signOptions { + hl = "GitSignsChange"; + text = "┃"; + numhl = "GitSignsChangeNr"; + linehl = "GitSignsChangeLn"; + }; + delete = signOptions { + hl = "GitSignsDelete"; + text = "▁"; + numhl = "GitSignsDeleteNr"; + linehl = "GitSignsDeleteLn"; + }; + topdelete = signOptions { + hl = "GitSignsDelete"; + text = "▔"; + numhl = "GitSignsDeleteNr"; + linehl = "GitSignsDeleteLn"; + }; + changedelete = signOptions { + hl = "GitSignsChange"; + text = "~"; + numhl = "GitSignsChangeNr"; + linehl = "GitSignsChangeLn"; + }; + untracked = signOptions { + hl = "GitSignsAdd"; + text = "┆"; + numhl = "GitSignsAddNr"; + linehl = "GitSignsAddLn"; + }; + }; + + worktrees = let + worktreeType = types.submodule { + freeformType = with types; attrsOf anything; + options = { + toplevel = mkOption { + type = with helpers.nixvimTypes; maybeRaw str; + }; + + gitdir = mkOption { + type = with helpers.nixvimTypes; maybeRaw str; + }; + }; + }; + in + helpers.mkNullOrOption (types.listOf worktreeType) '' + Detached working trees. + If normal attaching fails, then each entry in the table is attempted with the work tree + details set. + ''; + + on_attach = helpers.mkNullOrLuaFn '' + Callback called when attaching to a buffer. Mainly used to setup keymaps + when `config.keymaps` is empty. The buffer number is passed as the first + argument. + + This callback can return `false` to prevent attaching to the buffer. + + Example: + ```lua + function(bufnr) + if vim.api.nvim_buf_get_name(bufnr):match() then + -- Don't attach to specific buffers whose name matches a pattern + return false + end + -- Setup keymaps + vim.api.nvim_buf_set_keymap(bufnr, 'n', 'hs', 'lua require"gitsigns".stage_hunk()', {}) + ... -- More keymaps + end + ``` + ''; + + watch_gitdir = { + enable = helpers.defaultNullOpts.mkBool true '' + When opening a file, a `libuv` watcher is placed on the respective `.git` directory to detect + when changes happen to use as a trigger to update signs. + ''; + + follow_files = helpers.defaultNullOpts.mkBool true '' + If a file is moved with `git mv`, switch the buffer to the new location. + ''; + }; + + sign_priority = helpers.defaultNullOpts.mkUnsignedInt 6 '' + Priority to use for signs. + ''; + + signcolumn = helpers.defaultNullOpts.mkBool true '' + Enable/disable symbols in the sign column. + + When enabled the highlights defined in `signs.*.hl` and symbols defined in `signs.*.text` are + used. + ''; + + numhl = helpers.defaultNullOpts.mkBool false '' + Enable/disable 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 = helpers.defaultNullOpts.mkBool false '' + Enable/disable 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`. + ''; + + show_deleted = helpers.defaultNullOpts.mkBool false '' + Show the old version of hunks inline in the buffer (via virtual lines). + + Note: Virtual lines currently use the highlight `GitSignsDeleteVirtLn`. + ''; + + diff_opts = let + diffOptType = types.submodule { + freeformType = with types; attrsOf anything; + options = { + algorithm = + helpers.defaultNullOpts.mkEnumFirstDefault + ["myers" "minimal" "patience" "histogram"] + '' + Diff algorithm to use. Values: + - "myers" the default algorithm + - "minimal" spend extra time to generate the smallest possible diff + - "patience" patience diff algorithm + - "histogram" histogram diff algorithm + ''; + + internal = helpers.defaultNullOpts.mkBool false '' + Use Neovim's built in `xdiff` library for running diffs. + ''; + + indent_heuristic = helpers.defaultNullOpts.mkBool false '' + Use the indent heuristic for the internal diff library. + ''; + + vertical = helpers.defaultNullOpts.mkBool true '' + Start diff mode with vertical splits. + ''; + + linematch = helpers.mkNullOrOption types.int '' + Enable second-stage diff on hunks to align lines. + Requires `internal=true`. + ''; + + ignore_blank_lines = helpers.defaultNullOpts.mkBool true '' + Ignore changes where lines are blank. + ''; + + ignore_whitespace_change = helpers.defaultNullOpts.mkBool true '' + Ignore changes in amount of white space. + It should ignore adding trailing white space, but not leading white space. + ''; + + ignore_whitespace = helpers.defaultNullOpts.mkBool true '' + Ignore all white space changes. + ''; + + ignore_whitespace_change_at_eol = helpers.defaultNullOpts.mkBool true '' + Ignore white space changes at end of line. + ''; + }; + }; + in + helpers.mkNullOrOption diffOptType '' + Diff options. + If set to null they are derived from the vim `diffopt`. + ''; + + base = helpers.mkNullOrOption types.str '' + The object/revision to diff against. + See `|gitsigns-revision|`. + ''; + + count_chars = + helpers.defaultNullOpts.mkAttrsOf types.str + '' + { + "__unkeyed_1" = "1"; + "__unkeyed_2" = "2"; + "__unkeyed_3" = "3"; + "__unkeyed_4" = "4"; + "__unkeyed_5" = "5"; + "__unkeyed_6" = "6"; + "__unkeyed_7" = "7"; + "__unkeyed_8" = "8"; + "__unkeyed_9" = "9"; + "+" = ">"; + } + '' + '' + The count characters used when `signs.*.show_count` is enabled. + The `+` entry is used as a fallback. With the default, any count outside of 1-9 uses the `>` + character in the sign. + + Possible use cases for this field: + - to specify unicode characters for the counts instead of 1-9. + - to define characters to be used for counts greater than 9. + ''; + + status_formatter = + helpers.defaultNullOpts.mkLuaFn + '' + function(status) + local added, changed, removed = status.added, status.changed, status.removed + local status_txt = {} + if added and added > 0 then + table.insert(status_txt, '+' .. added) + end + if changed and changed > 0 then + table.insert(status_txt, '~' .. changed) + end + if removed and removed > 0 then + table.insert(status_txt, '-' .. removed) + end + return table.concat(status_txt, ' ') + end + '' + "Function used to format `b:gitsigns_status`."; + + max_file_length = helpers.defaultNullOpts.mkUnsignedInt 40000 '' + Max file length (in lines) to attach to. + ''; + + preview_config = + helpers.defaultNullOpts.mkAttrsOf types.anything + '' + { + border = "single"; + style = "minimal"; + relative = "cursor"; + row = 0; + col = 1; + } + '' + '' + Option overrides for the Gitsigns preview window. + Table is passed directly to `nvim_open_win`. + ''; + + auto_attach = helpers.defaultNullOpts.mkBool true '' + Automatically attach to files. + ''; + + attach_to_untracked = helpers.defaultNullOpts.mkBool true '' + Attach to untracked files. + ''; + + update_debounce = helpers.defaultNullOpts.mkUnsignedInt 100 '' + Debounce time for updates (in milliseconds). + ''; + + current_line_blame = helpers.defaultNullOpts.mkBool false '' + Adds an unobtrusive and customisable blame annotation at the end of the current line. + The highlight group used for the text is `GitSignsCurrentLineBlame`. + ''; + + current_line_blame_opts = { + virt_text = helpers.defaultNullOpts.mkBool true '' + Whether to show a virtual text blame annotation + ''; + + virt_text_pos = helpers.defaultNullOpts.mkEnumFirstDefault ["eol" "overlay" "right_align"] '' + Blame annotation position. + + Available values: + - `eol` Right after eol character. + - `overlay` Display over the specified column, without shifting the underlying text. + - `right_align` Display right aligned in the window. + ''; + + delay = helpers.defaultNullOpts.mkUnsignedInt 1000 '' + Sets the delay (in milliseconds) before blame virtual text is displayed. + ''; + + ignore_whitespace = helpers.defaultNullOpts.mkBool false '' + Ignore whitespace when running blame. + ''; + + virt_text_priority = helpers.defaultNullOpts.mkUnsignedInt 100 '' + Priority of virtual text. + ''; + }; + + current_line_blame_formatter = + helpers.defaultNullOpts.mkStr + " , - " + '' + String or function used to format the virtual text of `current_line_blame`. + + When a string, accepts the following format specifiers: + - `` + - `` + - `` + - `` + - `` + - `` or `` + - `` + - `` + - `` + - `` or `` + - `` + - `` + - `` + - `` + + For `` and ``, `FORMAT` can be any valid date + format that is accepted by `os.date()` with the addition of `%R` (defaults to `%Y-%m-%d`): + - `%a` abbreviated weekday name (e.g., Wed) + - `%A` full weekday name (e.g., Wednesday) + - `%b` abbreviated month name (e.g., Sep) + - `%B` full month name (e.g., September) + - `%c` date and time (e.g., 09/16/98 23:48:10) + - `%d` day of the month (16) [01-31] + - `%H` hour, using a 24-hour clock (23) [00-23] + - `%I` hour, using a 12-hour clock (11) [01-12] + - `%M` minute (48) [00-59] + - `%m` month (09) [01-12] + - `%p` either "am" or "pm" (pm) + - `%S` second (10) [00-61] + - `%w` weekday (3) [0-6 = Sunday-Saturday] + - `%x` date (e.g., 09/16/98) + - `%X` time (e.g., 23:48:10) + - `%Y` full year (1998) + - `%y` two-digit year (98) [00-99] + - `%%` the character `%´ + - `%R` relative (e.g., 4 months ago) + + When a function: + + Parameters: + - `{name}` Git user name returned from `git config user.name` + - `{blame_info}` Table with the following keys: + - `abbrev_sha`: string + - `orig_lnum`: integer + - `final_lnum`: integer + - `author`: string + - `author_mail`: string + - `author_time`: integer + - `author_tz`: string + - `committer`: string + - `committer_mail`: string + - `committer_time`: integer + - `committer_tz`: string + - `summary`: string + - `previous`: string + - `filename`: string + - `boundary`: true? + + Note that the keys map onto the output of: + `git blame --line-porcelain` + + - {opts} Passed directly from `settings.current_line_blame_formatter_opts`. + + Return: + The result of this function is passed directly to the `opts.virt_text` field of + `|nvim_buf_set_extmark|` and thus must be a list of `[text, highlight]` tuples. + ''; + + current_line_blame_formatter_nc = + helpers.defaultNullOpts.mkStr + " " + '' + String or function used to format the virtual text of `|gitsigns-config-current_line_blame|` + for lines that aren't committed. + + See `|gitsigns-config-current_line_blame_formatter|` for more information. + ''; + + trouble = helpers.mkNullOrOption types.bool '' + When using setqflist() or setloclist(), open Trouble instead of the + quickfix/location list window. + + Default: `pcall(require, 'trouble')` + ''; + + yadm = { + enable = helpers.defaultNullOpts.mkBool false '' + Enable YADM support. + ''; + }; + + word_diff = helpers.defaultNullOpts.mkBool false '' + Highlight intra-line word differences in the buffer. + Requires `config.diff_opts.internal = true`. + ''; + + debug_mode = helpers.defaultNullOpts.mkBool false '' + Enables debug logging and makes the following functions available: `dump_cache`, + `debug_messages`, `clear_debug`. + ''; +} diff --git a/tests/test-sources/plugins/git/gitsigns.nix b/tests/test-sources/plugins/git/gitsigns.nix new file mode 100644 index 00000000..9694b405 --- /dev/null +++ b/tests/test-sources/plugins/git/gitsigns.nix @@ -0,0 +1,144 @@ +{ + empty = { + plugins.gitsigns.enable = true; + }; + + example = { + plugins.gitsigns = { + enable = true; + + settings = { + signs = { + add = { + hl = "GitSignsAdd"; + text = "┃"; + numhl = "GitSignsAddNr"; + linehl = "GitSignsAddLn"; + }; + change = { + hl = "GitSignsChange"; + text = "┃"; + numhl = "GitSignsChangeNr"; + linehl = "GitSignsChangeLn"; + }; + delete = { + hl = "GitSignsDelete"; + text = "▁"; + numhl = "GitSignsDeleteNr"; + linehl = "GitSignsDeleteLn"; + }; + topdelete = { + hl = "GitSignsDelete"; + text = "▔"; + numhl = "GitSignsDeleteNr"; + linehl = "GitSignsDeleteLn"; + }; + changedelete = { + hl = "GitSignsChange"; + text = "~"; + numhl = "GitSignsChangeNr"; + linehl = "GitSignsChangeLn"; + }; + untracked = { + hl = "GitSignsAdd"; + text = "┆"; + numhl = "GitSignsAddNr"; + linehl = "GitSignsAddLn"; + }; + }; + worktrees = [ + { + toplevel.__raw = "vim.env.HOME"; + gitdir.__raw = "vim.env.HOME .. '/projects/dotfiles/.git'"; + } + ]; + on_attach = '' + function(bufnr) + if vim.api.nvim_buf_get_name(bufnr):match("test.txt") then + -- Don't attach to specific buffers whose name matches a pattern + return false + end + -- Setup keymaps + vim.api.nvim_buf_set_keymap(bufnr, 'n', 'hs', 'lua require"gitsigns".stage_hunk()', {}) + end + ''; + watch_gitdir = { + enable = true; + follow_files = true; + }; + sign_priority = 6; + signcolumn = true; + numhl = false; + linehl = false; + show_deleted = false; + diff_opts = { + algorithm = "myers"; + internal = false; + indent_heuristic = false; + vertical = true; + linematch = null; + ignore_blank_lines = true; + ignore_whitespace_change = true; + ignore_whitespace = true; + ignore_whitespace_change_at_eol = true; + }; + base = null; + count_chars = { + "__unkeyed_1" = "1"; + "__unkeyed_2" = "2"; + "__unkeyed_3" = "3"; + "__unkeyed_4" = "4"; + "__unkeyed_5" = "5"; + "__unkeyed_6" = "6"; + "__unkeyed_7" = "7"; + "__unkeyed_8" = "8"; + "__unkeyed_9" = "9"; + "+" = ">"; + }; + status_formatter = '' + function(status) + local added, changed, removed = status.added, status.changed, status.removed + local status_txt = {} + if added and added > 0 then + table.insert(status_txt, '+' .. added) + end + if changed and changed > 0 then + table.insert(status_txt, '~' .. changed) + end + if removed and removed > 0 then + table.insert(status_txt, '-' .. removed) + end + return table.concat(status_txt, ' ') + end + ''; + max_file_length = 40000; + preview_config = { + border = "single"; + style = "minimal"; + relative = "cursor"; + row = 0; + col = 1; + }; + auto_attach = true; + attach_to_untracked = true; + update_debounce = 100; + current_line_blame = false; + current_line_blame_opts = { + virt_text = true; + virt_text_pos = "eol"; + delay = 1000; + ignore_whitespace = false; + virt_text_priority = 100; + }; + current_line_blame_formatter = " , - "; + current_line_blame_formatter_nc = " "; + trouble = false; + yadm = { + enable = false; + }; + word_diff = false; + debug_mode = false; + }; + }; + }; +}