From 9abe34873b1ea7c5fcc0bad20b311d85b04fc648 Mon Sep 17 00:00:00 2001 From: Peter Odding Date: Tue, 14 Jun 2011 06:43:24 +0200 Subject: 2x faster syntax highlighting using Python Interface to Vim :-) --- misc/easytags/highlight.py | 55 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 misc/easytags/highlight.py (limited to 'misc/easytags/highlight.py') diff --git a/misc/easytags/highlight.py b/misc/easytags/highlight.py new file mode 100644 index 0000000..b7a9cf3 --- /dev/null +++ b/misc/easytags/highlight.py @@ -0,0 +1,55 @@ +''' +This Python script is part of the easytags plug-in for the Vim text editor. The +Python Interface to Vim is used to load this script which accelerates dynamic +syntax highlighting by reimplementing tag file reading and :syntax command +generation in Python with a focus on doing the least amount of work. + +Author: Peter Odding +Last Change: June 14, 2011 +URL: http://peterodding.com/code/vim/easytags +''' + +# TODO Cache the contents of tags files to further improve performance? + +import re +import vim +import sys + +def easytags_ping(): + print 'it works!' + +def easytags_gensyncmd(tagsfiles, filetype, tagkinds, syntaxgroup, prefix, suffix, filters): + # Get arguments from Vim. + if filters: + tagkinds = filters['kind'] + # Shallow parse tags files for matching identifiers. + pattern = '^([^\t]+)\t[^\t]+\t[^\t]+\t' + tagkinds + '\tlanguage:' + filetype + compiled_pattern = re.compile(pattern, re.IGNORECASE) + matches = {} + for fname in tagsfiles: + handle = open(fname) + for line in handle: + m = compiled_pattern.match(line) + if m and ('match' not in filters or re.search(filters['match'], line)) \ + and ('nomatch' not in filters or not re.search(filters['nomatch'], line)): + matches[m.group(1)] = True + handle.close() + # Generate Vim :syntax command to highlight identifiers. + patterns, commands = [], [] + counter, limit = 0, 1024 * 20 + to_escape = re.compile(r'[.*^$/\\~\[\]]') + for ident in matches.keys(): + escaped = to_escape.sub(r'\\\0', ident) + patterns.append(escaped) + counter += len(escaped) + if counter > limit: + commands.append(_easytags_makecmd(syntaxgroup, prefix, suffix, patterns)) + patterns = [] + counter = 0 + if patterns: + commands.append(_easytags_makecmd(syntaxgroup, prefix, suffix, patterns)) + return ' | '.join(commands) + +def _easytags_makecmd(syntaxgroup, prefix, suffix, patterns): + template = r'syntax match %s /%s\%%(%s\)%s/ containedin=ALLBUT,.*String.*,.*Comment.*,cIncluded' + return template % (syntaxgroup, prefix, r'\|'.join(patterns), suffix) -- cgit v1.2.3