Vim+ctagsでパッケージ名つき関数についてジャンプできるようにする

Perlを使うようになってからはコード書きにVimを使うようになったのだが、Eclipseと違ってコードを追いかけるのが大変。

そこでctagsを使ってタグファイルを生成してそれを読み込ませるようにしてみたところ、シンボル上でCtrl-]を押して定義にジャンプしたりCtrl-tを使って戻ったりできるようになり若干楽になったのだが、なぜか

    Hoe::Fuga::hehe(0);

のようなパッケージ名つき関数呼び出しなどではタグジャンプしてくれない。

生成されたタグファイルの中身を見てみるとそもそも「Hoe::Fuga::hehe」のエントリがないので、ctagsに素敵なオプションをつけることで生成してくれたりしないかななどとネットで情報を探してみたのだが、なぜか対策が見つからなかった。

これは個人的にはイタいのだが、みんな困ってないのかな?…それはさておき、次のようなスクリプトを書いて「Hoe::Fuga::hehe」のエントリを追加するようにしてみた。

fqmn:

#!/usr/bin/perl

use strict;

#MAIN
{
    die <<USAGE if scalar(@ARGV) != 2;
Usage: $0 TAG_FILE SOURCE_DIR
USAGE

    my $file = $ARGV[0];
    my $sourcedir = $ARGV[1];
    if ($sourcedir =~ m|/$|) {
        $sourcedir = $`; 
    }   

    open IN, $file or die "Can't open $file\n";
    my @lines;
    while (<IN>) {
        chomp;
        my $line = $_; 
        $line =~ /^([^\t]+)\t([^\t]+)\t([^\t]+)\t([^\t]+)/;
        my ($word, $path, $pattern, $flag) = ($1, $2, $3, $4);

        if (defined($flag)) {
            if ($pattern =~ m|^/\^sub\s+|) {
                my $p = substr($path, length($sourcedir) + 1); 
                $p = $` if $p =~ /\.pm$/;
                $p =~ s|/|::|g;

                my $w = $p . "::" . $word;

                push(@lines, [$w, "$w\t$path\t$pattern\t$flag"]);
            }   
        }   

        push(@lines, [$word, $line]);

    }   
    close IN; 

    my @sorted = sort { $a->[0] cmp $b->[0] } @lines;

    for (@sorted) {
        print $_->[1], "\n";
    }   
}

これで、まず普通にタグファイルを生成して、

ctags -f tags.orig -R -h ".pm" /path/to/pm

次のようにして、

fqmn tags.orig /path/to/pm > tags

生成されたtagsを使うようにすればOK。これで快適になった。