parent
87dce5ee27
commit
182fd7880d
|
@ -709,7 +709,7 @@ class Application(object):
|
||||||
p = w.logical_cursor()
|
p = w.logical_cursor()
|
||||||
|
|
||||||
blen = len(w.buffer.lines)
|
blen = len(w.buffer.lines)
|
||||||
count = w.mode.header #XYZ
|
count = w.mode.header
|
||||||
(x, y) = w.first.xy()
|
(x, y) = w.first.xy()
|
||||||
(vy, vx) = (None, None)
|
(vy, vx) = (None, None)
|
||||||
while count < slot.height:
|
while count < slot.height:
|
||||||
|
@ -778,30 +778,30 @@ class Application(object):
|
||||||
w = slot.window
|
w = slot.window
|
||||||
modename = w.mode.name()
|
modename = w.mode.name()
|
||||||
|
|
||||||
# XYZ
|
# draw the header
|
||||||
rstrs = w.mode.get_header(w)
|
rstrs = w.mode.get_header(w)
|
||||||
assert len(rstrs) >= w.mode.header
|
assert len(rstrs) >= w.mode.header
|
||||||
for j in range(0, w.mode.header):
|
for j in range(0, w.mode.header):
|
||||||
rstrs[j].draw(self.win, slot.y_offset + j, slot.x_offset)
|
rstrs[j].draw(self.win, slot.y_offset + j, slot.x_offset)
|
||||||
# XYZ
|
|
||||||
|
|
||||||
|
# draw the actual slot
|
||||||
self._draw_slot(i)
|
self._draw_slot(i)
|
||||||
|
|
||||||
# highlighted regions
|
# highlighted regions
|
||||||
for hr in self.highlighted_ranges:
|
for hr in self.highlighted_ranges:
|
||||||
(high_w, p1, p2, fg, bg) = hr
|
(high_w, p1, p2, fg, bg) = hr
|
||||||
if w is high_w and p2 >= w.first and p1 <= w.last:
|
if w is high_w and p2 >= w.first and p1 <= w.last:
|
||||||
#count = 0
|
count = w.mode.header
|
||||||
count = w.mode.header #XYZ
|
|
||||||
x, y = w.first.xy()
|
x, y = w.first.xy()
|
||||||
px = p1.x
|
px = p1.x
|
||||||
while count < slot.heigh:
|
while count < slot.height:
|
||||||
if p1.y == y and px >= x and px - x < slot.width:
|
if p1.y == y and px >= x and px - x < slot.width:
|
||||||
|
sy, sx = slot.y_offset + count, px - x + w.mode.lmargin
|
||||||
if slot.width > p2.x - x:
|
if slot.width > p2.x - x:
|
||||||
self.highlight_chars(slot.y_offset + count, px-x + w.mode.lmargin, p2.x-x, fg, bg)
|
self.highlight_chars(sy, sx, p2.x-x, fg, bg)
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
self.highlight_chars(slot.y_offset + count, px-x + w.mode.lmargin, slot.width - 1, fg, bg)
|
self.highlight_chars(sy, sx, slot.width - 1, fg, bg)
|
||||||
px += slot.width - px + x - 1
|
px += slot.width - px + x - 1
|
||||||
if x + slot.width > len(w.buffer.lines[y]):
|
if x + slot.width > len(w.buffer.lines[y]):
|
||||||
x = 0
|
x = 0
|
||||||
|
@ -827,8 +827,7 @@ class Application(object):
|
||||||
x, y = w.first.xy()
|
x, y = w.first.xy()
|
||||||
lm, rm = w.mode.lmargin, w.mode.rmargin
|
lm, rm = w.mode.lmargin, w.mode.rmargin
|
||||||
lines = w.buffer.lines
|
lines = w.buffer.lines
|
||||||
#count = 0
|
count = w.mode.header
|
||||||
count = w.mode.header #XYZ
|
|
||||||
k = x // (slot.width - lm - rm)
|
k = x // (slot.width - lm - rm)
|
||||||
modename = w.mode.name()
|
modename = w.mode.name()
|
||||||
lit = w.mode.name() in w.buffer.highlights
|
lit = w.mode.name() in w.buffer.highlights
|
||||||
|
|
21
lex.py
21
lex.py
|
@ -18,6 +18,27 @@ class Token(object):
|
||||||
self.link = link
|
self.link = link
|
||||||
self._debug = False
|
self._debug = False
|
||||||
assert parent is None or hasattr(parent, 'name'), 'oh no %r' % parent
|
assert parent is None or hasattr(parent, 'name'), 'oh no %r' % parent
|
||||||
|
|
||||||
|
def match(self, name, string):
|
||||||
|
return self.name == name and self.string == string
|
||||||
|
def matchs(self, name, strings):
|
||||||
|
return self.name == name and self.string in strings
|
||||||
|
def matchp(self, pairs):
|
||||||
|
for (name, string) in pairs:
|
||||||
|
if self.match(name, string):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def fqmatch(self, name, string):
|
||||||
|
return self.fqname() == name and self.string == string
|
||||||
|
def fqmatchs(self, name, strings):
|
||||||
|
return self.fqname() == name and self.string in strings
|
||||||
|
def fqmatchp(self, pairs):
|
||||||
|
for (name, string) in pairs:
|
||||||
|
if self.fqmatch(name, string):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
def parents(self):
|
def parents(self):
|
||||||
if self.parent is not None:
|
if self.parent is not None:
|
||||||
parents = self.parent.parents()
|
parents = self.parent.parents()
|
||||||
|
|
182
mode/java.py
182
mode/java.py
|
@ -1,4 +1,5 @@
|
||||||
import color, mode, tab
|
import color, mode, tab
|
||||||
|
import context
|
||||||
from lex import Grammar, PatternRule, RegionRule
|
from lex import Grammar, PatternRule, RegionRule
|
||||||
from mode.python import StringGrammar2
|
from mode.python import StringGrammar2
|
||||||
from mode.c import CTabber2
|
from mode.c import CTabber2
|
||||||
|
@ -35,136 +36,77 @@ class JavaGrammar(Grammar):
|
||||||
PatternRule(r"eol", r"\n$"),
|
PatternRule(r"eol", r"\n$"),
|
||||||
]
|
]
|
||||||
|
|
||||||
class JavaTabber(CTabber2):
|
class JavaTabber2(tab.StackTabber2):
|
||||||
|
open_tokens = {'delimiter': {'{': '}', '(': ')', '[': ']'}}
|
||||||
|
close_tokens = {'delimiter': {'}': '{', ')': '(', ']': '['}}
|
||||||
|
control_tokens = {'keyword': {'if': 1, 'else': 1, 'while': 1, 'do': 1, 'for': 1}}
|
||||||
|
end_at_eof = False
|
||||||
|
end_at_tokens = {'delimiter': {';': 1}}
|
||||||
|
nocontinue_tokens = {'delimiter': {';': 1},
|
||||||
|
'java_comment.start': 1,
|
||||||
|
'java_comment.data': 1,
|
||||||
|
'java_comment.end': 1}
|
||||||
|
start_free_tokens = {'string.start': 'string.end'}
|
||||||
|
end_free_tokens = {'string.end': 'string.start'}
|
||||||
def is_base(self, y):
|
def is_base(self, y):
|
||||||
if y == 0:
|
if y == 0:
|
||||||
return True
|
return True
|
||||||
|
else:
|
||||||
highlighter = self.mode.window.buffer.highlights[self.mode.name()]
|
|
||||||
if not highlighter.tokens[y]:
|
|
||||||
return False
|
return False
|
||||||
|
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')
|
||||||
|
|
||||||
for t in highlighter.tokens[y]:
|
class JavaContext(context.Context):
|
||||||
if t.name == 'null':
|
def _regen_stack(self, y):
|
||||||
pass
|
if y > 0 and self.namelines[y - 1][1]:
|
||||||
elif t.name == 'keyword':
|
return list(self.namelines[y - 1][1])
|
||||||
if t.string in ('class', 'interface'):
|
else:
|
||||||
return True
|
return []
|
||||||
elif t.string in ('public', 'private', 'protected', 'static',
|
|
||||||
'final', 'native', 'synchronized', 'abstract',
|
|
||||||
'threadsafe', 'transient'):
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
|
|
||||||
return False
|
def _build_name_map(self, y1, y2, last, curr, stack):
|
||||||
|
blen = len(self.mode.window.buffer.lines)
|
||||||
|
highlights = self.mode.window.get_highlighter()
|
||||||
|
i = y1
|
||||||
|
|
||||||
# detecting function declarations is annoying; this assumes that people
|
while i < y2:
|
||||||
# won't put a variable type and name on different lines, but that they
|
if not stack:
|
||||||
# might do that for function return type and name.
|
curr = None
|
||||||
#
|
|
||||||
# unfortunately, valid function return types might include any of the
|
|
||||||
# four types of tokens below
|
|
||||||
decl = False
|
|
||||||
for t in highlighter.tokens[y]:
|
|
||||||
if t.name in ('keyword', 'identifier', 'structname', 'enumname'):
|
|
||||||
decl = True
|
|
||||||
continue
|
|
||||||
if decl and t.name == 'function':
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
decl = False
|
|
||||||
break
|
|
||||||
if decl:
|
|
||||||
return True
|
|
||||||
|
|
||||||
return False
|
g = highlights.tokens[i]
|
||||||
|
gl = len(g)
|
||||||
|
|
||||||
def _handle_open_token(self, currlvl, y, i):
|
if gl > 2 and g[0].match('keyword', 'class'):
|
||||||
self._opt_pop('cont')
|
curr = g[2].string
|
||||||
token = self.get_token(y, i)
|
elif gl > 4 and g[2].match('keyword', 'class'):
|
||||||
if token.string == '{':
|
curr = g[4].string
|
||||||
self._opt_pop('cond')
|
|
||||||
currlvl = tab.StackTabber._handle_open_token(self, currlvl, y, i)
|
|
||||||
return currlvl
|
|
||||||
def _handle_close_token(self, currlvl, y, i):
|
|
||||||
w = self.mode.tabwidth
|
|
||||||
self._opt_pop('cont')
|
|
||||||
currlvl = tab.StackTabber._handle_close_token(self, currlvl, y, i)
|
|
||||||
token = self.get_token(y, i)
|
|
||||||
if self.is_rightmost_token(y, i):
|
|
||||||
if token.string == '}':
|
|
||||||
self._opt_pop('cond')
|
|
||||||
self._opt_pop('cont')
|
|
||||||
elif self._peek_name() == 'cond':
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
self._opt_append('cont', currlvl + w)
|
|
||||||
return currlvl
|
|
||||||
def _handle_other_token(self, currlvl, y, i):
|
|
||||||
w = self.mode.tabwidth
|
|
||||||
token = self.get_token(y, i)
|
|
||||||
fqname = token.fqname()
|
|
||||||
if fqname == 'delimiter' and token.string == ';':
|
|
||||||
self._opt_pop('cond')
|
|
||||||
self._opt_pop('cont')
|
|
||||||
self._opt_pop('cond')
|
|
||||||
|
|
||||||
elif fqname == 'keyword':
|
if curr is not None and curr not in self.names:
|
||||||
if token.string in ('do', 'else', 'for', 'if', 'while'):
|
self.names[curr] = i
|
||||||
self._append('cond', currlvl + w)
|
|
||||||
elif token.string == 'break':
|
|
||||||
self._opt_pop('case', 'while', 'for')
|
|
||||||
elif token.string == 'continue':
|
|
||||||
self._opt_pop('while', 'for')
|
|
||||||
elif token.string == 'case':
|
|
||||||
self._opt_pop('case')
|
|
||||||
currlvl = self.get_curr_level()
|
|
||||||
self._opt_append('case', currlvl + w)
|
|
||||||
|
|
||||||
elif fqname == 'string.start':
|
if i == y2 - 1 and curr != self.namelines[i][0] and y2 < blen:
|
||||||
self._opt_append('string', None)
|
y2 += 1
|
||||||
elif fqname == 'string.end':
|
|
||||||
self._opt_pop('string')
|
|
||||||
if self.is_rightmost_token(y, i):
|
|
||||||
self._opt_append('cont', currlvl + w)
|
|
||||||
|
|
||||||
# TODO: this could be a lot better
|
for t in g:
|
||||||
elif fqname == 'macro':
|
if t.match('delimiter', '{'):
|
||||||
currlvl = 0
|
stack.append(t.string)
|
||||||
elif fqname.startswith('macro.start'):
|
elif t.match('delimiter', '}'):
|
||||||
self._opt_append('macro', None)
|
#assert stack, "uh oh"
|
||||||
currlvl = 0
|
if stack:
|
||||||
elif fqname.startswith('macro.end'):
|
stack.pop(-1)
|
||||||
self._opt_pop('macro', None)
|
|
||||||
|
|
||||||
elif fqname.startswith('macroblock.start'):
|
if curr:
|
||||||
self._opt_append('macroblock', None)
|
self.namelines[i] = (curr, tuple(stack))
|
||||||
currlvl = 0
|
i += 1
|
||||||
elif fqname.startswith('macroblock.end'):
|
|
||||||
self._opt_pop('macroblock', None)
|
|
||||||
|
|
||||||
if self.is_rightmost_token(y, i):
|
|
||||||
if self._has_markers() and self._peek_name() == 'cond':
|
|
||||||
pass
|
|
||||||
elif(not fqname.startswith('string') and
|
|
||||||
not fqname.startswith('java-comment') and
|
|
||||||
not fqname.startswith('macro') and
|
|
||||||
not fqname == 'delimiter' and
|
|
||||||
not fqname == 'header' and
|
|
||||||
not fqname == 'null' and
|
|
||||||
not fqname == 'eol' and
|
|
||||||
token.string not in ('}', ';', '(', '{', '[', ',')):
|
|
||||||
self._opt_append('cont', currlvl + w)
|
|
||||||
return currlvl
|
|
||||||
|
|
||||||
class Java(mode.Fundamental):
|
class Java(mode.Fundamental):
|
||||||
modename = 'Java'
|
modename = 'Java'
|
||||||
extensions = ['.java']
|
extensions = ['.java']
|
||||||
tabbercls = JavaTabber
|
tabbercls = JavaTabber2
|
||||||
grammar = JavaGrammar
|
grammar = JavaGrammar
|
||||||
|
|
||||||
opentokens = ('delimiter',)
|
opentokens = ('delimiter',)
|
||||||
opentags = {'(': ')', '[': ']', '{': '}'}
|
opentags = {'(': ')', '[': ']', '{': '}'}
|
||||||
closetokens = ('delimiter',)
|
closetokens = ('delimiter',)
|
||||||
|
@ -182,10 +124,26 @@ class Java(mode.Fundamental):
|
||||||
'java_integer': ('green', 'default', 'bold'),
|
'java_integer': ('green', 'default', 'bold'),
|
||||||
'java_float': ('green', 'default', 'bold'),
|
'java_float': ('green', 'default', 'bold'),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
format = "%(flag)s %(bname)-18s (%(mname)s) %(indent)s %(cursor)s/%(mark)s %(perc)s [%(func)s]"
|
||||||
|
def get_status_names(self):
|
||||||
|
names = mode.Fundamental.get_status_names(self)
|
||||||
|
c = self.window.logical_cursor()
|
||||||
|
names['func'] = self.get_line_function(c.y)
|
||||||
|
return names
|
||||||
|
|
||||||
def __init__(self, w):
|
def __init__(self, w):
|
||||||
mode.Fundamental.__init__(self, w)
|
mode.Fundamental.__init__(self, w)
|
||||||
self.add_bindings('close-paren', (')',))
|
self.add_bindings('close-paren', (')',))
|
||||||
self.add_bindings('close-brace', ('}',))
|
self.add_bindings('close-brace', ('}',))
|
||||||
self.add_bindings('close-bracket', (']',))
|
self.add_bindings('close-bracket', (']',))
|
||||||
|
self.context = JavaContext(self)
|
||||||
|
|
||||||
|
def get_functions(self):
|
||||||
|
return self.context.get_names()
|
||||||
|
def get_function_names(self):
|
||||||
|
return self.context.get_name_list()
|
||||||
|
def get_line_function(self, y):
|
||||||
|
return self.context.get_line_name(y)
|
||||||
|
|
||||||
install = Java.install
|
install = Java.install
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
import lex
|
||||||
|
|
||||||
|
class Rule(object):
|
||||||
|
def __init__(self, *rules):
|
||||||
|
self.rules = rules
|
||||||
|
def match(self, tokens):
|
||||||
|
raise Exception("unimplemented")
|
||||||
|
|
||||||
|
class Match(Rule):
|
||||||
|
method = lex.Token.match
|
||||||
|
def __init__(self, *args):
|
||||||
|
self.args = args
|
||||||
|
def match(self, tokens):
|
||||||
|
if not tokens:
|
||||||
|
return False
|
||||||
|
elif method(tokens[0], *self.args):
|
||||||
|
tokens.pop(0)
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
class Matchs(Match):
|
||||||
|
method = lex.Token.matchs
|
||||||
|
class Matchp(Match):
|
||||||
|
method = lex.Token.matchp
|
||||||
|
|
||||||
|
class Fqmatch(Match):
|
||||||
|
method = lex.Token.fqmatch
|
||||||
|
class Fqmatchs(Match):
|
||||||
|
method = lex.Token.fqmatchs
|
||||||
|
class Fqmatchp(Match):
|
||||||
|
method = lex.Token.fqmatchp
|
||||||
|
|
||||||
|
class And(Rule):
|
||||||
|
def match(self, tokens):
|
||||||
|
for r in self.rules:
|
||||||
|
if not r.match(tokens):
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
class Or(Rule):
|
||||||
|
def match(self, tokens):
|
||||||
|
for r in self.rules:
|
||||||
|
if r.match(tokens):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
class Repeat(Rule):
|
||||||
|
def __init__(self, rule, minimum, maximum):
|
||||||
|
self.rule = rule
|
||||||
|
self.minimum = minimum
|
||||||
|
self.maximum = maximum
|
||||||
|
def match(self, tokens):
|
||||||
|
for i in range(0, self.minimum):
|
||||||
|
if not self.rule.match(tokens):
|
||||||
|
return False
|
||||||
|
while self.rules.match(tokens):
|
||||||
|
pass
|
||||||
|
return True
|
||||||
|
self.rule.match(tokens)
|
||||||
|
return True
|
||||||
|
|
||||||
|
class Star(Rule):
|
||||||
|
def __init__(self, rule):
|
||||||
|
self.rule = rule
|
||||||
|
def match(self, tokens):
|
||||||
|
if not self.rule.match(tokens):
|
||||||
|
return False
|
||||||
|
while self.rules.match(tokens):
|
||||||
|
pass
|
||||||
|
return True
|
||||||
|
class End(Rule):
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
def match(self, tokens):
|
||||||
|
return not tokens
|
||||||
|
|
Loading…
Reference in New Issue