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