diff --git a/clavim.py b/clavim.py index 1f28447..6fae895 100755 --- a/clavim.py +++ b/clavim.py @@ -13,25 +13,24 @@ import clang.cindex import vim + def clavim_init(): + sys.argv[0] = '' + sys.path.append(vim.eval('s:plugin_path')) global index index = clang.cindex.Index.create() global translationUnits - translationUnits = dict() - global update - update = False + translationUnits = {} def get_current_file(): file = "\n".join(vim.eval("getline(1, '$')")) return (vim.current.buffer.name, file) -def get_current_translation_unit(update = False): - current_file = get_current_file() +def get_current_translation_unit(current_file): filename = vim.current.buffer.name if filename in translationUnits: tu = translationUnits[filename] - if update: - tu.reparse([current_file]) + tu.reparse([current_file]) return tu tu = index.parse(filename) @@ -41,40 +40,57 @@ def get_current_translation_unit(update = False): return None translationUnits[filename] = tu - tu.reparse([current_file]) return tu -def cursorvisit_callback(node, parent, userdata): - if node.kind == userdata['kind']: - if node.extent.start.file is None: - return 2 - lib = clang.cindex.conf.lib - - my_node = dict() - my_node['name'] = lib.clang_getCursorDisplayName(node) - my_node['kind'] = node.kind.name - my_node['file'] = node.extent.start.file.name - my_node['line'] = node.location.line - my_node['start'] = node.extent.start.column - my_node['end'] = node.extent.end.column - userdata['nodes'].append(my_node) +def cursorvisit_callback(node, parent, data): + f = node.extent.start.file + lib = clang.cindex.conf.lib + if node.kind != data['kind']: + return 2 + if f is None: + return 2 + + converted_node = { + 'name': lib.clang_getCursorDisplayName(node), + 'kind': node.kind.name, + 'file': f.name, + 'line': node.location.line, + 'start': node.extent.start.column, + 'end': node.extent.end.column, + } + data['nodes'].append(converted_node) return 2 def find_cursors(tu, kind): - nodes = [] - userdata = dict() - - userdata['nodes'] = nodes - userdata['kind'] = kind + callback_data = { + 'nodes': [], + 'kind': kind, + } # visit children clang.cindex.conf.lib.clang_visitChildren( tu.cursor, clang.cindex.callbacks['cursor_visit'](cursorvisit_callback), - userdata) + callback_data + ) + + return callback_data['nodes'] + +def highlight_expressions(): + global cursors + # find all clang cursors + tu = get_current_translation_unit(get_current_file) + MEMBER_REF_EXPR = clang.cindex.CursorKind.MEMBER_REF_EXPR + cursors = find_cursors(tu, MEMBER_REF_EXPR) + + keys = 'line start end'.split() + syn_match = r"syn match clavimMember /\%%%sl\%%%sc.*\%%%sc/" + for x in cursors: + if x['file'] == vim.current.buffer.name: + t = tuple(str(x[k]) for k in keys) + vim.command(syn_match % t) - return nodes def main(): index = clang.cindex.Index.create() @@ -84,11 +100,8 @@ def main(): nodes = find_cursors(tu, kind) print 'nodes (%s):' % (len(nodes)) + keys = 'name kind file line start end'.split() + template = ' '.join(['%1s = %%(%1s)s' % k for k in keys]) for x in nodes: - print 'name=%s kind=%s file=%s line=%s start=%s end=%s' % ( - x['name'], - x['kind'], - x['file'], - x['line'], - x['start'], - x['end']) + print template % x + diff --git a/clavim.vim b/clavim.vim index 632b56d..3fcad82 100644 --- a/clavim.vim +++ b/clavim.vim @@ -6,9 +6,6 @@ hi clavimMember ctermbg=Cyan ctermfg=Black guibg=#8CCBEA guifg=Black hi clavimError ctermbg=Red ctermfg=Black guibg=Red guifg=Black function! s:ClavimInit() - python import sys - python sys.argv[0] = '' - exe 'python sys.path = ["' . s:plugin_path . '"] + sys.path' exe 'pyfile ' . s:plugin_path . '/clavim.py' set ut=100 " the time in milliseconds after a keystroke when you want to reparse the AST python clavim_init() @@ -18,29 +15,10 @@ function! s:ClavimInit() endfunction function! s:ClavimHighlightMemberExpressions() -python << endpython -global update -global cursors - -if update: - vim.command("syn clear clavimMember") - -cursors = find_cursors(get_current_translation_unit(update), clang.cindex.CursorKind.MEMBER_REF_EXPR) -keys = 'line start end'.split() -for x in cursors: - t = tuple(str(x[k]) for k in keys) - if x['file'] == vim.current.buffer.name: - vim.command(r"syn match clavimMember /\%%%sl\%%%sc.*\%%%sc/" % t) - -update = True - -endpython - + call ClavimClearHighlights() + python highlight_expressions() endfunction function! s:ClavimClearHighlights() -python << endpython - global cursors - vim.command("syn clear clavimMember") -endpython + syn clear clavimMember endfunction