diff --git a/lua/libmodal/src/Layer.lua b/lua/libmodal/src/Layer.lua index 200145f..f72689d 100644 --- a/lua/libmodal/src/Layer.lua +++ b/lua/libmodal/src/Layer.lua @@ -1,4 +1,7 @@ +--- @type libmodal.globals local globals = require 'libmodal/src/globals' + +--- @type libmodal.utils local utils = require 'libmodal/src/utils' --- Normalizes a `buffer = true|false|0` argument into a number. @@ -143,6 +146,12 @@ function Layer:map(mode, lhs, rhs, options) end end +--- @param keymaps_by_mode table the keymaps (e.g. `{n = {gg = {rhs = 'G', silent = true}}}`) +--- @return libmodal.Layer +function Layer.new(keymaps_by_mode) + return setmetatable({existing_keymaps_by_mode = {}, layer_keymaps_by_mode = keymaps_by_mode, active = false}, Layer) +end + --- restore one keymapping to its original state. --- @param buffer? number the buffer to unmap from (`nil` if it is not buffer-local) --- @param mode string the mode of the keymap. @@ -175,11 +184,4 @@ function Layer:unmap(buffer, mode, lhs) self.existing_keymaps_by_mode[mode][lhs] = nil end -return -{ - --- @param keymaps_by_mode table the keymaps (e.g. `{n = {gg = {rhs = 'G', silent = true}}}`) - --- @return libmodal.Layer - new = function(keymaps_by_mode) - return setmetatable({existing_keymaps_by_mode = {}, layer_keymaps_by_mode = keymaps_by_mode, active = false}, Layer) - end -} +return Layer diff --git a/lua/libmodal/src/Mode.lua b/lua/libmodal/src/Mode.lua index 57c71dc..e9593a4 100644 --- a/lua/libmodal/src/Mode.lua +++ b/lua/libmodal/src/Mode.lua @@ -1,6 +1,11 @@ -local globals = require 'libmodal/src/globals' +--- @type libmodal.globals +local globals = require 'libmodal/src/globals' + +--- @type libmodal.collections.ParseTable local ParseTable = require 'libmodal/src/collections/ParseTable' -local utils = require 'libmodal/src/utils' + +--- @type libmodal.utils +local utils = require 'libmodal/src/utils' --- @class libmodal.Mode --- @field private exit libmodal.utils.Vars @@ -111,6 +116,7 @@ function Mode:enter() -- if there were errors, handle them. if not ok then + --- @diagnostic disable-next-line:param-type-mismatch if `not ok` then `mode_result` is a string utils.notify_error('Error during nvim-libmodal mode', mode_result) continue_mode = false else @@ -195,7 +201,7 @@ return local self = setmetatable( { exit = utils.Vars.new('exit', name), - indicator = utils.Indicator.mode(name), + indicator = utils.Indicator.new('LibmodalPrompt', '-- ' .. name .. ' --'), input = utils.Vars.new('input', name), instruction = instruction, name = name, @@ -213,6 +219,7 @@ return -- determine if a default `Help` should be created. if not self.instruction[HELP] then + --- @diagnostic disable-next-line:param-type-mismatch we checked that `instruction` is a table above self.help = utils.Help.new(self.instruction, 'KEY MAP') end diff --git a/lua/libmodal/src/Prompt.lua b/lua/libmodal/src/Prompt.lua index 07db09d..d22309b 100644 --- a/lua/libmodal/src/Prompt.lua +++ b/lua/libmodal/src/Prompt.lua @@ -1,4 +1,7 @@ +--- @type libmodal.globals local globals = require 'libmodal/src/globals' + +--- @type libmodal.utils local utils = require 'libmodal/src/utils' --- @class libmodal.Prompt @@ -95,6 +98,7 @@ function Prompt:enter() -- if there were errors. if not ok then + --- @diagnostic disable-next-line:param-type-mismatch if `not ok` then `mode_result` is a string utils.notify_error('Error during nvim-libmodal mode', prompt_result) continue_mode = false else @@ -116,7 +120,7 @@ return local self = setmetatable( { exit = utils.Vars.new('exit', name), - indicator = utils.Indicator.prompt(name), + indicator = utils.Indicator.new('LibmodalStar', '* ' .. name .. ' > '), input = utils.Vars.new('input', name), instruction = instruction, name = name @@ -140,6 +144,7 @@ return if not contained_help then -- assign it. completions[#completions + 1] = HELP + --- @diagnostic disable-next-line:param-type-mismatch we checked that `instruction` is a table above self.help = utils.Help.new(instruction, 'COMMAND') end diff --git a/lua/libmodal/src/collections/ParseTable.lua b/lua/libmodal/src/collections/ParseTable.lua index 0b223f7..8dcde56 100644 --- a/lua/libmodal/src/collections/ParseTable.lua +++ b/lua/libmodal/src/collections/ParseTable.lua @@ -1,9 +1,12 @@ ---- the number corresponding to in vim. -local CR = 13 +--- @type libmodal.globals local globals = require 'libmodal/src/globals' +--- the number corresponding to in vim. +local CR = string.byte(vim.api.nvim_replace_termcodes('', true, true, true)) + --- @class libmodal.collections.ParseTable -local ParseTable = require('libmodal/src/utils/classes').new(nil) +--- @field CR number the byte representation of `` +local ParseTable = require('libmodal/src/utils/classes').new {CR = CR} --- reverse the order of elements in some `tbl` --- @param tbl table the table to reverse @@ -93,6 +96,19 @@ function ParseTable:get(key_dict) return get(self, table_reverse(key_dict)) end +--- create a new `libmodal.collections.ParseTable` from a user-provided table. +--- @param user_table table keymaps (e.g. `{zfo = 'tabnew'}`) +--- @return libmodal.collections.ParseTable +function ParseTable.new(user_table) + local self = setmetatable({}, ParseTable) + + -- parse the passed in table. + self:parse_put_all(user_table) + + -- return the new `ParseTable`. + return self +end + --- parse `key` and retrieve its value --- @param key string the left-hand-side of the mapping to retrieve --- @return false|fun()|nil|string|table match a string/func when fully found; a table when partially found; false when not found. @@ -123,20 +139,4 @@ function ParseTable:parse_put_all(keys_and_values) end end -return -{ - CR = CR, - - --- create a new `libmodal.collections.ParseTable` from a user-provided table. - --- @param user_table table keymaps (e.g. `{zfo = 'tabnew'}`) - --- @return libmodal.collections.ParseTable - new = function(user_table) - local self = setmetatable({}, ParseTable) - - -- parse the passed in table. - self:parse_put_all(user_table) - - -- return the new `ParseTable`. - return self - end, -} +return ParseTable diff --git a/lua/libmodal/src/collections/Stack.lua b/lua/libmodal/src/collections/Stack.lua index d6bac6d..342fb83 100644 --- a/lua/libmodal/src/collections/Stack.lua +++ b/lua/libmodal/src/collections/Stack.lua @@ -1,6 +1,11 @@ --- @class libmodal.collections.Stack local Stack = require('libmodal/src/utils/classes').new(nil) +--- @return libmodal.collections.Stack +function Stack.new() + return setmetatable({}, Stack) +end + --- @return unknown top the foremost value of the stack function Stack:peek() return self[#self] @@ -19,9 +24,4 @@ function Stack:push(value) self[#self + 1] = value end -return -{ - new = function() - return setmetatable({}, Stack) - end, -} +return Stack diff --git a/lua/libmodal/src/collections/init.lua b/lua/libmodal/src/collections/init.lua index 79fa303..e31af42 100644 --- a/lua/libmodal/src/collections/init.lua +++ b/lua/libmodal/src/collections/init.lua @@ -4,5 +4,5 @@ return { ParseTable = require 'libmodal/src/collections/ParseTable', - Stack = require 'libmodal/src/collections/Stack' + Stack = require 'libmodal/src/collections/Stack' } diff --git a/lua/libmodal/src/globals.lua b/lua/libmodal/src/globals.lua index c50949e..81014cb 100644 --- a/lua/libmodal/src/globals.lua +++ b/lua/libmodal/src/globals.lua @@ -1,48 +1,34 @@ -local VIM_FALSE = 0 -local VIM_TRUE = 1 - --- @class libmodal.globals ---- @field private ESC_NR number ---- @field private TYPE_FUNC string ---- @field private TYPE_NUM string ---- @field private TYPE_STR string ---- @field private TYPE_TBL string ---- @field private VIM_FALSE number ---- @field private VIM_TRUE number -return +--- @field ESC_NR number the key-code for the escape character. +--- @field TYPE_FUNC string the string which is returned by `type(function() end)` (or any function) +--- @field TYPE_NUM string the string which is returned by `type(0)` (or any number) +--- @field TYPE_STR string the string which is returned by `type ''` (or any string) +--- @field TYPE_TBL string the string which is returned by `type {}` (or any table) +--- @field VIM_FALSE number the value of Vimscript's `v:false` +--- @field VIM_TRUE number the value of Vimscript's `v:true` +local globals = { - --- the key-code for the escape character. ESC_NR = 27, - - --- the string which is returned by `type(function() end)` (or any function) TYPE_FUNC = type(function() end), - - --- the string which is returned by `type(0)` (or any number) TYPE_NUM = type(0), - - --- the string which is returned by `type ''` (or any string) TYPE_STR = type '', - - --- the string which is returned by `type {}` (or any table) TYPE_TBL = type {}, - - --- the value of Vimscript's `v:false` - VIM_FALSE = VIM_FALSE, - - --- the value of Vimscript's `v:true` - VIM_TRUE = VIM_TRUE, - - --- assert some value is either `false` or `v:false`. - --- @param val boolean|number - --- @return boolean - is_false = function(val) - return val == false or val == VIM_FALSE - end, - - --- assert some value is either `true` or `v:true`. - --- @param val boolean|number - --- @return boolean - is_true = function(val) - return val == true or val == VIM_TRUE - end + VIM_FALSE = 0, + VIM_TRUE = 1, } + +--- assert some value is either `false` or `v:false`. +--- @param val boolean|number +--- @return boolean +function globals.is_false(val) + return val == false or val == globals.VIM_FALSE +end + +--- assert some value is either `true` or `v:true`. +--- @param val boolean|number +--- @return boolean +function globals.is_true(val) + return val == true or val == globals.VIM_TRUE +end + +return globals diff --git a/lua/libmodal/src/init.lua b/lua/libmodal/src/init.lua index 57d4022..c7b5436 100644 --- a/lua/libmodal/src/init.lua +++ b/lua/libmodal/src/init.lua @@ -1,16 +1,18 @@ --- @class libmodal ---- @field private collections libmodal.collections ---- @field private globals libmodal.globals ---- @field private Layer libmodal.Layer ---- @field private Mode libmodal.Mode ---- @field private Prompt libmodal.Prompt ---- @field private utils libmodal.utils -return +--- @field collections libmodal.collections +--- @field globals libmodal.globals +--- @field Layer libmodal.Layer +--- @field Mode libmodal.Mode +--- @field Prompt libmodal.Prompt +--- @field utils libmodal.utils +local libmodal = { collections = require 'libmodal/src/collections', - globals = require 'libmodal/src/globals', - Layer = require 'libmodal/src/Layer', - Mode = require 'libmodal/src/Mode', - Prompt = require 'libmodal/src/Prompt', - utils = require 'libmodal/src/utils', + globals = require 'libmodal/src/globals', + Layer = require 'libmodal/src/Layer', + Mode = require 'libmodal/src/Mode', + Prompt = require 'libmodal/src/Prompt', + utils = require 'libmodal/src/utils', } + +return libmodal diff --git a/lua/libmodal/src/utils/Help.lua b/lua/libmodal/src/utils/Help.lua index 88d5dcf..2820dfb 100644 --- a/lua/libmodal/src/utils/Help.lua +++ b/lua/libmodal/src/utils/Help.lua @@ -1,3 +1,4 @@ +--- @type libmodal.globals local globals = require 'libmodal/src/globals' --- @class libmodal.utils.Help @@ -27,6 +28,32 @@ local function align_columns(tbl, longest_key_len) return to_print end +--- create a default help table with `commands_or_maps` and vim expressions. +--- @param commands_or_maps {[string]: fun()|string} commands or mappings to vim expressions. +--- @param title string +--- @return libmodal.utils.Help +function Help.new(commands_or_maps, title) + -- find the longest key in the table, or at least the length of the title + local longest_key_maps = string.len(title) + for key, _ in pairs(commands_or_maps) do + local key_len = string.len(key) + if key_len > longest_key_maps then + longest_key_maps = key_len + end + end + + -- create a new `Help`. + return setmetatable( + { + [1] = ' ', + [2] = table.concat(align_columns({[title] = 'VIM EXPRESSION'}, longest_key_maps)), + [3] = table.concat(align_columns({[string.rep('-', string.len(title))] = '--------------'}, longest_key_maps)), + [4] = table.concat(align_columns(commands_or_maps, longest_key_maps)), + }, + Help + ) +end + --- show the contents of this `Help`. function Help:show() for _, help_text in ipairs(self) do @@ -35,33 +62,4 @@ function Help:show() vim.fn.getchar() end ---[[/* CLASS `Help` */]] - -return -{ - --- create a default help table with `commands_or_maps` and vim expressions. - --- @param commands_or_maps {[string]: fun()|string} commands or mappings to vim expressions. - --- @param title string - --- @return libmodal.utils.Help - new = function(commands_or_maps, title) - -- find the longest key in the table, or at least the length of the title - local longest_key_maps = string.len(title) - for key, _ in pairs(commands_or_maps) do - local key_len = string.len(key) - if key_len > longest_key_maps then - longest_key_maps = key_len - end - end - - -- create a new `Help`. - return setmetatable( - { - [1] = ' ', - [2] = table.concat(align_columns({[title] = 'VIM EXPRESSION'}, longest_key_maps)), - [3] = table.concat(align_columns({[string.rep('-', string.len(title))] = '--------------'}, longest_key_maps)), - [4] = table.concat(align_columns(commands_or_maps, longest_key_maps)), - }, - Help - ) - end -} +return Help diff --git a/lua/libmodal/src/utils/Indicator.lua b/lua/libmodal/src/utils/Indicator.lua index 662e273..5995caa 100644 --- a/lua/libmodal/src/utils/Indicator.lua +++ b/lua/libmodal/src/utils/Indicator.lua @@ -1,28 +1,13 @@ -local MODE_HIGHLIGHT = 'LibmodalPrompt' -local PROMPT_HIGHLIGHT = 'LibmodalStar' - --- @class libmodal.utils.Indicator ---- @field public hl string the highlight group to use when printing `str` ---- @field public str string the text to write +--- @field hl string the highlight group to use when printing `str` +--- @field str string the text to write local Indicator = {} --- @param highlight_group string the highlight group to use when printing `str` --- @param str string what to print --- @return libmodal.utils.Indicator function Indicator.new(highlight_group, str) - return - { - hl = highlight_group, - str = str, - } -end - -function Indicator.mode(mode_name) - return Indicator.new(MODE_HIGHLIGHT, '-- ' .. mode_name .. ' --') -end - -function Indicator.prompt(prompt_name) - return Indicator.new(PROMPT_HIGHLIGHT, '* ' .. prompt_name .. ' > ') + return {hl = highlight_group, str = str} end return Indicator diff --git a/lua/libmodal/src/utils/Popup.lua b/lua/libmodal/src/utils/Popup.lua index ce0de25..baf81cc 100644 --- a/lua/libmodal/src/utils/Popup.lua +++ b/lua/libmodal/src/utils/Popup.lua @@ -27,6 +27,13 @@ function Popup:close(keep_buffer) end end +--- @return libmodal.utils.Popup +function Popup.new(config) + local self = setmetatable({buffer = vim.api.nvim_create_buf(false, true), input_chars = {}}, Popup) + self:open(config) + return self +end + --- attempt to open this popup. If the popup was already open, close it and re-open it. function Popup:open(config) if not config then @@ -75,11 +82,4 @@ function Popup:refresh(input_bytes) vim.api.nvim_win_set_width(self.window, #self.input_chars) end -return -{ - new = function(config) - local self = setmetatable({buffer = vim.api.nvim_create_buf(false, true), input_chars = {}}, Popup) - self:open(config) - return self - end -} +return Popup diff --git a/lua/libmodal/src/utils/Vars.lua b/lua/libmodal/src/utils/Vars.lua index dc44733..9fb8fac 100644 --- a/lua/libmodal/src/utils/Vars.lua +++ b/lua/libmodal/src/utils/Vars.lua @@ -3,49 +3,48 @@ --- @field private var_name string the highlight group to use when printing `str` local Vars = require('libmodal/src/utils/classes').new(nil) ---- @return string name the global Neovim setting -function Vars:name() - return self.mode_name .. self.var_name -end - --- @return unknown `vim.g[self:name()])` function Vars:get() return vim.g[self:name()] end ---- @param val unknown set `vim.g[self:name()])` equal to this value -function Vars:set(val) - vim.g[self:name()] = val +--- @return string name the global Neovim setting +function Vars:name() + return self.mode_name .. self.var_name end -return -{ - --- 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 - new = function(var_name, mode_name) - local self = setmetatable({}, Vars) +--- 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 +--- @return libmodal.utils.Vars +function Vars.new(var_name, mode_name) + local self = setmetatable({}, Vars) - local function no_spaces(str_with_spaces, first_letter_modifier) - local split_str = vim.split(string.gsub(str_with_spaces, vim.pesc '_', vim.pesc ' '), ' ') + local function no_spaces(str_with_spaces, first_letter_modifier) + local split_str = vim.split(string.gsub(str_with_spaces, vim.pesc '_', vim.pesc ' '), ' ') - local function camel_case(str, func) - return func(string.sub(str, 0, 1) or '') .. string.lower(string.sub(str, 2) or '') - end - - split_str[1] = camel_case(split_str[1], first_letter_modifier) + local function camel_case(str, func) + return func(string.sub(str, 0, 1) or '') .. string.lower(string.sub(str, 2) or '') + end - for i = 2, #split_str do split_str[i] = - camel_case(split_str[i], string.upper) - end + split_str[1] = camel_case(split_str[1], first_letter_modifier) - return table.concat(split_str) + for i = 2, #split_str do split_str[i] = + camel_case(split_str[i], string.upper) end - self.mode_name = no_spaces(mode_name, string.lower) + return table.concat(split_str) + end + + self.mode_name = no_spaces(mode_name, string.lower) + self.var_name = 'Mode' .. no_spaces(var_name, string.upper) - self.var_name = 'Mode' .. no_spaces(var_name, string.upper) + return self +end - return self - end -} +--- @param val unknown set `vim.g[self:name()])` equal to this value +function Vars:set(val) + vim.g[self:name()] = val +end + +return Vars diff --git a/lua/libmodal/src/utils/api.lua b/lua/libmodal/src/utils/api.lua index 00d5afc..b4fc563 100644 --- a/lua/libmodal/src/utils/api.lua +++ b/lua/libmodal/src/utils/api.lua @@ -1,24 +1,9 @@ +--- @type libmodal.globals local globals = require 'libmodal/src/globals' --- @class libmodal.utils.api local api = {} ---- echo a list of `Indicator`s with their associated highlighting. ---- @param indicators libmodal.utils.Indicator|libmodal.utils.Indicator[] the indicators to echo -function api.hi_echo(indicators) - if indicators.hl then -- wrap the single indicator in a table to form a list of indicators - indicators = {indicators} - end - - api.redraw() - - for _, indicator in ipairs(indicators) do - vim.api.nvim_command('echohl ' .. indicator.hl .. " | echon '" .. indicator.str .. "'") - end - - vim.api.nvim_command 'echohl None' -end - --- send a character to exit a mode. --- @param exit_char? number|string the character used to exit the mode, or ESCAPE if none was provided. function api.mode_exit(exit_char) diff --git a/lua/libmodal/src/utils/classes.lua b/lua/libmodal/src/utils/classes.lua index 91e44f0..989b48b 100644 --- a/lua/libmodal/src/utils/classes.lua +++ b/lua/libmodal/src/utils/classes.lua @@ -1,17 +1,18 @@ --- @class libmodal.utils.classes -return -{ - --- define a metatable. - --- @param template? table the default value - new = function(template) - -- set self to `template`, or `{}` if nil. - local self = template or {} +local classes = {} - -- set `__index`. - if not self.__index then - self.__index = self - end +--- define a metatable. +--- @param template? table the default value +function classes.new(template) + -- set self to `template`, or `{}` if nil. + local self = template or {} - return self - end, -} + -- set `__index`. + if not self.__index then + self.__index = self + end + + return self +end + +return classes diff --git a/lua/libmodal/src/utils/init.lua b/lua/libmodal/src/utils/init.lua index 6371a8d..e50df7a 100644 --- a/lua/libmodal/src/utils/init.lua +++ b/lua/libmodal/src/utils/init.lua @@ -1,28 +1,29 @@ --- @class libmodal.utils ---- @field private completions libmodal.utils.api ---- @field private classes libmodal.utils.classes ---- @field private Indicator libmodal.utils.Indicator ---- @field private Help libmodal.utils.Help ---- @field private Popup libmodal.utils.Popup ---- @field private Vars libmodal.utils.Vars -return +--- @field api libmodal.utils.api +--- @field classes libmodal.utils.classes +--- @field Indicator libmodal.utils.Indicator +--- @field Help libmodal.utils.Help +--- @field Popup libmodal.utils.Popup +--- @field Vars libmodal.utils.Vars +local utils = { api = require 'libmodal/src/utils/api', classes = require 'libmodal/src/utils/classes', Indicator = require 'libmodal/src/utils/Indicator', Help = require 'libmodal/src/utils/Help', - - --- `vim.notify` with a `msg` some `error` which has a `vim.v.throwpoint` and `vim.v.exception`. - --- @param msg string - --- @param err string - notify_error = function(msg, err) - vim.notify( - msg .. ': ' .. vim.v.throwpoint .. '\n' .. vim.v.exception .. '\n' .. err, - vim.log.levels.ERROR, - {title = 'nvim-libmodal'} - ) - end, - Popup = require 'libmodal/src/utils/Popup', Vars = require 'libmodal/src/utils/Vars', } + +--- `vim.notify` with a `msg` some `error` which has a `vim.v.throwpoint` and `vim.v.exception`. +--- @param msg string +--- @param err string +function utils.notify_error(msg, err) + vim.notify( + msg .. ': ' .. vim.v.throwpoint .. '\n' .. vim.v.exception .. '\n' .. err, + vim.log.levels.ERROR, + {title = 'nvim-libmodal'} + ) +end + +return utils