pmacs3/mode/go.py

157 lines
5.3 KiB
Python

import os.path
from subprocess import Popen, PIPE, STDOUT
from method.shell import Exec
from mode import Fundamental
import tab
from lex import Grammar, PatternRule, RegionRule, PatternMatchRule, OverridePatternRule
from mode.python import StringGrammar2
from mode.c import CommentGrammar
# TODO: actually handle unicode correctly
# In The Unicode Standard 5.1, Section 4.5 General Category-Normative defines a
# set of character categories. Go treats those characters in category Lu, Ll,
# Lt, Lm, or Lo as Unicode letters, and those in category Nd as Unicode digits.
chr1 = '[a-zA-Z_]'
chr2 = '[a-zA-Z0-9_]'
word = chr1 + chr2 + '*'
escaped = [
PatternRule('escaped', r'\\[abfnrtv\\\'"]'),
PatternRule('octal', r'\\[0-7]{3}'),
PatternRule('hex', r'\\x[a-fA-F0-9]{2}'),
PatternRule('unicode', r'\\u[a-fA-F0-9]{4}'),
PatternRule('unicode', r'\\U[a-fA-F0-9]{8}'),
PatternRule('illegal', r'\\.*'),
]
class StringGrammar(Grammar):
rules = escaped + [PatternRule('data', r'[^\\"]+')]
class CharGrammar(Grammar):
rules = escaped + [PatternRule('data', r"[^\\']+")]
class RawStringGrammar(Grammar):
rules = [PatternRule('data', '[^`]+')]
class GoGrammar(Grammar):
rules = [
PatternRule('spaces', r' +'),
PatternRule('go.comment', '//.*$'),
RegionRule('go.comment', r'/\*', CommentGrammar, r'\*/'),
PatternRule("delimiter", r"(?:\(|\)|\[|\]|\{|\}|,|;|:=|:|!=|!|&\^=|&\^|\.\.\.|\.|>>=|>>|<<=|<<|%=|%|--|-=|-|\+\+|\+=|\+|==|=|\&\&|\&=|\&|\|\||\|=|\||<-|<=|<|>=|>|\^=|\^|\*=|\*|/=|/)"),
PatternRule('eol', r"\n$"),
PatternMatchRule('', '(func)( +)(' + word + ')', 'go.keyword', 'spaces', 'go.function'),
PatternMatchRule('', '(package)( +)(' + word + ')', 'go.keyword', 'spaces', 'go.package'),
PatternRule('go.keyword', r"(?:var|type|switch|struct|select|return|range|package|map|interface|import|if|goto|go|func|for|fallthrough|else|defer|default|continue|const|chan|case|break)(?!" + chr2 + ")"),
PatternRule('go.predeclared', r'(?:uint64|uint32|uint16|uint8|uintptr|uint|true|string|println|print|panicln|panic|nil|new|make|len|iota|int64|int32|int16|int8|int|float64|float32|float|false|closed|close|cap|byte|bool)(?!' + chr2 + ")"),
PatternRule('go.integer', r'(?:[1-9][0-9]*|0[0-9]*|0[xX][a-fA-F0-9]+)'),
RegionRule('go.char', "'", CharGrammar, "'"),
RegionRule('go.string', '"', StringGrammar, '"'),
RegionRule('go.string', '`', RawStringGrammar, '`'),
]
# white is for delimiters, operators, numbers
default = ('default', 'default')
# magenta is for keywords/builtins
lo_magenta = ('magenta202', 'default')
hi_magenta = ('magenta505', 'default')
# red is for comments
lo_red = ('red300', 'default')
hi_red = ('red511', 'default')
# orange is for macro definitions, headers and constants
hi_orange = ('yellow531', 'default')
lo_orange = ('yellow520', 'default')
# yellow is for parts of macros
hi_yellow = ('yellow551', 'default')
lo_yellow = ('yellow330', 'default')
# green is for strings and characters
lo_green = ('green030', 'default')
hi_green = ('green050', 'default')
# cyan is for types
lo_cyan = ('cyan033', 'default')
hi_cyan = ('cyan155', 'default')
# blue is definitions, functions and some macros
lo_blue = ('blue113', 'default')
hi_blue = ('blue225', 'default')
class Go(Fundamental):
name = 'Go'
extensions = ['.go']
grammar = GoGrammar
opentokens = ('delimiter',)
opentags = {'(': ')', '[': ']', '{': '}'}
closetokens = ('delimiter',)
closetags = {')': '(', ']': '[', '}': '{'}
#actions = [CCheckSyntax, CMake]
format = "%(flag)s %(bname)s (%(mname)s) %(indent)s %(cursor)s %(perc)s [%(func)s]"
commentc = '//'
colors = {
'go.comment': hi_red,
'go.comment.start': hi_red,
'go.comment.data': hi_red,
'go.comment.end': hi_red,
'go.char.start': lo_green,
'go.char.end': lo_green,
'go.char.data': hi_green,
'go.char.escaped': hi_magenta,
'go.char.octal': hi_magenta,
'go.char.unicode': hi_magenta,
'go.char.hex': hi_magenta,
'go.string.start': lo_green,
'go.string.end': lo_green,
'go.string.data': hi_green,
'go.string.escaped': hi_magenta,
'go.string.octal': hi_magenta,
'go.string.unicode': hi_magenta,
'go.string.hex': hi_magenta,
'go.package': hi_magenta,
'go.predeclared': hi_magenta,
'go.keyword': hi_cyan,
}
#config = {
# 'go.syntax-cmd': "gcc -x c -fsyntax-only %(path)s",
# 'go.syntax-rel-dir': False,
# 'go.make-cmd': "make",
# 'go.make-rel-dir': True,
#}
lconfig = {
'ignore_suffix': ['.5', '.6', '.8'],
}
#_bindings = {
# 'close-paren': (')',),
# 'close-brace': ('}',),
# 'close-bracket': (']',),
# 'c-check-syntax': ('C-c s',),
# 'c-make': ('C-c C-c',),
#}
#
#def get_functions(self): return {}
#def get_function_names(self): return []
#def get_line_function(self, y): return None
#def get_status_names(self):
# names = Fundamental.get_status_names(self)
# c = self.window.logical_cursor()
# names['func'] = self.get_line_function(c.y)
# return names
install = Go.install