Initial conversion of prompt

pull/3/head
Iron-E 4 years ago
parent 7c2f9694d8
commit 523261dcbc
No known key found for this signature in database
GPG Key ID: 19B71B7B7B021D22

@ -657,6 +657,29 @@ When submitting an issue, please describe the following:
==============================================================================
8. Changelog *libmodal-changelog*
0.5.0 ~
Additions: ~
* New class `libmodal.Mode`
* New class `libmodal.Mode.Popup`
* New class `libmodal.Prompt`
* New class `libmodal.Vars`
Breaking Changes: ~
* Removed `libmodal.utils.vars`
* Moved `libmodal.utils.Indicator` to `libmodal.Indicator`
* Moved `libmodal.utils.Indicator.Entry` to
`libmodal.Indicator.HighlightSegment`
Changes: ~
*Error deprecated `libmodal.mode.enter()`
* Use `libmodal.Mode.new(…):enter()` instead.
*Error deprecated `libmodal.prompt.enter()`
* Use `libmodal.Prompt.new(…):enter()` instead.
* Allowed creation of |libmodal-mode| and |libmodal-prompt| table-objects.
* Call `{mode}:enter()` to enter the mode.
* More efficient recursion.
0.4.1 ~
Fixes: ~
@ -672,7 +695,6 @@ When submitting an issue, please describe the following:
* Fix bug where help was always shown upon entering an invalid key-combo in
`libmodal.mode.enter()`.
0.3.1 ~
Fixes: ~

@ -4,24 +4,24 @@
*/
--]]
local Entry = {}
local HighlightSegment = {}
--[[
/*
* CLASS `Entry`
* CLASS `HighlightSegment`
*/
--]]
--------------------------------
--[[ SUMMARY:
* Create a new `Indicator.Entry`.
* Create a new `Indicator.HighlightSegment`.
]]
--[[ PARAMS:
* `hlgroup` => The `highlight-group` to be used for this `Indicator.Entry`.
* `str` => The text for this `Indicator.Entry`.
* `hlgroup` => The `highlight-group` to be used for this `Indicator.HighlightSegment`.
* `str` => The text for this `Indicator.HighlightSegment`.
]]
--------------------------------
function Entry.new(hlgroup, str)
function HighlightSegment.new(hlgroup, str)
return {
['hl'] = hlgroup,
['str'] = str
@ -34,4 +34,4 @@ end
*/
--]]
return Entry
return HighlightSegment

@ -0,0 +1,82 @@
--[[
/*
* MODULE
*/
--]]
local Indicator = {}
Indicator.HighlightSegment = require('libmodal/src/Indicator/HighlightSegment')
-- highlight group names
local _HL_GROUP_PROMPT = 'LibmodalPrompt'
local _HL_GROUP_STAR = 'LibmodalStar'
local _HL_GROUP_NONE = 'None'
-- `libmodal.mode` `HighlightSegment`s.
local _ENTRY_MODE_START = Indicator.HighlightSegment.new(_HL_GROUP_PROMPT, '-- ')
local _ENTRY_MODE_END = Indicator.HighlightSegment.new(_HL_GROUP_PROMPT, ' --')
-- `libmodal.prompt` `HighlightSegment`s.
local _ENTRY_PROMPT_START = Indicator.HighlightSegment.new(_HL_GROUP_STAR, '* ')
local _ENTRY_PROMPT_END = Indicator.HighlightSegment.new(_HL_GROUP_PROMPT, ' > ')
--[[
/*
* META `Indicator`
*/
--]]
local _metaIndicator = {
_ENTRY_MODE_START, nil, _ENTRY_MODE_END
}
_metaIndicator.__index = _metaIndicator
local _PROMPT_TEMPLATE = {
'* ', ' > '
}
--[[
/*
* CLASS `Indicator`
*/
--]]
---------------------------------
--[[ SUMMARY:
* Create a new `Indicator` for a mode.
]]
--[[ PARAMS:
* `modeName` => the name of the mode that this `Indicator` is for.
]]
---------------------------------
function Indicator.mode(modeName)
local self = {}
setmetatable(self, _metaIndicator)
self[2] = Indicator.HighlightSegment.new(
_HL_GROUP_PROMPT, tostring(modeName)
)
return self
end
-----------------------------------
--[[ SUMMARY:
* Create a new `Indicator` for a prompt.
]]
--[[ PARAMS:
* `modeName` => the name of the mode that this `Indicator` is for.
]]
-----------------------------------
function Indicator.prompt(modeName)
return table.concat(_PROMPT_TEMPLATE, modeName)
end
--[[
/*
* PUBLICIZE MODULE
*/
--]]
return Indicator

