From 186b790febffd6d16c2ba6bbe55655ddbdeec894 Mon Sep 17 00:00:00 2001 From: Shayan Rashid <40346418+ShyProton@users.noreply.github.com> Date: Fri, 1 Sep 2023 03:17:31 -0400 Subject: [PATCH] hardtime: init plugin + tests (#569) * hardtime: init * hardtime: completed + tests added * hardtime: adds missing extraOptions to setupOptions * hardtime: applies suggested changes --- plugins/default.nix | 1 + plugins/utils/hardtime.nix | 168 ++++++++ tests/test-sources/plugins/utils/hardtime.nix | 396 ++++++++++++++++++ 3 files changed, 565 insertions(+) create mode 100644 plugins/utils/hardtime.nix create mode 100644 tests/test-sources/plugins/utils/hardtime.nix diff --git a/plugins/default.nix b/plugins/default.nix index 7f92209a..71d4cf5c 100644 --- a/plugins/default.nix +++ b/plugins/default.nix @@ -95,6 +95,7 @@ ./utils/endwise.nix ./utils/floaterm.nix ./utils/goyo.nix + ./utils/hardtime.nix ./utils/harpoon.nix ./utils/illuminate.nix ./utils/indent-blankline.nix diff --git a/plugins/utils/hardtime.nix b/plugins/utils/hardtime.nix new file mode 100644 index 00000000..527bb9e6 --- /dev/null +++ b/plugins/utils/hardtime.nix @@ -0,0 +1,168 @@ +{ + config, + pkgs, + lib, + ... +}: +with lib; let + cfg = config.plugins.hardtime; + helpers = import ../helpers.nix {inherit lib;}; +in { + options = { + plugins.hardtime = + helpers.extraOptionsOptions + // { + enable = mkEnableOption "Enable hardtime."; + + package = helpers.mkPackageOption "hardtime" pkgs.vimPlugins.hardtime-nvim; + + maxTime = helpers.defaultNullOpts.mkUnsignedInt 1000 '' + Maximum time (in milliseconds) to consider key presses as repeated. + ''; + + maxCount = helpers.defaultNullOpts.mkUnsignedInt 2 '' + Maximum count of repeated key presses allowed within the `max_time` period. + ''; + + disableMouse = helpers.defaultNullOpts.mkBool true '' + Disable mouse support. + ''; + + hint = helpers.defaultNullOpts.mkBool true '' + Enable hint messages for better commands. + ''; + + notification = helpers.defaultNullOpts.mkBool true '' + Enable notification messages for restricted and disabled keys. + ''; + + allowDifferentKey = helpers.defaultNullOpts.mkBool false '' + Allow different keys to reset the count. + ''; + + enabled = helpers.defaultNullOpts.mkBool true '' + Whether the plugin in enabled by default or not. + ''; + + resettingKeys = helpers.mkNullOrOption (with types; attrsOf (listOf str)) '' + Keys in what modes that reset the count. + + default: + ```nix + { + "1" = [ "n" "x" ]; + "2" = [ "n" "x" ]; + "3" = [ "n" "x" ]; + "4" = [ "n" "x" ]; + "5" = [ "n" "x" ]; + "6" = [ "n" "x" ]; + "7" = [ "n" "x" ]; + "8" = [ "n" "x" ]; + "9" = [ "n" "x" ]; + "c" = [ "n" ]; + "C" = [ "n" ]; + "d" = [ "n" ]; + "x" = [ "n" ]; + "X" = [ "n" ]; + "y" = [ "n" ]; + "Y" = [ "n" ]; + "p" = [ "n" ]; + "P" = [ "n" ]; + } + ``` + ''; + + restrictedKeys = helpers.mkNullOrOption (with types; attrsOf (listOf str)) '' + Keys in what modes triggering the count mechanism. + + default: + ```nix + { + "h" = [ "n" "x" ]; + "j" = [ "n" "x" ]; + "k" = [ "n" "x" ]; + "l" = [ "n" "x" ]; + "-" = [ "n" "x" ]; + "+" = [ "n" "x" ]; + "gj" = [ "n" "x" ]; + "gk" = [ "n" "x" ]; + "" = [ "n" "x" ]; + "" = [ "n" "x" ]; + "" = [ "n" "x" ]; + "" = [ "n" "x" ]; + } + ``` + ''; + + restrictionMode = helpers.defaultNullOpts.mkEnumFirstDefault ["block" "hint"] '' + The behavior when `restricted_keys` trigger count mechanism. + ''; + + disabledKeys = helpers.mkNullOrOption (with types; attrsOf (listOf str)) '' + Keys in what modes are disabled. + + default: + ```nix + { + "" = [ "" "i" ]; + "" = [ "" "i" ]; + "" = [ "" "i" ]; + "" = [ "" "i" ]; + } + ``` + ''; + + disabledFiletypes = helpers.mkNullOrOption (with types; listOf str) '' + `hardtime.nvim` is disabled under these filetypes. + + default: + ```nix + ["qf" "netrw" "NvimTree" "lazy" "mason"] + ``` + ''; + + hints = helpers.mkNullOrOption (with types; + attrsOf (submodule { + options = { + message = lib.mkOption { + description = "Hint message to be displayed."; + type = helpers.rawType; + }; + + length = lib.mkOption { + description = "The length of actual key strokes that matches this pattern."; + type = types.ints.unsigned; + }; + }; + })) '' + `key` is a string pattern you want to match, `value` is a table + of hint massage and pattern length. + ''; + }; + }; + + config = let + setupOptions = with cfg; + { + inherit hint notification enabled hints; + + max_time = maxTime; + max_count = maxCount; + disable_mouse = disableMouse; + allow_different_key = allowDifferentKey; + resetting_keys = resettingKeys; + restricted_keys = restrictedKeys; + restriction_mode = restrictionMode; + disabled_keys = disabledKeys; + disabled_filetypes = disabledFiletypes; + } + // extraOptions; + in + mkIf cfg.enable { + extraPlugins = [cfg.package]; + + extraConfigLua = '' + require("hardtime").setup(${helpers.toLuaObject setupOptions}) + ''; + }; +} diff --git a/tests/test-sources/plugins/utils/hardtime.nix b/tests/test-sources/plugins/utils/hardtime.nix new file mode 100644 index 00000000..ec3c82d9 --- /dev/null +++ b/tests/test-sources/plugins/utils/hardtime.nix @@ -0,0 +1,396 @@ +{ + empty = { + plugins.hardtime.enable = true; + }; + + defaults = { + plugins.hardtime = { + enable = true; + + maxTime = 1000; + maxCount = 2; + disableMouse = true; + hint = true; + notification = true; + allowDifferentKey = false; + enabled = true; + restrictionMode = "block"; + + resettingKeys = { + "1" = ["n" "x"]; + "2" = ["n" "x"]; + "3" = ["n" "x"]; + "4" = ["n" "x"]; + "5" = ["n" "x"]; + "6" = ["n" "x"]; + "7" = ["n" "x"]; + "8" = ["n" "x"]; + "9" = ["n" "x"]; + "c" = ["n"]; + "C" = ["n"]; + "d" = ["n"]; + "x" = ["n"]; + "X" = ["n"]; + "y" = ["n"]; + "Y" = ["n"]; + "p" = ["n"]; + "P" = ["n"]; + }; + + restrictedKeys = { + "h" = ["n" "x"]; + "j" = ["n" "x"]; + "k" = ["n" "x"]; + "l" = ["n" "x"]; + "-" = ["n" "x"]; + "+" = ["n" "x"]; + "gj" = ["n" "x"]; + "gk" = ["n" "x"]; + "" = ["n" "x"]; + "" = ["n" "x"]; + "" = ["n" "x"]; + "" = ["n" "x"]; + }; + + disabledKeys = { + "" = ["" "i"]; + "" = ["" "i"]; + "" = ["" "i"]; + "" = ["" "i"]; + }; + + disabledFiletypes = ["qf" "netrw" "NvimTree" "lazy" "mason"]; + + hints = { + "[kj]%^" = { + message.__raw = '' + function(key) + return "Use " + .. (key == "k^" and "-" or " or +") + .. " instead of " + .. key + end + ''; + length = 2; + }; + + "%$a" = { + message.__raw = '' + function() + return "Use A instead of $a" + end + ''; + length = 2; + }; + + "%^i" = { + message.__raw = '' + function() + return "Use I instead of ^i" + end + ''; + length = 2; + }; + + "%D[k-]o" = { + message.__raw = '' + function(keys) + return "Use O instead of " .. keys:sub(2) + end + ''; + length = 3; + }; + + "%D[j+]O" = { + message.__raw = '' + function(keys) + return "Use o instead of " .. keys:sub(2) + end + ''; + length = 3; + }; + + "[^fFtT]li" = { + message.__raw = '' + function() + return "Use a instead of li" + end + ''; + length = 3; + }; + + "2([dcy=<>])%1" = { + message.__raw = '' + function(key) + return "Use " .. key:sub(3) .. "j instead of " .. key + end + ''; + length = 3; + }; + + "[^dcy=]f.h" = { + message.__raw = '' + function(keys) + return "Use t" .. keys:sub(3, 3) .. " instead of " .. keys:sub(2) + end + ''; + length = 4; + }; + + "[^dcy=]F.l" = { + message.__raw = '' + function(keys) + return "Use T" .. keys:sub(3, 3) .. " instead of " .. keys:sub(2) + end + ''; + length = 4; + }; + + "[^dcy=]T.h" = { + message.__raw = '' + function(keys) + return "Use F" .. keys:sub(3, 3) .. " instead of " .. keys:sub(2) + end + ''; + length = 4; + }; + + "[^dcy=]t.l" = { + message.__raw = '' + function(keys) + return "Use f" .. keys:sub(3, 3) .. " instead of " .. keys:sub(2) + end + ''; + length = 4; + }; + + "d[bBwWeE%^%$]i" = { + message.__raw = '' + function(keys) + return "Use " .. "c" .. keys:sub(2, 2) .. " instead of " .. keys + end + ''; + length = 3; + }; + + "dg[eE]i" = { + message.__raw = '' + function(keys) + return "Use " .. "c" .. keys:sub(2, 3) .. " instead of " .. keys + end + ''; + length = 4; + }; + + "d[tTfF].i" = { + message.__raw = '' + function(keys) + return "Use " .. "c" .. keys:sub(2, 3) .. " instead of " .. keys + end + ''; + length = 4; + }; + + "d[ia][\"'`{}%[%]()<>bBwWspt]i" = { + message.__raw = '' + function(keys) + return "Use " .. "c" .. keys:sub(2, 3) .. " instead of " .. keys + end + ''; + length = 4; + }; + + "Vgg[dcy=<>]" = { + message.__raw = '' + function(keys) + return "Use " .. keys:sub(4, 4) .. "gg instead of " .. keys + end + ''; + length = 4; + }; + + "Vgg\".[dy]" = { + message.__raw = '' + function(keys) + return "Use " .. keys:sub(4, 6) .. "gg instead of " .. keys + end + ''; + length = 6; + }; + + "VG[dcy=<>]" = { + message.__raw = '' + function(keys) + return "Use " .. keys:sub(3, 3) .. "G instead of " .. keys + end + ''; + length = 3; + }; + + "VG\".[dy]" = { + message.__raw = '' + function(keys) + return "Use " .. keys:sub(3, 5) .. "G instead of " .. keys + end + ''; + length = 5; + }; + + "V%d[kj][dcy=<>]" = { + message.__raw = '' + function(keys) + return "Use " + .. keys:sub(4, 4) + .. keys:sub(2, 3) + .. " instead of " + .. keys + end + ''; + length = 4; + }; + + "V%d[kj]\".[dy]" = { + message.__raw = '' + function(keys) + return "Use " + .. keys:sub(4, 6) + .. keys:sub(2, 3) + .. " instead of " + .. keys + end + ''; + length = 6; + }; + + "V%d%d[kj][dcy=<>]" = { + message.__raw = '' + function(keys) + return "Use " + .. keys:sub(5, 5) + .. keys:sub(2, 4) + .. " instead of " + .. keys + end + ''; + length = 5; + }; + + "V%d%d[kj]\".[dy]" = { + message.__raw = '' + function(keys) + return "Use " + .. keys:sub(5, 7) + .. keys:sub(2, 4) + .. " instead of " + .. keys + end + ''; + length = 7; + }; + + "[vV][bBwWeE%^%$][dcy=<>]" = { + message.__raw = '' + function(keys) + return "Use " + .. keys:sub(3, 3) + .. keys:sub(2, 2) + .. " instead of " + .. keys + end + ''; + length = 3; + }; + + "[vV][bBwWeE%^%$]\".[dy]" = { + message.__raw = '' + function(keys) + return "Use " + .. keys:sub(3, 5) + .. keys:sub(2, 2) + .. " instead of " + .. keys + end + ''; + length = 5; + }; + + "[vV]g[eE][dcy=<>]" = { + message.__raw = '' + function(keys) + return "Use " + .. keys:sub(4, 4) + .. keys:sub(2, 3) + .. " instead of " + .. keys + end + ''; + length = 4; + }; + + "[vV]g[eE]\".[dy]" = { + message.__raw = '' + function(keys) + return "Use " + .. keys:sub(4, 6) + .. keys:sub(2, 3) + .. " instead of " + .. keys + end + ''; + length = 6; + }; + + "[vV][tTfF].[dcy=<>]" = { + message.__raw = '' + function(keys) + return "Use " + .. keys:sub(4, 4) + .. keys:sub(2, 3) + .. " instead of " + .. keys + end + ''; + length = 4; + }; + + "[vV][tTfF].\".[dy]" = { + message.__raw = '' + function(keys) + return "Use " + .. keys:sub(4, 6) + .. keys:sub(2, 3) + .. " instead of " + .. keys + end + ''; + length = 6; + }; + "[vV][ia][\"'`{}%[%]()<>bBwWspt][dcy=<>]" = { + message.__raw = '' + function(keys) + return "Use " + .. keys:sub(4, 4) + .. keys:sub(2, 3) + .. " instead of " + .. keys + end + ''; + length = 4; + }; + + "[vV][ia][\"'`{}%[%]()<>bBwWspt]\".[dy]" = { + message.__raw = '' + function(keys) + return "Use " + .. keys:sub(4, 6) + .. keys:sub(2, 3) + .. " instead of " + .. keys + end + ''; + length = 6; + }; + }; + }; + }; +}