diff --git a/autoload/libmodal.vim b/autoload/libmodal.vim index d2e373c..c0adb9d 100644 --- a/autoload/libmodal.vim +++ b/autoload/libmodal.vim @@ -1,14 +1,4 @@ -let libmodal#_replacements = [ -\ '.', ':', '&', '@', ',', '\\/', '?', -\ '(', ')', -\ '{', '}', -\ '[', ']', -\ '+', '\\*', '\\!', '\\^', '\\>', '\\<', '%', '=', -\ '\\$', -\ '\\' -\] - -let libmodal#_winOpenOpts = { +let s:winOpenOpts = { \ 'anchor' : 'SW', \ 'col' : &columns - 1, \ 'focusable': v:false, @@ -19,46 +9,6 @@ let libmodal#_winOpenOpts = { \ 'width' : 25, \} -" SUMMARY: -" * Provide completions for a `libmodal.prompt`. -" PARAMS: -" * `completions` => the list of completions. -" RETURNS: -" * A function that accepts: -" * `argLead` => the current line being edited, stops at the cursor. -" * `cmdLine` => the current line being edited -" * `cursorPos` => the position of the cursor -function! libmodal#CreateCompletionsProvider(completions) - function! l:completionsProvider(argLead, cmdLine, cursorPos) abort closure - " replace conjoining characters with spaces. - let l:spacedArgLead = a:argLead - for l:replacement in s:replacements - let l:spacedArgLead = substitute(l:spacedArgLead, l:replacement, ' ', 'g') - endfor - - " split the spaced version of `argLead`. - let l:splitArgLead = split(splitArgLead, ' ') - - " make sure the user is in a position were this function - " will provide accurate completions. - if len(splitArgLead) > 1 | return v:none | end - - " get the word selected by the user. - let l:word = l:splitArgLead[1] - - " get all matches from the completions list. - let l:completions = [] - for l:completion in s:completions - if stridx(l:completion, l:word) > -1 - let l:completions = add(l:completions, l:completion) - endif - endfor - return l:completions - endfunction - - return funcref('l:completionsProvider') -endfunction - " PLACEHOLDER. function! libmodal#Enter(...) abort echo '' @@ -79,5 +29,5 @@ endfunction " RETURNS: " * A window handle. function! libmodal#WinOpen(bufHandle) abort - return nvim_open_win(a:bufHandle, 0, libmodal#_winOpenOpts) + return nvim_open_win(a:bufHandle, 0, s:winOpenOpts) endfunction diff --git a/examples/lua/prompt-callback.lua b/examples/lua/prompt-callback.lua index 02a308c..667f1df 100644 --- a/examples/lua/prompt-callback.lua +++ b/examples/lua/prompt-callback.lua @@ -1,14 +1,15 @@ local libmodal = require('libmodal') +local api = vim.api local commandList = {'new', 'close', 'last'} function barMode() - local uinput = vim.api.nvim_get_var('tabModeInput') + local uinput = vim.api.nvim_get_var('barModeInput') if uinput == 'new' then - execute 'tabnew' + api.nvim_command('tabnew') elseif uinput == 'close' then - execute 'tabclose' + api.nvim_command('tabclose') elseif uinput == 'last' then - execute 'tablast' + api.nvim_command('tablast') end end diff --git a/examples/lua/supress-exit.lua b/examples/lua/supress-exit.lua index f57f7d6..71f0fe6 100644 --- a/examples/lua/supress-exit.lua +++ b/examples/lua/supress-exit.lua @@ -6,7 +6,7 @@ function barMode() ) if uinput == '' then - vim.api.nvim_command("echo 'You cant leave using .'") + vim.api.nvim_command("echom 'You cant leave using .'") elseif uinput == 'q' then vim.api.nvim_set_var('barModeExit', true) end diff --git a/lua/libmodal/src/base/globals.lua b/lua/libmodal/src/base/globals.lua index c60c29d..8b17964 100644 --- a/lua/libmodal/src/base/globals.lua +++ b/lua/libmodal/src/base/globals.lua @@ -12,6 +12,7 @@ local globals = {} */ --]] +globals.DEFAULT_ERROR_MESSAGE = 'vim-libmodal error' globals.ESC_NR = 27 globals.TYPE_FUNC = 'function' globals.TYPE_NUM = 'number' diff --git a/lua/libmodal/src/mode/init.lua b/lua/libmodal/src/mode/init.lua index 7880a30..a886a80 100644 --- a/lua/libmodal/src/mode/init.lua +++ b/lua/libmodal/src/mode/init.lua @@ -147,9 +147,7 @@ local function _initCombos(modeName, comboTable) -- create a floating window local buf = api.nvim_create_buf(false, true) vars.buffers.instances[modeName] = buf - vars.windows.instances[modeName] = api.nvim_eval( - 'libmodal#WinOpen(' .. buf .. ')' - ) + vars.windows.instances[modeName] = api.nvim_call_function('libmodal#WinOpen', {buf}) -- Build the parse tree. vars.combos.instances[modeName] = mode.ParseTable.new(comboTable) diff --git a/lua/libmodal/src/prompt/init.lua b/lua/libmodal/src/prompt/init.lua index 706a984..b87d2a2 100644 --- a/lua/libmodal/src/prompt/init.lua +++ b/lua/libmodal/src/prompt/init.lua @@ -24,6 +24,52 @@ local prompt = {} */ --]] +------------------------------------------------------- +--[[ SUMMARY: + * Provide completions for a `libmodal.prompt`. +]] +--[[ PARAMS: + * `completions` => the list of completions. +]] +--[[ RETURNS: + * A function that accepts: + * `argLead` => the current line being edited, stops at the cursor. + * `cmdLine` => the current line being edited + * `cursorPos` => the position of the cursor + * Used for `input()` VimL. +]] +------------------------------------------------------- +function prompt._createCompletionsProvider(completions) + return function(argLead, cmdLine, cursorPos) + -- replace conjoining characters with spaces. + local spacedArgLead = argLead + for _, v in ipairs(_replacements) do + spacedArgLead = string.gsub(spacedArgLead, v, ' ') + end + + -- split the spaced version of `argLead`. + local splitArgLead = utils.strings.split(splitArgLead, ' ') + + -- make sure the user is in a position were this function + -- will provide accurate completions. + if #splitArgLead > 1 then return nil end + + -- get the word selected by the user. + local word = splitArgLead[1] + + -- get all matches from the completions list. + local matches = {} + local i = 1 + for _, v in ipairs(completions) do + if string.match(word, completion) then + matches[i] = completion + i = i + 1 + end + end + return matches + end +end + -------------------------- --[[ SUMMARY: @@ -69,24 +115,29 @@ function prompt.enter(...) api.nvim_redraw() -- compose prompt command - local cmd = "input('" .. indicator .. "', ''" - if completions then cmd = - cmd .. ", 'customlist,funcref(\"libmodal#CreateCompletionsProvider\", [" - .. completions .. - "])'" - end + --[[ TODO: completions won't work until neovim 0.5 + look into v:lua when it drops. + + local cmd = "input('" .. indicator .. "', ''" + if completions then cmd = + cmd .. ", 'customlist,funcref(\"libmodal#CreateCompletionsProvider\", [" + .. completions .. + "])'" + end + -- get input from prompt + local uinput = api.nvim_eval(cmd .. ')') -- closing bracket ends beginning 'input(' + --]] - -- get input from prompt - local uinput = api.nvim_eval(cmd .. ')') -- closing bracket ends beginning 'input(' + local uinput = api.nvim_call_function('input', {indicator}) -- if a:2 is a function then call it. if string.len(uinput) > 0 then vars.nvim_set(vars.input, modeName, uinput) - if completions then + if type(args[2]) == globals.TYPE_TBL then if args[2][uinput] then api.nvim_command(args[2][uinput]) else - api.nvim_show_err('Unknown command.') + api.nvim_show_err(globals.DEFAULT_ERROR_MESSAGE, 'Unknown command') end else args[2]() diff --git a/lua/libmodal/src/utils/api.lua b/lua/libmodal/src/utils/api.lua index e521a21..5aeb0a2 100644 --- a/lua/libmodal/src/utils/api.lua +++ b/lua/libmodal/src/utils/api.lua @@ -36,7 +36,7 @@ function api.nvim_echo(str) api.nvim_command("echo " .. tostring(str)) end ------------------------------------ +------------------------------------ --[[ SUMMARY: * Check whether or not some variable exists. ]] @@ -44,9 +44,9 @@ end * `scope` => The scope of the variable (i.e. `g`, `l`, etc.) * `var` => the variable to check for. ]] ------------------------------------ +------------------------------------ function api.nvim_exists(scope, var) - return api.nvim_eval("exists('" .. scope .. ":" .. var .. "')") == globals.VIM_TRUE + return api.nvim_call_function('exists', {scope .. ':' .. var}) == globals.VIM_TRUE end ------------------------- @@ -68,15 +68,13 @@ end '"endwhile"' } - return tonumber(vim.api.nvim_eval( - "execute([" .. table.concat(cmd, ',') .. "])" - )) + return tonumber(vim.api.nvim_call_function("execute",cmd)) ``` However, I'm not sure if it would accidentally affect text. ]] ------------------------- function api.nvim_input() - return api.nvim_eval('getchar()') + return api.nvim_call_function('getchar', {}) end --------------------------------- @@ -91,11 +89,11 @@ end local resetHighlight = Entry.new('None', '') function api.nvim_lecho(hlTables) api.nvim_redraw() - table.insert(hlTables, resetHighlight) + hlTables[#hlTables+1] = resetHighlight for _, hlTable in ipairs(hlTables) do api.nvim_command( -- `:echohl` the hlgroup and then `:echon` the string. - "echohl " .. hlTable.hl .. " | echon '" .. hlTable.str .. "'" + "echohl " .. tostring(hlTable.hl) .. " | echon '" .. tostring(hlTable.str) .. "'" ) end end @@ -119,13 +117,14 @@ end * `msg` => the message of the error. ]] -------------------------------------- +local returnEntry = Entry.new('Question', '\nPress any key to return.') function api.nvim_show_err(title, msg) api.nvim_lecho({ - Entry.new('Title', title .. '\n'), - Entry.new('Error', msg), - Entry.new('Question', '\n[Press any key to return]') + Entry.new('Title', tostring(title) .. '\n'), + Entry.new('Error', tostring(msg)), + returnEntry }) - api.nvim_command('call getchar()') + api.nvim_call_function('getchar', {}) end --[[ diff --git a/lua/libmodal/src/utils/init.lua b/lua/libmodal/src/utils/init.lua index f0be704..9e36c7f 100644 --- a/lua/libmodal/src/utils/init.lua +++ b/lua/libmodal/src/utils/init.lua @@ -1,3 +1,11 @@ +--[[ + /* + * IMPORTS + */ +--]] + +local globals = require('libmodal/src/base/globals') + --[[ /* * MODULE @@ -20,12 +28,12 @@ utils.WindowState = require('libmodal/src/utils/WindowState') function utils.showError(pcallErr) utils.api.nvim_bell() - utils.api.nvim_show_err( 'vim-libmodal error', + utils.api.nvim_show_err(globals.DEFAULT_ERROR_MESSAGE, utils.api.nvim_get_vvar('throwpoint') .. '\n' .. utils.api.nvim_get_vvar('exception') .. '\n' .. - pcallErr + tostring(pcallErr) ) end