plugins/todo-comments: refactoring + tests (#239)

This commit is contained in:
Gaétan Lepage 2023-03-12 11:49:41 +01:00 committed by GitHub
parent 8b21fd5872
commit 933c87c282
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 305 additions and 106 deletions

View file

@ -7,6 +7,13 @@
with lib; let
cfg = config.plugins.todo-comments;
helpers = import ../helpers.nix {inherit lib;};
commands = {
todoQuickFix = "TodoQuickFix";
todoLocList = "TodoLocList";
todoTrouble = "TodoTrouble";
todoTelescope = "TodoTelescope";
};
in {
options = {
plugins.todo-comments =
@ -19,103 +26,109 @@ in {
"todo-comments"
pkgs.vimPlugins.todo-comments-nvim;
signs = helpers.defaultNullOpts.mkBool true ''
Show icons in the signs column.
'';
signs = helpers.defaultNullOpts.mkBool true "Show icons in the signs column.";
signPriority = helpers.defaultNullOpts.mkInt 8 "Sign priority.";
keywords = helpers.mkNullOrOption (types.nullOr types.attrs) ''
Configurations for keywords to be recognized as todo comments.
Default:
```
{
FIX = {
icon = " "; # Icon used for the sign, and in search results.
color = "error"; # Can be a hex color, or a named color.
alt = [ "FIXME" "BUG" "FIXIT" "ISSUE" ]; # A set of other keywords that all map to this FIX keywords.
};
TODO = { icon = " "; color = "info"; };
HACK = { icon = " "; color = "warning"; };
WARN = { icon = " "; color = "warning"; alt = [ "WARNING" "XXX" ]; };
PERF = { icon = " "; alt = [ "OPTIM" "PERFORMANCE" "OPTIMIZE" ]; };
NOTE = { icon = " "; color = "hint"; alt = [ "INFO" ]; };
TEST = { icon = " "; color = "test"; alt = [ "TESTING" "PASSED" "FAILED" ]; };
};
```
'';
guiStyle = mkOption {
description = "The gui style for highlight groups.";
default = null;
type = types.nullOr (types.submodule ({...}: {
keywords =
helpers.mkNullOrOption
(types.attrsOf (types.submodule {
options = {
fg = helpers.defaultNullOpts.mkStr "NONE" ''
The gui style to use for the fg highlight group.
icon = helpers.mkNullOrOption types.str ''
Icon used for the sign, and in search results.
'';
bg = helpers.defaultNullOpts.mkStr "BOLD" ''
The gui style to use for the bg highlight group.
color = helpers.mkNullOrOption types.str ''
Can be a hex color, or a named color.
'';
alt = helpers.mkNullOrOption (types.listOf types.str) ''
A set of other keywords that all map to this FIX keywords.
'';
signs = helpers.mkNullOrOption types.bool ''
Configure signs for some keywords individually.
'';
};
}));
}))
''
Configurations for keywords to be recognized as todo comments.
Default:
```
{
FIX = {
icon = " "; # Icon used for the sign, and in search results.
color = "error"; # Can be a hex color, or a named color.
alt = [ "FIXME" "BUG" "FIXIT" "ISSUE" ]; # A set of other keywords that all map to this FIX keywords.
};
TODO = { icon = " "; color = "info"; };
HACK = { icon = " "; color = "warning"; };
WARN = { icon = " "; color = "warning"; alt = [ "WARNING" "XXX" ]; };
PERF = { icon = " "; alt = [ "OPTIM" "PERFORMANCE" "OPTIMIZE" ]; };
NOTE = { icon = " "; color = "hint"; alt = [ "INFO" ]; };
TEST = { icon = " "; color = "test"; alt = [ "TESTING" "PASSED" "FAILED" ]; };
};
```
'';
guiStyle = helpers.mkCompositeOption "The gui style for highlight groups." {
fg = helpers.defaultNullOpts.mkStr "NONE" ''
The gui style to use for the fg highlight group.
'';
bg = helpers.defaultNullOpts.mkStr "BOLD" ''
The gui style to use for the bg highlight group.
'';
};
mergeKeywords = helpers.defaultNullOpts.mkBool true ''
When true, custom keywords will be merged with the default
'';
highlight = mkOption {
description = "Highlight options";
default = null;
type = types.nullOr (types.submodule ({...}: {
options = {
multiline = helpers.defaultNullOpts.mkBool true ''
Enable multiline todo comments.
'';
highlight = helpers.mkCompositeOption "Highlight options." {
multiline = helpers.defaultNullOpts.mkBool true ''
Enable multiline todo comments.
'';
multilinePattern = helpers.defaultNullOpts.mkStr "^." ''
Lua pattern to match the next multiline from the start of the
matched keyword.
'';
multilinePattern = helpers.defaultNullOpts.mkStr "^." ''
Lua pattern to match the next multiline from the start of the
matched keyword.
'';
multilineContext = helpers.defaultNullOpts.mkInt 10 ''
Extra lines that will be re-evaluated when changing a line.
'';
multilineContext = helpers.defaultNullOpts.mkInt 10 ''
Extra lines that will be re-evaluated when changing a line.
'';
before = helpers.defaultNullOpts.mkStr "" ''
"fg" or "bg" or empty.
'';
before = helpers.defaultNullOpts.mkStr "" ''
"fg" or "bg" or empty.
'';
keyword = helpers.defaultNullOpts.mkStr "wide" ''
"fg", "bg", "wide", "wide_bg", "wide_fg" or empty.
(wide and wide_bg is the same as bg, but will also highlight
surrounding characters, wide_fg acts accordingly but with fg).
'';
keyword = helpers.defaultNullOpts.mkStr "wide" ''
"fg", "bg", "wide", "wide_bg", "wide_fg" or empty.
(wide and wide_bg is the same as bg, but will also highlight
surrounding characters, wide_fg acts accordingly but with fg).
'';
after = helpers.defaultNullOpts.mkStr "fg" ''
"fg" or "bg" or empty.
'';
after = helpers.defaultNullOpts.mkStr "fg" ''
"fg" or "bg" or empty.
'';
pattern =
helpers.mkNullOrOption
(types.oneOf [types.str (types.listOf types.str)]) ''
Pattern or list of patterns, used for highlighting (vim regex)
'';
pattern = helpers.mkNullOrOption (with types; either str (listOf str)) ''
Pattern or list of patterns, used for highlighting (vim regex)
'';
commentsOnly = helpers.defaultNullOpts.mkBool true ''
Uses treesitter to match keywords in comments only.
'';
commentsOnly = helpers.defaultNullOpts.mkBool true ''
Uses treesitter to match keywords in comments only.
'';
maxLineLen = helpers.defaultNullOpts.mkInt 400 ''
Ignore lines longer than this.
'';
maxLineLen = helpers.defaultNullOpts.mkInt 400 ''
Ignore lines longer than this.
'';
exclude = helpers.mkNullOrOption (types.listOf types.str) ''
List of file types to exclude highlighting.
'';
};
}));
exclude = helpers.mkNullOrOption (types.listOf types.str) ''
List of file types to exclude highlighting.
'';
};
colors =
@ -137,35 +150,64 @@ in {
```
'';
search = mkOption {
description = "Search options.";
default = null;
type = types.nullOr (types.submodule ({...}: {
options = {
command = helpers.defaultNullOpts.mkStr "rg" ''
Command to use for searching for keywords.
'';
args = helpers.mkNullOrOption (types.listOf types.str) ''
Arguments to use for the search command in list form.
search = helpers.mkCompositeOption "Search options." {
command = helpers.defaultNullOpts.mkStr "rg" "Command to use for searching for keywords.";
Default:
```
[
"--color=never"
"--no-heading"
"--with-filename"
"--line-number"
"--column"
];
```
'';
pattern = helpers.defaultNullOpts.mkStr "[[\b(KEYWORDS):]]" ''
Regex that will be used to match keywords.
Don't replace the (KEYWORDS) placeholder.
'';
};
}));
args = helpers.mkNullOrOption (types.listOf types.str) ''
Arguments to use for the search command in list form.
Default:
```
[
"--color=never"
"--no-heading"
"--with-filename"
"--line-number"
"--column"
];
```
'';
pattern = helpers.defaultNullOpts.mkStr "[[\b(KEYWORDS):]]" ''
Regex that will be used to match keywords.
Don't replace the (KEYWORDS) placeholder.
'';
};
# Keyboard shortcuts for :Todo* commands
keymapsSilent = mkOption {
type = types.bool;
description = "Whether todo-comments keymaps should be silent.";
default = false;
};
keymaps = let
mkKeymapOption = optionName: funcName:
helpers.mkCompositeOption "Keymap settings for the `:${funcName}` function." {
key = mkOption {
type = types.str;
description = "Key for the `${funcName}` function.";
};
cwd = mkOption {
type = types.nullOr types.str;
description = "Specify the directory to search for comments";
default = null;
example = "~/projects/foobar";
};
keywords = mkOption {
type = types.nullOr types.str;
description = ''
Comma separated list of keywords to filter results by.
Keywords are case-sensitive.
'';
default = null;
example = "TODO,FIX";
};
};
in
mapAttrs mkKeymapOption commands;
};
};
@ -173,11 +215,25 @@ in {
setupOptions =
{
signs = cfg.signs;
signPriority = cfg.signPriority;
sign_priority = cfg.signPriority;
keywords = cfg.keywords;
guiStyle = cfg.guiStyle;
mergeKeywords = cfg.mergeKeywords;
highlight = cfg.highlight;
gui_style = cfg.guiStyle;
merge_keywords = cfg.mergeKeywords;
highlight = helpers.ifNonNull' cfg.highlight {
inherit
(cfg.highlight)
multiline
before
keyword
after
pattern
exclude
;
multiline_pattern = cfg.highlight.multilinePattern;
multiline_context = cfg.highlight.multilineContext;
comments_only = cfg.highlight.commentsOnly;
max_line_len = cfg.highlight.maxLineLen;
};
colors = cfg.colors;
search = cfg.search;
}
@ -188,5 +244,36 @@ in {
extraConfigLua = ''
require("todo-comments").setup${helpers.toLuaObject setupOptions}
'';
maps.normal = let
silent = cfg.keymapsSilent;
keymaps = cfg.keymaps;
in
mkMerge (
mapAttrsToList
(
optionName: funcName: let
keymap = keymaps.${optionName};
key = keymap.key;
cwd = optionalString (!isNull keymap.cwd) " cwd=${keymap.cwd}";
keywords = optionalString (!isNull keymap.keywords) " keywords=${keymap.keywords}";
action = ":${funcName}${cwd}${keywords}<CR>";
in (mkIf (keymap != null) {
${key} = {
inherit silent action;
};
})
)
commands
);
# Automatically enable plugins if keymaps have been set
plugins = mkMerge [
(mkIf (!isNull cfg.keymaps.todoTrouble) {trouble.enable = true;})
(mkIf (!isNull cfg.keymaps.todoTelescope) {telescope.enable = true;})
];
};
}