diff --git a/doc/libmodal.txt b/doc/libmodal.txt index cb9e9df..8c55646 100644 --- a/doc/libmodal.txt +++ b/doc/libmodal.txt @@ -262,7 +262,45 @@ MODE *libmodal-mode* *libmodal.m |lua-eval| For type conversions between Vimscript to |Lua|. |libmodal-examples| For examples of this function. -`libmodal.mode`.switch(...) *libmodal.mode:switch()* +`libmodal.mode.map`.fn({f}, ...) *libmodal.mode.map.fn()* + + Because |libmodal-mode|s expose the `self` parameter to |lua-function|s in + |lua-table|s, mapping certain functions may not work as you expect. For + example: >lua + libmodel.mode.enter('foo', { + a = vim.cmd.undo, -- error! + }) +< + This is because some functions accept |lua-nil| as a parameter (e.g. + `vim.cmd.undo()` is OK) but not accept parameters of certain types (e.g. + `vim.cmd.undo('foo')` is an error). In this case (expanding the previous + example to highlight the problem): >lua + libmodel.mode.enter('foo', { + -- equivalent to `a = vim.cmd.undo` + a = function(self) vim.cmd.undo(self) end, + }) +< `self` (a |libmodal.Mode|) is not an appropriate parmeter to `vim.cmd.undo`. + + To fix this, one can explcitly write the following as mapping: >lua + libmodel.mode.enter('foo', { + a = function() vim.cmd.undo() end, -- error! + }) +< However, this is tiresome. To simplify this process, `libmodal.mode.map.fn` + was created. + + Parameters: ~ + {f} the function to map + ... arguments to the function + + Example: ~ +>lua + local fn = libomdal.mode.map.fn + libmodal.mode.enter('Foo', { + a = fn(vim.cmd.undo), + b = fn(print, 'hello'), + }) + +`libmodal.mode.map`.switch(...) *libmodal.mode.map.switch()* Convenience wrapper for |Mode:switch()|. @@ -272,7 +310,7 @@ MODE *libmodal-mode* *libmodal.m Example: ~ >lua libmodal.mode.enter('Foo', { - f = libmodal.mode.switch('Bar', { + f = libmodal.mode.map.switch('Bar', { b = function() vim.notify('Inside Bar mode') end, diff --git a/examples/lua/keymaps-supress-exit.lua b/examples/lua/keymaps-supress-exit.lua index c2725c5..c407265 100644 --- a/examples/lua/keymaps-supress-exit.lua +++ b/examples/lua/keymaps-supress-exit.lua @@ -22,7 +22,7 @@ local fooModeKeymaps = 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 + z = libmodal.mode.map.switch('Bar', barModeKeymaps), -- the same as above, but more convenience } -- tell the mode not to exit automatically diff --git a/examples/lua/keymaps.lua b/examples/lua/keymaps.lua index 7f39edd..aa5b2ba 100644 --- a/examples/lua/keymaps.lua +++ b/examples/lua/keymaps.lua @@ -24,7 +24,9 @@ local fooModeKeymaps = o = 'norm o', p = 'bp', - zf = 'split', + x = libmodal.mode.map.fn(vim.notify, 'hello'), + + zf = libmodal.mode.map.fn(vim.cmd.split), zfc = 'q', zff = split_twice, zfo = 'vsplit', diff --git a/lua/libmodal/init.lua b/lua/libmodal/init.lua index dc4cf7b..47b9cdb 100644 --- a/lua/libmodal/init.lua +++ b/lua/libmodal/init.lua @@ -53,11 +53,47 @@ function libmodal.mode.enter(name, instruction, supress_exit) mode:enter() end +--- @see libmodal.mode.map.switch +function libmodal.mode.switch(...) + vim.deprecate('libmodal.mode.switch', 'libmodal.mode.map.switch', '4.0.0', 'nvim-libmodal') + return libmodal.mode.map.switch(...) +end + +libmodal.mode.map = {} + +--- Example: +--- ```lua +--- { +--- a = vim.cmd.undo, -- Error +--- b = function() vim.cmd.undo() end, -- OK +--- c = fn(vim.cmd.undo), -- Good +--- } +--- ``` +--- +--- @generic T +--- @param f fun(...: T) the function to map +--- @param ... T arguments to `f` +--- @return fun() # that calls `f` which the arguments provided +function libmodal.mode.map.fn(f, ...) + local args = { ... } + return function() + f(unpack(args)) + end +end + --- `enter` a mode using the arguments given, and do not return to the current mode. +--- +--- Example: +--- ```lua +--- { +--- a = switch('foo', {--[[Foo mode keymaps go here]]}), +--- } +--- ``` +--- --- @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(...) +function libmodal.mode.map.switch(...) local args = { ... } return function(self) self:switch(unpack(args))