From 77904a6adbb536d28421950a400c59a66e456330 Mon Sep 17 00:00:00 2001 From: Iron-E Date: Mon, 11 Mar 2024 15:33:02 -0400 Subject: [PATCH] ref(Vars): track local copy of global value --- lua/libmodal/Mode.lua | 22 +++++------ lua/libmodal/Prompt.lua | 4 +- lua/libmodal/utils/Vars.lua | 73 ++++++++++++++++++++++++++++++------- 3 files changed, 73 insertions(+), 26 deletions(-) diff --git a/lua/libmodal/Mode.lua b/lua/libmodal/Mode.lua index 123dc8a..9f2204d 100644 --- a/lua/libmodal/Mode.lua +++ b/lua/libmodal/Mode.lua @@ -47,8 +47,8 @@ function Mode:execute_instruction(instruction) vim.api.nvim_command(instruction) end - self.count:set(0) - self.count1:set(1) + self.count:set_global(0) + self.count1:set_global(1) self:redraw_virtual_cursor() end @@ -61,7 +61,7 @@ function Mode:check_input_for_mapping() self.flush_input_timer:stop() -- append the latest input to the locally stored input history. - self.input_bytes[#self.input_bytes + 1] = self.global_input:get() + self.input_bytes[#self.input_bytes + 1] = self.global_input:get_global() -- get the command based on the users input. local cmd = self.mappings:get(self.input_bytes) @@ -115,8 +115,8 @@ function Mode:enter() self.popups:push(utils.Popup.new()) end - self.count:set(0) - self.count1:set(1) + self.count:set_global(0) + self.count1:set_global(1) self.local_exit = false @@ -162,7 +162,7 @@ end --- @private --- @return boolean `true` if the mode's exit was flagged function Mode:exit_flagged() - return self.local_exit or globals.is_true(self.global_exit:get()) + return self.local_exit or globals.is_true(self.global_exit:get_global()) end --- get input from the user. @@ -185,13 +185,13 @@ function Mode:get_user_input() end -- set the global input variable to the new input. - self.global_input:set(user_input) + self.global_input:set_global(user_input) if ZERO <= user_input and user_input <= NINE then - local oldCount = self.count:get() + local oldCount = self.count:get_global() local newCount = tonumber(oldCount .. string.char(user_input)) - self.count:set(newCount) - self.count1:set(math.max(1, newCount)) + self.count:set_global(newCount) + self.count1:set_global(math.max(1, newCount)) end if not self.supress_exit and user_input == globals.ESC_NR then -- the user wants to exit. @@ -321,7 +321,7 @@ function Mode.new(name, instruction, supress_exit) self.timeouts = utils.Vars.new('timeouts', self.name) -- read the correct timeout variable. - self.timeouts_enabled = self.timeouts:get() or vim.g.libmodalTimeouts + self.timeouts_enabled = self.timeouts:get_global() or vim.g.libmodalTimeouts end return self diff --git a/lua/libmodal/Prompt.lua b/lua/libmodal/Prompt.lua index 830c93a..e16723c 100644 --- a/lua/libmodal/Prompt.lua +++ b/lua/libmodal/Prompt.lua @@ -60,10 +60,10 @@ function Prompt:get_user_input() --- @param user_input string local function user_input_callback(user_input) if user_input and user_input:len() > 0 then -- the user actually entered something. - self.input:set(user_input) + self.input:set_global(user_input) self:execute_instruction(user_input) - local should_exit = self.exit:get() + local should_exit = self.exit:get_global() if should_exit ~= nil then continue_prompt = not should_exit end diff --git a/lua/libmodal/utils/Vars.lua b/lua/libmodal/utils/Vars.lua index 77fbf8a..7a75704 100644 --- a/lua/libmodal/utils/Vars.lua +++ b/lua/libmodal/utils/Vars.lua @@ -1,23 +1,15 @@ --- @class libmodal.utils.Vars --- @field private mode_name string the highlight group to use when printing `str` +--- @field private value? unknown the local value of the variable --- @field private var_name string the highlight group to use when printing `str` local Vars = require('libmodal.utils.classes').new() ---- @return unknown `vim.g[self:name()])` -function Vars:get() - return vim.g[self:name()] -end - ---- @return string name the global Neovim setting -function Vars:name() - return self.mode_name .. self.var_name -end - --- create a new set of variables --- @param var_name string the name of the key used to refer to this variable in `Vars`. --- @param mode_name string the name of the mode +--- @param default_global? unknown the default global value --- @return libmodal.utils.Vars -function Vars.new(var_name, mode_name) +function Vars.new(var_name, mode_name, default_global) local self = setmetatable({}, Vars) --- @param str_with_spaces string @@ -42,15 +34,70 @@ function Vars.new(var_name, mode_name) self.mode_name = no_spaces(mode_name, string.lower) self.var_name = 'Mode' .. no_spaces(var_name, string.upper) + self.value = nil + + if default_global ~= nil and self:get_global() == nil then + self:set_global(default_global) + end return self end --- @generic T ---- @param val T set `g:{self:name()})` equal to this value +--- @return T value the local value if it exists, or the global value +function Vars:get() + local local_value = self:get_local() + if local_value == nil then + return self:get_global() + end + + return local_value +end + +--- @generic T +--- @return T global_value the global value +function Vars:get_local() + return self.value +end + +--- @generic T +--- @return T global_value the global value +function Vars:get_global() + return vim.g[self:name()] +end + +--- @return string name the global Neovim setting +function Vars:name() + return self.mode_name .. self.var_name +end + +--- NOTE: the local value is only set if not `nil`, for backwards compatibility purposes. +--- local values did not always exist, and since `get` prefers local values, it may +--- too-eagerly shadow the global variable. +--- @param val unknown set local value if it exists, or the global value --- @return nil function Vars:set(val) - vim.api.nvim_set_var(self:name(), val) + if self:get_local() == nil then + self:set_global(val) + else + self:set_local(val) + end +end + +--- @param val unknown set the local value equal to this +--- @return nil +function Vars:set_local(val) + self.value = val +end + +--- @param val unknown set the global value equal to this +--- @return nil +function Vars:set_global(val) + if val == nil then + vim.api.nvim_del_var(self:name()) -- because `nvim_set_var('foo', nil)` actually sets 'foo' to `vim.NIL` + else + vim.api.nvim_set_var(self:name(), val) + end end return Vars