symbian-qemu-0.9.1-12/python-2.6.1/Misc/Vim/vim_syntax.py
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 from __future__ import with_statement
       
     2 
       
     3 import keyword
       
     4 import exceptions
       
     5 import __builtin__
       
     6 from string import Template
       
     7 from sys import subversion
       
     8 
       
     9 comment_header = '''" Auto-generated Vim syntax file for Python (%s: r%s).
       
    10 "
       
    11 " To use: copy or symlink to ~/.vim/syntax/python.vim'''
       
    12 
       
    13 statement_header = """
       
    14 if exists("b:current_syntax")
       
    15   finish
       
    16 endif"""
       
    17 
       
    18 statement_footer = '''
       
    19 " Uncomment the 'minlines' statement line and comment out the 'maxlines'
       
    20 " statement line; changes behaviour to look at least 2000 lines previously for
       
    21 " syntax matches instead of at most 200 lines
       
    22 syn sync match pythonSync grouphere NONE "):$"
       
    23 syn sync maxlines=200
       
    24 "syn sync minlines=2000
       
    25 
       
    26 let b:current_syntax = "python"'''
       
    27 
       
    28 looping = ('for', 'while')
       
    29 conditionals = ('if', 'elif', 'else')
       
    30 boolean_ops = ('and', 'in', 'is', 'not', 'or')
       
    31 import_stmts = ('import', 'from')
       
    32 object_defs = ('def', 'class')
       
    33 
       
    34 exception_names = sorted(exc for exc in dir(exceptions)
       
    35                                 if not exc.startswith('__'))
       
    36 
       
    37 # Need to include functions that start with '__' (e.g., __import__), but
       
    38 # nothing that comes with modules (e.g., __name__), so just exclude anything in
       
    39 # the 'exceptions' module since we want to ignore exceptions *and* what any
       
    40 # module would have
       
    41 builtin_names = sorted(builtin for builtin in dir(__builtin__)
       
    42                             if builtin not in dir(exceptions))
       
    43 
       
    44 escapes = (r'+\\[abfnrtv\'"\\]+', r'"\\\o\{1,3}"', r'"\\x\x\{2}"',
       
    45             r'"\(\\u\x\{4}\|\\U\x\{8}\)"', r'"\\$"')
       
    46 
       
    47 todos = ("TODO", "FIXME", "XXX")
       
    48 
       
    49 # XXX codify?
       
    50 numbers = (r'"\<0x\x\+[Ll]\=\>"', r'"\<\d\+[LljJ]\=\>"',
       
    51             '"\.\d\+\([eE][+-]\=\d\+\)\=[jJ]\=\>"',
       
    52             '"\<\d\+\.\([eE][+-]\=\d\+\)\=[jJ]\=\>"',
       
    53             '"\<\d\+\.\d\+\([eE][+-]\=\d\+\)\=[jJ]\=\>"')
       
    54 
       
    55 contained = lambda x: "%s contained" % x
       
    56 
       
    57 def str_regexes():
       
    58     """Generator to yield various combinations of strings regexes"""
       
    59     regex_template = Template('matchgroup=Normal ' +
       
    60                                 'start=+[uU]\=${raw}${sep}+ ' +
       
    61                                 'end=+${sep}+ ' +
       
    62                                 '${skip} ' +
       
    63                                 '${contains}')
       
    64     skip_regex = Template(r'skip=+\\\\\|\\${sep}+')
       
    65     for raw in ('', '[rR]'):
       
    66         for separator in ("'", '"', '"""', "'''"):
       
    67             if len(separator) == 1:
       
    68                 skip = skip_regex.substitute(sep=separator)
       
    69             else:
       
    70                 skip = ''
       
    71             contains = 'contains=pythonEscape' if not raw else ''
       
    72             yield regex_template.substitute(raw=raw, sep=separator, skip=skip,
       
    73                                             contains = contains)
       
    74 
       
    75 space_errors = (r'excludenl "\S\s\+$"ms=s+1', r'" \+\t"', r'"\t\+ "')
       
    76 
       
    77 statements = (
       
    78                 ('',
       
    79                     # XXX Might need to change pythonStatement since have
       
    80                     # specific Repeat, Conditional, Operator, etc. for 'while',
       
    81                     # etc.
       
    82                     [("Statement", "pythonStatement", "keyword",
       
    83                         (kw for kw in keyword.kwlist
       
    84                             if kw not in (looping + conditionals + boolean_ops +
       
    85                                         import_stmts + object_defs))
       
    86                       ),
       
    87                      ("Statement", "pythonStatement", "keyword",
       
    88                          (' '.join(object_defs) +
       
    89                              ' nextgroup=pythonFunction skipwhite')),
       
    90                      ("Function","pythonFunction", "match",
       
    91                          contained('"[a-zA-Z_][a-zA-Z0-9_]*"')),
       
    92                      ("Repeat", "pythonRepeat", "keyword", looping),
       
    93                      ("Conditional", "pythonConditional", "keyword",
       
    94                          conditionals),
       
    95                      ("Operator", "pythonOperator", "keyword", boolean_ops),
       
    96                      ("PreCondit", "pythonPreCondit", "keyword", import_stmts),
       
    97                      ("Comment", "pythonComment", "match",
       
    98                          '"#.*$" contains=pythonTodo'),
       
    99                      ("Todo", "pythonTodo", "keyword",
       
   100                          contained(' '.join(todos))),
       
   101                      ("String", "pythonString", "region", str_regexes()),
       
   102                      ("Special", "pythonEscape", "match",
       
   103                          (contained(esc) for esc in escapes
       
   104                              if not '$' in esc)),
       
   105                      ("Special", "pythonEscape", "match", r'"\\$"'),
       
   106                     ]
       
   107                 ),
       
   108                 ("python_highlight_numbers",
       
   109                     [("Number", "pythonNumber", "match", numbers)]
       
   110                 ),
       
   111                 ("python_highlight_builtins",
       
   112                     [("Function", "pythonBuiltin", "keyword", builtin_names)]
       
   113                 ),
       
   114                 ("python_highlight_exceptions",
       
   115                     [("Exception", "pythonException", "keyword",
       
   116                         exception_names)]
       
   117                 ),
       
   118                 ("python_highlight_space_errors",
       
   119                     [("Error", "pythonSpaceError", "match",
       
   120                         ("display " + err for err in space_errors))]
       
   121                 )
       
   122              )
       
   123 
       
   124 def syn_prefix(type_, kind):
       
   125     return 'syn %s %s    ' % (type_, kind)
       
   126 
       
   127 def fill_stmt(iterable, fill_len):
       
   128     """Yield a string that fills at most fill_len characters with strings
       
   129     returned by 'iterable' and separated by a space"""
       
   130     # Deal with trailing char to handle ' '.join() calculation
       
   131     fill_len += 1
       
   132     overflow = None
       
   133     it = iter(iterable)
       
   134     while True:
       
   135         buffer_ = []
       
   136         total_len = 0
       
   137         if overflow:
       
   138             buffer_.append(overflow)
       
   139             total_len += len(overflow) + 1
       
   140             overflow = None
       
   141         while total_len < fill_len:
       
   142             try:
       
   143                 new_item = it.next()
       
   144                 buffer_.append(new_item)
       
   145                 total_len += len(new_item) + 1
       
   146             except StopIteration:
       
   147                 if buffer_:
       
   148                     break
       
   149                 if overflow:
       
   150                     yield overflow
       
   151                 return
       
   152         if total_len > fill_len:
       
   153             overflow = buffer_.pop()
       
   154             total_len -= len(overflow) - 1
       
   155         ret = ' '.join(buffer_)
       
   156         assert len(ret) <= fill_len
       
   157         yield ret
       
   158 
       
   159 FILL = 80
       
   160 
       
   161 def main(file_path):
       
   162     with open(file_path, 'w') as FILE:
       
   163         # Comment for file
       
   164         print>>FILE, comment_header % subversion[1:]
       
   165         print>>FILE, ''
       
   166         # Statements at start of file
       
   167         print>>FILE, statement_header
       
   168         print>>FILE, ''
       
   169         # Generate case for python_highlight_all
       
   170         print>>FILE, 'if exists("python_highlight_all")'
       
   171         for statement_var, statement_parts in statements:
       
   172             if statement_var:
       
   173                 print>>FILE, '  let %s = 1' % statement_var
       
   174         else:
       
   175             print>>FILE, 'endif'
       
   176             print>>FILE, ''
       
   177         # Generate Python groups
       
   178         for statement_var, statement_parts in statements:
       
   179             if statement_var:
       
   180                 print>>FILE, 'if exists("%s")' % statement_var
       
   181                 indent = '  '
       
   182             else:
       
   183                 indent = ''
       
   184             for colour_group, group, type_, arguments in statement_parts:
       
   185                 if not isinstance(arguments, basestring):
       
   186                     prefix = syn_prefix(type_, group)
       
   187                     if type_ == 'keyword':
       
   188                         stmt_iter = fill_stmt(arguments,
       
   189                                             FILL - len(prefix) - len(indent))
       
   190                         try:
       
   191                             while True:
       
   192                                 print>>FILE, indent + prefix + stmt_iter.next()
       
   193                         except StopIteration:
       
   194                             print>>FILE, ''
       
   195                     else:
       
   196                         for argument in arguments:
       
   197                             print>>FILE, indent + prefix + argument
       
   198                         else:
       
   199                             print>>FILE, ''
       
   200 
       
   201                 else:
       
   202                     print>>FILE, indent + syn_prefix(type_, group) + arguments
       
   203                     print>>FILE, ''
       
   204             else:
       
   205                 if statement_var:
       
   206                     print>>FILE, 'endif'
       
   207                     print>>FILE, ''
       
   208             print>>FILE, ''
       
   209         # Associating Python group with Vim colour group
       
   210         for statement_var, statement_parts in statements:
       
   211             if statement_var:
       
   212                 print>>FILE, '  if exists("%s")' % statement_var
       
   213                 indent = '    '
       
   214             else:
       
   215                 indent = '  '
       
   216             for colour_group, group, type_, arguments in statement_parts:
       
   217                 print>>FILE, (indent + "hi def link %s %s" %
       
   218                                 (group, colour_group))
       
   219             else:
       
   220                 if statement_var:
       
   221                     print>>FILE, '  endif'
       
   222                 print>>FILE, ''
       
   223         # Statements at the end of the file
       
   224         print>>FILE, statement_footer
       
   225 
       
   226 if __name__ == '__main__':
       
   227     main("python.vim")