Add a script that auto-generates a Vim syntax highlighting file for Python.

Just symlink or copy python.vim to ~/.vim/syntax/ .  Also included is a sample
Python file with basic expressions to make sure they are highlighted.

Also add a Vim directory in Misc to hold all Vim configuration files.
This commit is contained in:
Brett Cannon 2006-02-25 14:52:53 +00:00
parent d074beb692
commit a4fe18227d
3 changed files with 413 additions and 0 deletions

145
Misc/Vim/python.vim Normal file
View File

@ -0,0 +1,145 @@
" Auto-generated Vim syntax file for Python
"
" To use: copy or symlink to ~/.vim/syntax/python.vim
if exists("b:current_syntax")
finish
endif
if exists("python_highlight_all")
let python_highlight_numbers = 1
let python_highlight_builtins = 1
let python_highlight_exceptions = 1
let python_highlight_space_errors = 1
endif
syn keyword pythonStatement assert break continue del except exec finally
syn keyword pythonStatement global lambda pass print raise return try yield
syn keyword pythonStatement def class nextgroup=pythonFunction skipwhite
syn match pythonFunction "[a-zA-Z_][a-zA-Z0-9_]*" contained
syn keyword pythonRepeat for while
syn keyword pythonConditional if elif else
syn keyword pythonOperator and in is not or
syn keyword pythonPreCondit import from
syn match pythonComment "#.*$" contains=pythonTodo
syn keyword pythonTodo TODO FIXME XXX contained
syn region pythonString matchgroup=Normal start=+[uU]\='+ end=+'+ skip=+\\\\\|\\'+ contains=pythonEscape
syn region pythonString matchgroup=Normal start=+[uU]\="+ end=+"+ skip=+\\\\\|\\"+ contains=pythonEscape
syn region pythonString matchgroup=Normal start=+[uU]\="""+ end=+"""+ contains=pythonEscape
syn region pythonString matchgroup=Normal start=+[uU]\='''+ end=+'''+ contains=pythonEscape
syn region pythonString matchgroup=Normal start=+[uU]\=[rR]'+ end=+'+ skip=+\\\\\|\\'+
syn region pythonString matchgroup=Normal start=+[uU]\=[rR]"+ end=+"+ skip=+\\\\\|\\"+
syn region pythonString matchgroup=Normal start=+[uU]\=[rR]"""+ end=+"""+
syn region pythonString matchgroup=Normal start=+[uU]\=[rR]'''+ end=+'''+
syn match pythonEscape +\\[abfnrtv\'"\\]+ contained
syn match pythonEscape "\\\o\{1,3}" contained
syn match pythonEscape "\\x\x\{2}" contained
syn match pythonEscape "\(\\u\x\{4}\|\\U\x\{8}\)" contained
syn match pythonEscape "\\$"
if exists("python_highlight_numbers")
syn match pythonNumber "\<0x\x\+[Ll]\=\>"
syn match pythonNumber "\<\d\+[LljJ]\=\>"
syn match pythonNumber "\.\d\+\([eE][+-]\=\d\+\)\=[jJ]\=\>"
syn match pythonNumber "\<\d\+\.\([eE][+-]\=\d\+\)\=[jJ]\=\>"
syn match pythonNumber "\<\d\+\.\d\+\([eE][+-]\=\d\+\)\=[jJ]\=\>"
endif
if exists("python_highlight_builtins")
syn keyword pythonBuiltin unichr all set abs vars int __import__ unicode
syn keyword pythonBuiltin enumerate reduce coerce intern exit issubclass
syn keyword pythonBuiltin divmod file Ellipsis apply isinstance open any
syn keyword pythonBuiltin locals help filter basestring slice copyright min
syn keyword pythonBuiltin super sum tuple hex execfile long id xrange chr
syn keyword pythonBuiltin complex bool zip pow dict True oct NotImplemented
syn keyword pythonBuiltin map None float hash getattr buffer max reversed
syn keyword pythonBuiltin object quit len repr callable credits setattr
syn keyword pythonBuiltin eval frozenset sorted ord __debug__ hasattr
syn keyword pythonBuiltin delattr False input license classmethod type
syn keyword pythonBuiltin raw_input list iter compile reload range globals
syn keyword pythonBuiltin staticmethod str property round dir cmp
endif
if exists("python_highlight_exceptions")
syn keyword pythonException GeneratorExit ImportError RuntimeError
syn keyword pythonException UnicodeTranslateError MemoryError StopIteration
syn keyword pythonException PendingDeprecationWarning EnvironmentError
syn keyword pythonException LookupError OSError DeprecationWarning
syn keyword pythonException UnicodeError FloatingPointError ReferenceError
syn keyword pythonException NameError OverflowWarning IOError SyntaxError
syn keyword pythonException FutureWarning SystemExit Exception EOFError
syn keyword pythonException StandardError ValueError TabError KeyError
syn keyword pythonException ZeroDivisionError SystemError
syn keyword pythonException UnicodeDecodeError IndentationError
syn keyword pythonException AssertionError TypeError IndexError
syn keyword pythonException RuntimeWarning KeyboardInterrupt UserWarning
syn keyword pythonException SyntaxWarning UnboundLocalError ArithmeticError
syn keyword pythonException Warning NotImplementedError AttributeError
syn keyword pythonException OverflowError UnicodeEncodeError
endif
if exists("python_highlight_space_errors")
syn match pythonSpaceError display excludenl "\S\s\+$"ms=s+1
syn match pythonSpaceError display " \+\t"
syn match pythonSpaceError display "\t\+ "
endif
hi def link pythonStatement Statement
hi def link pythonStatement Statement
hi def link pythonFunction Function
hi def link pythonRepeat Repeat
hi def link pythonConditional Conditional
hi def link pythonOperator Operator
hi def link pythonPreCondit PreCondit
hi def link pythonComment Comment
hi def link pythonTodo Todo
hi def link pythonString String
hi def link pythonEscape Special
hi def link pythonEscape Special
if exists("python_highlight_numbers")
hi def link pythonNumber Number
endif
if exists("python_highlight_builtins")
hi def link pythonBuiltin Function
endif
if exists("python_highlight_exceptions")
hi def link pythonException Exception
endif
if exists("python_highlight_space_errors")
hi def link pythonSpaceError Error
endif
" Uncomment the 'minlines' statement line and comment out the 'maxlines'
" statement line; changes behaviour to look at least 2000 lines previously for
" syntax matches instead of at most 200 lines
syn sync match pythonSync grouphere NONE "):$"
syn sync maxlines=200
"syn sync minlines=2000
let b:current_syntax = "python"

36
Misc/Vim/syntax_test.py Normal file
View File

@ -0,0 +1,36 @@
"""Test file for syntax highlighting of editors.
Meant to cover a wide range of different types of statements and expressions.
Not necessarily sensical.
"""
assert True
def foo(): pass
foo() # Uncoloured
while False: pass
1 and 2
if False: pass
from sys import path
# Comment
# XXX catch your attention
'single-quote', u'unicode'
"double-quote"
"""triple double-quote"""
'''triple single-quote'''
r'raw'
ur'unicode raw'
'escape\n'
'\04' # octal
'\xFF' # hex
'\u1111' # unicode character
1
1L
1.0
.1
1+2j
[] # Uncoloured
{} # Uncoloured
() # Uncoloured
all
GeneratorExit
trailing_whitespace = path

232
Misc/Vim/vim_syntax.py Normal file
View File

@ -0,0 +1,232 @@
import keyword
import exceptions
import __builtin__
from string import Template
comment_header = """" Auto-generated Vim syntax file for Python
"
" To use: copy or symlink to ~/.vim/syntax/python.vim"""
statement_header = """
if exists("b:current_syntax")
finish
endif"""
statement_footer = '''
" Uncomment the 'minlines' statement line and comment out the 'maxlines'
" statement line; changes behaviour to look at least 2000 lines previously for
" syntax matches instead of at most 200 lines
syn sync match pythonSync grouphere NONE "):$"
syn sync maxlines=200
"syn sync minlines=2000
let b:current_syntax = "python"'''
looping = ('for', 'while')
conditionals = ('if', 'elif', 'else')
boolean_ops = ('and', 'in', 'is', 'not', 'or')
import_stmts = ('import', 'from')
object_defs = ('def', 'class')
exception_names = frozenset(exc for exc in dir(exceptions)
if not exc.startswith('__'))
# Need to include functions that start with '__' (e.g., __import__), but
# nothing that comes with modules (e.g., __name__), so just exclude anything in
# the 'exceptions' module since we want to ignore exceptions *and* what any
# module would have
builtin_names = frozenset(builtin for builtin in dir(__builtin__)
if builtin not in dir(exceptions))
escapes = (r'+\\[abfnrtv\'"\\]+', r'"\\\o\{1,3}"', r'"\\x\x\{2}"',
r'"\(\\u\x\{4}\|\\U\x\{8}\)"', r'"\\$"')
todos = ("TODO", "FIXME", "XXX")
# XXX codify?
numbers = (r'"\<0x\x\+[Ll]\=\>"', r'"\<\d\+[LljJ]\=\>"',
'"\.\d\+\([eE][+-]\=\d\+\)\=[jJ]\=\>"',
'"\<\d\+\.\([eE][+-]\=\d\+\)\=[jJ]\=\>"',
'"\<\d\+\.\d\+\([eE][+-]\=\d\+\)\=[jJ]\=\>"')
contained = lambda x: "%s contained" % x
def str_regexes():
"""Generator to yield various combinations of strings regexes"""
regex_template = Template('matchgroup=Normal ' +
'start=+[uU]\=${raw}${sep}+ ' +
'end=+${sep}+ ' +
'${skip} ' +
'${contains}')
skip_regex = Template(r'skip=+\\\\\|\\${sep}+')
for raw in ('', '[rR]'):
for separator in ("'", '"', '"""', "'''"):
if len(separator) == 1:
skip = skip_regex.substitute(sep=separator)
else:
skip = ''
if not raw:
contains = 'contains=pythonEscape'
else:
contains = ''
yield regex_template.substitute(raw=raw, sep=separator, skip=skip,
contains = contains)
space_errors = (r'excludenl "\S\s\+$"ms=s+1', r'" \+\t"', r'"\t\+ "')
statements = (
('',
# XXX Might need to change pythonStatement since have
# specific Repeat, Conditional, Operator, etc. for 'while',
# etc.
[("Statement", "pythonStatement", "keyword",
(kw for kw in keyword.kwlist
if kw not in (looping + conditionals + boolean_ops +
import_stmts + object_defs))
),
("Statement", "pythonStatement", "keyword",
(' '.join(object_defs) +
' nextgroup=pythonFunction skipwhite')),
("Function","pythonFunction", "match",
contained('"[a-zA-Z_][a-zA-Z0-9_]*"')),
("Repeat", "pythonRepeat", "keyword", looping),
("Conditional", "pythonConditional", "keyword",
conditionals),
("Operator", "pythonOperator", "keyword", boolean_ops),
("PreCondit", "pythonPreCondit", "keyword", import_stmts),
("Comment", "pythonComment", "match",
'"#.*$" contains=pythonTodo'),
("Todo", "pythonTodo", "keyword",
contained(' '.join(todos))),
("String", "pythonString", "region", str_regexes()),
("Special", "pythonEscape", "match",
(contained(esc) for esc in escapes
if not '$' in esc)),
("Special", "pythonEscape", "match", r'"\\$"'),
]
),
("python_highlight_numbers",
[("Number", "pythonNumber", "match", numbers)]
),
("python_highlight_builtins",
[("Function", "pythonBuiltin", "keyword", builtin_names)]
),
("python_highlight_exceptions",
[("Exception", "pythonException", "keyword",
exception_names)]
),
("python_highlight_space_errors",
[("Error", "pythonSpaceError", "match",
("display " + err for err in space_errors))]
)
)
def syn_prefix(type_, kind):
return 'syn %s %s ' % (type_, kind)
def fill_stmt(iterable, fill_len):
"""Yield a string that fills at most fill_len characters with strings
returned by 'iterable' and separated by a space"""
# Deal with trailing char to handle ' '.join() calculation
fill_len += 1
overflow = None
it = iter(iterable)
while True:
buffer_ = []
total_len = 0
if overflow:
buffer_.append(overflow)
total_len += len(overflow) + 1
overflow = None
while total_len < fill_len:
try:
new_item = it.next()
buffer_.append(new_item)
total_len += len(new_item) + 1
except StopIteration:
if buffer_:
break
if not buffer_ and overflow:
yield buffer_
return
else:
return
if total_len > fill_len:
overflow = buffer_.pop()
total_len -= len(overflow) - 1
ret = ' '.join(buffer_)
assert len(ret) <= fill_len
yield ret
FILL = 80
def main(file_path):
FILE = open(file_path, 'w')
try:
# Comment for file
print>>FILE, comment_header
print>>FILE, ''
# Statements at start of file
print>>FILE, statement_header
print>>FILE, ''
# Generate case for python_highlight_all
print>>FILE, 'if exists("python_highlight_all")'
for statement_var, statement_parts in statements:
if statement_var:
print>>FILE, ' let %s = 1' % statement_var
else:
print>>FILE, 'endif'
print>>FILE, ''
# Generate Python groups
for statement_var, statement_parts in statements:
if statement_var:
print>>FILE, 'if exists("%s")' % statement_var
indent = ' '
else:
indent = ''
for colour_group, group, type_, arguments in statement_parts:
if not isinstance(arguments, basestring):
prefix = syn_prefix(type_, group)
if type_ == 'keyword':
stmt_iter = fill_stmt(arguments,
FILL - len(prefix) - len(indent))
try:
while True:
print>>FILE, indent + prefix + stmt_iter.next()
except StopIteration:
print>>FILE, ''
else:
for argument in arguments:
print>>FILE, indent + prefix + argument
else:
print>>FILE, ''
else:
print>>FILE, indent + syn_prefix(type_, group) + arguments
print>>FILE, ''
else:
if statement_var:
print>>FILE, 'endif'
print>>FILE, ''
print>>FILE, ''
# Associating Python group with Vim colour group
for statement_var, statement_parts in statements:
if statement_var:
print>>FILE, ' if exists("%s")' % statement_var
indent = ' '
else:
indent = ' '
for colour_group, group, type_, arguments in statement_parts:
print>>FILE, (indent + "hi def link %s %s" %
(group, colour_group))
else:
if statement_var:
print>>FILE, ' endif'
print>>FILE, ''
# Statements at the end of the file
print>>FILE, statement_footer
finally:
FILE.close()
if __name__ == '__main__':
main("python.vim")