from tab import StackTabber2 from mode import Fundamental from lex import Grammar, PatternRule, RegionRule, PatternMatchRule from mode.sh import ShGrammar from mode.xml import XMLGrammar from mode.pipe import Pipe from method.shell import Interact from method import Method, arg import default import urllib2 import os import re chr1 = '[a-zA-Z_]' chr2 = '[a-zA-Z_0-9]' word = chr1 + chr2 + '*' class NestedCommentGrammar(Grammar): pass NestedCommentGrammar.rules = [ RegionRule('comment', r'/\*', NestedCommentGrammar, r'\*/'), PatternRule('data', r'(?:[^\*]|\*(?!/))+'), ] class StringGrammar(Grammar): rules = [ PatternRule('escaped', r"\\u[0-9A-Fa-f]{4}|\\[0-7]{1,3}|\\[btnfr\"'\\]"), PatternRule('data', r'[^\\"]+'), ] class SubTypeGrammar(Grammar): pass SubTypeGrammar.rules = [ RegionRule('sub', r'\[', SubTypeGrammar, r'\]'), PatternRule('scala.type', '(?:[a-zA-Z0-9_.]+| *=> *)+'), PatternRule('spaces', ' +'), PatternRule('scala.annotation', '@[a-zA-Z_][a-zA-Z0-9_]*'), ] class ScalaGrammar(Grammar): rules = [ PatternRule('scala.comment', '//.*$'), RegionRule('scala.comment', r'/\*', NestedCommentGrammar, r'\*/'), RegionRule('scala.script', r'#!.+$', ShGrammar, r'!#'), PatternMatchRule('x', r'(? *)+)', 'delimiter', 'scala.type'), PatternMatchRule('x', r'(? *)+)', 'delimiter', 'spaces', 'scala.type'), #PatternMatchRule('x', r'(?<=[a-zA-Z0-9_ ])(:)([a-zA-Z0-9_]+)', # 'delimiter', 'scala.type'), #PatternMatchRule('x', r'(?<=[a-zA-Z0-9_ ])(:)( +)([a-zA-Z0-9_]+)', # 'delimiter', 'spaces', 'scala.type'), PatternMatchRule('x', r'(extends|with|new)( +)([a-zA-Z0-9_.]+)', 'scala.reserved', 'spaces', 'scala.type'), #PatternMatchRule('x', r'(with)( +)([a-zA-Z0-9_.]+)', # 'scala.reserved', 'spaces', 'scala.type'), #PatternMatchRule('x', r'(new)( +)([a-zA-Z0-9_.]+)', # 'scala.reserved', 'spaces', 'scala.type'), PatternRule('scala.def', '(?<=(?|:|/|\+|-|\*|=)'), RegionRule('sub', r'(?<=:)\(', SubTypeGrammar, r'\)'), PatternRule('delimiter', r'(?:;|{|}|\(|\)|,|\.|<(?![a-zA-Z_])|>|:|/|\+|-|\*|=)'), RegionRule('sub', r'\[', SubTypeGrammar, r'\]'), RegionRule('scala.inline', r'(?:^| )(?=<[a-zA-Z_])', XMLGrammar, '^[ \t]*$'), PatternRule('spaces', r'(?:\t| )+'), PatternRule('eol', r'\n'), #PatternRule('scala.def', '(?<=(? ') t = self.ret_re.sub(') => ', t) t = t.replace(': ', ':') t = t.replace(',', ', ') w.set_error(t) class ScalaGotoDefinition(ScalaXRayBase): generic_re = re.compile('\[.+\]') def _execute(self, w, **vargs): word = w.get_token().string if word is None or word.strip() == "": w.set_error('no word selected') return n = w.cursor_byte_offset() t = self.type_lookup(n, w) if not t: w.set_error('%s has unknown type' % word) return # remove generics t = self.generic_re.sub('', t) path, n = self.type_def_lookup(t, w) if not path: w.set_error('%s not found' % t) return b = w.buffer a = w.application b2 = a.open_path(path) a.switch_buffer(b2) if b == b2: a.methods['goto-char'].execute(w, charno=n - 1) a.methods['center-view'].execute(w) else: a.methods['goto-char'].execute(b2.windows[0], charno=n - 1) a.methods['center-view'].execute(b2.windows[0]) w.set_error('opening %s...' % path) # white is for delimiters, operators, numbers default = ('default', 'default') # magenta is for keywords/builtins lo_magenta = ('magenta202', 'default') hi_magenta = ('magenta414', '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 Scala(Fundamental): name = 'Scala' extensions = ['.scala'] tabwidth = 2 tabbercls = ScalaTabber grammar = ScalaGrammar commentc = '//' actions = [ScalaStart, ScalaDocBrowse, ScalaDocLookup, ScalaGetType, ScalaGotoDefinition] opentokens = ('delimiter', 'sub.start', 'sub.sub.start', 'sub.sub.sub.start') opentags = {'(': ')', '[': ']', '{': '}'} closetokens = ('delimiter', 'sub.end', 'sub.sub.end', 'sub.sub.sub.end') closetags = {')': '(', ']': '[', '}': '{'} config = { 'scala.api': 'http://www.scala-lang.org/api/current/allclasses.html', 'scala.api-base': 'http://www.scala-lang.org/api/current', 'scala.type-abbrev': True, } colors = { 'scala.script.start': hi_red, 'scala.script.end': hi_red, 'scala.annotation': lo_orange, 'scala.pseudo': hi_magenta, 'scala.reserved': hi_cyan, 'scala.integer': default, 'scala.float': default, 'scala.bareword': default, 'scala.symbol': hi_orange, 'scala.class': hi_yellow, 'scala.object': hi_yellow, 'scala.trait': hi_yellow, 'scala.type': hi_magenta, 'scala.def': hi_blue, 'scala.def': hi_blue, } _bindings = { 'scala-get-type': ('M-,',), 'scala-goto-definition': ('C-c ,',), 'close-paren': (')',), 'close-brace': ('}',), 'close-bracket': (']',), } class ScalaPipe(Pipe): name = 'scalapipe' grammar = ScalaGrammar def install(*args): Scala.install(*args) ScalaPipe.install(*args)