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?

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.

5
  • 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 '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 2 '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> May 2 '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 2 '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. May 2 '18 at 22:02

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.