Comments (7)
I'll implement version one, it seems the simplest 👍
from nvim-libmodal.
Exiting libmodal seems to require one press per mode switched. My expected behaviour is that pressing would immediately take me to Normal mode, just like how all Vim modes work. Do you agree?
My thinking about it is like this:
- Entering a libmodal mode is like entering Insert, from which you press
<Esc>
once to return to Normal. - Entering a sub-mode (i.e. a libmodal mode inside a libmodal mode) is like
:h i_CTRL-O
, from which you press<Esc>
twice to return to Normal.
If not, is there some other way to exit libmodal? There doesn't seem to be a require('libmodal').mode.exit() that I can create a mapping for
I opened a PR for this :)
local M = {}
M.mode1 = {
m = function()
vim.notify('Mode 1')
end,
n = function(self)
require('libmodal').mode.enter('My mode 2', M.mode2)
self:exit()
end
}
M.mode2 = {
m = function()
vim.notify('Mode 2')
end,
n = function(self)
require('libmodal').mode.enter('Mode 1', M.mode1)
self:exit()
end
}
vim.keymap.set('n', 'M', function()
require('libmodal').mode.enter('Mode 1', M.mode1)
end)
from nvim-libmodal.
Calling Mode:exit()
to switch between modes may cause confusion for the users of my plugin in case they try to create ModeChanged
autocmds that trigger when going between custom modes like so:
autocmd ModeChanged customMode1:customMode2 ...
Since your solution switches custom modes via normal mode they would have to listen for n:customMode2
, but then there's no way to differentiate between switching libmodal modes and entering a libmodal mode from normal mode.
One alternative solution that might be a little cleaner API-wise could be to add a new libmodal.mode.switch()
function which switches to another libmodal mode without stacking. I still think Mode:exit()
is very useful to have as well for other use cases.
What do you say? Would that be possible to implement? 🙂
from nvim-libmodal.
I'm sure something like what you describe could be implemented— I just want to make sure I understand the details first.
Since your solution switches custom modes via normal mode they would have to listen for n:customMode2, but then there's no way to differentiate between switching libmodal modes and entering a libmodal mode from normal mode.
tl;dr: if it's exiting to normal before entering the new mode, that's a bug, and if it's happening to you I'll fix it 😁
Just to be clear, self:exit()
doesn't immediately return to Normal mode. It works like this:
- A
Mode
is essentially a loop overvim.fn.getchar
. getchar
receives the pressed character, which is (in this case) mapped to a function that callsself:exit()
.self:exit()
flags a desire to exit next loop iteration.- Before
getchar
is called again, the exit flag is checked, so the mode terminates.
So, to annotate the example above:
{ -- Foo mode
n = function(self)
-- enter Bar mode
libmodal.mode.enter('Bar', keymap)
-- Bar mode has exited
-- flag Foo mode to exit instead of taking input again
self:exit()
end,
}
Because of this, self:exit()
can even come before libmodal.mode.enter(…)
and the result will (if it works correctly) be the same.
Thus ModeChanged n:Bar
and ModeChanged Foo:Bar
will (again, ideally) be different.
One alternative solution that might be a little cleaner API-wise could be to add a new libmodal.mode.switch() function which switches to another libmodal mode without stacking.
Which of these suits your needs best?
-- 1. Swap means "enter another mode and after it exits, exit the current mode"
libmodal.mode.swap = function(...)
return function(self)
libmodal.mode.enter(...)
self:exit()
end
end
-- 2. Swap means "exit the current mode, and then enter a new mode"
libmodal.mode.swap = function(...)
return function(self)
self:exit(function() -- ← this doesn't work right now, just bikeshedding!
libmodal.mode.enter(...)
end)
end
end
from nvim-libmodal.
Ah, you're right!
Which of these suits your needs best?
I'm not sure what the difference would be between the two, but to me the latter one makes more sense semantically since it first exit, then enter the next mode, right? Would there be any difference in behaviour between the two versions?
from nvim-libmodal.
Would there be any difference in behaviour between the two versions?
Ultimately the big difference will be in the ModeChanged
events. For example:
{ -- Foo mode
-- `swap` v1
n = function(self)
libmodal.mode.enter('Bar', {})
self:exit()
end,
-- `swap` v2
m = function(self)
self:exit(function() -- ← again, this is hypothetical
libmodal.mode.enter('Bar', {})
end)
end,
}
Entering this mode (from Normal) emits ModeChanged n:Foo
. Then:
n
pressedModeChanged Foo:Bar
(enter Bar mode)ModeChanged Bar:Foo
(when Bar mode exits)ModeChanged Foo:n
(exit Foo mode)
m
pressedModeChanged Foo:n
(exit Foo mode)ModeChanged n:Bar
(enter Bar mode)ModeChanged Bar:n
(when Bar mode exits)
from nvim-libmodal.
Hmm, I think both version should work for me so v1 is probably fine. What do you think? 🙂
from nvim-libmodal.
Related Issues (20)
- consider move initialization to lua HOT 5
- Visual block mode needs to be added to galaxyline config HOT 2
- Indicator functionality within a Layer, OR cursor functionality within a Mode. HOT 2
- Support mapping to function in Layer HOT 1
- Bad styling HOT 1
- Compatibility with `sindrets/winshift.nvim` HOT 2
- feline archieved switch to lualine? HOT 4
- Layers don't seem to be reusable HOT 1
- Error encountered: Expected lua string HOT 6
- Using default bindings from within a mode HOT 8
- Bug: cursor movements aren't updated until after leaving mode HOT 4
- Bug: `vim.v.count` is always 0 HOT 7
- Modifier mappings don't seem to work support HOT 2
- `CursorMoved` / `CursorMovedI` isn't triggered inside custom mode HOT 4
- `TextChanged` isn't triggered in custom mode HOT 3
- What's the best way to expose the mode keymaps table to my consumers? HOT 4
- Attempt to compare number with string in Mode.lua:296 HOT 5
- Importing libmodal prevents pasting into command prompt HOT 5
- "Error while calling lua chunk for luaeval()... Undefined variable: _instruction" HOT 6
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from nvim-libmodal.