diff --git a/lua/libmodal/Mode.lua b/lua/libmodal/Mode.lua index 9f2204d..8bff827 100644 --- a/lua/libmodal/Mode.lua +++ b/lua/libmodal/Mode.lua @@ -4,22 +4,20 @@ local utils = require 'libmodal.utils' --- @type libmodal.utils --- @class libmodal.Mode --- @field private flush_input_timer unknown ---- @field private global_exit libmodal.utils.Vars ---- @field private global_input libmodal.utils.Vars --- @field private help? libmodal.utils.Help ---- @field private input libmodal.utils.Vars ---- @field private count libmodal.utils.Vars ---- @field private count1 libmodal.utils.Vars ---- @field private input_bytes? number[] +--- @field private input_bytes? number[] local `input` history --- @field private instruction fun()|{[string]: fun()|string} ---- @field private local_exit boolean --- @field private mappings libmodal.collections.ParseTable +--- @field private modeline string[][] --- @field private name string --- @field private ns number the namespace where cursor highlights are drawn on --- @field private popups libmodal.collections.Stack ---- @field private show_name fun() --- @field private supress_exit boolean ---- @field private timeouts_enabled boolean +--- @field public count libmodal.utils.Vars[number] +--- @field public count1 libmodal.utils.Vars[number] +--- @field public exit libmodal.utils.Vars[boolean] +--- @field public input libmodal.utils.Vars[number] +--- @field public timeouts? libmodal.utils.Vars[boolean] local Mode = utils.classes.new() local HELP_CHAR = '?' @@ -47,8 +45,8 @@ function Mode:execute_instruction(instruction) vim.api.nvim_command(instruction) end - self.count:set_global(0) - self.count1:set_global(1) + self.count:set(0) + self.count1:set(1) self:redraw_virtual_cursor() end @@ -61,7 +59,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_global() + self.input_bytes[#self.input_bytes + 1] = self.input:get() -- get the command based on the users input. local cmd = self.mappings:get(self.input_bytes) @@ -76,7 +74,7 @@ function Mode:check_input_for_mapping() end self.input_bytes = {} - elseif command_type == 'table' and globals.is_true(self.timeouts_enabled) then -- the command was a table, meaning that it MIGHT match. + elseif command_type == 'table' and globals.is_true(self.timeouts:get()) then -- the command was a table, meaning that it MIGHT match. local timeout = vim.api.nvim_get_option_value('timeoutlen', {}) self.flush_input_timer:start( -- start the timer timeout, 0, vim.schedule_wrap(function() @@ -115,10 +113,8 @@ function Mode:enter() self.popups:push(utils.Popup.new()) end - self.count:set_global(0) - self.count1:set_global(1) - - self.local_exit = false + self.count:set(0) + self.count1:set(1) --- HACK: https://github.com/neovim/neovim/issues/20793 vim.api.nvim_command 'highlight Cursor blend=100' @@ -151,30 +147,16 @@ function Mode:enter() vim.api.nvim_exec_autocmds('ModeChanged', {pattern = self.name .. ':' .. previous_mode}) end ---- exit this instance of the mode. ---- WARN: does not interrupt the current mode to exit. It only flags that exit is desired for when control yields back ---- to the mode. ---- @return nil -function Mode:exit() - self.local_exit = true -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_global()) -end - --- get input from the user. --- @private --- @return boolean more_input function Mode:get_user_input() - if self:exit_flagged() then + if self.exit:get() then return false end -- echo the indicator. - self.show_name() + self:show_mode() -- capture input. local user_input = vim.fn.getchar() @@ -185,13 +167,13 @@ function Mode:get_user_input() end -- set the global input variable to the new input. - self.global_input:set_global(user_input) + self.input:set(user_input) if ZERO <= user_input and user_input <= NINE then - local oldCount = self.count:get_global() + local oldCount = self.count:get() local newCount = tonumber(oldCount .. string.char(user_input)) - self.count:set_global(newCount) - self.count1:set_global(math.max(1, newCount)) + self.count:set(newCount) + self.count1:set(math.max(1, newCount)) end if not self.supress_exit and user_input == globals.ESC_NR then -- the user wants to exit. @@ -229,6 +211,16 @@ function Mode:render_virt_cursor() vim.highlight.range(0, self.ns, 'Cursor', { line_nr, col_nr }, { line_nr, col_nr + 1 }, {}) end +--- show the mode indicator, if it is enabled +function Mode:show_mode() + utils.api.redraw() + + local showmode = vim.api.nvim_get_option_value('showmode', {}) + if showmode then + vim.api.nvim_echo({{'-- ' .. self.name .. ' --', 'LibmodalPrompt'}}, false, {}) + end +end + --- `enter` a `Mode` using the arguments given, and then flag the current mode to exit. --- @param ... unknown arguments to `Mode.new` --- @return nil @@ -279,23 +271,16 @@ function Mode.new(name, instruction, supress_exit) { count = utils.Vars.new('count', name), count1 = utils.Vars.new('count1', name), - global_exit = utils.Vars.new('exit', name), - global_input = utils.Vars.new('input', name), + exit = utils.Vars.new('exit', name), + input = utils.Vars.new('input', name), instruction = instruction, - local_exit = false, name = name, ns = vim.api.nvim_create_namespace('libmodal' .. name), + modeline = {{'-- ' .. name .. ' --', 'LibmodalPrompt'}}, }, Mode ) - self.show_name = vim.o.showmode and - function() - utils.api.redraw() - vim.api.nvim_echo({{'-- ' .. name .. ' --', 'LibmodalPrompt'}}, false, {}) - end or - utils.api.redraw - -- define the exit flag self.supress_exit = supress_exit or false @@ -318,10 +303,7 @@ function Mode.new(name, instruction, supress_exit) self.popups = require('libmodal.collections.Stack').new() -- create a variable for whether or not timeouts are enabled. - self.timeouts = utils.Vars.new('timeouts', self.name) - - -- read the correct timeout variable. - self.timeouts_enabled = self.timeouts:get_global() or vim.g.libmodalTimeouts + self.timeouts = utils.Vars.new('timeouts', self.name, vim.g.libmodalTimeouts) end return self