From 514a51877df9fe41ffc38c5237e3c4e5327e7607 Mon Sep 17 00:00:00 2001 From: Gaetan Lepage Date: Tue, 16 Apr 2024 14:35:42 +0200 Subject: [PATCH] plugins/statuscol: init --- plugins/default.nix | 1 + plugins/ui/statuscol.nix | 185 ++++++++++++++++++++ tests/test-sources/plugins/ui/statuscol.nix | 61 +++++++ 3 files changed, 247 insertions(+) create mode 100644 plugins/ui/statuscol.nix create mode 100644 tests/test-sources/plugins/ui/statuscol.nix diff --git a/plugins/default.nix b/plugins/default.nix index ef66974b..1e20a842 100644 --- a/plugins/default.nix +++ b/plugins/default.nix @@ -114,6 +114,7 @@ ./ui/image.nix ./ui/neoscroll.nix ./ui/noice.nix + ./ui/statuscol.nix ./ui/transparent.nix ./ui/twilight.nix ./ui/virt-column.nix diff --git a/plugins/ui/statuscol.nix b/plugins/ui/statuscol.nix new file mode 100644 index 00000000..1f8db24e --- /dev/null +++ b/plugins/ui/statuscol.nix @@ -0,0 +1,185 @@ +{ + lib, + helpers, + config, + pkgs, + ... +}: +with lib; + helpers.neovim-plugin.mkNeovimPlugin config { + name = "statuscol"; + originalName = "statuscol.nvim"; + defaultPackage = pkgs.vimPlugins.statuscol-nvim; + + maintainers = [maintainers.GaetanLepage]; + + settingsOptions = { + setopt = helpers.defaultNullOpts.mkBool true '' + Whether to set the `statuscolumn` option, may be set to false for those who want to use the + click handlers in their own `statuscolumn`: `_G.Sc[SFL]a()`. + Although I recommend just using the segments field below to build your statuscolumn to + benefit from the performance optimizations in this plugin. + ''; + + thousands = helpers.defaultNullOpts.mkNullable (with types; either str (enum [false])) "false" '' + `false` or line number thousands separator string ("." / ","). + ''; + + relculright = helpers.defaultNullOpts.mkBool false '' + Whether to right-align the cursor line number with `relativenumber` set. + ''; + + ft_ignore = helpers.defaultNullOpts.mkListOf types.str "null" '' + Lua table with 'filetype' values for which `statuscolumn` will be unset. + ''; + + bt_ignore = helpers.defaultNullOpts.mkListOf types.str "null" '' + Lua table with 'buftype' values for which `statuscolumn` will be unset. + ''; + + segments = let + segmentType = types.submodule { + freeformType = with types; attrsOf anything; + options = { + text = mkOption { + type = with helpers.nixvimTypes; listOf (either str rawLua); + description = "Segment text."; + example = ["%C"]; + }; + + click = helpers.mkNullOrStr '' + `%@` click function label, applies to each text element. + ''; + + hl = helpers.mkNullOrStr '' + `%#` highlight group label, applies to each text element. + ''; + + condition = + helpers.mkNullOrOption + ( + with helpers.nixvimTypes; + listOf (either bool rawLua) + ) + "Table of booleans or functions returning a boolean."; + + sign = { + name = helpers.defaultNullOpts.mkListOf types.str "[]" '' + List of lua patterns to match the sign name against. + ''; + + text = helpers.defaultNullOpts.mkListOf types.str "[]" '' + List of lua patterns to match the extmark sign text against. + ''; + + namespace = helpers.defaultNullOpts.mkListOf types.str "[]" '' + List of lua patterns to match the extmark sign namespace against. + ''; + + maxwidth = helpers.defaultNullOpts.mkUnsignedInt 1 '' + Maximum number of signs that will be displayed in this segment + ''; + + colwidth = helpers.defaultNullOpts.mkUnsignedInt 2 '' + Maximum number of display cells per sign in this segment. + ''; + + auto = helpers.defaultNullOpts.mkBool false '' + When true, the segment will not be drawn if no signs matching the pattern are + currently placed in the buffer. + ''; + + fillchar = helpers.defaultNullOpts.mkStr " " '' + Character used to fill a segment with less signs than maxwidth. + ''; + + fillcharhl = helpers.mkNullOrStr '' + Highlight group used for fillchar (SignColumn/CursorLineSign if omitted). + ''; + }; + }; + }; + in + helpers.defaultNullOpts.mkListOf segmentType + '' + [ + { + text = ["%C"]; + click = "v:lua.ScFa"; + } + { + text = ["%s"]; + click = "v:lua.ScSa"; + } + { + text = [ + {__raw = "require('statuscol.builtin').lnumfunc";} + " " + ]; + condition = [ + true + {__raw = "require('statuscol.builtin').not_empty";} + ]; + click = "v:lua.ScLa"; + } + ] + '' + "The statuscolumn can be customized through the `segments` option."; + + clickmod = helpers.defaultNullOpts.mkStr "c" '' + Modifier used for certain actions in the builtin clickhandlers: + `a` for Alt, `c` for Ctrl and `m` for Meta. + ''; + + clickhandlers = mkOption { + type = with helpers.nixvimTypes; attrsOf strLuaFn; + default = {}; + description = '' + Builtin click handlers. + ''; + apply = mapAttrs (_: helpers.mkRaw); + example = { + Lnum = "require('statuscol.builtin').lnum_click"; + FoldClose = "require('statuscol.builtin').foldclose_click"; + FoldOpen = "require('statuscol.builtin').foldopen_click"; + FoldOther = "require('statuscol.builtin').foldother_click"; + }; + }; + }; + + settingsExample = { + setopt = true; + thousands = "."; + relculright = true; + ft_ignore = null; + bt_ignore = null; + segments = [ + { + text = ["%C"]; + click = "v:lua.ScFa"; + } + { + text = ["%s"]; + click = "v:lua.ScSa"; + } + { + text = [ + {__raw = "require('statuscol.builtin').lnumfunc";} + " " + ]; + condition = [ + true + {__raw = "require('statuscol.builtin').not_empty";} + ]; + click = "v:lua.ScLa"; + } + ]; + clickmod = "c"; + clickhandlers = { + Lnum = "require('statuscol.builtin').lnum_click"; + FoldClose = "require('statuscol.builtin').foldclose_click"; + FoldOpen = "require('statuscol.builtin').foldopen_click"; + FoldOther = "require('statuscol.builtin').foldother_click"; + }; + }; + } diff --git a/tests/test-sources/plugins/ui/statuscol.nix b/tests/test-sources/plugins/ui/statuscol.nix new file mode 100644 index 00000000..c8f7fb9b --- /dev/null +++ b/tests/test-sources/plugins/ui/statuscol.nix @@ -0,0 +1,61 @@ +{ + empty = { + plugins.statuscol.enable = true; + }; + + defaults = { + plugins.statuscol = { + enable = true; + + settings = { + setopt = true; + thousands = false; + relculright = false; + ft_ignore = null; + bt_ignore = null; + segments = [ + { + text = ["%C"]; + click = "v:lua.ScFa"; + } + { + text = ["%s"]; + click = "v:lua.ScSa"; + } + { + text = [ + {__raw = "require('statuscol.builtin').lnumfunc";} + " " + ]; + condition = [ + true + {__raw = "require('statuscol.builtin').not_empty";} + ]; + click = "v:lua.ScLa"; + } + ]; + clickmod = "c"; + clickhandlers = { + Lnum = "require('statuscol.builtin').lnum_click"; + FoldClose = "require('statuscol.builtin').foldclose_click"; + FoldOpen = "require('statuscol.builtin').foldopen_click"; + FoldOther = "require('statuscol.builtin').foldother_click"; + DapBreakpointRejected = "require('statuscol.builtin').toggle_breakpoint"; + DapBreakpoint = "require('statuscol.builtin').toggle_breakpoint"; + DapBreakpointCondition = "require('statuscol.builtin').toggle_breakpoint"; + DiagnosticSignError = "require('statuscol.builtin').diagnostic_click"; + DiagnosticSignHint = "require('statuscol.builtin').diagnostic_click"; + DiagnosticSignInfo = "require('statuscol.builtin').diagnostic_click"; + DiagnosticSignWarn = "require('statuscol.builtin').diagnostic_click"; + GitSignsTopdelete = "require('statuscol.builtin').gitsigns_click"; + GitSignsUntracked = "require('statuscol.builtin').gitsigns_click"; + GitSignsAdd = "require('statuscol.builtin').gitsigns_click"; + GitSignsChange = "require('statuscol.builtin').gitsigns_click"; + GitSignsChangedelete = "require('statuscol.builtin').gitsigns_click"; + GitSignsDelete = "require('statuscol.builtin').gitsigns_click"; + gitsigns_extmark_signs_ = "require('statuscol.builtin').gitsigns_click"; + }; + }; + }; + }; +}