Into the Horizon

programming, photography, and daily log

(SublimeText3) ST3でSublimeLinter(Perlの構文チェック)とPerlTidy(Perlのソース整形)

以下、かなり詰まったのでメモ。つらい。

SublimeLinter

SublimeLinterはコードの構文にエラーがあるとリアルタイムで表示してくれる必須ツール。ビルドしてみたらエラーになっちゃった…いや;忘れてた、ビルドし直し…ああここも忘れてる、なんて繰り返すのはアホらしいですよね。

もともとST2でpythonを書いてた頃にお世話になってましたが、ST2ではperlのlinterがなぜか上手く起動しなかったので、いいきっかけかなと思い最近ST3に乗り換えました。乗り換えたところ、基本的にはSublimeLinterも問題無く動いてくれていたのですが、ちょっと困った問題があったのでシェアします

自作のモジュールをuseした場合、useの部分がエラーになってしまう

ビルド時にコンパイルエラーになる問題は、Preferences -> Settings(Default) のbuild_envを設定することで解決できます 参考 。例えば以下。

"build_env":
    {
             "PATH": "/opt/local/bin/",  //Sublimeで実行されるPerlのバージョンとターミナルで実行されるバージョンが違うときは、実行しているPerlのパスが違うのでここで指定しましょう
              "PERL5LIB": "/Users/username/mylib/" //自作ライブラリはここで指定
    }

…が、どうやらここで指定したPERL5LIBはSublimeLinterの設定には引き継がれないようなのです。 単にuseがエラーになるだけならまあ無視できるんですが、useでエラーになるとそれ以降のコードをチェックしてくれないので、linterが機能してくれません。ということでこれを解決します。

とはいえ上手い解決策が思いつかなかったので、linterのソースコードを直接弄りましたw こういうとき、sublimepythonでわかりやすく書かれているのでどこに何をすればいいかが分かりやすくて好きです。 以下のパスのlinter.pyの36行目辺りに、以下のように書き足します。

#~/Sublime Text 3/Packages/SublimeLinter-contrib-perl/linter.py 
    def cmd(self):
        """
        Return the command line to execute.

        Overridden so we can add include paths based on the 'include_dirs'
        settings.

        """

        command = [self.executable_path, '-c']
        command.append('-I')
        command.append('include_path_hogehoge')

コメントにある通り、include_dirsを設定すれば良い気がするんですが…settingsに書き足しても上手く行きませんでした。どこに書けば良いんだろう? (sublimeソースコード見ること結構多いので、そろそろプラグインの書き方を学んだ方が手っ取り早い気がする…。)

ちゃんとした解決方法をご存知の方、教えて頂ければ幸いです。

  • ※2014/11/24追記 include_dirsは、SublimeLinterのsettingsの"user"->"linters"->"perl" の中みたいですね。気づいてみれば最初に気づくべきことでしたが、なんか分かりづらいなあ…

PerlTidy

Linterは構文チェックでしたが、Tidyはperlソースコードを綺麗に整形してくれるプラグイン。コードの整形に時間を使うのもまた無駄なので、このツールもまた必須ですね(そして、整形されたコードを普段から見てると、整形の必要がないコードを書く癖がついてくると思ってます)。 使用には別途perltidyというコマンドラインツールが必要。

普通はcpanm Perl::Tidyすればperltidyが入るっぽいんですが、binがついてこなかったので(? これ、よくわかってないです)、Makefile.PLをどっかからダウンロードしてきて手動でmakeしました。 そこまではよかったんですが、コマンドラインperltidyと打つとCan't locate Perl/Tidy.pm in @INC とのメッセージ。これはパスが通ってないためなので、PERL5LIB=/opt/local/hoge perltidy とやれば、コマンドラインではとりあえず動くようになるんですが…

問題はこの設定をST3のPerlTidyでどう反映させるのかということ。例のごとく、build_envに設定しても反映されません。envとして設定すれば良い、みたいな記事を読んだんですがそれも無駄…。

色々試しても尽く駄目で、結局ソースファイルを弄って、pythonがsubprocessするときに環境変数を渡して上手くいきました。(subprocess使ってることが分かった時点で即これ気づけばよかった…アホだった…)

# ~/Sublime Text 3/Packages/PerlTidy/perltidy/helpers.py
# run_perltidy関数の、subprocess_argsを書き換える
subprocess_args = {
        'bufsize': -1,
        'shell': False,
        'stdin': subprocess.PIPE,
        'stdout': subprocess.PIPE,
        'stderr': subprocess.PIPE,
        'env': {"PERL5LIB":"/opt/local/lib/perl5/site_perl/5.16.3/..."}
    }

helpers.pyを直接弄った…という体で書きましたが、PerlTidyCommand.pyがhelpers.pyをなんかうまく読み込んでくれなかったので(どこ読み込んでるんだろう?)、PerlTidyCommand.pyという大本のファイルにrun_perltidy関数だけコピペして関数名renameして使いました。

ついでに、perltidyに与える引数は、同じ関数内の適当な位置でcmd_finalを書き換えました。

cmd_final.append('-l=78')   #1行の長さを78文字に

これでとりあえず動くようになりました。 色々分かってないままとりあえず動かしたのは、知識と時間が足りなかったためです………。今後暇あったら解決します。 割と時間使ってしまったけれど、PerlTidyめっちゃ便利。頑張ってよかった

追記
  1. 同期はあまり詰まらず入れていた。cpanmで入れたperltidyならこんな面倒なことしなくていいっぽい……(そして自分はcpanmではいるbinファイルの所在の在処をわかってなかっただけっぽいorz