Sometimes I want to open vim in preparation of opening a file in the directory tree.

So i start it without a file:


Then I use a map to open NERDTree:


This fails with

NERDTree: no file for the current buffer

OK so this is perhaps a deficiency in the plugin, and I want to add a check (either to use inside my bind, or to PR upstream to handle this edge case for the plugin).

How do I check that I am in a [No Name] buffer? @%? :f?

1 Answer 1

nnoremap <Leader>f :call SmartNERDTree()<CR>

function! SmartNERDTree()                   
    if @% == ""

I'm sure it would be possible to make it a oneliner in the map. The question is about whether it would be more readable.

  • 1
    Use a map expression to get a one-liner, e.g. nnoremap <expr> <leader>f ':call ' . (@% == '' ? 'NERDTreeToggle' : 'NERDTreeFind') . "\<cr>". See :h :map-expression. However, I feel readability is more important as you may want make edits in the future and functions can be simpler for such cases. May 2, 2018 at 19:59
  • Do you know if the expr is required? It makes maintenance a lot less palatable. I know I can make an if with |s inline and all that. But ? conditional operator would be somewhat more elegant. I just a bit of trouble finding out whether vimscript even has that operator. it seems that it does...
    – Steven Lu
    May 2, 2018 at 20:21
  • 1
    You can do it many ways if you don't want to use <expr>. Use :execute, e.g. nnoremap <leader>f :execute (@% == '' ? 'NERDTreeToggle' : 'NERDTreeFind')<cr> or use <c-r>= e.g. nnoremap <leader>f :<c-r>=@% == '' ? 'NERDTreeToggle' : 'NERDTreeFind'<cr><cr> or as you say with an :if and |, e.g. nnoremap <leader>f :if @% == ""<bar> NERDTreeToggle<bar>else<bar> NERDTreeFind<bar>endif<cr> May 2, 2018 at 20:40
  • I'm sort of joking but sort of not. This discussion only re-confirms the notion that VimScript is a horrible, horrible language. ;) Could you spell it out more plainly why a ternary cannot actually be put directly into a map?
    – Steven Lu
    May 2, 2018 at 21:37
  • 1
    This is an "statement" vs expression issue, e.g. :set filetype=python vs :let &filetype=somefunc(arg). Anything that is sourced or executed via command-line(:) is a statement/command. A command may take a certain syntax or sometimes an expression. I used :execute above because :execute takes an expression and then executes it as a command. It is can be a tricky. I would recommend reading :h eval (actually whole manual would be best). May also want to look into Learn Vimscript the Hard Way by Steve Losh. May 2, 2018 at 22:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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