タオルケット体操

サツバツいんたーねっとでゲームとかガジェットのレビューとかをします

Pythonのローカル変数をシンタクスハイライトするVimプラグインを書きはじめた

Sponsored link

ネタ元

Rubyのローカル変数をシンタクスハイライトするVimプラグインを書いた - TODESKING

gifzo

hachibeeDI/python_hl_lvar.vim · GitHub

まだめっちゃ微妙!

とりあえずカーソルがある関数のみハイライトしてるけど、単にsyntaxを指定しているだけなので関係ないやつも同じ名前ならハイライトされちゃったりとかする。
場所込みで指定するのってどうどうやるんや……matchaddとかで調べるのか

ネタ元だとかなり細かくシンタックスしてるけど、実装的にも動作的にも重たいとつらそうなので、とりあえず今のところは名前を引っ張ってきて正規表現で指定してるだけですごめんなさい。

しくみ

astという構文解析モジュールを使って、引数とローカル変数への代入をひっぱってる

python << EOF
import sys
import ast
from itertools import takewhile

def extract_assignment(funcdef_lines):
    if not func_def_lines:
      return []
    tabspace = len(list(takewhile(lambda x: x == ' ', func_def_lines[0])))
    func_definition = '\n'.join([line[tabspace:] for line in func_def_lines])
    definition_node = ast.walk(ast.parse(func_definition, mode='single').body[0])
    next(definition_node)
    result = []
    result_add = result.extend
    for z in definition_node:
        if isinstance(z, ast.arguments):
            v = [getattr(a, 'id', None) for a in z.args]
            result_add(filter(bool, v))
        if isinstance(z, ast.Assign):
            v = [getattr(v, 'id', None) for v in z.targets]
            result_add(filter(bool, v))
    return result


try:
  func_def_lines = vim.eval('l:funcdef')
  assignments = extract_assignment(func_def_lines)
  vim.command('let result = "{0}"'.format(' '.join(assignments)))
except Exception as e:
  # TODO: debug part
  print e
EOF

現状のVim力があまりに低すぎて、ソースがコピペとかアレとかが色々とアレなのでアレする必要がある。