@ -6,6 +6,7 @@
local globals = require('libmodal/src/globals')
local utils = require('libmodal/src/utils')
local Stack = require('libmodal/src/collections/Stack')
local Vars = require('libmodal/src/Vars')
local api = utils.api
@ -21,8 +22,6 @@ local Mode = {}
Mode.ParseTable = require('libmodal/src/mode/ParseTable')
Mode.Popup = require('libmodal/src/Mode/Popup')
local _metaMode = {}
local _HELP = '?'
local _TIMEOUT = {
['CHAR'] = 'ø',
@ -39,6 +38,15 @@ _TIMEOUT.NR = string.byte(_TIMEOUT.CHAR)
*/
--]]
local _metaMode = {}
_metaMode.__index = _metaMode
self._exit = Vars.new('exit')
_metaMode._indicator = nil
_metaMode._instruction = nil
_metaMode._name = nil
_metaMode._winState = nil
-----------------------------------------------
--[[ SUMMARY:
* Parse `self._mappings` and see if there is any command to execute.
@ -46,15 +54,15 @@ _TIMEOUT.NR = string.byte(_TIMEOUT.CHAR)
-----------------------------------------------
function _metaMode:_checkInputForMapping()
-- Stop any running timers
if self._flushInputTimer then
self._flushInputTimer:stop()
end
self._modeEnterData:peek().flushInputTimer:stop()
-- Append the latest input to the locally stored input history.
self._input.bytes[#self._input.bytes + 1] = self._input:nvimGet(self._name)
local input = self._modeEnterData:peek().input
input.bytes[#input.bytes + 1] = input:nvimGet(self._name)
-- Get the command based on the users input.
local cmd = self._mappings:get(self._input.bytes)
local cmd = self._mappings:get(input.bytes)
-- Get the type of the command.
local commandType = type(cmd)
@ -62,10 +70,10 @@ function _metaMode:_checkInputForMapping()
-- if there was no matching command
if cmd == false then
if #self._input.bytes < 2 and self._input.bytes[1] == string.byte(_HELP) then
if #input.bytes < 2 and input.bytes[1] == string.byte(_HELP) then
self._help:show()
end
self._input:clear()
input:clear()
-- The command was a table, meaning that it MIGHT match.
elseif commandType == globals.TYPE_TBL
and globals.isTrue(self._timeouts.enabled)
@ -73,7 +81,7 @@ function _metaMode:_checkInputForMapping()
-- Create a new timer
-- start the timer
self._flushInputTimer:start(
self._modeEnterData:peek().flushInputTimer:start(
_TIMEOUT.LEN, 0, vim.schedule_wrap(function()
-- Send input to interrupt a blocking `getchar`
_TIMEOUT:SEND()
@ -82,17 +90,18 @@ function _metaMode:_checkInputForMapping()
api.nvim_command(cmd[Mode.ParseTable.CR])
end
-- clear input
self._input:clear()
self._popup:refresh(self._input.bytes)
input:clear()
self._modeEnterData:peek().popup:refresh(input.bytes)
end)
)
-- The command was an actual vim command.
else
api.nvim_command(cmd)
self._input:clear()
input:clear()
end
self._popup:refresh(self._input.bytes)
self._modeEnterData:peek().popup:refresh(input.bytes)
end
--------------------------
@ -101,25 +110,25 @@ end
]]
--------------------------
function _metaMode:enter()
-- intialize variables that are needed for each recurse of a function
if self._instruction == globals.TYPE_TBL then
-- Create a timer
self._flushInputTimer = vim.loop.new_timer()
-- Initialize the input history variable.
self._input = {
['bytes'] = {},
----------------------------
--[[ SUMMARY:
* Clear the self.bytes table.
]]
----------------------------
['clear'] = function(__self)
__self.bytes = {}
end
}
-- create a floating window
self._popup = Mode.Popup.new()
local input = Vars.new('input')
input.bytes = {}
function input:clear()
self.bytes = {}
end
self._modeEnterData:push({
-- Create a timer
['flushInputTimer'] = vim.loop.new_timer(),
-- assign input
['input'] = input,
-- create a floating window
['popup'] = Mode.Popup.new()
})
end
--[[ MODE LOOP. ]]
@ -161,18 +170,21 @@ function _metaMode:_initMappings()
self._help = utils.Help.new(self._instruction, 'KEY MAP')
end
-- Create a table for mode-specific data.
self._modeEnterData = Stack.new()
-- Build the parse tree.
self._mappings = Mode.ParseTable.new(self._instruction)
end
------------------------------------
-------------------------------
--[[ SUMMARY:
* Loop an initialized `mode`.
]]
--[[ RETURNS:
* `boolean` => whether or not the mode should continue
]]
------------------------------------
-------------------------------
function _metaMode:_inputLoop()
-- If the mode is not handling exit events automatically and the global exit var is true.
if self._exit.supress
@ -193,7 +205,7 @@ function _metaMode:_inputLoop()
end
-- Set the global input variable to the new input.
self._input:nvimSet(self._name, userInput)
self._modeEnterData:peek().input:nvimSet(self._name, userInput)
-- Make sure that the user doesn't want to exit.
if not self._exit.supress
@ -215,16 +227,18 @@ end
---------------------------------
function _metaMode:_tearDown()
if self._instruction == globals.TYPE_TBL then
self._flushInputTimer:stop()
self._flushInputTimer = nil
local modeEnterData = self._modeEnterData:pop()
modeEnterData.flushInputTimer:stop()
modeEnterData.flushInputTimer = nil
for k, _ in pairs(self._input) do
self._input[k] = nil
for k, _ in pairs(modeEnterData.input) do
modeEnterData.input[k] = nil
end
self._input = nil
modeEnterData.input = nil
self._popup:close()
self._popup = nil
modeEnterData.popup:close()
modeEnterData.popup = nil
end
self._winState:restore()
@ -236,7 +250,7 @@ end
*/
--]]
------------------------
-----------------------------------------
--[[ SUMMARY:
* Enter a mode.
]]
@ -245,13 +259,11 @@ end
* `instruction` => the mode callback, or mode combo table.
* `...` => optional exit supresion flag.
]]
------------------------
-- TODO
-----------------------------------------
function Mode.new(name, instruction, ...)
-- Inherit the metatable.
self = {}
setmetatable(self, _metaMode)
self.__index = self
-- Define the exit flag
self._exit = Vars.new('exit')

