Skip to content

Commit

Permalink
feat: Mode:exit (#30)
Browse files Browse the repository at this point in the history
* 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`
  • Loading branch information
Iron-E committed Mar 11, 2024
1 parent 3966014 commit 1ecc4ad
Show file tree
Hide file tree
Showing 6 changed files with 296 additions and 110 deletions.
63 changes: 63 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -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
95 changes: 78 additions & 17 deletions doc/libmodal.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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|,
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.

See: |api|, |lua-api|, https://github.com/Iron-E/nvim-tabmode,
Expand Down Expand Up @@ -127,7 +127,9 @@ FUNCTIONS *libmodal-usage-function

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.

Parameters: ~
Expand All @@ -138,24 +140,22 @@ FUNCTIONS *libmodal-usage-function
{instruction} What to do when accepting user input.

- If {instruction} is a `dict`/`table`, then it is treated as a
map of user key-chord to Vim |command|s. Example: >
-- LUA
map of user key-chord to Vim |command|s. Example: >lua
local modeInstruction = {
zf = 'split',
zfo = 'vsplit',
-- You can also use lua functions
zfc = function() return 'tabnew' end
zfc = function() vim.api.nvim_command 'tabnew' end
}
" VIMSCRIPT
< >vim
let s:modeInstruction = {
'zf': 'split',
'zfo': 'vsplit',
'zfc': 'tabnew'
}
<

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
that |getchar()| completes. The user input is received through
Expand All @@ -172,7 +172,7 @@ FUNCTIONS *libmodal-usage-function
       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
would otherwise have to be programmed manually if a
`function` is specified.
Expand All @@ -188,15 +188,76 @@ FUNCTIONS *libmodal-usage-function
- If |v:false|/`false`, then <Esc> is automatically mapped to
exiting.
- If |v:true|/`true`, then <Esc> is ignored unless specified by
the user. In such cases, the user should set the
`g:`{name}`ModeExit` variable to `true` when exiting is
desired. See |libmodal-examples|.
the user. In such cases, when exiting is desired the user should
either:
- set the `g:`{name}`ModeExit` variable to `true`, or
- use |libmodal.Mode:exit()|
See |libmodal-examples|.

See also: ~
|lua-eval| For type conversions between Vimscript to |Lua|.
|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`.enter({keymap} [, {exit_char}]) *libmodal.layer.enter()*

Expand Down Expand Up @@ -307,7 +368,7 @@ FUNCTIONS *libmodal-usage-function
{mode} and {lhs} are the same as in |vim.keymap.del()| except that a {mode}
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: ~
|libmodal-examples| For an example.
Expand Down Expand Up @@ -364,7 +425,7 @@ FUNCTIONS *libmodal-usage-function
       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`.

{completions} An array-like `table` of commands that are offered by
Expand All @@ -375,10 +436,10 @@ FUNCTIONS *libmodal-usage-function
- If unspecified, and {instruction} is not a `table`, then no
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.

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.


Expand Down Expand Up @@ -416,7 +477,7 @@ Name Default Description
`LibmodalPrompt` `ModeMsg` Color for the mode 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.

--------------------------------------------------------------------------------
Expand Down
19 changes: 17 additions & 2 deletions examples/lua/keymaps-supress-exit.lua
Original file line number Diff line number Diff line change
@@ -1,10 +1,25 @@
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
local fooModeKeymaps =
{
[''] = 'echom "You cant exit using escape."',
q = 'let g:fooModeExit = 1'
[k '<Esc>'] = 'echom "You cant exit using escape."',
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
Expand Down
8 changes: 6 additions & 2 deletions examples/lua/keymaps.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,14 @@ end
-- register keymaps for splitting windows and then closing windows
local fooModeKeymaps =
{
h = 'norm h',
j = 'norm j',
k = 'norm k',
l = 'norm l',
zf = 'split',
zfo = 'vsplit',
zfc = 'q',
zff = split_twice
zff = split_twice,
zfo = 'vsplit',
}

-- enter the mode using the keymaps
Expand Down
Loading

0 comments on commit 1ecc4ad

Please sign in to comment.