How do I programmatically inject keystrokes into Vim's input queue from a function or mapping?
Answer
feedkeys()
Explanation
The feedkeys({keys}, {flags}) function inserts a string of keystrokes into Vim's input queue as if the user had typed them. This is invaluable when you need to trigger complex sequences from a function or mapping — especially when you need to switch modes, pass special keys, or pre-populate a search or command prompt for the user to continue editing.
How it works
call feedkeys("iHello World\<Esc>", 'n')
- First argument: the key sequence string. Use
\<Key>notation for special keys:\<Esc>,\<CR>,\<C-w>, etc. - Second argument flags control how keys are processed:
'n'— apply no remapping (likenoremap), the most common choice't'— process keys as if typed by the user (goes through the typeahead buffer)'x'— execute the keys immediately and only return after processing completes'i'— insert at the head of the typeahead buffer (runs before any already-pending input)
Example
A mapping that opens a search prompt pre-filled with the word under the cursor and lets the user edit it before executing:
nnoremap <leader>/ :call feedkeys('/\<' . expand('<cword>') . '\>', 'n')<CR>
A function that simulates pressing <C-d> to list completion candidates after triggering omnicomplete:
function! ShowOmniList()
call feedkeys("\<C-x>\<C-o>\<C-d>", 'n')
endfunction
Tips
- Use
feedkeys()when:normal!is not enough — for example, when you need to pass keystrokes that change modes or interact with the command line - The
'x'flag forces synchronous execution and is useful in tests and scripts where you need the result immediately - Avoid
feedkeys()for simple normal-mode operations;:normal! {keys}is simpler and sufficient in those cases - In Neovim,
vim.api.nvim_feedkeys()provides the Lua equivalent with the same semantics