@ -0,0 +1,204 @@
--[[
/*
* IMPORTS
*/
--]]
local globals = require('libmodal/src/globals')
local Stack = require('libmodal/src/collections/Stack')
local utils = require('libmodal/src/utils')
local Vars = require('libmodal/src/Vars')
local api = utils.api
--[[
/*
* MODULE
*/
--]]
local Prompt = {}
local _HELP = 'help'
local _replacements = {
'(', ')', '[', ']', '{', '}',
'=', '+', '<', '>', '^',
',', '/', ':', '?', '@', '!', '$', '*', '.', '%', '&', '\\',
}
--[[
/*
* META `Prompt`
*/
--]]
local _metaPrompt = {}
_metaPrompt.__index = _metaPrompt
_metaPrompt._indicator = nil
_metaPrompt._input = nil
_metaPrompt._instruction = nil
_metaPrompt._name = nil
function _metaPrompt:_inputLoop()
-- clear previous `echo`s.
api.nvim_redraw()
-- get user input based on `instruction`.
local userInput = ''
if self._completions then userInput =
api.nvim_call_function('libmodal#_inputWith', {
self._indicator, self._completions
})
else userInput =
api.nvim_call_function('input', {
self._indicator
})
end
-- if a:2 is a function then call it.
if string.len(userInput) > 0 then
self._input:nvimSet(self._name, userInput)
if type(self._instruction) == globals.TYPE_TBL then
if self._instruction[userInput] then -- there is a defined command for the input.
api.nvim_command(instruction[userInput])
elseif userInput == _HELP then -- the user did not define a 'help' command, so use the default.
self._help:show()
else -- show an error.
api.nvim_show_err(globals.DEFAULT_ERROR_TITLE, 'Unknown command')
end
else instruction()
end
else return false
end
return true
end
function _metaPrompt:enter()
-- enter the mode using a loop.
local continueMode = true
while continueMode == true do
local noErrors, result = pcall(self._inputLoop, self)
-- if there were errors.
if not noErrors then
utils.showError(err)
continueMode = false
else
continueMode = result
end
end
end
--[[
/*
* CLASS `Prompt`
*/
--]]
------------------------------------------------------
--[[ SUMMARY:
* Provide completions for a `libmodal.prompt`.
]]
--[[ PARAMS:
* `completions` => the list of completions.
]]
--[[ RETURNS:
* A function that accepts:
* `argLead` => the current line being edited, stops at the cursor.
* `cmdLine` => the current line being edited
* `cursorPos` => the position of the cursor
* Used for `input()` VimL.
]]
------------------------------------------------------
function Prompt.createCompletionsProvider(completions)
return function(argLead, cmdLine, cursorPos)
if string.len(cmdLine) < 1 then
return completions
end
-- replace conjoining characters with spaces.
local spacedArgLead = argLead
for _, v in ipairs(_replacements) do
spacedArgLead, _ = string.gsub(spacedArgLead, vim.pesc(v), ' ')
end
-- split the spaced version of `argLead`.
local splitArgLead = vim.split(spacedArgLead, ' ', true)
-- make sure the user is in a position were this function
-- will provide accurate completions.
if #splitArgLead > 1 then
return nil
end
-- get the word selected by the user. (don't compare case)
local word = string.upper(splitArgLead[1])
-- get all matches from the completions list.
local matches = {}
for _, v in ipairs(completions) do
-- test if `word` is inside of `completions`:`v`, ignoring case.
if string.match(vim.pesc(string.upper(v)), word) then
matches[#matches + 1] = v -- preserve case when providing completions.
end
end
return matches
end
end
-------------------------------------------
--[[ SUMMARY:
* Enter a prompt.
]]
--[[ PARAMS:
* `name` => the prompt name.
* `instruction` => the prompt callback, or mode command table.
* `...` => a completions table.
]]
-------------------------------------------
function Prompt.new(name, instruction, ...)
self = {}
setmetatable(self, _metaPrompt)
self._indicator = utils.indicator.prompt(name)
self._input = vars.new('input')
self._instruction = instruction
self._name = name
-- get the arguments
local userCompletions = unpack({...})
-- get the completion list.
if type(instruction) == globals.TYPE_TBL then -- unload the keys of the mode command table.
-- Create one if the user specified a command table.
local completions = {}
local containedHelp = false
for k, _ in pairs(instruction) do
completions[#completions + 1] = k
if k == _HELP then containedHelp = true
end
end
if not containedHelp then -- assign it.
completions[#completions + 1] = _HELP
vars.help.instances[modeName] = utils.Help.new(instruction, 'COMMAND')
end
self._completions = completions
elseif userCompletions then
-- Use the table that the user gave.
self._completions = userCompletions
end
end
--[[
/*
* PUBLICIZE MODULE
*/
--]]
return Prompt

@ -25,6 +25,7 @@ Vars.libmodalTimeouts = api.nvim_get_var('libmodalTimeouts')
--]]
local _metaVars = {}
_metaVars.__index = _metaVars
-- Instances of variables pertaining to a certain mode.
_metaVars.varName = nil
@ -83,7 +84,6 @@ end
function Vars.new(keyName)
self = {}
setmetatable(self, _metaVars)
self.__index = self
self._varName = 'Mode' .. string.upper(
string.sub(keyName, 0, 1)

@ -0,0 +1,83 @@
--[[
/*
* MODULE `Stack`
*/
--]]
local Stack = {}
--[[
/*
* META `Stack`
*/
--]]
local _metaStack = {}
_metaStack.__index = _metaStack
_metaStack._len = 0
_metaStack._top = nil
--------------------------------
--[[ SUMMARY:
* Get the foremost value in `self`.
]]
--[[
* The foremost value in `self`.
]]
--------------------------------
function _metaStack:peek()
return top
end
-------------------------
--[[ SUMMARY:
* Remove the foremost value in `self` and return it.
]]
--[[ RETURNS:
* The foremost value in `self`.
]]
-------------------------
function _metaStack:pop()
if len < 1 then return nil
end
-- Store the previous top of the stack.
local previousTop = self._top
-- Remove the previous top of the stack.
self[_len] = nil
-- Update the values of the stack.
self._len = self._len - 1
self._top = self[_len]
-- Return the previous top of the stack.
return previousTop
end
-------------------------------
--[[ SUMMARY:
* Push some `value` onto `self`.
]]
--[[ PARAMS:
* `value` => the value to append to `self`.
]]
-------------------------------
function _metaStack:push(value)
self._len = self._len + 1
self[_len] = value
end
--[[
/*
* CLASS `Stack`
*/
--]]
function Stack.new()
local self = {}
setmetatable(self, _metaStack)
return self
end

@ -0,0 +1,3 @@
local collections = {}
collections.Stack = require('libmodal/src/collections/Stack')
return collections

@ -4,11 +4,7 @@
*/
--]]
local globals = require('libmodal/src/globals')
local utils = require('libmodal/src/utils')
local api = utils.api
local vars = utils.vars
local Mode = require('libmodal/src/Mode')
--[[
/*
@ -17,7 +13,8 @@ local vars = utils.vars
--]]
local mode = {}
mode.ParseTable = require('libmodal/src/mode/ParseTable')
mode.ParseTable = Mode.ParseTable
--[[
/*
@ -25,216 +22,6 @@ mode.ParseTable = require('libmodal/src/mode/ParseTable')
*/
--]]
local _HELP = '?'
local _TIMEOUT_CHAR = 'ø'
local _TIMEOUT_NR = string.byte(_TIMEOUT_CHAR)
local _TIMEOUT_LEN = api.nvim_get_option('timeoutlen')
----------------------------------------
--[[ SUMMARY:
* Reset libmodal's internal counter of user input to default.
]]
----------------------------------------
local function _clearUserInput(modeName)
vars.input.instances[modeName] = {}
end
----------------------------------------------
--[[ SUMMARY:
* Update the floating window with the latest user input.
]]
--[[ PARAMS:
* `modeName` => the name of the mode.
]]
----------------------------------------------
local function _updateFloatingWindow(modeName)
local userInput = {}
for _, v in ipairs(vars.input.instances[modeName]) do
userInput[#userInput + 1] = string.char(v)
end
api.nvim_buf_set_lines(
vars.buffers.instances[modeName],
0, 1, true, {table.concat(userInput)}
)
end
-------------------------------------
--[[ SUMMARY:
* Parse the `comboDict` and see if there is any command to execute.
]]
--[[ PARAMS:
* `modeName` => the name of the mode that is currently active.
]]
-------------------------------------
local function _comboSelect(modeName)
-- Stop any running timers
if vars.timer.instances[modeName] then
vars.timer.instances[modeName]:stop()
vars.timer.instances[modeName] = nil
end
-- Append the latest input to the locally stored input history.
local userInputHistory = vars.input.instances[modeName]
userInputHistory[#userInputHistory + 1] = vars.nvim_get(
vars.input, modeName
)
-- Get the combo dict.
local comboTable = vars.combos.instances[modeName]
-- Get the command based on the users input.
local cmd = comboTable:get(userInputHistory)
-- Get the type of the command.
local commandType = type(cmd)
local clearUserInput = false
-- if there was no matching command
if cmd == false then
if #userInputHistory < 2 and userInputHistory[1] == string.byte(_HELP) then
vars.help.instances[modeName]:show()
end
clearUserInput = true
-- The command was a table, meaning that it MIGHT match.
elseif commandType == globals.TYPE_TBL
and globals.isTrue(vars.timeouts.instances[modeName])
then
-- Create a new timer
vars.timer.instances[modeName] = vim.loop.new_timer()
-- start the timer
vars.timer.instances[modeName]:start(
_TIMEOUT_LEN, 0, vim.schedule_wrap(function()
-- Send input to interrupt a blocking `getchar`
api.nvim_feedkeys(_TIMEOUT_CHAR, '', false)
-- if there is a command, execute it.
if cmd[mode.ParseTable.CR] then
api.nvim_command(cmd[mode.ParseTable.CR])
end
-- clear input
_clearUserInput(modeName)
_updateFloatingWindow(modeName)
end)
)
-- The command was an actual vim command.
else
api.nvim_command(cmd)
clearUserInput = true
end
if clearUserInput then
_clearUserInput(modeName)
end
_updateFloatingWindow(modeName)
end
------------------------------------------------
--[[ SUMMARY:
* Set the initial values used for parsing user input as combos.
]]
--[[ PARAMS:
* `modeName` => the name of the mode being initialized.
* `comboTable` => the table of combos being initialized.
]]
------------------------------------------------
local function _initCombos(modeName, comboTable)
-- Placeholder for timeout value.
local doTimeout = nil
-- Read the correct timeout variable.
if api.nvim_exists('g', vars.timeouts:name(modeName)) then doTimeout =
vars.nvim_get(vars.timeouts, modeName)
else doTimeout =
vars.libmodalTimeouts
end
-- Assign the timeout variable according to `doTimeout`
vars.timeouts.instances[modeName] = doTimeout
-- create a floating window
local buf = api.nvim_create_buf(false, true)
vars.buffers.instances[modeName] = buf
vars.windows.instances[modeName] = api.nvim_call_function('libmodal#_winOpen', {buf})
-- Determine if a default `Help` should be created.
if not comboTable[_HELP] then
vars.help.instances[modeName] = utils.Help.new(comboTable, 'KEY MAP')
end
-- Build the parse tree.
vars.combos.instances[modeName] = mode.ParseTable.new(comboTable)
-- Initialize the input history variable.
_clearUserInput(modeName)
end
-----------------------------------------------------
--[[ SUMMARY:
* Remove variables used for a mode.
]]
--[[ PARAMS:
* `modeName` => the name of the mode.
* `winState` => the window state prior to mode activation.
]]
-----------------------------------------------------
local function _modeEnterTeardown(modeName, winState)
if vars.windows.instances[modeName] then
api.nvim_win_close(
vars.windows.instances[modeName], false
)
end
vars:tearDown(modeName)
api.nvim_command("mode | echo '' | call garbagecollect()")
winState:restore()
end
--------------------------------------------------------------------------------
--[[ SUMMARY:
* Loop an initialized `mode`.
]]
--[[ PARAMS:
* `handleExitEvents` => whether or not to automatically exit on `<Esc>` press.
* `indicator` => the indicator for the mode.
* `modeInstruction` => the instructions for the mode.
* `modeName` => the name of the `mode`.
]]
--[[ RETURNS:
* `boolean` => whether or not the mode should continue
]]
--------------------------------------------------------------------------------
local function _modeLoop(handleExitEvents, indicator, modeInstruction, modeName)
-- If the mode is not handling exit events automatically and the global exit var is true.
if not handleExitEvents and globals.isTrue(
vars.nvim_get(vars.exit, modeName)
) then return false end
-- Echo the indicator.
api.nvim_lecho(indicator)
-- Capture input.
local userInput = api.nvim_input()
-- Return if there was a timeout event.
if userInput == _TIMEOUT_NR then
return true
end
-- Set the global input variable to the new input.
vars.nvim_set(vars.input, modeName, userInput)
-- Make sure that the user doesn't want to exit.
if handleExitEvents and userInput == globals.ESC_NR then
return false
-- If the second argument was a dict, parse it.
elseif type(modeInstruction) == globals.TYPE_TBL then
_comboSelect(modeName)
-- If the second argument was a function, execute it.
else modeInstruction() end
return true
end
------------------------
--[[ SUMMARY:
* Enter a mode.
@ -245,49 +32,8 @@ end
* `args[3]` => optional exit supresion flag.
]]
------------------------
function mode.enter(...)
local args = {...}
--[[ SETUP. ]]
-- Create the indicator for the mode.
local indicator = utils.Indicator.mode(args[1])
-- Grab the state of the window.
local winState = utils.WindowState.new()
-- Convert the name into one that can be used for variables.
local modeName = string.lower(args[1])
-- Determine whether or not this function should handle exiting automatically.
local handleExitEvents = true
if #args > 2 then
handleExitEvents = globals.isFalse(args[3])
end
-- Determine whether a callback was specified, or a combo table.
if type(args[2]) == globals.TYPE_TBL then
_initCombos(modeName, args[2])
end
--[[ MODE LOOP. ]]
local continueMode = true
while continueMode == true do
-- Try (using pcall) to use the mode.
local noErrors = true
noErrors, continueMode = pcall(_modeLoop,
handleExitEvents, indicator, args[2], modeName
)
-- If there were errors, handle them.
if noErrors == false then
utils.showError(continueMode)
continueMode = false
end
end
_modeEnterTeardown(modeName, winState)
function mode.enter(name, instruction, ...)
Mode.new(name, instruction, ...):enter()
end
--[[

@ -1,70 +0,0 @@
--[[
/*
* IMPORTS
*/
--]]
local Entry = require('libmodal/src/utils/Indicator/Entry')
--[[
/*
* MODULE
*/
--]]
local Indicator = {}
-- highlight group names
local _HL_GROUP_PROMPT = 'LibmodalPrompt'
local _HL_GROUP_STAR = 'LibmodalStar'
local _HL_GROUP_NONE = 'None'
-- `libmodal.mode` `Entry`s.
local _ENTRY_MODE_START = Entry.new(_HL_GROUP_PROMPT, '-- ')
local _ENTRY_MODE_END = Entry.new(_HL_GROUP_PROMPT, ' --')
-- `libmodal.prompt` `Entry`s.
local _ENTRY_PROMPT_START = Entry.new(_HL_GROUP_STAR, '* ')
local _ENTRY_PROMPT_END = Entry.new(_HL_GROUP_PROMPT, ' > ')
--[[
/*
* CLASS `Indicator`
*/
--]]
---------------------------------
--[[ SUMMARY:
* Create a new `Indicator` for a mode.
]]
--[[ PARAMS:
* `modeName` => the name of the mode that this `Indicator` is for.
]]
---------------------------------
function Indicator.mode(modeName)
return {
_ENTRY_MODE_START,
Entry.new(_HL_GROUP_PROMPT, tostring(modeName)),
_ENTRY_MODE_END
}
end
-----------------------------------
--[[ SUMMARY:
* Create a new `Indicator` for a prompt.
]]
--[[ PARAMS:
* `modeName` => the name of the mode that this `Indicator` is for.
]]
-----------------------------------
function Indicator.prompt(modeName)
return '* ' .. tostring(modeName) .. ' > '
end
--[[
/*
* PUBLICIZE MODULE
*/
--]]
return Indicator

@ -5,7 +5,7 @@
--]]
local globals = require('libmodal/src/globals')
local Entry = require('libmodal/src/utils/Indicator/Entry')
local HighlightSegment = require('libmodal/src/Indicator/HighlightSegment')
--[[
/*
@ -105,12 +105,11 @@ end
* `msg` => the message of the error.
]]
--------------------------------------
-- local returnEntry = Entry.new('Question', '\nPress any key to return.')
-- local returnHighlightSegment = HighlightSegment.new('Question', '\nPress any key to return.')
function api.nvim_show_err(title, msg)
api.nvim_lecho({
Entry.new('Title', tostring(title) .. '\n'),
Entry.new('Error', tostring(msg)),
-- returnEntry
HighlightSegment.new('Title', tostring(title) .. '\n'),
HighlightSegment.new('Error', tostring(msg)),
})
api.nvim_call_function('getchar', {})
end

@ -16,8 +16,6 @@ local globals = require('libmodal/src/globals')
local utils = {}
utils.api = require('libmodal/src/utils/api')
utils.Help = require('libmodal/src/utils/Help')
utils.Indicator = require('libmodal/src/utils/Indicator')
utils.vars = require('libmodal/src/utils/vars')
utils.WindowState = require('libmodal/src/utils/WindowState')
--[[

@ -1,103 +0,0 @@
--[[
/*
* IMPORTS
*/
--]]
local globals = require('libmodal/src/globals')
local api = vim.api
--[[
/*
* MODULE
*/
--]]
local vars = {}
vars.libmodalTimeouts = api.nvim_get_var('libmodalTimeouts')
--[[
/*
* HELPERS
*/
--]]
------------------------------------
--[[ SUMMARY:
* Create a new entry in `vars`
]]
--[[ PARAMS:
* `keyName` => the name of the key used to refer to this variable in `vars`.
* `varName` => the name of the variable as it is stored in vim.
]]
------------------------------------
local function new(keyName)
vars[keyName] = {
-- Instances of variables pertaining to a certain mode.
instances = {},
_varName = 'Mode'
.. string.upper(string.sub(keyName, 0, 1))
.. string.sub(keyName, 2),
---------------------------------
--[[ SUMMARY:
* Get the name of `modeName`s global setting.
]]
--[[ PARAMS:
* `modeName` => the name of the mode.
]]
---------------------------------
name = function(__self, modeName)
return string.lower(modeName) .. __self._varName
end,
}
end
------------------------------------
--[[ SUMMARY:
* Retrieve a variable value.
]]
--[[ PARAMS:
* `var` => the `vars.*` table to retrieve the value of.
* `modeName` => the mode name this value is being retrieved for.
]]
------------------------------------
function vars.nvim_get(var, modeName)
return api.nvim_get_var(var:name(modeName))
end
function vars.nvim_set(var, modeName, val)
api.nvim_set_var(var:name(modeName), val)
end
function vars:tearDown(modeName)
for _, v in pairs(self) do
if type(v) == globals.TYPE_TBL and v.instances[modeName] then
v.instances[modeName] = nil
end
end
end
--[[
/*
* VARS
*/
--]]
new('buffers' )
new('combos' )
new('completions' )
new('exit' )
new('help' )
new('input' )
new('timeouts' )
new('timer' )
new('windows' )
--[[
/*
* PUBLICIZE MODULE
*/
--]]
return vars
Loading…
Cancel
Save