improvements to the big 3: c, python, perl
--HG-- branch : pmacs2
This commit is contained in:
parent
bbe7bee4c5
commit
b4d9a69663
81
mode/c.py
81
mode/c.py
|
@ -1,6 +1,6 @@
|
||||||
import os, re
|
import os, re
|
||||||
from subprocess import Popen, PIPE, STDOUT
|
from subprocess import Popen, PIPE, STDOUT
|
||||||
import color, default, method, method.shell, mode, tab
|
import color, context, default, method, method.shell, mode, tab
|
||||||
from lex import Grammar, PatternRule, RegionRule, OverridePatternRule
|
from lex import Grammar, PatternRule, RegionRule, OverridePatternRule
|
||||||
from mode.python import StringGrammar
|
from mode.python import StringGrammar
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ from mode.python import StringGrammar
|
||||||
class MacroGrammar(Grammar):
|
class MacroGrammar(Grammar):
|
||||||
rules = [
|
rules = [
|
||||||
PatternRule('name', r'(?:(?<=#define )) *[a-zA-Z_][a-zA-Z0-9_]*'),
|
PatternRule('name', r'(?:(?<=#define )) *[a-zA-Z_][a-zA-Z0-9_]*'),
|
||||||
PatternRule(r"unop", r"\+=|-=|\*=|/=|//=|%=|&=\|\^=|>>=|<<=|\*\*="),
|
PatternRule(r"unop", r"\+=|-=|\*=|/=|//=|%=|&=|\^=|>>=|<<=|\*\*=|\|="),
|
||||||
PatternRule(r'binop', r"\+|<>|<<|<=|<|-|>>|>=|>|\*\*|&|\*|\||/|\^|==|//|~|!=|%"),
|
PatternRule(r'binop', r"\+|<>|<<|<=|<|-|>>|>=|>|\*\*|&|\*|\||/|\^|==|//|~|!=|%"),
|
||||||
PatternRule(r"delimiter", r"->|\.|\(|\)|\[|\]|{|}|@|,|:|`|;|=|\?"),
|
PatternRule(r"delimiter", r"->|\.|\(|\)|\[|\]|{|}|@|,|:|`|;|=|\?"),
|
||||||
PatternRule(r"integer", r"-?(?:0(?![x0-9])|[1-9][0-9]*|0[0-7]+|0[xX][0-9a-fA-F]+)[lL]?"),
|
PatternRule(r"integer", r"-?(?:0(?![x0-9])|[1-9][0-9]*|0[0-7]+|0[xX][0-9a-fA-F]+)[lL]?"),
|
||||||
|
@ -38,6 +38,7 @@ class CGrammar(Grammar):
|
||||||
PatternRule(r'function', r'[a-zA-Z_][a-zA-Z0-9_]*(?= *\()'),
|
PatternRule(r'function', r'[a-zA-Z_][a-zA-Z0-9_]*(?= *\()'),
|
||||||
|
|
||||||
PatternRule(r'builtin', r"(?:NULL|TRUE|FALSE)"),
|
PatternRule(r'builtin', r"(?:NULL|TRUE|FALSE)"),
|
||||||
|
PatternRule(r'c_type', r'[a-zA-Z_][a-zA-Z0-9_]*(?= +[a-zA-Z_])'),
|
||||||
PatternRule(r'identifier', r"[a-zA-Z_][a-zA-Z0-9_]*"),
|
PatternRule(r'identifier', r"[a-zA-Z_][a-zA-Z0-9_]*"),
|
||||||
PatternRule(r"unop", r"\+=|-=|\*=|/=|//=|%=|&=\|\^=|>>=|<<=|\*\*="),
|
PatternRule(r"unop", r"\+=|-=|\*=|/=|//=|%=|&=\|\^=|>>=|<<=|\*\*="),
|
||||||
PatternRule(r'binop', r"\+|<>|<<|<=|<|-|>>|>=|>|\*\*|&|\*|\||/|\^|==|//|~|!=|%"),
|
PatternRule(r'binop', r"\+|<>|<<|<=|<|-|>>|>=|>|\*\*|&|\*|\||/|\^|==|//|~|!=|%"),
|
||||||
|
@ -97,7 +98,7 @@ class CTabber(tab.StackTabber):
|
||||||
self._opt_pop('cont')
|
self._opt_pop('cont')
|
||||||
token = self.get_token(y, i)
|
token = self.get_token(y, i)
|
||||||
if token.string == '{':
|
if token.string == '{':
|
||||||
self._pop_while('cond', 'cont')
|
self._pop_while('cond', 'cont', 'case')
|
||||||
if self.is_leftmost_token(y, i):
|
if self.is_leftmost_token(y, i):
|
||||||
currlvl = self.get_curr_level()
|
currlvl = self.get_curr_level()
|
||||||
tab.StackTabber._handle_open_token(self, currlvl, y, i)
|
tab.StackTabber._handle_open_token(self, currlvl, y, i)
|
||||||
|
@ -105,11 +106,13 @@ class CTabber(tab.StackTabber):
|
||||||
def _handle_close_token(self, currlvl, y, i):
|
def _handle_close_token(self, currlvl, y, i):
|
||||||
w = self.mode.tabwidth
|
w = self.mode.tabwidth
|
||||||
self._opt_pop('cont')
|
self._opt_pop('cont')
|
||||||
currlvl = tab.StackTabber._handle_close_token(self, currlvl, y, i)
|
|
||||||
token = self.get_token(y, i)
|
token = self.get_token(y, i)
|
||||||
|
if token.string == '}':
|
||||||
|
self._opt_pop('case')
|
||||||
|
currlvl = tab.StackTabber._handle_close_token(self, currlvl, y, i)
|
||||||
if self.is_rightmost_token(y, i):
|
if self.is_rightmost_token(y, i):
|
||||||
if token.string == '}':
|
if token.string == '}':
|
||||||
self._pop_while('cond', 'cont')
|
self._pop_while('cond', 'cont', 'case')
|
||||||
elif self._has_markers() and self._peek_name() == 'cond':
|
elif self._has_markers() and self._peek_name() == 'cond':
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
|
@ -198,6 +201,54 @@ class CMake(method.shell.Exec):
|
||||||
self._doit(w, w.buffer.path, w.application.config['c.make-cmd'],
|
self._doit(w, w.buffer.path, w.application.config['c.make-cmd'],
|
||||||
cmdname='c-make')
|
cmdname='c-make')
|
||||||
|
|
||||||
|
class CContext(context.Context):
|
||||||
|
def _regen_stack(self, y):
|
||||||
|
if y > 0 and self.namelines[y - 1][1]:
|
||||||
|
return list(self.namelines[y - 1][1])
|
||||||
|
else:
|
||||||
|
return []
|
||||||
|
|
||||||
|
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
|
||||||
|
starting = curr and not bool(stack)
|
||||||
|
while i < y2:
|
||||||
|
if not starting and not stack:
|
||||||
|
curr = None
|
||||||
|
|
||||||
|
g = highlights.tokens[i]
|
||||||
|
if not stack and len(g) > 2 and g[0].name in ('c_type', 'keyword'):
|
||||||
|
g2 = [x for x in g if x.name != 'spaces']
|
||||||
|
j = 0
|
||||||
|
while j < len(g2) - 1 and g2[j].name in ('keyword', 'c_type'):
|
||||||
|
j += 1
|
||||||
|
if j < len(g2) and g2[j].name == 'function':
|
||||||
|
curr = g2[j].string
|
||||||
|
starting = True
|
||||||
|
|
||||||
|
if curr is not None and curr not in self.names:
|
||||||
|
self.names[curr] = i
|
||||||
|
|
||||||
|
if i == y2 - 1 and curr != self.namelines[i][0] and y2 < blen:
|
||||||
|
y2 += 1
|
||||||
|
|
||||||
|
m = self.mode
|
||||||
|
for t in g:
|
||||||
|
if t.name == 'delimiter' and t.string == '{':
|
||||||
|
stack.append(t.string)
|
||||||
|
starting = False
|
||||||
|
elif t.name == 'delimiter' and t.string == '}':
|
||||||
|
if not stack:
|
||||||
|
# we are totally hosed. start over. ugh.
|
||||||
|
#self.build_name_map()
|
||||||
|
raise Exception, "we're totally hosed"
|
||||||
|
return
|
||||||
|
stack.pop(-1)
|
||||||
|
if curr:
|
||||||
|
self.namelines[i] = (curr, tuple(stack))
|
||||||
|
i += 1
|
||||||
|
|
||||||
class C(mode.Fundamental):
|
class C(mode.Fundamental):
|
||||||
modename = 'C'
|
modename = 'C'
|
||||||
extensions = ['.c', '.h', '.cpp']
|
extensions = ['.c', '.h', '.cpp']
|
||||||
|
@ -230,6 +281,7 @@ class C(mode.Fundamental):
|
||||||
'header': ('green', 'default', 'bold'),
|
'header': ('green', 'default', 'bold'),
|
||||||
'structname': ('yellow', 'default', 'bold'),
|
'structname': ('yellow', 'default', 'bold'),
|
||||||
'enumname': ('yellow', 'default', 'bold'),
|
'enumname': ('yellow', 'default', 'bold'),
|
||||||
|
'c_type': ('green', 'default', 'bold'),
|
||||||
}
|
}
|
||||||
config = {
|
config = {
|
||||||
'c.syntax-cmd': "gcc -x c -fsyntax-only %(path)s",
|
'c.syntax-cmd': "gcc -x c -fsyntax-only %(path)s",
|
||||||
|
@ -238,6 +290,15 @@ class C(mode.Fundamental):
|
||||||
'c.make-rel-dir': True,
|
'c.make-rel-dir': True,
|
||||||
}
|
}
|
||||||
actions = [CCheckSyntax, CMake]
|
actions = [CCheckSyntax, CMake]
|
||||||
|
|
||||||
|
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', (')',))
|
||||||
|
@ -245,5 +306,15 @@ class C(mode.Fundamental):
|
||||||
self.add_bindings('close-bracket', (']',))
|
self.add_bindings('close-bracket', (']',))
|
||||||
self.add_bindings('c-check-syntax', ('C-c s',))
|
self.add_bindings('c-check-syntax', ('C-c s',))
|
||||||
self.add_bindings('c-make', ('C-c C-c',))
|
self.add_bindings('c-make', ('C-c C-c',))
|
||||||
|
self.context = CContext(self)
|
||||||
|
self.functions = None
|
||||||
|
self.funclines = None
|
||||||
|
|
||||||
|
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 = C.install
|
install = C.install
|
||||||
|
|
16
mode/perl.py
16
mode/perl.py
|
@ -743,20 +743,12 @@ class Perl(mode.Fundamental):
|
||||||
completers = {
|
completers = {
|
||||||
'perlfunction': PerlFunctionCompleter(),
|
'perlfunction': PerlFunctionCompleter(),
|
||||||
}
|
}
|
||||||
format = "%(flag)s %(bname)-18s (%(mname)s) %(cursor)s/%(mark)s %(perc)s [%(func)s]"
|
format = "%(flag)s %(bname)-18s (%(mname)s) %(indent)s %(cursor)s/%(mark)s %(perc)s [%(func)s]"
|
||||||
#format = "%(flag)s %(bname)-18s (%(mname)s) %(cursor)s/%(mark)s %(perc)s"
|
#format = "%(flag)s %(bname)-18s (%(mname)s) %(cursor)s/%(mark)s %(perc)s"
|
||||||
def get_status_names(self):
|
def get_status_names(self):
|
||||||
w = self.window
|
names = mode.Fundamental.get_status_names(self)
|
||||||
c = w.logical_cursor()
|
c = self.window.logical_cursor()
|
||||||
names = {
|
names['func'] = self.get_line_function(c.y)
|
||||||
'bname': w.buffer.name(),
|
|
||||||
'mname': self.name(),
|
|
||||||
'flag': self._get_flag(),
|
|
||||||
'perc': self._get_perc(),
|
|
||||||
'cursor': '(%d,%d)' % (c.y + 1, c.x + 1),
|
|
||||||
'mark': self._get_mark(),
|
|
||||||
'func': self.get_line_function(c.y),
|
|
||||||
}
|
|
||||||
return names
|
return names
|
||||||
def __init__(self, w):
|
def __init__(self, w):
|
||||||
mode.Fundamental.__init__(self, w)
|
mode.Fundamental.__init__(self, w)
|
||||||
|
|
|
@ -481,20 +481,15 @@ class Python(mode.Fundamental):
|
||||||
"pythonfunction": PythonFunctionCompleter(),
|
"pythonfunction": PythonFunctionCompleter(),
|
||||||
"pythonclass": PythonClassCompleter(),
|
"pythonclass": PythonClassCompleter(),
|
||||||
}
|
}
|
||||||
format = "%(flag)s %(bname)-18s (%(mname)s) %(cursor)s/%(mark)s %(perc)s [%(name)s]"
|
|
||||||
|
format = "%(flag)s %(bname)-18s (%(mname)s) %(indent)s %(cursor)s/%(mark)s %(perc)s [%(name)s]"
|
||||||
|
|
||||||
def get_status_names(self):
|
def get_status_names(self):
|
||||||
w = self.window
|
names = mode.Fundamental.get_status_names(self)
|
||||||
c = w.logical_cursor()
|
c = self.window.logical_cursor()
|
||||||
names = {
|
names['name'] = self.context.get_line_name(c.y)
|
||||||
'bname': w.buffer.name(),
|
|
||||||
'mname': self.name(),
|
|
||||||
'flag': self._get_flag(),
|
|
||||||
'perc': self._get_perc(),
|
|
||||||
'cursor': '(%d,%d)' % (c.y + 1, c.x + 1),
|
|
||||||
'mark': self._get_mark(),
|
|
||||||
'name': self.context.get_line_name(c.y),
|
|
||||||
}
|
|
||||||
return names
|
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', (')',))
|
||||||
|
|
Loading…
Reference in New Issue