feat: `Mode:exit` (#30)

* fix(Mode): adapt to changes in `timeoutlen`

* feat(libmodal): do `self:exit()` inside callback

* docs: `Mode:exit`

* style: .editorconfig

* docs(libmodal): fix broken example

* feat(Mode): `self:switch`

* docs: `Mode:switch`

* feat(libmodal): `mode.switch`

Wraps `Mode:switch` for convenience

* docs: `libmodal.mode.switch`

* docs(examples): `*.switch`
pull/32/head
Iron-E 2 months ago committed by GitHub
parent 3966014dbc
commit 1ecc4add3b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,63 @@
root = false
[*]
charset = utf-8
end_of_line = lf
indent_size = tab
indent_style = tab
insert_final_newline = true
tab_width = 3
trim_trailing_whitespace = true
[doc/*.txt]
max_line_length = 80
[*.{yaml,yml}]
indent_style = space
[*.lua]
align_array_table = true
align_call_args = false
align_continuous_assign_statement = false
align_continuous_inline_comment = true
align_continuous_rect_table_field = false
align_function_params = false
align_if_branch = false
auto_collapse_lines = true
break_all_list_when_line_exceed = true
call_arg_parentheses = remove_table_only
continuation_indent = 1
detect_end_of_line = false
ignore_space_after_colon = false
ignore_spaces_inside_function_call = false
line_space_after_comment = max(2)
line_space_after_do_statement = max(2)
line_space_after_expression_statement = max(2)
line_space_after_for_statement = max(2)
line_space_after_function_statement = fixed(2)
line_space_after_if_statement = max(2)
line_space_after_local_or_assign_statement = max(2)
line_space_after_repeat_statement = max(2)
line_space_after_while_statement = max(2)
max_line_length = 120
never_indent_before_if_condition = false
never_indent_comment_on_if_branch = false
quote_style = single
remove_call_expression_list_finish_comma = false
space_after_comma = true
space_after_comma_in_for_statement = true
space_around_concat_operator = true
space_around_math_operator = true
space_around_table_append_operator = false
space_around_table_field_list = true
space_before_attribute = true
space_before_closure_open_parenthesis = false
space_before_function_call_open_parenthesis = false
space_before_function_call_single_arg = false
space_before_function_open_parenthesis = false
space_before_inline_comment = 1
space_before_open_square_bracket = false
space_inside_function_call_parentheses = false
space_inside_function_param_list_parentheses = false
space_inside_square_brackets = false
trailing_table_separator = smart

@ -85,7 +85,7 @@ The following is a reference for high-level functions meant to be used by mode
creators. For those who wish to see a low-level specification of |libmodal|, creators. For those who wish to see a low-level specification of |libmodal|,
see |libmodal-lua|. see |libmodal-lua|.
Note: Examples for all topics covered here can be found in the "examples" NOTE: Examples for all topics covered here can be found in the "examples"
folder at the root of the repository. folder at the root of the repository.
See: |api|, |lua-api|, https://github.com/Iron-E/nvim-tabmode, See: |api|, |lua-api|, https://github.com/Iron-E/nvim-tabmode,
@ -127,7 +127,9 @@ FUNCTIONS *libmodal-usage-function
To take input on a line-by-line basis, see |libmodal-prompt|. To take input on a line-by-line basis, see |libmodal-prompt|.
Note: `libmodal.mode.enter()`/`libmodal#Enter()` may be called from inside NOTE: mode transitions trigger |ModeChanged| events.
NOTE: `libmodal.mode.enter()`/`libmodal#Enter()` may be called from inside
itself. See |libmodal-examples| for an example. itself. See |libmodal-examples| for an example.
Parameters: ~ Parameters: ~
@ -138,16 +140,14 @@ FUNCTIONS *libmodal-usage-function
{instruction} What to do when accepting user input. {instruction} What to do when accepting user input.
- If {instruction} is a `dict`/`table`, then it is treated as a - If {instruction} is a `dict`/`table`, then it is treated as a
map of user key-chord to Vim |command|s. Example: > map of user key-chord to Vim |command|s. Example: >lua
-- LUA
local modeInstruction = { local modeInstruction = {
zf = 'split', zf = 'split',
zfo = 'vsplit', zfo = 'vsplit',
-- You can also use lua functions -- You can also use lua functions
zfc = function() return 'tabnew' end zfc = function() vim.api.nvim_command 'tabnew' end
} }
< >vim
" VIMSCRIPT
let s:modeInstruction = { let s:modeInstruction = {
'zf': 'split', 'zf': 'split',
'zfo': 'vsplit', 'zfo': 'vsplit',
@ -155,7 +155,7 @@ FUNCTIONS *libmodal-usage-function
} }
< <
Note: If no `?` key is defined, one will be created automatically. NOTE: If no `?` key is defined, one will be created automatically.
- If {instruction} is a `function`, then it is called every time - If {instruction} is a `function`, then it is called every time
that |getchar()| completes. The user input is received through that |getchar()| completes. The user input is received through
@ -172,7 +172,7 @@ FUNCTIONS *libmodal-usage-function
       lua require('libmodal').mode.enter('FOO', 's:foo')        lua require('libmodal').mode.enter('FOO', 's:foo')
< <
Note: Some QoL features are available by default when NOTE: Some QoL features are available by default when
specifying a `dict`/`table` value for {instruction} that specifying a `dict`/`table` value for {instruction} that
would otherwise have to be programmed manually if a would otherwise have to be programmed manually if a
`function` is specified. `function` is specified.
@ -188,15 +188,76 @@ FUNCTIONS *libmodal-usage-function
- If |v:false|/`false`, then <Esc> is automatically mapped to - If |v:false|/`false`, then <Esc> is automatically mapped to
exiting. exiting.
- If |v:true|/`true`, then <Esc> is ignored unless specified by - If |v:true|/`true`, then <Esc> is ignored unless specified by
the user. In such cases, the user should set the the user. In such cases, when exiting is desired the user should
`g:`{name}`ModeExit` variable to `true` when exiting is either:
desired. See |libmodal-examples|. - set the `g:`{name}`ModeExit` variable to `true`, or
- use |libmodal.Mode:exit()|
See |libmodal-examples|.
See also: ~ See also: ~
|lua-eval| For type conversions between Vimscript to |Lua|. |lua-eval| For type conversions between Vimscript to |Lua|.
|libmodal-examples| For examples of this function. |libmodal-examples| For examples of this function.
*libmodal.mode:switch()*
`libmodal.mode`.switch(...)
Convenience wrapper for |Mode:switch()|.
Parameters: ~
See |Mode:switch()|.
Example: ~
>lua
libmodal.mode.enter('Foo', {
f = libmodal.mode.switch('Bar', {
b = function()
vim.notify('Inside Bar mode')
end,
}),
})
<
*libmodal.Mode:exit()*
`libmodal.Mode`:exit()
When the {instruction} parameter to |libmodal.mode.enter()| is a
|lua-table|, one can use |lua-function|s as mappings. When this is done, the
`self` parameter becomes available, and from this the `:exit()` function can
be called.
WARNING: this call will *not* interrupt |getchar()| (see |libmodal-mode|).
call `exit` only inside a `function` mapping as shown below.
Example: ~
>lua
libmodal.mode.enter('Foo', {
q = function(self)
self:exit()
end,
})
<
*libmodal.Mode:switch()*
`libmodal.Mode`:switch(...)
|libmodal.mode.enter()| a new mode, and when it is finished, |Mode:exit()|
the current mode.
Parameters: ~
See |libmodal.mode.enter()|.
Example: ~
>lua
libmodal.mode.enter('Foo', {
f = function(self)
self:switch('Bar', {
b = function()
vim.notify('Inside Bar mode')
end,
})
end,
})
<
*libmodal-layer* *libmodal.layer* *libmodal-layer* *libmodal.layer*
`libmodal.layer`.enter({keymap} [, {exit_char}]) *libmodal.layer.enter()* `libmodal.layer`.enter({keymap} [, {exit_char}]) *libmodal.layer.enter()*
@ -307,7 +368,7 @@ FUNCTIONS *libmodal-usage-function
{mode} and {lhs} are the same as in |vim.keymap.del()| except that a {mode} {mode} and {lhs} are the same as in |vim.keymap.del()| except that a {mode}
table is not supported. table is not supported.
Note: this function cannot be called until after |libmodal.Layer:enter()| NOTE: this function cannot be called until after |libmodal.Layer:enter()|
See also: ~ See also: ~
|libmodal-examples| For an example. |libmodal-examples| For an example.
@ -364,7 +425,7 @@ FUNCTIONS *libmodal-usage-function
       lua require('libmodal').prompt.enter('FOO', 's:foo')        lua require('libmodal').prompt.enter('FOO', 's:foo')
< <
Note: If you want to create commands with arguments, you will NOTE: If you want to create commands with arguments, you will
need to use a `function`. need to use a `function`.
{completions} An array-like `table` of commands that are offered by {completions} An array-like `table` of commands that are offered by
@ -375,10 +436,10 @@ FUNCTIONS *libmodal-usage-function
- If unspecified, and {instruction} is not a `table`, then no - If unspecified, and {instruction} is not a `table`, then no
completions will be provided. completions will be provided.
Note: If no `help` command is defined, one will be created NOTE: If no `help` command is defined, one will be created
automatically. automatically.
Note: The user may set the `g:`{name}`ModeExit` variable to NOTE: The user may set the `g:`{name}`ModeExit` variable to
`true` at any time to prematurely exit. `true` at any time to prematurely exit.
@ -416,7 +477,7 @@ Name Default Description
`LibmodalPrompt` `ModeMsg` Color for the mode text. `LibmodalPrompt` `ModeMsg` Color for the mode text.
`LibmodalStar` `StatusLine` Color for the prompt text. `LibmodalStar` `StatusLine` Color for the prompt text.
Note: `LibmodalStar`'s name — while not indicative of its use — is used for NOTE: `LibmodalStar`'s name — while not indicative of its use — is used for
the sake of backwards compatability. the sake of backwards compatability.
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------

@ -1,10 +1,25 @@
local libmodal = require 'libmodal' local libmodal = require 'libmodal'
local k = vim.keycode or function(s)
return vim.api.nvim_replace_termcodes(s, true, true, true)
end
local barModeKeymaps = {
p = function() vim.notify('Hello!') end,
}
-- register key commands and what they do -- register key commands and what they do
local fooModeKeymaps = local fooModeKeymaps =
{ {
[''] = 'echom "You cant exit using escape."', [k '<Esc>'] = 'echom "You cant exit using escape."',
q = 'let g:fooModeExit = 1' q = 'let g:fooModeExit = 1', -- exits all instances of this mode
x = function(self)
self:exit() -- exits this instance of the mode
end,
y = function(self)
self:switch('Bar', barModeKeymaps) -- enters Bar and then exits Foo when it is done
end,
z = libmodal.mode.switch('Bar', barModeKeymaps), -- the same as above, but more convenience
} }
-- tell the mode not to exit automatically -- tell the mode not to exit automatically

@ -9,10 +9,14 @@ end
-- register keymaps for splitting windows and then closing windows -- register keymaps for splitting windows and then closing windows
local fooModeKeymaps = local fooModeKeymaps =
{ {
h = 'norm h',
j = 'norm j',
k = 'norm k',
l = 'norm l',
zf = 'split', zf = 'split',
zfo = 'vsplit',
zfc = 'q', zfc = 'q',
zff = split_twice zff = split_twice,
zfo = 'vsplit',
} }
-- enter the mode using the keymaps -- enter the mode using the keymaps

@ -3,12 +3,13 @@ local ParseTable = require 'libmodal.collections.ParseTable'
local utils = require 'libmodal.utils' --- @type libmodal.utils local utils = require 'libmodal.utils' --- @type libmodal.utils
--- @class libmodal.Mode --- @class libmodal.Mode
--- @field private exit libmodal.utils.Vars
--- @field private flush_input_timer unknown --- @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 help? libmodal.utils.Help
--- @field private input libmodal.utils.Vars
--- @field private input_bytes? number[] --- @field private input_bytes? number[]
--- @field private instruction fun()|{[string]: fun()|string} --- @field private instruction fun()|{[string]: fun()|string}
--- @field private local_exit boolean
--- @field private mappings libmodal.collections.ParseTable --- @field private mappings libmodal.collections.ParseTable
--- @field private name string --- @field private name string
--- @field private ns number the namespace where cursor highlights are drawn on --- @field private ns number the namespace where cursor highlights are drawn on
@ -22,17 +23,17 @@ local HELP_CHAR = '?'
local TIMEOUT = local TIMEOUT =
{ {
CHAR = ' ', CHAR = ' ',
LEN = vim.go.timeoutlen,
SEND = function(self) vim.api.nvim_feedkeys(self.CHAR, 'nt', false) end SEND = function(self) vim.api.nvim_feedkeys(self.CHAR, 'nt', false) end
} }
TIMEOUT.CHAR_NUMBER = TIMEOUT.CHAR:byte() TIMEOUT.CHAR_NUMBER = TIMEOUT.CHAR:byte()
--- execute the `instruction`. --- execute the `instruction`.
--- @param instruction fun()|string a Lua function or Vimscript command. --- @private
--- @param instruction fun(libmodal.Mode)|string a Lua function or Vimscript command.
--- @return nil --- @return nil
function Mode:execute_instruction(instruction) function Mode:execute_instruction(instruction)
if type(instruction) == 'function' then if type(instruction) == 'function' then
instruction() instruction(self)
else else
vim.api.nvim_command(instruction) vim.api.nvim_command(instruction)
end end
@ -42,13 +43,14 @@ end
--- check the user's input against the `self.instruction` mappings to see if there is anything to execute. --- check the user's input against the `self.instruction` mappings to see if there is anything to execute.
--- if there is nothing to execute, the user's input is rendered on the screen (as does Vim by default). --- if there is nothing to execute, the user's input is rendered on the screen (as does Vim by default).
--- @private
--- @return nil --- @return nil
function Mode:check_input_for_mapping() function Mode:check_input_for_mapping()
-- stop any running timers -- stop any running timers
self.flush_input_timer:stop() self.flush_input_timer:stop()
-- append the latest input to the locally stored input history. -- append the latest input to the locally stored input history.
self.input_bytes[#self.input_bytes + 1] = self.input:get() self.input_bytes[#self.input_bytes + 1] = self.global_input:get()
-- get the command based on the users input. -- get the command based on the users input.
local cmd = self.mappings:get(self.input_bytes) local cmd = self.mappings:get(self.input_bytes)
@ -64,8 +66,9 @@ function Mode:check_input_for_mapping()
self.input_bytes = {} 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_enabled) 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 self.flush_input_timer:start( -- start the timer
TIMEOUT.LEN, 0, vim.schedule_wrap(function() timeout, 0, vim.schedule_wrap(function()
-- send input to interrupt a blocking `getchar` -- send input to interrupt a blocking `getchar`
TIMEOUT:SEND() TIMEOUT:SEND()
-- if there is a command, execute it. -- if there is a command, execute it.
@ -87,6 +90,7 @@ function Mode:check_input_for_mapping()
end end
--- clears the virtual cursor from the screen --- clears the virtual cursor from the screen
--- @private
function Mode:clear_virt_cursor() function Mode:clear_virt_cursor()
vim.api.nvim_buf_clear_namespace(0, self.ns, 0, -1); vim.api.nvim_buf_clear_namespace(0, self.ns, 0, -1);
end end
@ -100,6 +104,8 @@ function Mode:enter()
self.popups:push(utils.Popup.new()) self.popups:push(utils.Popup.new())
end end
self.local_exit = false
--- HACK: https://github.com/neovim/neovim/issues/20793 --- HACK: https://github.com/neovim/neovim/issues/20793
vim.api.nvim_command 'highlight Cursor blend=100' vim.api.nvim_command 'highlight Cursor blend=100'
vim.schedule(function() vim.opt.guicursor:append { 'a:Cursor/lCursor' } end) vim.schedule(function() vim.opt.guicursor:append { 'a:Cursor/lCursor' } end)
@ -131,11 +137,25 @@ function Mode:enter()
vim.api.nvim_exec_autocmds('ModeChanged', {pattern = self.name .. ':' .. previous_mode}) vim.api.nvim_exec_autocmds('ModeChanged', {pattern = self.name .. ':' .. previous_mode})
end 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())
end
--- get input from the user. --- get input from the user.
--- @private
--- @return boolean more_input --- @return boolean more_input
function Mode:get_user_input() function Mode:get_user_input()
-- if the mode is not handling exit events automatically and the global exit var is true. if self:exit_flagged() then
if self.supress_exit and globals.is_true(self.exit:get()) then
return false return false
end end
@ -151,7 +171,7 @@ function Mode:get_user_input()
end end
-- set the global input variable to the new input. -- set the global input variable to the new input.
self.input:set(user_input) self.global_input:set(user_input)
if not self.supress_exit and user_input == globals.ESC_NR then -- the user wants to exit. if not self.supress_exit and user_input == globals.ESC_NR then -- the user wants to exit.
return false -- as in, "I don't want to continue." return false -- as in, "I don't want to continue."
@ -173,7 +193,34 @@ function Mode:get_user_input()
return true return true
end end
--- clears and then renders the virtual cursor
--- @private
function Mode:redraw_virtual_cursor()
self:clear_virt_cursor()
self:render_virt_cursor()
end
--- render the virtual cursor using extmarks
--- @private
function Mode:render_virt_cursor()
local line_nr, col_nr = unpack(vim.api.nvim_win_get_cursor(0))
line_nr = line_nr - 1 -- win_get_cursor returns +1 for our purpose
vim.highlight.range(0, self.ns, 'Cursor', { line_nr, col_nr }, { line_nr, col_nr + 1 }, {})
end
--- `enter` a `Mode` using the arguments given, and then flag the current mode to exit.
--- @param ... unknown arguments to `Mode.new`
--- @return nil
--- @see libmodal.Mode.enter which `...` shares the layout of
--- @see libmodal.Mode.exit
function Mode:switch(...)
local mode = Mode.new(...)
mode:enter()
self:exit()
end
--- uninitialize variables from after exiting the mode. --- uninitialize variables from after exiting the mode.
--- @private
--- @return nil --- @return nil
function Mode:tear_down() function Mode:tear_down()
if type(self.instruction) == 'table' then if type(self.instruction) == 'table' then
@ -197,22 +244,11 @@ function Mode:tear_down()
utils.api.redraw() utils.api.redraw()
end end
--- clears and then renders the virtual cursor
function Mode:redraw_virtual_cursor()
self:clear_virt_cursor()
self:render_virt_cursor()
end
--- render the virtual cursor using extmarks
function Mode:render_virt_cursor()
local line_nr, col_nr = unpack(vim.api.nvim_win_get_cursor(0))
line_nr = line_nr - 1 -- win_get_cursor returns +1 for our purpose
vim.highlight.range(0, self.ns, 'Cursor', { line_nr, col_nr }, { line_nr, col_nr + 1 }, {})
end
--- create a new mode. --- create a new mode.
--- @private
--- @param name string the name of the mode. --- @param name string the name of the mode.
--- @param instruction fun()|string|table a Lua function, keymap dictionary, Vimscript command. --- @param instruction fun(libmodal.Mode)|string|table a Lua function, keymap dictionary, Vimscript command.
--- @param supress_exit? boolean
--- @return libmodal.Mode --- @return libmodal.Mode
function Mode.new(name, instruction, supress_exit) function Mode.new(name, instruction, supress_exit)
name = vim.trim(name) name = vim.trim(name)
@ -220,9 +256,10 @@ function Mode.new(name, instruction, supress_exit)
-- inherit the metatable. -- inherit the metatable.
local self = setmetatable( local self = setmetatable(
{ {
exit = utils.Vars.new('exit', name), global_exit = utils.Vars.new('exit', name),
input = utils.Vars.new('input', name), global_input = utils.Vars.new('input', name),
instruction = instruction, instruction = instruction,
local_exit = false,
name = name, name = name,
ns = vim.api.nvim_create_namespace('libmodal' .. name), ns = vim.api.nvim_create_namespace('libmodal' .. name),
}, },

@ -1,71 +1,77 @@
--- @class libmodal --- @class libmodal
local libmodal = setmetatable( local libmodal = setmetatable({}, {
{ __index = function(tbl, key)
layer = if key ~= 'Layer' then
{ return rawget(tbl, key)
--- enter a new layer. else
--- @param keymap table the keymaps (e.g. `{n = {gg = {rhs = 'G', silent = true}}}`) if vim.deprecate then
--- @param exit_char? string a character which can be used to exit the layer from normal mode. vim.deprecate('`libmodal.Layer`', '`libmodal.layer`', '4.0.0', 'nvim-libmodal')
--- @return fun()|nil exit a function to exit the layer, or `nil` if `exit_char` is passed else
enter = function(keymap, exit_char) vim.notify_once(
local layer = require('libmodal.Layer').new(keymap) '`libmodal.Layer` is deprecated in favor of `libmodal.layer`. It will work FOR NOW, but uncapitalize that `L` please :)',
layer:enter() vim.log.levels.WARN,
{title = 'nvim-libmodal'}
)
end
if exit_char then return rawget(tbl, 'layer')
layer:map('n', exit_char, function() layer:exit() end, {}) end
else end,
return function() layer:exit() end })
end
end,
--- create a new layer. libmodal.layer = {}
--- @param keymap table the keymaps (e.g. `{n = {gg = {rhs = 'G', silent = true}}}`)
--- @return libmodal.Layer
new = function(keymap)
return require('libmodal.Layer').new(keymap)
end,
},
mode = --- enter a new layer.
{ --- @param keymap table the keymaps (e.g. `{n = {gg = {rhs = 'G', silent = true}}}`)
--- enter a mode. --- @param exit_char? string a character which can be used to exit the layer from normal mode.
--- @param name string the name of the mode. --- @return fun()|nil exit a function to exit the layer, or `nil` if `exit_char` is passed
--- @param instruction fun()|string|table a Lua function, keymap dictionary, Vimscript command. function libmodal.layer.enter(keymap, exit_char)
enter = function(name, instruction, supress_exit) local layer = require('libmodal.Layer').new(keymap)
require('libmodal.Mode').new(name, instruction, supress_exit):enter() layer:enter()
end
},
prompt = if exit_char then
{ layer:map('n', exit_char, function() layer:exit() end, {})
--- enter a prompt. else
--- @param name string the name of the prompt return function() layer:exit() end
--- @param instruction fun()|{[string]: fun()|string} what to do with user input end
--- @param user_completions? string[] a list of possible inputs, provided by the user end
enter = function(name, instruction, user_completions)
require('libmodal.Prompt').new(name, instruction, user_completions):enter()
end
}
},
{
__index = function(tbl, key)
if key ~= 'Layer' then
return rawget(tbl, key)
else
if vim.deprecate then
vim.deprecate('`libmodal.Layer`', '`libmodal.layer`', '4.0.0', 'nvim-libmodal')
else
vim.notify_once(
'`libmodal.Layer` is deprecated in favor of `libmodal.layer`. It will work FOR NOW, but uncapitalize that `L` please :)',
vim.log.levels.WARN,
{title = 'nvim-libmodal'}
)
end
return rawget(tbl, 'layer') --- create a new layer.
end --- @param keymap table the keymaps (e.g. `{n = {gg = {rhs = 'G', silent = true}}}`)
end, --- @return libmodal.Layer
} function libmodal.layer.new(keymap)
) return require('libmodal.Layer').new(keymap)
end
libmodal.mode = {}
--- enter a mode.
--- @param name string the name of the mode.
--- @param instruction fun()|string|table a Lua function, keymap dictionary, Vimscript command.
function libmodal.mode.enter(name, instruction, supress_exit)
local mode = require('libmodal.Mode').new(name, instruction, supress_exit)
mode:enter()
end
--- `enter` a mode using the arguments given, and do not return to the current mode.
--- @param ... unknown arguments to `libmodal.mode.enter`
--- @return fun(self: libmodal.Mode) switcher enters the mode
--- @see libmodal.mode.enter which this function takes the same arguments as
function libmodal.mode.switch(...)
local args = { ... }
return function(self)
self:switch(unpack(args))
end
end
libmodal.prompt = {}
--- enter a prompt.
--- @param name string the name of the prompt
--- @param instruction fun()|{[string]: fun()|string} what to do with user input
--- @param user_completions? string[] a list of possible inputs, provided by the user
function libmodal.prompt.enter(name, instruction, user_completions)
require('libmodal.Prompt').new(name, instruction, user_completions):enter()
end
return libmodal return libmodal

Loading…
Cancel
Save