You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nvim-libmodal/doc/libmodal.txt

888 lines
29 KiB
Plaintext

*libmodal.txt* Create modes for Neovim
*libmodal*
*nvim-libmodal*
4 years ago
=============================================================================
0. Table of Contents *libmodal-toc*
1. About ................ |libmodal-about|
2. Usage ................ |libmodal-usage|
4 years ago
3. Examples ............. |libmodal-examples|
4. Configuration ........ |libmodal-configuration|
5. License .............. |libmodal-license|
6. Bugs ................. |libmodal-bugs|
7. Contributing ......... |libmodal-contributing|
8. Changelog ............ |libmodal-changelog|
9. Credits .............. |libmodal-credits|
4 years ago
==============================================================================
1. About *libmodal-about*
|nvim-libmodal|:
- Author, Iron-E @ https://github.com/Iron-E & https://gitlab.com/Iron_E
- GitHub @ https://github.com/Iron-E/nvim-libmodal
Complete rewrite of |vim-libmodal|:
- Author, Iron-E @ https://github.com/Iron-E & https://gitlab.com/Iron_E
- GitHub @ https://github.com/Iron-E/vim-libmodal
|libmodal| is a Neovim library/|plugin| aimed at simplifying the creation
of new "modes" (e.g. |Insert|, |Normal|). The entrance of modes is
creator-defined, and their exit defaults to <Esc>. The use and name of
modes is also creator-defined, and is outlined in |libmodal-usage|.
See: |vim-modes|
------------------------------------------------------------------------------
USE CASE *libmodal-use-case-example*
4 years ago
As an |init.vim| configuration grows, it becomes harder to create keybindings
that alphabetically represent the action that they perform. To get around
this, |libmodal| allows users to create a new "layer" of keybindings contained
within a pseudo-|vim-mode|. This layer of keybindings can be bound to a
command which executes `libmodal.mode.enter()` or `libmodal.prompt.enter()`,
and any settings outside of these commands are preserved.
For example, say that a user of Neovim regularly uses |:diffsplit| to merge
changes from `git`. They might define a "DIFF" mode that takes input and
directly translates it into |:diff|* operations. This would allow them to
For instance, perhaps this mode is defined so that `n` goes to the next diff
(like `]c`), and `N` goes to the previous diff (like `[c`). This would make
going from diff to diff more rememberable, as `n` is commonly used because of
`/` searches.
Suppose that the mode also numbers each |:buffer|, so that you don't have
to remember which |:diffsplit| to |:diffget| from. The numbers would disappear
when you leave the mode.
Finally, there could be a help key, `?`, which would show exactly which keys
have been mapped and what they do.
You can see such a mode here:
* https://gist.github.com/Iron-E/f36116e8862ea03fd195e4e0a48cb05d
Outside of the |libmodal-mode|, `n` still searches for the |last-pattern|, and
the buffers are not visibly numbered. Any setup that a |libmodal-mode| does to
inderpret keybindings is undone before the mode ends (while any changes to
buffers persevere).
4 years ago
See: |libmodal-usage|
==============================================================================
2. Usage *libmodal-usage*
The |libmodal| interface is designed completely in |Lua|. It is compatable
with Vimscript, and so one may either:
1. Define a |Lua| interface for your mode (see |libmodal-examples|).
* Use |lua-require| as a |user-command|.
* See |lua-require-example| for information about how to do this.
* See `Iron-E/nvim-tabmode` for a complete example.
* See `Iron-E/mode-fugidiff.lua` on GitHub Gists for another example.
2. |call| `libmodal#Enter()` or `libmodal#Prompt()` from Vimscript.
4 years ago
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"
folder at the root of the repository.
See: |api|, |lua-api|, https://github.com/Iron-E/nvim-tabmode,
https://gist.github.com/Iron-E/f36116e8862ea03fd195e4e0a48cb05d
------------------------------------------------------------------------------
FUNCTIONS *libmodal-usage-functions*
*libmodal-mode* *libmodal#Enter()* *libmodal.mode.enter()*
`libmodal.mode`.enter({name}, {instruction} [, {supressExit}])
`libmodal`#Enter({name}, {instruction} [, {supressExit}])
4 years ago
Enter a new |vim-mode| using {instruction} to determine what actions will
be taken upon specific user inputs.
User input is taken one character at a time using |getchar()|. It is
passed through a |g:var| determined by the {name} of the mode. For
example, if {name} is "FOO" then the |g:var| is `g:fooModeInput`.
Additionally, this input is reported as a |char2nr| number, and as such
should be decoded with `string.char()` (|nr2char| in |Lua|) if working
with raw characters is desired.
To take input on a line-by-line basis, see |libmodal-prompt|.
Note: `libmodal.mode.enter()`/`libmodal#Enter()` may be called from inside
itself. See |libmodal-examples-submodes| for an example.
4 years ago
Parameters: ~
{name} The name of the mode (e.g. |INSERT|).
- Case-sensitive. Caps are recommended.
{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
4 years ago
local modeInstruction = {
['zf'] = 'split',
['zfo'] = 'vsplit',
['zfc'] = 'tabnew'
}
" VIMSCRIPT
let s:modeInstruction = {
'zf': 'split',
'zfo': 'vsplit',
'zfc': 'tabnew'
}
<
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
`g:{name}ModeInput` (see above).
*Error you cannot pass a funcref to Lua from Vimscript!
       - If you want to use a |funcref()| for {instruction}, it
       must be the name of the function as a `string`.
       - This only works on Neovim 0.5+. Example: >
       " VIMSCRIPT
       function! s:foo() abort
       echo 'It works'
       call getchar()
       endfunction
       lua require('libmodal').mode.enter('FOO', 's:foo')
<
4 years ago
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.
4 years ago
- A user's typed characters will show in the
lower right corner when {instruction} is a table.
- If `g:libmodalTimeouts` is enabled, then user input will be
subjected to the |timeoutlen|.
4 years ago
{supressExit} Whether or not to automatically exit the mode upon an
<Esc> press.
- If |v:false|/`false`, then <Esc> is automatically mapped to
4 years ago
exiting.
- If |v:true|/`true`, then <Esc> is ignored unless specified by
4 years ago
the user. In such cases, the user should set the
`g:`{name}`ModeExit` variable to `true` when exiting is
desired. See |libmodal-examples-supress-exit|.
See also: ~
|lua-eval| For type conversions between Vimscript to
|Lua|.
4 years ago
|libmodal-examples-mode| For examples of this function.
4 years ago
`libmodal.layer`.enter({keymap}) *libmodal-layer* *libmodal.layer.enter()*
While a |libmodal-mode| ignores behavior that has not been explicitly
defined, a |libmodal-layer| allows unrecognized |input| to be passed back
into Neovim for analysis.
So, if you have only defined a few keybindings, all of the remaining ones
from a user's configuration would still work— only new keymaps will be
overwritten.
Parameters: ~
4 years ago
{keymap} The keymap for the layer. General template is this: >
{
[<mode>] = {
[<lhs>] = {
['rhs'] = <rhs>,
<opts>
},
},
}
< Where {mode}, {lhs}, {rhs}, and {opts} are the same as in
|nvim_set_keymap()|
Return: ~
* The `function` used to undo changes made by the layer.
See also: ~
|libmodal-examples-layers| For an example.
4 years ago
|nvim_set_keymap()| For more information about {keymap}.
*libmodal-prompt* *libmodal#Prompt()* *libmodal.prompt.enter()*
`libmodal.prompt`.enter({name}, {instruction} [, {completions}])
`libmodal`#Prompt({name}, {instruction} [, {completions}])
4 years ago
Besides accepting user input like keys in |Normal-mode|, |libmodal| is
also capable of prompting the user for |input| like |Cmdline-mode|. To
define a |Cmdline-mode|-like prompt, use this function rather than
`libmodal.mode.enter()`/`libmodal#Enter()`.
4 years ago
User input is taken using |input()|. It is passed through a |g:var|
determined by the {name} of the mode. For example, if {name} is "FOO"
then the |g:var| is `g:fooModeInput`.
Parameters: ~
{name} The name of the mode (e.g. |INSERT|).
- Case-sensitive. Caps are recommended.
{instruction} What to do when accepting user input.
- If {instruction} is a `dict`/`table`, then it is treated as a
map of user inputs to Vim |command|s. Example: >
-- LUA
local modeInstruction = {
['new'] = 'tabnew',
['close'] = 'tabclose',
['last'] = 'tablast'
}
" VIMSCRIPT
let s:modeInstruction = {
'new': 'tabnew',
'close': 'tabclose',
'last': 'tablast'
}
<
4 years ago
- If {instruction} is a `function`, then it is called
every time that |input()| completes. The user input
is received through `g:{name}ModeInput` (see above).
*Error you cannot pass a funcref to Lua from Vimscript!
       - If you want to use a |funcref()| for {instruction}, it
       must be the name of the function as a `string`.
       - This only works on Neovim 0.5+. Example: >
       " VIMSCRIPT
       function! s:foo() abort
       echo 'It works'
       call getchar()
       endfunction
       lua require('libmodal').prompt.enter('FOO', 's:foo')
<
4 years ago
Note: If you want to create commands with arguments, you will
need to use a `function`.
4 years ago
{completions} An array-like `table` of commands that are offered by
the prompt.
- Automatically generated when {instruction} is a `table`.
- Used to provide auto-completion when the user is typing.
- 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
automatically.
See also: ~
|lua-eval| For type conversions between Vimscript to |Lua|.
|libmodal-examples-prompt| For examples of this function.
==============================================================================
3. Examples *libmodal-examples*
Below are examples written in |Lua| to help show how specific features of
|libmodal| may be implemented. In each example, the name of the mode is
defined as "FOO". Additionally, each category of example has one example for
both `function` and `table` {instruction}s.
The source code can be either copied from here or downloaded from the
repository's `examples/lua` folder. Assuming |libmodal| is installed, they can
all be tested using the |luafile| |command|.
See: |libmodal-usage|, |libmodal-use-case|, |lua-require-example|.
------------------------------------------------------------------------------
MODES *libmodal-examples-modes*
4 years ago
Using a callback `function`: >
local api = vim.api
local libmodal = require('libmodal')
local fooModeInputHistory = {}
local function clearHistory(indexToCheck)
if #fooModeInputHistory >= indexToCheck then
fooModeInputHistory = {}
end
end
function fooMode()
fooModeInputHistory[#fooModeInputHistory + 1] = string.char(
api.nvim_get_var('fooModeInput')
)
local index = 1
if fooModeInputHistory[1] == 'z' then
if fooModeInputHistory[2] == 'f' then
if fooModeInputHistory[3] == 'o' then
api.nvim_command("echom 'It works!'")
else index = 3 end
else index = 2 end
end
clearHistory(index)
end
libmodal.mode.enter('FOO', fooMode)
<
using a |key-mapping| `dict`: >
let s:barModeCombos = {
\ 'zf': 'split',
\ 'zfo': 'vsplit',
\ 'zfc': 'tabnew'
\}
call libmodal#Enter('BAR', s:barModeCombos)
<
4 years ago
Using a |key-mapping| `table`: >
local libmodal = require('libmodal')
local fooModeCombos = {
['zf'] = 'split',
['zfo'] = 'vsplit',
['zfc'] = 'tabnew'
}
4 years ago
libmodal.mode.enter('FOO', fooModeCombos)
<
Exit Supression ~
4 years ago
*libmodal-examples-supress-exit*
4 years ago
Using a callback `function`: >
local libmodal = require('libmodal')
4 years ago
function fooMode()
local userInput = string.char(
vim.api.nvim_get_var('fooModeInput')
)
4 years ago
if userInput == '' then
vim.api.nvim_command("echom 'You cant leave using <Esc>.'")
elseif userInput == 'q' then
vim.api.nvim_set_var('fooModeExit', true)
end
end
4 years ago
vim.api.nvim_set_var('fooModeExit', 0)
libmodal.mode.enter('FOO', fooMode, true)
<
Using a |key-mapping| `dict`: >
let s:barModeCombos = {
\ '': 'echom "You cant exit using escape."',
\ 'q': 'let g:barModeExit = 1'
\}
let g:barModeExit = 0
call libmodal#Enter('BAR', s:barModeCombos, 1)
<
4 years ago
Using a |key-mapping| `table`: >
local libmodal = require('libmodal')
local fooModeCombos = {
[''] = 'echom "You cant exit using escape."',
['q'] = 'let g:fooModeExit = 1'
}
vim.api.nvim_set_var('fooModeExit', 0)
libmodal.mode.enter('FOO', fooModeCombos, true)
<
Submodes ~
4 years ago
*libmodal-examples-submodes*
4 years ago
Using a callback `function`: >
local libmodal = require('libmodal')
local fooModeRecurse = 0
4 years ago
function fooMode()
local userInput = string.char(vim.api.nvim_get_var(
'foo' .. tostring(fooModeRecurse) .. 'ModeInput'
))
if userInput == 'z' then
fooModeRecurse = fooModeRecurse + 1
enter()
fooModeRecurse = fooModeRecurse - 1
end
end
function enter()
libmodal.mode.enter('FOO' .. fooModeRecurse, fooMode)
end
enter()
<
Using a |key-mapping| `table`: >
let s:barModeRecurse = 0
let s:barModeCombos = {
\ 'z': 'BarModeEnter',
\}
function! s:BarMode()
let s:barModeRecurse += 1
call libmodal#Enter('BAR' . s:barModeRecurse, s:barModeCombos)
let s:barModeRecurse -= 1
endfunction
command! BarModeEnter call s:BarMode()
execute 'BarModeEnter'
<
4 years ago
Using a |key-mapping| `table`: >
local libmodal = require('libmodal')
local fooModeRecurse = 0
local fooModeCombos = {
['z'] = 'lua fooMode()'
}
4 years ago
function fooMode()
fooModeRecurse = fooModeRecurse + 1
libmodal.mode.enter('FOO' .. fooModeRecurse, fooModeCombos)
fooModeRecurse = fooModeRecurse - 1
end
fooMode()
<
------------------------------------------------------------------------------
LAYERS *libmodal-examples-layers*
>
local libmodal = require('libmodal')
4 years ago
-- save the exit function
local exitFunc = libmodal.layer.enter({
['n'] = { -- normal mode
['gg'] = { -- remap `gg`
['rhs'] = 'G', -- map it to `G`
['noremap'] = true -- don't remap
},
4 years ago
['G'] = { -- remap `G`
['rhs'] = 'gg', -- map it to `gg`
['noremap'] = true -- don't remap
}
}
4 years ago
})
-- exit the mode in five seconds
vim.loop.new_timer():start(5000, 0,
vim.schedule_wrap(exitFunc)
)
<
------------------------------------------------------------------------------
PROMPTS *libmodal-examples-prompts*
4 years ago
Using a callback `function`: >
local libmodal = require('libmodal')
local api = vim.api
local commandList = {'new', 'close', 'last'}
function fooMode()
local userInput = vim.api.nvim_get_var('fooModeInput')
if userInput == 'new' then
api.nvim_command('tabnew')
elseif userInput == 'close' then
api.nvim_command('tabclose')
elseif userInput == 'last' then
api.nvim_command('tablast')
end
end
libmodal.prompt.enter('FOO', fooMode, commandList)
<
Using a |command| `dict`: >
let s:commands = {
\ 'new': 'tabnew',
\ 'close': 'tabclose',
\ 'last': 'tablast'
\}
call libmodal#Prompt('TAB', s:commands)
<
4 years ago
Using a |command| `table`: >
local libmodal = require('libmodal')
local commands = {
['new'] = 'tabnew',
['close'] = 'tabclose',
['last'] = 'tablast'
}
libmodal.prompt.enter('BAR', commands)
<
==============================================================================
4. Configuration *libmodal-configuration*
The following specifies what settings may be used to configure
|libmodal-mode|s and |libmodal-prompt|s.
------------------------------------------------------------------------------
HIGHLIGHT GROUPS *libmodal-highlight-groups*
4 years ago
The following |highlight-groups| can be |config|ured to change a mode's |color|s:
Name Default Description
---------------- ------------ --------------------------
`LibmodalPrompt` `ModeMsg` Color for the mode text.
`LibmodalStar` `StatusLine` Color for the prompt text.
4 years ago
Note: `LibmodalStar`'s name — while not indicative of its use — is used for
the sake of backwards compatability.
- While |nvim-libmodal| might not be 100% backwards compatable with
|vim-libmodal| due to limitations of Neovim 0.4, an update will ship
when Neovim 0.5 launches that will introduce interoperaability between
the two.
------------------------------------------------------------------------------
TIMEOUTS *libmodal-timeouts* *g:libmodalTimeouts*
4 years ago
When `libmodal.mode.enter()`'s {instruction} argument is a `table`, mode
creators may also enable the use of Vim's built-in 'timeout' feature.
To enable 'timeout's, one may set the following |variables|:
Lua: ~
>
" Set libmodal modes to turn timeouts on.
vim.api.nvim_set_var('libmodalTimeouts', true)
" Enable timeouts for specific mode.
vim.api.nvim_set_var('{name}ModeTimeouts', true)
<
Vimscript: ~
>
" Set libmodal modes to turn timeouts on.
let g:libmodalTimeouts = 1
" Enable timeouts for specific mode.
let g:{name}ModeTimeouts = 1
<
Similarly, to disable them, one may set them to `0`.
When `g:libmodalTimeouts` or `g:{name}ModeTimeouts` is set to `1`, |libmodal|
4 years ago
will automatically execute commands that have mappings that might also be
longer mappings. For example:
If a mode specifies `zf` and `zfo` as mappings,
- Turning 'timeout's on will cause `zf` to be executed if the user waits
for 'timeoutlen' without typing another character.
- If 'timeout' were to be off in this case, then the user would either
have to hit <CR> to execute `zf` or hit `o` to execute `zfo`.
NOTE: `g:libmodalTimeouts` defaults to the 'timeout' value.
4 years ago
NOTE: The `g:limbodalTimeouts` variable should NOT be defined by plugins.
- Allow users to decide whether or not they want timeouts to be
enabled globally themselves.
NOTE: Mode-specific timeout variables will override `g:libmodalTimeouts`.
When enabled, |libmodal-timeouts| will reference the mode user's 'timeoutlen'
as specified in their |config|. This way, modes will feel consistent to users
by default.
4 years ago
However, mode creators may change 'timeoutlen' upon entrance of a mode, and
then reset it upon exit. Example:
4 years ago
Vimscript: ~
>
4 years ago
function! s:FooMode() abort
" Get the user's preferred timeout length.
let l:timeoutlen = &timeoutlen
" Set it to something else, like 1500ms
let &timeoutlen = 1500
" Enter a mode
call libmodal#Enter(…)
" Reset the timeout
let &timeoutlen = l:timeoutlen
endfunction
<
Lua: ~
>
local api = vim.api
local libmodal = require('libmodal')
function fooMode()
-- Get the user's preferred timeout length.
local prevTimeoutLen = api.nvim_get_option('timeoutlen')
-- Set it to something else, like 1500ms.
api.nvim_set_option('timeoutlen', 1500)
-- Enter a mode.
libmodal.mode.enter(…)
-- Restore the `timeoutlen`
api.nvim_set_option('timeoutlen', prevTimeoutLen)
end
<
4 years ago
Mode creators who use `function` {instruction}s may define timeouts manually
using |timers|, which is how |libmodal| implements them internally.
4 years ago
==============================================================================
5. License *libmodal-license*
4 years ago
`nvim-libmodal` Create new "modes" for Neovim.
Copyright © 2020 Iron-E
4 years ago
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
4 years ago
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
4 years ago
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
4 years ago
==============================================================================
6. Bugs *libmodal-bugs*
* `libmodal#Enter()` does not work when {instruction} is a |funcref|.
* See |E5004|.
* `libmodal#Prompt()` does not work when {instruction} is a |funcref|.
* See |E5004|.
4 years ago
==============================================================================
7. Contributing *libmodal-contributing*
The following describes what should be done if an individual wishes to
contribute something to the `Iron-E/nvim-libmodal` repository.
------------------------------------------------------------------------------
CODE *libmodal-contributing-code*
4 years ago
Bugfixes ~
4 years ago
If you discover a bug and believe you know the solution to fixing it, then
submit a bug report and state that you are working on a fix (and what that
fix might be), and what general timeframe the fix may be completed in
(months, weeks, days, etc.).
4 years ago
When the fix is complete, submit a PR that references the issue you
submitted.
4 years ago
Features ~
4 years ago
If there is a feature you would like to be a part of |libmodal|, the best
thing you can do is submit a feature request, and then state that you are
working on a pull request (PR) so others don't attempt to do the same work
at the same time.
4 years ago
When you believe your feature is complete, write some examples for it in
the `examples/lua` folder, and add them to |libmodal-examples| as
appropriate.
4 years ago
Assure that all existing |libmodal-examples| continue to work with your
feature, unless a breaking change was discussed on the feature request.
If you need help getting them to pass, you can ask for help on the PR.
4 years ago
Reference the issue you submitted on the PR so that the two show up
together when looking back at the history.
4 years ago
Contributing documentation is not necessary but appreciated, since the
person who knows the most about the feature being implemented is most
likely the one implementing it.
------------------------------------------------------------------------------
DOCUMENTATION *libmodal-contributing-documentation*
4 years ago
If there is a problem with the documentation, or you see an area where it
could be improved, don't hesitate to submit an issue and a PR. At the very
least it will exist in history if such an issue comes up again, and likely it
will serve to help yourself and others with more clear and concise wording, or
with more helpful and practical examples.
------------------------------------------------------------------------------
ISSUES *libmodal-contributing-issues*
4 years ago
Issues are greatly welcomed on the GitHub repository, whether they are bug
reports, feature requests, documentation improvements, or misunderstandings:
it's all good to have in the archive.
When submitting an issue, please describe the following:
1. Context regarding the issue (how you discovered it, pertinent information,
etc.)
2. Detailed description of the issue.
3. Steps to reproduce (if applicable).
4. Expected behavior (if applicable).
5. Attached media (screenshots, logs, etc.) (if applicable).
==============================================================================
8. Changelog *libmodal-changelog*
0.7.0 ~
Additions: ~
* Ability to pass `function`s into |libmodal-mode| from Vimscript.
* Ability to pass `function`s into |libmodal-prompt| from Vimscript.
* Add examples for doing almost everything that this plugin can do, from
Vimscript (although I still think Lua makes it easier).
0.6.3 ~
Fixes: ~
* Fix being unable to paste into Vim's command line after importing
the `libmodal.util.api` table.
0.6.2 ~
Fixes: ~
* Remove unused variables
0.6.1 ~
Fixes: ~
* Mode names with spaces or underscores are now represented correctly
by |libmodal-lua-Vars.name()|.
0.6.0 ~
Additions: ~
* New module: |libmodal-layer|s.
* Allows for use of built-in modes with overwriting of keymaps.
* New class `libmodal.Layer`.
* New function `libmodal.layer.enter()`.
* New examples for new additions.
* `libmodal.collections.ParseTable`:
* Added new `:parseGet()` method to replace the `:get()`
implementation.
*
* Added new `libmodal.collections.ParseTable.parse()` method.
* You can override it to change how the `ParseTable` parses its keys.
* Added `ParseTable.stringSplit()`.
Breaking Changes: ~
* Moved `libmodal.Mode.Popup` to `libmodal.collections.Popup`.
* Changed `libmodal.collections.ParseTable.parseGet()` back to
`libmodal.collections.ParseTable.get()`.
* `:get()` requires that keys have been parsed according to
`.parse()`.
Changes: ~
* Exposed more functionality of `libmodal.collections.Popup`.
0.5.0 ~
Additions: ~
4 years ago
* New class `libmodal.collections.Stack`.
* New class `libmodal.Mode`.
* New class `libmodal.Mode.Popup`.
* New class `libmodal.Prompt`.
* New class `libmodal.Vars`.
Breaking Changes: ~
4 years ago
* Moved `libmodal.mode.ParseTable` to `libmodal.collections.ParseTable`.
* Removed `libmodal.utils.vars`.
* Moved `libmodal.utils.Indicator` to `libmodal.Indicator`.
* Moved `libmodal.utils.Indicator.Entry` to
4 years ago
`libmodal.Indicator.HighlightSegment`.
Changes: ~
4 years ago
* Allow creation of |libmodal-mode| and |libmodal-prompt| table-objects.
* Call `libmodal.Mode.new()` or `libmodal.Prompt.new()` to create one.
* Call `{mode}:enter()` to enter the mode.
* More consistent mode recursion with `libmodal.collections.Stack`.
4 years ago
* Mode creators can now override specific functionality by copying
portions of the source code, or changing the values that are
referenced by the mode directly.
* This allows for finer control over how a mode behaves.
* It also allows for modes to inherit each other through
`setmetatable()`.
4 years ago
* Removed program logic from `libmodal.mode.enter()`.
* Now internally calls `libmodal.Mode.new(…):enter()` instead.
* Removed program logic from `libmodal.prompt.enter()`.
* Now internally calls `libmodal.Prompt.new(…):enter()` instead.
4 years ago
Fixes: ~
* Fix unexpected behavior when repeating `libmodal.mode.enter()` calls
with the from within themselves.
* Mode popup windows may be closed prematurely by entering two different
modes and then exiting them in reverse order, among other things. All
previously known mysterious behavior is corrected.
0.4.1 ~
Fixes: ~
* Fix reference to `libmodal/src/prompt` as `libmodal/src/path`.
0.4.0 ~
Additions: ~
* Add partial support for |vim-libmodal|.
Fixes: ~
* Fix bad reference to `vars.windows`.
* Fix bug where help was always shown upon entering an invalid key-combo in
`libmodal.mode.enter()`.
0.3.1 ~
Fixes: ~
* Fix bug where everytime `api.nvim_lecho()` was called, its {hlTables} would
infinitely grow with placeholder "None" entries.
4 years ago
0.3.0 ~
Additions: ~
* Generate `?` mapping for |libmodal-mode|s.
Fixes: ~
* Fix |libmodal-timeouts| not being respected.
4 years ago
0.2.1 ~
Fixes: ~
* Fix `help` command completion being shown during an {instruction}
callback `function` when none should be shown.
4 years ago
0.2.0 ~
Additions: ~
* |libmodal-prompt| implemetation from |vim-libmodal|.
* |libmodal-prompt|s now automatically generate `help` command if none is
provided.
4 years ago
0.1.0 ~
Additions: ~
* |libmodal-mode| implementation from |vim-libmodal|.
4 years ago
==============================================================================
9. Credits *libmodal-credits*
Credit Reason
--------------------- ----------------------------------
Daniel Steinberg |vim-win| creator and inspiration.
Iron-E Primary contibuter/maintainer.
neoclide/|coc-nvim| Development environment provider.
r/Neovim |Lua| and Neovim reference.
Roberto Ierusalimschy "Programming In Lua: 5.1".
Steve Losh "Learn Vimscript The Hard Way".
tbastos/vim-lua Syntax highlighting for |Lua|.
u/Mambu38 |Lua| reference.
u/oryiesis Inspiration.
www.lua-users.org |Lua| reference.
www.stackoverflow.com Vimscript and |Lua| reference.
4 years ago
==============================================================================
vim:tw=78:ts=4:ft=help:norl: