Does vim expose an api for manipulating argv before the "main program" looks at it?

I want to be able to use the syntax:

$ vim /path/to/my/file:100

and have it mean the same thing as

$ vim +100 /path/to/my/file

if /path/to/my/file:100 does not itself exist.

I can potentially see writing a wrapper script that does something like the example below, but I would really prefer to keep the logic inside my .vimrc if possible.

#!/usr/bin/env perl
use strict;
use warnings;

my @args;

foreach my $x (@ARGV) {
    my $candidate = (not (-f $x)) and ($x =~ /:/);
    if ($candidate) {
        my ($path, $linum) = split /:/, $x, 2;
        push @args, ("+" . $linum, $path);
    } else {
        push @args, $x;

exec "vim", @args;

You could write a dirty function for doing this for you:

au BufNewFile * nested call ReadFile()

func! ReadFile()
  let l:filename = expand('%:p')
  if l:filename =~ ':\d\+$'
    let l:number = matchstr(l:filename, ':\zs\d\+$')
    let l:filename = matchstr(l:filename, '^[^:]*')
    execute 'bd |  e! '. l:filename
    call cursor(l:number, 1)

This is not beatiful and has some downfalls, but could get you started.

Credits to muru for the nested modifier!

  • 2
    This is indeed a little bit more complex as we may want to jump to a buffer already opened, we need to apply ftdetect after the :edit. BTW, I don't remember why, I actually have a keepalt e. Aug 9 '17 at 15:16
  • Aah here comes @lucHermitte again. Sorry was a bit in a hurry, wasn't the last version. I do not think that keepalt is needed here, since i delete the "wrong" buffer (Or maybe i misunderstood something). I didn't really understand what you are saying in the first part. As far as I understand it, the do BufRead will trigger the ftdetect, as always I would be thankfully to hear where I am wrong ;-) (This seems to make no problems with opening already open buffers...) Aug 10 '17 at 11:34
  • 1
    Maybe use a nested autocmd, instead of manually calling do BufRead? See vi.stackexchange.com/q/2195/205
    – muru
    Aug 10 '17 at 11:49
  • @muru that is great, thank you very much. I've searched for something like this. Aug 10 '17 at 11:54
  • Also: I'd use :\d\+$ to ensure the line number is at the end of the string, just in case we get an argument like foo:1.bar:10, and use ^.*\ze: to get the filename
    – muru
    Aug 10 '17 at 12:04

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.