mooeditでperlのctagを置き換える

mooeditエディターには、ソース名を表示するためのプラグインがあります。 彼は標準のctagsを使用していますが、これは控えめに言うとPerlでは機能しません。 ctagsは関数名のみを検出しますが、もっと欲しいです:









最初に、Perlのctags呼び出しがどのように発生するかを確認し、この場合にユーティリティを置き換える方法について考えてみましょう。 moo / plugins / ctags / ctags-doc.cを見ると、この場合の呼び出しは次のようになっていることが明らかになります。



ctags -u --fields=afksS --excmd=number -f '_' '  '
      
      







これがPerlであることを明示的に示すものはありません。 したがって、 ファイルユーティリティを使用して状況をキャッチします。 システムのctagsの代わりに呼び出される〜/ bin / ctagsファイルを作成します。



 #!/bin/bash FILE=`file $6 2>&1` RX='Perl.*' if [[ "$FILE" =~ $RX ]] ; then ~/bin/perltags $6 > $5 else /usr/bin/ctags "$@" fi
      
      







ここで〜/ bin / perltagsがどうなるかを考える必要があります 。 原則として、 vimユーザーはpltagsおよびperltagsユーティリティに精通していますが 、私にはまったく満足しませんでした。 CPANはperl-tagsユーティリティを見つけました。 ただし、 mooeditで使用するには、ファイルで変更する必要があるため、(はい、そしてただの楽しみのために) 独自のを作成することにしました。



まず、形式を把握しましょう。 ctagsを開始すると、エディターは次の行を予期します。



   _;" kind
      
      







kind (giblets mooeditの用語では)は名前のタイプです( fは関数、 vは変数など)。



行番号の末尾に2つの文字が追加されました( ; " )-これはタイプミスではなく、エディターがクラッシュするだけです(明らかに、-- excmd = numberの後の欠陥)。



これですべてです。次に、解析対象を正確に理解する必要があります。 ソースコードをあまり深く分析する必要はありませんが、ソースコードを手に取るのは決して面倒ではありません。 したがって、 PPIを取得し、しばらくしてから表示されます
そのようなスクリプトは次のとおりです。
 #!/usr/bin/perl # ------------------------------------------------------------------------------ use 5.010; use strict; use PPI; my %variables; my %scheduled; my %subs; # ------------------------------------------------------------------------------ die "Usage: $0 file\n" unless $ARGV[0]; my $doc = PPI::Document->new( $ARGV[0] ); die "'$ARGV[0]', PPI::Document error!\n" unless $doc; # ------------------------------------------------------------------------------ my @tokens = $doc->children; foreach my $token ( @tokens ) { given ( $token->class ) { process_statement( $token ) when 'PPI::Statement'; process_variable( $token ) when 'PPI::Statement::Variable'; process_sub( $token ) when 'PPI::Statement::Sub'; process_scheduled( $token ) when 'PPI::Statement::Scheduled'; } } print_names( \%variables, 'v' ); print_names( \%subs, 'f' ); print_names( \%scheduled, 'p' ); # ------------------------------------------------------------------------------ sub add_name { my ( $list, $token, $content ) = @_; # $content    ,    -, ,    my $name = $token->content; $list->{$name} = () unless exists $list->{$name}; $list->{$name}->{ $token->line_number } = $content; } # ------------------------------------------------------------------------------ sub print_names { my ( $list, $type ) = @_; foreach my $name ( sort { my $an = $a =~ /^[\$\%\@](.+)$/ ? $1 : $a; my $bn = $b =~ /^[\$\%\@](.+)$/ ? $1 : $b; lc $an cmp lc $bn; } keys $list ) { foreach my $line ( sort { $a <=> $b } keys $list->{$name} ) { print "$name:$line\t$ARGV[0]\t$line;\"\t$type\n"; } } } # ------------------------------------------------------------------------------ # @EXPORT = qw(aaa), @EXPORT_OK = qw(bbb); # ------------------------------------------------------------------------------ sub process_statement { my ( $tok ) = @_; my @tokens = $tok->children; return unless $#tokens > 0; foreach my $token ( @tokens ) { add_name( \%variables, $token, $tok->content ) if $token->class eq 'PPI::Token::Symbol'; } } # ------------------------------------------------------------------------------ # sub aaa($$$); # sub aaa{}; # ------------------------------------------------------------------------------ sub process_sub { my ( $tok ) = @_; my @tokens = $tok->children; return unless $#tokens > 1; shift @tokens; foreach my $token ( @tokens ) { next if $token->class eq 'PPI::Token::Whitespace' or $token->class eq 'PPI::Token::Comment' or $token->class eq 'PPI::Token::Pod'; #     'sub'   PPI::Token::Word: return unless $token->class eq 'PPI::Token::Word'; add_name( \%subs, $token, $tok->content ); last; } } # ------------------------------------------------------------------------------ # my $aaa; # our ($aaa, $bbb); # ------------------------------------------------------------------------------ sub process_variable { my ( $tok ) = @_; my @tokens = $tok->children; foreach my $token ( @tokens ) { #    -   : process_variable( $token ), next if $token->class eq 'PPI::Structure::List'; process_variable( $token ), next if $token->class eq 'PPI::Statement::Expression'; add_name( \%variables, $token, $tok->content ) if $token->class eq 'PPI::Token::Symbol'; } } # ------------------------------------------------------------------------------ # BEGIN {}; CHECK, UNITCHECK, INIT, END # ------------------------------------------------------------------------------ sub process_scheduled { my ( $tok ) = @_; my @tokens = $tok->children; return unless $#tokens > 0; add_name( \%scheduled, $tokens[0], $tok->content ); } # ------------------------------------------------------------------------------
      
      







彼にできること:



各名前には、見つかった行の番号(向き)が追加され、プラグインウィンドウから、最初のラベルだけでなく、ラベルのすべての出現箇所を確認できます。 さらに、関数、変数、およびブロックは一般的なリストには含まれませんが、グループ化されます。










All Articles