From 1f285df66498952c9b1315fdc591c0c3e1d3b5f1 Mon Sep 17 00:00:00 2001 From: Gaetan Lepage Date: Fri, 2 Jun 2023 13:13:27 +0200 Subject: [PATCH] plugins/auto-save: init + test --- plugins/default.nix | 1 + plugins/utils/auto-save.nix | 157 ++++++++++++++++++ .../test-sources/plugins/utils/auto-save.nix | 47 ++++++ 3 files changed, 205 insertions(+) create mode 100644 plugins/utils/auto-save.nix create mode 100644 tests/test-sources/plugins/utils/auto-save.nix diff --git a/plugins/default.nix b/plugins/default.nix index d782b026..d0928fb5 100644 --- a/plugins/default.nix +++ b/plugins/default.nix @@ -73,6 +73,7 @@ ./ui/noice.nix ./utils/alpha.nix + ./utils/auto-save.nix ./utils/comment-nvim.nix ./utils/commentary.nix ./utils/conjure.nix diff --git a/plugins/utils/auto-save.nix b/plugins/utils/auto-save.nix new file mode 100644 index 00000000..d420c2fa --- /dev/null +++ b/plugins/utils/auto-save.nix @@ -0,0 +1,157 @@ +{ + pkgs, + config, + lib, + ... +}: +with lib; let + cfg = config.plugins.auto-save; + helpers = import ../helpers.nix {inherit lib;}; +in { + options.plugins.auto-save = + helpers.extraOptionsOptions + // { + enable = mkEnableOption "auto-save"; + + package = helpers.mkPackageOption "auto-save" pkgs.vimPlugins.auto-save-nvim; + + keymaps = { + silent = mkOption { + type = types.bool; + description = "Whether auto-save keymaps should be silent."; + default = false; + }; + + toggle = helpers.mkNullOrOption types.str "Keymap for running auto-save."; + }; + + enableAutoSave = helpers.defaultNullOpts.mkBool true '' + Whether to start auto-save when the plugin is loaded. + ''; + + executionMessage = { + message = + helpers.defaultNullOpts.mkNullable + (with types; either str helpers.rawType) + '' + { + __raw = \'\' + function() + return ("AutoSave: saved at " .. vim.fn.strftime("%H:%M:%S")) + end + \'\'; + } + '' + '' + The message to print en save. + This can be a lua function that returns a string. + ''; + + dim = + helpers.defaultNullOpts.mkNullable + (types.numbers.between 0 1) + "0.18" + "Dim the color of `message`."; + + cleaningInterval = helpers.defaultNullOpts.mkInt 1250 '' + Time (in milliseconds) to wait before automatically cleaning MsgArea after displaying + `message`. + See `:h MsgArea`. + ''; + }; + + triggerEvents = + helpers.defaultNullOpts.mkNullable (with types; listOf str) + ''["InsertLeave" "TextChanged"]'' + '' + Vim events that trigger auto-save. + See `:h events`. + ''; + + condition = + helpers.defaultNullOpts.mkStr + '' + function(buf) + local fn = vim.fn + local utils = require("auto-save.utils.data") + + if + fn.getbufvar(buf, "&modifiable") == 1 and utils.not_in(fn.getbufvar(buf, "&filetype"), {}) then + return true -- met condition(s), can save + end + return false -- can't save + end + '' + '' + Function that determines whether to save the current buffer or not. + - return true: if buffer is ok to be saved + - return false: if it's not ok to be saved + ''; + + writeAllBuffers = helpers.defaultNullOpts.mkBool false '' + Write all buffers when the current one meets `condition`. + ''; + + debounceDelay = helpers.defaultNullOpts.mkInt 135 '' + Saves the file at most every `debounce_delay` milliseconds. + ''; + + callbacks = + mapAttrs + ( + name: desc: + helpers.mkNullOrOption types.str "The code of the function that runs ${desc}." + ) + { + enabling = "when enabling auto-save"; + disabling = "when disabling auto-save"; + beforeAssertingSave = "before checking `condition`"; + beforeSaving = "before doing the actual save"; + afterSaving = "after doing the actual save"; + }; + }; + + config = let + options = + { + enabled = cfg.enableAutoSave; + execution_message = with cfg.executionMessage; { + inherit message dim; + cleaning_interval = cleaningInterval; + }; + trigger_events = cfg.triggerEvents; + condition = + helpers.ifNonNull' cfg.condition + (helpers.mkRaw cfg.condition); + write_all_buffers = cfg.writeAllBuffers; + debounce_delay = cfg.debounceDelay; + callbacks = with cfg.callbacks; + mapAttrs (name: value: helpers.ifNonNull' value (helpers.mkRaw value)) { + inherit enabling disabling; + before_asserting_save = beforeAssertingSave; + before_saving = beforeSaving; + after_saving = afterSaving; + }; + } + // cfg.extraOptions; + in + mkIf cfg.enable { + extraPlugins = [cfg.package]; + + extraConfigLua = '' + require('auto-save').setup(${helpers.toLuaObject options}) + ''; + + maps.normal = with cfg.keymaps; let + inherit (cfg.keymaps) silent; + in + mkMerge [ + (mkIf (toggle != null) { + ${toggle} = { + action = ":ASToggle"; + inherit silent; + }; + }) + ]; + }; +} diff --git a/tests/test-sources/plugins/utils/auto-save.nix b/tests/test-sources/plugins/utils/auto-save.nix new file mode 100644 index 00000000..d9790149 --- /dev/null +++ b/tests/test-sources/plugins/utils/auto-save.nix @@ -0,0 +1,47 @@ +{ + empty = { + plugins.auto-save.enable = true; + }; + + defaults = { + plugins.auto-save = { + enable = true; + + keymaps = { + silent = true; + toggle = "s"; + }; + enableAutoSave = true; + executionMessage = { + message.__raw = '' + function() + return ("AutoSave: saved at " .. vim.fn.strftime("%H:%M:%S")) + end + ''; + dim = 0.18; + cleaningInterval = 1250; + }; + triggerEvents = ["InsertLeave" "TextChanged"]; + condition = '' + function(buf) + local fn = vim.fn + local utils = require("auto-save.utils.data") + + if fn.getbufvar(buf, "&modifiable") == 1 and utils.not_in(fn.getbufvar(buf, "&filetype"), {}) then + return true -- met condition(s), can save + end + return false -- can't save + end + ''; + writeAllBuffers = false; + debounceDelay = 135; + callbacks = { + enabling = null; + disabling = null; + beforeAssertingSave = null; + beforeSaving = null; + afterSaving = null; + }; + }; + }; +}