Vim - tab drop

I use the :tabnew <filename> command a lot in Vim as I prefer tabs to buffers (Vim is more buffer-oriented, it's a matter of personal taste). But I'd prefer to be using :tab drop <filename> - the difference being that "tab drop" opens a new tab on the named file OR jumps to the existing tab on the file if there already is one, whereas "tabnew" opens a new tab on the file regardless of whether or not there's already one open. That's all fine: the problem is that "tab drop" is apparently seen as an advanced feature, and in Debian you have to install every Vim package there is, up to and including vim-gnome - even though this command works in Vim in a terminal. The logic for this has eluded me entirely. But what it means is that I frequently encounter systems (the default Mac Vim, although I usually brew install macvim, OpenWRT - yes, I know that's busybox - or text-only server systems) that don't have "tab drop". And I write Vim scripts that assume it exists, so I was looking for a programmatic way to check and degrade. My first lead was http://blog.sanctum.geek.nz/gracefully-degrading-vimrc/ , which is a great discussion of how to check if features exist and fail gracefully in Vim, but this proved trickier than I thought. I first wrote this:

function Newtab(infile)
    try
        tab drop a:infile
    catch
        tabnew a:infile
    endtry
endfunction

But succeed or fail, this edited a literal filename a:infile. I stumbled through a number of variants, including trying execute, but to my considerable surprise it was :help execute that finally got me to the correct format of the execute command and a working function:

function Newtab(infile)
    try
        execute "tab drop " . a:infile
    catch
        execute "tabnew " . a:infile
    endtry
endfunction

I mostly wanted this for scripting, but it's also nice to have it available as something I can call from the Vim command line, so:

command! -nargs=1 -complete=file Nt call Newtab(<f-args>)

This creates a new command - an "ex" command, one that gets prefaced by a colon. To understand what's going on here, I would highly recommend reading :help command - like most Vim help, it's quite terse. But unlike most Vim help, it's actually reasonably helpful. The short version goes like this:

  • ! - over-ride any previously existing command of the same name (without this, a reload of your ~/.vimrc throws an error because the command already exists
  • -nargs - how many arguments does it take (I should extend this to any number, but at the moment the function itself doesn't support more than one)
  • -complete - type of completion to use (hit tab on a partial filename and it will attempt to find a match)
  • Nt - the name of the command we're creating
  • call - "we're going to call a function
  • <f-args> - this is kind of ugly: you could use "<args>" to represent the supplied command line arguments, but "<f-args>" parses and escapes the arguments properly for use with a function
  • One fantastically annoying caveat that you may be wondering about: user-created functions and commands MUST start with a capital letter: I didn't have any choice in that