VimでPerldocを引く(Unix系OS編)


100213-0001.png

Perlでごりごり書いてるときに、モジュールのドキュメントが読みたくなることはよくある。GNU Screen + Vimでやってるときは別のウィンドウで「perldoc モジュール名」でもいいのだが、GVimではそういうわけにも行かない。

そんなときに便利なのが次のプラグイン。

PERLDOC2 – Perldoc with sytnax highlighting in vim : vim online
http://www.vim.org/scripts/script.php?script_id=2171

インストールは以下の手順で行う。

  1. CPANからPod::Simple::Vimモジュールをインストール1
  2. ダウンロードしたzipファイルの中身を~/.vimに解凍する
  3. .vimrcに次のような記述を追加
" Perldoc表示用
let g:Perldoc_path=expand("$HOME")."/.vim/perldoc_cache/"

expand以下がキャッシュディレクトリだ。ディレクトリ作成したりするのが面倒なら、単に「expand("$TEMP")."/"」とだけ指定しておけばいいかもしれない。使用法はコマンドモードで

:Perldoc モジュール名

とするとドキュメントが引ける。これだけでも十分読みやすいのだが、いくつか不満点があるので改良した。

  1. 別のウィンドウで開きたい
  2. モジュールだけじゃなく関数のドキュメントも引きたい
  3. カーソル下にある文字列をモジュール名と認識して引きたい

と言うわけで(かなりやっつけだが)改良したのが以下のもの。これを使うと、ここにカーソルを置いて

100213-0002.png

:Perldoc<Enter>とタイプするとドキュメントが表示される。

100213-0003.png

関数名も引ける。Vimを横に広く使ってないと不便かもしれないけれど、そこは適当にいじってください。

100213-0004.png

perldoc2.vim

perldoc2.vim – ダウンロード
~/.vim/pluginディレクトリに置く。

" 関数定義開始
function! Perldoc(pod)
    let pod = a:pod
    " もしpodがnullなら
    if !strlen(pod)
        " カーソル下にある、アルファベット、数字、コロンの組み合わせを
        " モジュール名として取得
        setlocal iskeyword=a-z,A-Z,48-57,_,:
        let pod = expand('<cword>')
        setlocal iskeyword<
    endif

    " pod2vimを使ってマニュアルを取得
    set shellredir:>
    let perldoc = system('pod2vim ' . shellescape(pod))
    set shellredir&

    " 取得できなかったら
    if !strlen(perldoc)
        echohl ErrorMsg
        echo 'ドキュメントが見つかりません : ' . pod
        echohl None
        return
    endif

    " キャッシュディレクトリが設定されていなかったら
    if !strlen(g:Perldoc_path)
        echohl ErrorMsg
        echo '最初に g:Perldoc_path を設定してください'
        echohl None
        return
    endif

    " キャッシュファイル名を作成
    let pod_name_with_hyphes = substitute(pod, '::', '-', 'g')
    let file_path = g:Perldoc_path . pod_name_with_hyphes
    let file_path = fnameescape(file_path)
    let file_as_list = split(perldoc, '\n')

    " キャッシュファイルに書き込み
    try
        call writefile(file_as_list, file_path)
    catch
        echohl ErrorMsg
        echo 'ファイルに書き込めませんでした : ' . file_path
        echohl None
        return
    endtry

    " 以前Perldocを表示したウィンドウを取得して
    let winnum = bufwinnr(g:__perldoc__)
    " 見つからなかったら新しく作成
    if winnum == -1
        execute 'vnew'
    else
        if winnr() != winnum
            exe winnum . 'wincmd w'
        endif
    endif

    " ウィンドウを画面の一番左に持って行き
    execute 'wincmd L'
    " サイズは横幅80桁に合わせる
    execute 'vertical resize 80'

    " 表示、及び各種設定
    execute 'silent edit ' . file_path

    " 次表示するときのためにバッファ名を保存
    let g:__perldoc__ = pod_name_with_hyphes
endfunction

let g:__perldoc__ = '__perldoc__'
command! -nargs=? Perldoc :call Perldoc('<args>')

pod2vim

pod2vim – ダウンロード
パスの通ったディレクトリに置く。

#!/usr/bin/perl
#    Modified: delphinus <delphinus@remora.cx>
#      Change: 30-Apr-2009.2009
# Last Change: 13-Feb-2010.2009

use strict;
use warnings;

use Pod::Find;
use Pod::Simple::Vim;

my $pod_name = shift; 
die ("Usage: pod2vim Module::Name_or_function") unless $pod_name;

my $pod_filename = Pod::Find::pod_where( {-inc => 1}, $pod_name );
my @pod;
# モジュール名が見つからなかったら関数を探す
unless ($pod_filename) {
    my @found_things = Pod::Find::pod_where( {-inc => 1}, "perlfunc" );
    &search_perlfaqs( \@found_things, \@pod, $pod_name );
    unshift @pod, "=over 8", "";
    push @pod, "=back";
}
die("No documentation found for \"$pod_name\"") unless $pod_filename or @pod;

my $parser = Pod::Simple::Vim->new;
my $perldoc;

$parser->output_string(\$perldoc);
$pod_filename ?
    $parser->parse_file( $pod_filename ):
    $parser->parse_lines( @pod, undef );

print $perldoc;

exit;

# Pod::Perldocから引用
sub search_perlfaqs {
    my ( $found_things, $pod, $search_key ) = @_;

    my $perlfunc = shift @$found_things;
    open(PFUNC, "<", $perlfunc)               # "Funk is its own reward"
        or die("Can't open $perlfunc: $!");

    # Functions like -r, -e, etc. are listed under `-X'.
    my $search_re = ($search_key =~ /^-[rwxoRWXOeszfdlpSbctugkTBMAC]$/)
                        ? '(?:I<)?-X' : quotemeta($search_key) ;

    my $re = 'Alphabetical Listing of Perl Functions';

    # Skip introduction
    local $_;
    while (<PFUNC>) {
        last if /^=head2 $re/;
    }

    # Look for our function
    my $found = 0;
    my $inlist = 0;
    while (<PFUNC>) {  # "The Mothership Connection is here!"
        if ( m/^=item\s+$search_re\b/ )  {
            $found = 1;
        }
        elsif (/^=item/) {
            last if $found > 1 and not $inlist;
        }
        next unless $found;
        if (/^=over/) {
            ++$inlist;
        }
        elsif (/^=back/) {
            --$inlist;
        }
        push @$pod, $_;
        ++$found if /^\w/;        # found descriptive text
    }
    close PFUNC                or die "Can't open $perlfunc: $!";

    return;
}

  1. ActivePerlのPPMではインストールできなかった。手作業でのインストールはまた別記事にでも書こう 

コメントを残す