The two functions in the script below can be called independently via key mappings <leader>1
and <leader>2
. In a perfect world, <leader>1
will always be called first. If the user forgets to do that, I want s:RunMe2nd()
to be helpful and call s:RunMe1st()
. However, it needs to use the user-defined command to display the legal values and get the one that will be passed to the function.
After some tinkering, I was able to do that with call feedkeys(":RunMe1st \<C-Z>", "t")
, but also I would like the execution of s:RunMe2nd()
to be blocked until :RunMe1st
finishes. Is that possible, and if so, how would I do it?
To see what I'm talking about, source the script, and then type <leader>2
. You will see the pop-up menu for the completion items, but underneath it you'll also see an error saying b:init
is undefined. echomsg
doesn't wait for feedkeys
to finish. Source the file again, and type <leader>1
then <leader>2
to see how it works when following the rules.
unlet! b:init " Re-source this file to reset.
command! -buffer -nargs=1 -complete=customlist,<SID>LegalValues RunMe1st :call <SID>RunMe1st("<args>")
setlocal wildcharm=<C-Z> " Used to open completion menu.
nnoremap <leader>1 :RunMe1st<space><C-Z>
nnoremap <leader>2 :call <SID>RunMe2nd()<CR>
function! s:LegalValues(ArgLead, CmdLine, CursorPos)
return ["hello", "world", "42"]
endfunction
function! s:RunMe1st(arg)
let b:init = a:arg
endfunction
function! s:RunMe2nd()
if !exists("b:init")
echomsg "You didn't run RunMe1st first. Let me help you."
" How do I get Vim to wait for the next statement to finish?
call feedkeys(":RunMe1st \<C-Z>", "t")
endif
echomsg "All good. You chose ".b:init
endfunction
input()
could use the same completion list as:command
. That's a much better solution than usingfeedkeys()
.