pythonとvimで非常に鬱陶しいのは、シンタックスエラーが起きた時の処理です。
python-lintをかけるという手法もありますか…まぁそれはともかく。
テストの前段階で何度も何度もエディタとターミナルを往復する…
これはストレスです。
以前作っていたoredb.pyではこれを、gvimからデバッガ実行→エラー捕捉→呼び出したgvimにファイル名を送り、さらにキーストロークを送りつけてエラー箇所を表示 ということをやっていましたが、pudbがあまりにも出来が良かったために放置となりました。日本語回りは若干弱いですけどね…
そこで考えました。
もっとごくシンプルに、エラー出力を奪って解析して、gvimでリモートオープンしてキーコマンドもリモートで送り、エラーの場所に飛ばすだけのプログラムを作ったらどうだろうか?と。
そんなわけで作りました。synerrjump.pyです。
最初、標準エラー出力から入力しようとしたという笑えることをしてしまいましたがw
そして次に、sys.std系でエラー出力を得られそうにないので、うーむ?と思って
「シェルスクリプトを作ってそいつが 2&>1 (エラー出力も標準出力に出しちゃう指定) して 標準出力を読んでスクレイピングする」
という手法を思いつきました。
で、一旦完成までたどり着いて満足していたのですが、ハッと閃きが。
subprocessで呼んで、エラー出力を奪えばいいだけなのでは?
なんとまぁそのとおりですね。まったく遠回りで間抜けなことをしてしまいました。
そして作りなおしたのがこれです。
synerrjump.py
#!/usr/bin/env python # -*- coding: UTF-8 -*- import sys import re import os import subprocess def execute_prog(args): args.insert(0,'python') p = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False) p.wait() return p.stderr.readlines() def decode_input(gvim_name,all_lines): ro_info=re.compile('File\s\"(.+)\",\sline\s([0-9]+)') matched=None lastline='' for line in all_lines: mo=ro_info.search(line) if mo: matched=mo lastline=line if matched: fpath=os.path.abspath(matched.group(1)) linenum=matched.group(2) print('error is file %s,line %s' % (fpath,linenum)) cmds=['gvim','--remote',fpath] cmds_keystroke=['gvim','--remote-send',"%sG" % linenum] if gvim_name!=None: svrname_cmd=['--servername',gvim_name] cmds[1:1]=svrname_cmd cmds_keystroke[1:1]=svrname_cmd #print(cmds) #print(cmds_keystroke) subprocess.call(cmds) subprocess.call(cmds_keystroke) print lastline else: print('no error found') if __name__ == '__main__': import getopt try: opts,args=getopt.getopt(sys.argv[1:],"hn:",["help","vimname="]) except getopt.GetoptError,e: print(str(e)) gvim_name=None for cmd,arg in opts: if cmd=='-h' or cmd=='--help': print "help document" elif cmd=='-n' or cmd=='--vimname': gvim_name=arg else: pass decode_input(gvim_name,execute_prog(args))
毎度お粗末なコードでございますが…動けばよかろうなのだァァァァッ!
なお、どんなエラーなのかは最後の行に表示されるので、それも表示しています。
これを使ったら作業が捗ること、捗ること。きっと似たようなものが既に存在しているに違いありません。
pythonとvimで非常に鬱陶しいのは、シンタックスエラーが起きた時の処理です。
python-lintをかけるという手法もありますか…まぁそれはともかく。
テストの前段階で何度も何度もエディタとターミナルを往復する…
これはストレスです。
以前作っていたoredb.pyではこれを、gvimからデバッガ実行→エラー捕捉→呼び出したgvimにファイル名を送り、さらにキーストロークを送りつけてエラー箇所を表示 ということをやっていましたが、pudbがあまりにも出来が良かったために放置となりました。日本語回りは若干弱いですけどね…
そこで考えました。
もっとごくシンプルに、エラー出力を奪って解析して、gvimでリモートオープンしてキーコマンドもリモートで送り、エラーの場所に飛ばすだけのプログラムを作ったらどうだろうか?と。
そんなわけで作りました。synerrjump.pyです。
最初、標準エラー出力から入力しようとしたという笑えることをしてしまいましたがw
そして次に、sys.std系でエラー出力を得られそうにないので、うーむ?と思って
「シェルスクリプトを作ってそいつが 2&>1 (エラー出力も標準出力に出しちゃう指定) して 標準出力を読んでスクレイピングする」
という手法を思いつきました。
で、一旦完成までたどり着いて満足していたのですが、ハッと閃きが。
subprocessで呼んで、エラー出力を奪えばいいだけなのでは?
なんとまぁそのとおりですね。まったく遠回りで間抜けなことをしてしまいました。
そして作りなおしたのがこれです。
synerrjump.py
#!/usr/bin/env python # -*- coding: UTF-8 -*- import sys import re import os import subprocess def execute_prog(args): args.insert(0,'python') p = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False) p.wait() return p.stderr.readlines() def decode_input(gvim_name,all_lines): ro_info=re.compile('File\s\"(.+)\",\sline\s([0-9]+)') matched=None lastline='' for line in all_lines: mo=ro_info.search(line) if mo: matched=mo lastline=line if matched: fpath=os.path.abspath(matched.group(1)) linenum=matched.group(2) print('error is file %s,line %s' % (fpath,linenum)) cmds=['gvim','--remote',fpath] cmds_keystroke=['gvim','--remote-send',"%sG" % linenum] if gvim_name!=None: svrname_cmd=['--servername',gvim_name] cmds[1:1]=svrname_cmd cmds_keystroke[1:1]=svrname_cmd #print(cmds) #print(cmds_keystroke) subprocess.call(cmds) subprocess.call(cmds_keystroke) print lastline else: print('no error found') if __name__ == '__main__': import getopt try: opts,args=getopt.getopt(sys.argv[1:],"hn:",["help","vimname="]) except getopt.GetoptError,e: print(str(e)) gvim_name=None for cmd,arg in opts: if cmd=='-h' or cmd=='--help': print "help document" elif cmd=='-n' or cmd=='--vimname': gvim_name=arg else: pass decode_input(gvim_name,execute_prog(args))
毎度お粗末なコードでございますが…動けばよかろうなのだァァァァッ!
なお、どんなエラーなのかは最後の行に表示されるので、それも表示しています。
これを使ったら作業が捗ること、捗ること。きっと似たようなものが既に存在しているに違いありません。