6

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

So i start it without a file:

vim

Then I use a map to open NERDTree:

:NERDTreeFind<CR>

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?

Steven Lu
  • 2,251
  • 15
  • 26

1 Answers1

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

function! SmartNERDTree()                   
    if @% == ""
        NERDTreeToggle                      
    else                                    
        NERDTreeFind                        
    endif                                   
endfun                                      

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.

Steven Lu
  • 2,251
  • 15
  • 26
  • 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. – Peter Rincker May 02 '18 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 02 '18 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> – Peter Rincker May 02 '18 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 02 '18 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. – Peter Rincker May 02 '18 at 22:02