So I have an input, something like this:

let dir = input("What is the directory you're looking for? ", "", "dir")

This works great for typing and and getting directory input. But what if the path was really long and I want to run the command again? Normally I would just press for command line recall, however when I do this it simply tries to complete a directory which is not what I want. I want Tab to complete directories, and to do command line recall. Is there any way to get this behavior without defining a custom completion function?

  • Ctrl+x , Ctrl+f completes filenames as well as directories. So, you can map them to tab in normal mode. – SibiCoder Apr 28 '16 at 15:28
  • 2
    @SibiCoder: yes but not in this case. CTRL-F open the command line window if executed from the command line :h c_CTRL-F – nobe4 Apr 28 '16 at 15:34

If you simply want to recall the last text given as an argument to input(), you could try the following mapping:

cnoremap <expr> <Up> getcmdtype() ==# '@' ? '<C-E><C-U>' . histget('@') : '<Up>'

Which can be broken down like this:

  • <expr>: type the evaluation of an expression
  • getcmdtype() ==# '@': check whether you are on the input line
  • '<C-E><C-U>' . histget('@'): if the previous test succeeded, hit <C-E><C-U> to clear the input line, then type the last entry from the input history (histget('@'))
  • '<Up>': otherwise, if you are somewhere else (command-line, expression register, search ...), simply hit <Up>

If you want to navigate across all the entries of the input history, you could try the following code:

let s:input_hist_index=0

function! s:InputHistory(dir) abort
    let s:input_hist_index += a:dir
    return "\<C-E>\<C-U>" . histget('@', s:input_hist_index)

cnoremap <expr> <Up> getcmdtype() ==# '@' ? <SID>InputHistory(-1) : '<Up>'
cnoremap <expr> <Down> getcmdtype() ==# '@' ? <SID>InputHistory(1) : '<Down>'

It's similar to the previous mapping, except it must track where you are in the input history, hence the script-local variable s:input_hist_index. There may be another way of doing it, maybe a native function, but I didn't find one in :h history-functions.

You can get more information with the following help topics:

:h <expr>
:h getcmdtype()
:h histget()
:h c_ctrl-e
:h c_ctrl-u 
  • Cool. Yeah, I think this will work. Thanks! Ok, I understand all of this except one thing: Could you tell me what <C-U> does in this context? I assume it's not the scrolling function that I find in :help CTRL-U. – Tumbler41 Apr 28 '16 at 18:04
  • 1
    @Tumbler41 <C-U> deletes from the cursor up to the beginning of the line. Without it, whenever you would hit <Up>, the mapping would add a new entry from the input history on the command-line without clearing it first. So <C-U> makes sure the command-line is always cleared before inserting something. You can get this information here: :h c_ctrl-u – user9433424 Apr 28 '16 at 18:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.