import os.path import time import tab from mode import Fundamental from method.shell import Interact from lex import Grammar, PatternRule, RegionRule, PatternMatchRule from point import Point from etags import TagManager class StringGrammar1(Grammar): rules = [ PatternRule('octal', r'\\[0-7]{3}'), PatternRule('hex', r'\\x[0-9a-fA-F]{2}'), PatternRule('escaped', r'\\.'), PatternRule('data', r'[^\\\']+'), ] class StringGrammar2(Grammar): rules = [ PatternRule('octal', r'\\[0-7]{3}'), PatternRule('hex', r'\\x[0-9a-fA-F]{2}'), PatternRule('escaped', r'\\.'), PatternRule('data', r'[^\\\"]+'), ] class RegexGrammar(Grammar): rules = [ PatternRule('octal', r'\\[0-7]{3}'), PatternRule('hex', r'\\x[0-9a-fA-F]{2}'), PatternRule('escaped', r'\\.'), PatternRule('data', r'[^/\\]+'), ] chr1 = '[a-zA-Z_]' chr2 = '[a-zA-Z_0-9]' word = chr1 + chr2 + '*' class JavascriptGrammar(Grammar): rules = [ PatternRule('comment', '//.*$'), RegionRule('comment', r'/\*', Grammar, '\*/'), RegionRule('comment', r''), PatternRule('continuation', r'\\(?= *$)'), PatternMatchRule('x', '(function)( +)(' + word + ')', 'js.reserved', 'spaces', 'js.function'), PatternMatchRule('x', '(class|new)( +)(' + word + ')', 'js.reserved', 'spaces', 'js.class'), PatternRule('js.reserved', '(?:abstract|as|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|false|finally|for|function|get|goto|if|import|implements|include|instanceof|interface|in|is|namespace|native|new|null|package|private|protected|public|return|set|super|switch|synchronized|this|throws|throw|transient|true|try|typeof|use|var|void|volatile|while|with)(?!' + chr2 + ')'), PatternRule('js.identifier', word), PatternRule('js.integer', "(?:0|[1-9][0-9]*|0[0-7]+|0[xX][0-9a-fA-F]+)[lL]?"), PatternRule('js.float', r"[0-9]+\.[0-9]*|\.[0-9]+|(?:[0-9]|[0-9]+\.[0-9]*|\.[0-9]+)[eE][\+-]?[0-9]+"), PatternRule('eol', r'\n'), PatternRule('spaces', ' +'), PatternRule('delimiter', r'%=|&&=|&=|\(|\)|\*=|\+=|,|-=|\.{3}|\.|/=(?= |$)|::|:|;|<<=|>>=|>>>=|\?|\[|\]|^=|^^=|\{|\}|\|=|\|\|='), # fucking javascript! # their lexer grammar requires one-token look-behind in order to know # whether a "/" starts a literal regex, or is part of a mathematical # expression/assignment. RegionRule('js.regex', r"(?<=[\(=:,]) */", RegexGrammar, "/[a-z]*"), PatternRule('js.operator', r'!==|!=|!|%|&&|&|\*|\+\+|\+|--|-|/|<<=|<<|<=|<|===|==|=|>>>=|>>>|>>=|>>|>=|>|\\|\|\|'), RegionRule('string', "'", StringGrammar1, "'"), RegionRule('string', '"', StringGrammar2, '"'), ] class JavascriptTabber2(tab.StackTabber2): fixed_indent = True open_tokens = {'delimiter': {'{': '}', '(': ')', '[': ']'}} close_tokens = {'delimiter': {'}': '{', ')': '(', ']': '['}} control_tokens = {'js.keyword': {'if': 1, 'else': 1, 'while': 1, 'do': 1, 'for': 1}} end_at_eof = False end_at_tokens = {'delimiter': {';': 1}} nocontinue_tokens = {'delimiter': {';': 1, ',': 1}, 'comment': 1, 'comment.start': 1, 'comment.data': 1, 'comment.end': 1} start_free_tokens = {'string.start': 'string.end'} end_free_tokens = {'string.end': 'string.start'} def is_base(self, y): if y == 0: return True highlighter = self.mode.window.buffer.highlights[self.mode.name] if not highlighter.tokens[y]: return False t = highlighter.tokens[y][0] return t.name == 'js.reserved' and t.string == 'function' def _is_indent(self, t): return t.name == 'spaces' def _is_ignored(self, t): return t.fqname() in ('spaces', 'eol', 'comment', 'comment.start', 'comment.data', 'comment.null', 'comment.end') class RhinoStart(Interact): args = [] reuse = True def _execute(self, w, **vargs): cmd = w.application.config.get('rhino.cmd', 'rhino') Interact._execute(self, w, bname='*Rhino*', cmd=cmd) class RhinoLoadFile(RhinoStart): args = [] reuse = True def _execute(self, w, **vargs): RhinoStart._execute(self, w, **vargs) b = w.application.get_buffer_by_name('*Rhino*') path = os.path.realpath(w.buffer.path) time.sleep(0.5) b.pipe_write('load("env.js");\n') time.sleep(0.5) b.pipe_write('load("%s");\n' % path) class JavascriptTagManager(TagManager): lang = 'Javascript' exts = set(('.js', '.json')) class Javascript(Fundamental): name = 'Javascript' extensions = ['.js', '.json'] tabwidth = 2 grammar = JavascriptGrammar tabbercls = JavascriptTabber2 tagcls = JavascriptTagManager commentc = '//' opentokens = ('delimiter',) opentags = {'(': ')', '[': ']', '{': '}'} closetokens = ('delimiter',) closetags = {')': '(', ']': '[', '}': '{'} colors = { 'js.function': ('blue', 'default', 'bold'), 'js.class': ('magenta', 'default', 'bold'), 'js.reserved': ('cyan', 'default', 'bold'), 'js.regex.start': ('cyan', 'default', 'bold'), 'js.regex.data': ('cyan', 'default', 'bold'), 'js.regex.null': ('cyan', 'default', 'bold'), 'js.regex.octal': ('magenta', 'default', 'bold'), 'js.regex.escaped': ('magenta', 'default', 'bold'), 'js.regex.end': ('cyan', 'default', 'bold'), } config = {'rhino.cmd': 'rhino'} actions = [RhinoStart, RhinoLoadFile] _bindings = { 'close-paren': (')',), 'close-brace': ('}',), 'close-bracket': (']',), } install = Javascript.install