lots of rendering fixes, more general completion support
--HG-- branch : pmacs2
This commit is contained in:
parent
c8d7bebc05
commit
f1308a4d34
|
@ -190,19 +190,20 @@ class Application(object):
|
||||||
method.DATATYPES['method'] = completer.MethodCompleter()
|
method.DATATYPES['method'] = completer.MethodCompleter()
|
||||||
method.DATATYPES['register'] = completer.RegisterCompleter()
|
method.DATATYPES['register'] = completer.RegisterCompleter()
|
||||||
method.DATATYPES['mode'] = completer.ModeCompleter()
|
method.DATATYPES['mode'] = completer.ModeCompleter()
|
||||||
method.DATATYPES['perlfunction'] = completer.PerlFunctionCompleter()
|
#method.DATATYPES['perlfunction'] = completer.PerlFunctionCompleter()
|
||||||
method.DATATYPES['pythonfunction'] = completer.PythonFunctionCompleter()
|
|
||||||
|
|
||||||
# set up curses
|
# set up curses
|
||||||
self.win = curses.newwin(self.y, self.x, 0, 0)
|
self.win = curses.newwin(self.y, self.x, 0, 0)
|
||||||
self.win.leaveok(0)
|
self.win.leaveok(0)
|
||||||
curses.meta(1)
|
curses.meta(1)
|
||||||
curses.cbreak()
|
curses.cbreak()
|
||||||
#curses.halfdelay(5)
|
|
||||||
curses.noecho()
|
curses.noecho()
|
||||||
curses.nonl()
|
curses.nonl()
|
||||||
curses.def_prog_mode()
|
curses.def_prog_mode()
|
||||||
|
|
||||||
|
def set_completer(self, datatype, completer):
|
||||||
|
method.DATATYPES[datatype] = completer
|
||||||
|
|
||||||
# this sets up a mode, as well as optionally adding information on when to
|
# this sets up a mode, as well as optionally adding information on when to
|
||||||
# auto-load the mode
|
# auto-load the mode
|
||||||
def setmode(self, name, cls, paths=[], basenames=[], extensions=[], detection=[]):
|
def setmode(self, name, cls, paths=[], basenames=[], extensions=[], detection=[]):
|
||||||
|
@ -582,8 +583,8 @@ class Application(object):
|
||||||
x = 0
|
x = 0
|
||||||
y += 1
|
y += 1
|
||||||
#XYZ
|
#XYZ
|
||||||
while w.ishidden(y) and y < len(w.buffer.lines):
|
#while w.ishidden(y) and y < len(w.buffer.lines):
|
||||||
y += 1
|
# y += 1
|
||||||
else:
|
else:
|
||||||
x += swidth
|
x += swidth
|
||||||
count += 1
|
count += 1
|
||||||
|
@ -628,8 +629,8 @@ class Application(object):
|
||||||
x = 0
|
x = 0
|
||||||
y += 1
|
y += 1
|
||||||
#XYZ
|
#XYZ
|
||||||
while w.ishidden(y) and y < len(w.buffer.lines):
|
#while w.ishidden(y) and y < len(w.buffer.lines):
|
||||||
y += 1
|
# y += 1
|
||||||
else:
|
else:
|
||||||
x += slot.width
|
x += slot.width
|
||||||
count += 1
|
count += 1
|
||||||
|
@ -665,8 +666,8 @@ class Application(object):
|
||||||
x = 0
|
x = 0
|
||||||
y += 1
|
y += 1
|
||||||
#XYZ
|
#XYZ
|
||||||
while w.ishidden(y) and y < len(w.buffer.lines):
|
#while w.ishidden(y) and y < len(w.buffer.lines):
|
||||||
y += 1
|
# y += 1
|
||||||
else:
|
else:
|
||||||
x += slot.width - 1
|
x += slot.width - 1
|
||||||
count += 1
|
count += 1
|
||||||
|
@ -684,9 +685,10 @@ class Application(object):
|
||||||
w = slot.window
|
w = slot.window
|
||||||
redattr = color.build_attr(color.pairs('red', 'default'))
|
redattr = color.build_attr(color.pairs('red', 'default'))
|
||||||
x, y = w.first.xy()
|
x, y = w.first.xy()
|
||||||
|
lm, rm = w.mode.lmargin, w.mode.rmargin
|
||||||
lines = w.buffer.lines
|
lines = w.buffer.lines
|
||||||
count = 0
|
count = 0
|
||||||
lm, rm = w.mode.lmargin, w.mode.rmargin
|
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
|
||||||
ended = False
|
ended = False
|
||||||
|
@ -695,7 +697,7 @@ class Application(object):
|
||||||
rlines = w.render_line_lit(y, slot.width - lm - rm)
|
rlines = w.render_line_lit(y, slot.width - lm - rm)
|
||||||
else:
|
else:
|
||||||
rlines = w.render_line_raw(y, slot.width - lm - rm)
|
rlines = w.render_line_raw(y, slot.width - lm - rm)
|
||||||
for j in range(0, len(rlines)):
|
for j in range(k, len(rlines)):
|
||||||
if lm:
|
if lm:
|
||||||
lcont = j > 0
|
lcont = j > 0
|
||||||
for rstr in slot.window.mode.get_lmargin(w, y, x, ended, lcont):
|
for rstr in slot.window.mode.get_lmargin(w, y, x, ended, lcont):
|
||||||
|
@ -707,6 +709,9 @@ class Application(object):
|
||||||
for rstr in slot.window.mode.get_rmargin(w, y, x, ended, rcont):
|
for rstr in slot.window.mode.get_rmargin(w, y, x, ended, rcont):
|
||||||
rstr.draw(self.win, slot.y_offset + count, slot.width - rm)
|
rstr.draw(self.win, slot.y_offset + count, slot.width - rm)
|
||||||
count += 1
|
count += 1
|
||||||
|
if count >= slot.height:
|
||||||
|
break
|
||||||
|
k = 0
|
||||||
y += 1
|
y += 1
|
||||||
ended = ended or y >= len(w.buffer.lines)
|
ended = ended or y >= len(w.buffer.lines)
|
||||||
|
|
||||||
|
|
12
completer.py
12
completer.py
|
@ -105,15 +105,3 @@ class RegisterCompleter(Completer):
|
||||||
class ModeCompleter(Completer):
|
class ModeCompleter(Completer):
|
||||||
def get_candidates(self, s, w=None):
|
def get_candidates(self, s, w=None):
|
||||||
return [n for n in w.application.modes if n.startswith(s)]
|
return [n for n in w.application.modes if n.startswith(s)]
|
||||||
|
|
||||||
class PerlFunctionCompleter(Completer):
|
|
||||||
def get_candidates(self, s, w=None):
|
|
||||||
old_window = w.buffer.method.old_window
|
|
||||||
functions = old_window.mode.get_functions()
|
|
||||||
return [n for n in functions if n.startswith(s)]
|
|
||||||
|
|
||||||
class PythonFunctionCompleter(Completer):
|
|
||||||
def get_candidates(self, s, w=None):
|
|
||||||
old_window = w.buffer.method.old_window
|
|
||||||
functions = old_window.mode.get_functions()
|
|
||||||
return [n for n in functions if n.startswith(s)]
|
|
||||||
|
|
|
@ -89,6 +89,7 @@ class Fundamental(Handler):
|
||||||
colors = {}
|
colors = {}
|
||||||
config = {}
|
config = {}
|
||||||
actions = []
|
actions = []
|
||||||
|
completers = {}
|
||||||
|
|
||||||
# margin/line numbering
|
# margin/line numbering
|
||||||
show_line_numbers = False
|
show_line_numbers = False
|
||||||
|
@ -113,6 +114,8 @@ class Fundamental(Handler):
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
app.methods[m.name] = m
|
app.methods[m.name] = m
|
||||||
|
for (datatype, completer) in cls.completers.iteritems():
|
||||||
|
app.set_completer(datatype, completer)
|
||||||
install = classmethod(install)
|
install = classmethod(install)
|
||||||
|
|
||||||
def __init__(self, w):
|
def __init__(self, w):
|
||||||
|
|
15
mode/perl.py
15
mode/perl.py
|
@ -1,5 +1,5 @@
|
||||||
import re, sets, string, sys
|
import re, sets, string, sys
|
||||||
import color, commands, default, method, mode, regex, tab
|
import color, commands, completer, default, method, mode, regex, tab
|
||||||
from point import Point
|
from point import Point
|
||||||
from lex import Grammar, PatternRule, ContextPatternRule, RegionRule, OverridePatternRule, PatternGroupRule
|
from lex import Grammar, PatternRule, ContextPatternRule, RegionRule, OverridePatternRule, PatternGroupRule
|
||||||
from method import Argument, Method, WrapParagraph
|
from method import Argument, Method, WrapParagraph
|
||||||
|
@ -577,6 +577,12 @@ class PerlWrapParagraph(method.WrapParagraph):
|
||||||
else:
|
else:
|
||||||
w.set_error("did not detect comment or pod lines")
|
w.set_error("did not detect comment or pod lines")
|
||||||
|
|
||||||
|
class PerlFunctionCompleter(completer.Completer):
|
||||||
|
def get_candidates(self, s, w=None):
|
||||||
|
old_window = w.buffer.method.old_window
|
||||||
|
functions = old_window.mode.get_functions()
|
||||||
|
return [n for n in functions if n.startswith(s)]
|
||||||
|
|
||||||
class Perl(mode.Fundamental):
|
class Perl(mode.Fundamental):
|
||||||
modename = 'Perl'
|
modename = 'Perl'
|
||||||
extensions = ['.pl', '.pm']
|
extensions = ['.pl', '.pm']
|
||||||
|
@ -604,7 +610,6 @@ class Perl(mode.Fundamental):
|
||||||
# basic stuff
|
# basic stuff
|
||||||
'escaped': ('magenta', 'default'),
|
'escaped': ('magenta', 'default'),
|
||||||
'null': ('default', 'default'),
|
'null': ('default', 'default'),
|
||||||
#'delimiter': ('default', 'default'),
|
|
||||||
'sub': ('cyan', 'default'),
|
'sub': ('cyan', 'default'),
|
||||||
'prototype': ('magenta', 'default'),
|
'prototype': ('magenta', 'default'),
|
||||||
'number': ('default', 'default'),
|
'number': ('default', 'default'),
|
||||||
|
@ -689,9 +694,11 @@ class Perl(mode.Fundamental):
|
||||||
PerlViewModulePerldoc, PerlViewWordPerldoc, PerlWrapParagraph,
|
PerlViewModulePerldoc, PerlViewWordPerldoc, PerlWrapParagraph,
|
||||||
PerlInitFunctions, PerlGotoFunction, PerlWhichFunction,
|
PerlInitFunctions, PerlGotoFunction, PerlWhichFunction,
|
||||||
PerlListFunctions]
|
PerlListFunctions]
|
||||||
|
completers = {
|
||||||
|
'perlfunction': PerlFunctionCompleter(),
|
||||||
|
}
|
||||||
def __init__(self, w):
|
def __init__(self, w):
|
||||||
mode.Fundamental.__init__(self, w)
|
mode.Fundamental.__init__(self, w)
|
||||||
|
|
||||||
self.add_bindings('perl-set-lib', ('C-c l',))
|
self.add_bindings('perl-set-lib', ('C-c l',))
|
||||||
self.add_bindings('perl-check-syntax', ('C-c s',))
|
self.add_bindings('perl-check-syntax', ('C-c s',))
|
||||||
self.add_bindings('perl-hash-cleanup', ('C-c h',))
|
self.add_bindings('perl-hash-cleanup', ('C-c h',))
|
||||||
|
@ -705,8 +712,6 @@ class Perl(mode.Fundamental):
|
||||||
self.add_bindings('close-paren', (')'))
|
self.add_bindings('close-paren', (')'))
|
||||||
self.add_bindings('close-bracket', (']'))
|
self.add_bindings('close-bracket', (']'))
|
||||||
self.add_bindings('close-brace', ('}'))
|
self.add_bindings('close-brace', ('}'))
|
||||||
|
|
||||||
# perl-specific
|
|
||||||
self.functions = None
|
self.functions = None
|
||||||
|
|
||||||
def build_function_map(self):
|
def build_function_map(self):
|
||||||
|
|
|
@ -173,12 +173,24 @@ class PythonTabber(tab.StackTabber):
|
||||||
self._append(token.string, currlvl + w)
|
self._append(token.string, currlvl + w)
|
||||||
return currlvl
|
return currlvl
|
||||||
|
|
||||||
class PythonInitFunctions(method.Method):
|
class PythonInitNames(method.Method):
|
||||||
'''Jump to a function defined in this module'''
|
'''Jump to a function defined in this module'''
|
||||||
def _execute(self, w, **vargs):
|
def _execute(self, w, **vargs):
|
||||||
w.mode.build_function_map()
|
w.mode.build_name_map()
|
||||||
w.application.set_error("Initialized function map")
|
w.application.set_error("Initialized name maps")
|
||||||
|
|
||||||
|
class PythonGotoName(method.Method):
|
||||||
|
'''Jump to a class or function defined in this module'''
|
||||||
|
args = [method.Argument("name", type(""), "pythonname", "Goto Name: ")]
|
||||||
|
def _execute(self, w, **vargs):
|
||||||
|
name = vargs['name']
|
||||||
|
d = {}
|
||||||
|
d.update(w.mode.get_classes())
|
||||||
|
d.update(w.mode.get_functions())
|
||||||
|
if name in d:
|
||||||
|
w.goto(Point(0, d[name]))
|
||||||
|
else:
|
||||||
|
w.application.set_error("Function %r was not found" % name)
|
||||||
class PythonGotoFunction(method.Method):
|
class PythonGotoFunction(method.Method):
|
||||||
'''Jump to a function defined in this module'''
|
'''Jump to a function defined in this module'''
|
||||||
args = [method.Argument("name", type(""), "pythonfunction", "Goto Function: ")]
|
args = [method.Argument("name", type(""), "pythonfunction", "Goto Function: ")]
|
||||||
|
@ -189,13 +201,24 @@ class PythonGotoFunction(method.Method):
|
||||||
w.goto(Point(0, functions[name]))
|
w.goto(Point(0, functions[name]))
|
||||||
else:
|
else:
|
||||||
w.application.set_error("Function %r was not found" % name)
|
w.application.set_error("Function %r was not found" % name)
|
||||||
|
class PythonGotoClass(method.Method):
|
||||||
|
'''Jump to a class defined in this module'''
|
||||||
|
args = [method.Argument("name", type(""), "pythonclass", "Goto Class: ")]
|
||||||
|
def _execute(self, w, **vargs):
|
||||||
|
name = vargs['name']
|
||||||
|
classes = w.mode.get_classes()
|
||||||
|
if name in classes:
|
||||||
|
w.goto(Point(0, classes[name]))
|
||||||
|
else:
|
||||||
|
w.application.set_error("Class %r was not found" % name)
|
||||||
|
|
||||||
class PythonListFunctions(method.Method):
|
class PythonListNames(method.Method):
|
||||||
'''Show the user all functions defined in this module'''
|
'''Show the user all functions defined in this module'''
|
||||||
def _execute(self, w, **vargs):
|
def _execute(self, w, **vargs):
|
||||||
names = w.mode.get_function_names()
|
names = w.mode.get_function_names()
|
||||||
output = "\n".join(names) + "\n"
|
names.extend(w.mode.get_class_names())
|
||||||
w.application.data_buffer("*Python-List-Functions*", output, switch_to=True)
|
output = '\n'.join(sorted(names)) + "\n"
|
||||||
|
w.application.data_buffer("*Python-List-Names*", output, switch_to=True)
|
||||||
|
|
||||||
class PythonCheckSyntax(method.Method):
|
class PythonCheckSyntax(method.Method):
|
||||||
'''Check the syntax of the current python file'''
|
'''Check the syntax of the current python file'''
|
||||||
|
@ -307,6 +330,24 @@ class PythonInsertTripleDquotes(method.Method):
|
||||||
for i in range(0, 3):
|
for i in range(0, 3):
|
||||||
w.backward()
|
w.backward()
|
||||||
|
|
||||||
|
class PythonFunctionCompleter(completer.Completer):
|
||||||
|
def get_candidates(self, s, w=None):
|
||||||
|
old_window = w.buffer.method.old_window
|
||||||
|
functions = old_window.mode.get_functions()
|
||||||
|
return [n for n in functions if n.startswith(s)]
|
||||||
|
class PythonClassCompleter(completer.Completer):
|
||||||
|
def get_candidates(self, s, w=None):
|
||||||
|
old_window = w.buffer.method.old_window
|
||||||
|
classes = old_window.mode.get_classes()
|
||||||
|
return [n for n in classes if n.startswith(s)]
|
||||||
|
class PythonNameCompleter(completer.Completer):
|
||||||
|
def get_candidates(self, s, w=None):
|
||||||
|
old_window = w.buffer.method.old_window
|
||||||
|
names = []
|
||||||
|
names.extend(old_window.mode.get_classes())
|
||||||
|
names.extend(old_window.mode.get_functions())
|
||||||
|
return [n for n in names if n.startswith(s)]
|
||||||
|
|
||||||
class Python(mode.Fundamental):
|
class Python(mode.Fundamental):
|
||||||
modename = 'Python'
|
modename = 'Python'
|
||||||
extensions = ['.py']
|
extensions = ['.py']
|
||||||
|
@ -332,26 +373,34 @@ class Python(mode.Fundamental):
|
||||||
config = {
|
config = {
|
||||||
'python.lib': '.',
|
'python.lib': '.',
|
||||||
}
|
}
|
||||||
actions = [PythonInitFunctions, PythonListFunctions, PythonGotoFunction,
|
actions = [PythonInitNames, PythonListNames, PythonGotoName,
|
||||||
PythonCheckSyntax, PythonDictCleanup, PythonInsertTripleSquotes,
|
PythonGotoFunction, PythonGotoClass, PythonCheckSyntax,
|
||||||
PythonInsertTripleDquotes]
|
PythonDictCleanup,
|
||||||
|
PythonInsertTripleSquotes, PythonInsertTripleDquotes]
|
||||||
|
completers = {
|
||||||
|
"pythonname": PythonNameCompleter(),
|
||||||
|
"pythonfunction": PythonFunctionCompleter(),
|
||||||
|
"pythonclass": PythonClassCompleter(),
|
||||||
|
}
|
||||||
def __init__(self, w):
|
def __init__(self, w):
|
||||||
mode.Fundamental.__init__(self, w)
|
mode.Fundamental.__init__(self, w)
|
||||||
# tag matching
|
|
||||||
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', (']',))
|
||||||
# add python-specific methods
|
self.add_bindings('python-goto-name', ('C-c M-g',))
|
||||||
self.add_bindings('python-goto-function', ('C-c M-g',))
|
self.add_bindings('python-goto-function', ('C-c M-f',))
|
||||||
|
self.add_bindings('python-goto-class', ('C-c M-c',))
|
||||||
self.add_bindings('python-check-syntax', ('C-c s',))
|
self.add_bindings('python-check-syntax', ('C-c s',))
|
||||||
self.add_bindings('python-dict-cleanup', ('C-c h',))
|
self.add_bindings('python-dict-cleanup', ('C-c h',))
|
||||||
self.add_bindings('python-insert-triple-squotes', ('C-c M-\'',))
|
self.add_bindings('python-insert-triple-squotes', ('C-c M-\'',))
|
||||||
self.add_bindings('python-insert-triple-dquotes', ('C-c M-"',))
|
self.add_bindings('python-insert-triple-dquotes', ('C-c M-"',))
|
||||||
# other python
|
|
||||||
|
self.classes = None
|
||||||
self.functions = None
|
self.functions = None
|
||||||
def build_function_map(self):
|
def build_name_map(self):
|
||||||
b = self.window.buffer
|
b = self.window.buffer
|
||||||
scope_stack = []
|
scope_stack = []
|
||||||
|
self.classes = {}
|
||||||
self.functions = {}
|
self.functions = {}
|
||||||
for i in range(0, len(b.lines)):
|
for i in range(0, len(b.lines)):
|
||||||
if regex.whitespace.match(b.lines[i]):
|
if regex.whitespace.match(b.lines[i]):
|
||||||
|
@ -368,15 +417,20 @@ class Python(mode.Fundamental):
|
||||||
if m:
|
if m:
|
||||||
(ws, typ, name) = m.groups()
|
(ws, typ, name) = m.groups()
|
||||||
lvl = len(ws)
|
lvl = len(ws)
|
||||||
|
if typ == 'class':
|
||||||
|
#raise Exception, repr(m.groups())
|
||||||
|
d = self.classes
|
||||||
|
else:
|
||||||
|
d = self.functions
|
||||||
if scope_stack:
|
if scope_stack:
|
||||||
prefix = '.'.join([x[1] for x in scope_stack])
|
prefix = '.'.join([x[1] for x in scope_stack])
|
||||||
self.functions['%s.%s' % (prefix, name)] = i
|
d['%s.%s' % (prefix, name)] = i
|
||||||
else:
|
else:
|
||||||
self.functions[name] = i
|
d[name] = i
|
||||||
scope_stack.append((len(ws), name))
|
scope_stack.append((len(ws), name))
|
||||||
def get_functions(self):
|
def get_functions(self):
|
||||||
if self.functions is None:
|
if self.functions is None:
|
||||||
self.build_function_map()
|
self.build_name_map()
|
||||||
return self.functions
|
return self.functions
|
||||||
def get_function_names(self):
|
def get_function_names(self):
|
||||||
functions = self.get_functions()
|
functions = self.get_functions()
|
||||||
|
@ -384,5 +438,15 @@ class Python(mode.Fundamental):
|
||||||
pairs.sort()
|
pairs.sort()
|
||||||
names = [x[1] for x in pairs]
|
names = [x[1] for x in pairs]
|
||||||
return names
|
return names
|
||||||
|
def get_classes(self):
|
||||||
|
if self.classes is None:
|
||||||
|
self.build_name_map()
|
||||||
|
return self.classes
|
||||||
|
def get_class_names(self):
|
||||||
|
classes = self.get_classes()
|
||||||
|
pairs = [[classes[key], key] for key in classes]
|
||||||
|
pairs.sort()
|
||||||
|
names = [x[1] for x in pairs]
|
||||||
|
return names
|
||||||
|
|
||||||
install = Python.install
|
install = Python.install
|
||||||
|
|
|
@ -9,4 +9,9 @@ class RenderString(object):
|
||||||
self.x = x
|
self.x = x
|
||||||
self.attrs = attrs
|
self.attrs = attrs
|
||||||
def draw(self, cwin, y, x):
|
def draw(self, cwin, y, x):
|
||||||
|
try:
|
||||||
cwin.addstr(y, self.x + x, self.string, self.attrs)
|
cwin.addstr(y, self.x + x, self.string, self.attrs)
|
||||||
|
except:
|
||||||
|
#return
|
||||||
|
raise Exception, "cwin.addstr(%d, %d + %d, %r, %r) failed" % \
|
||||||
|
(y, self.x, x, self.string, self.attrs)
|
||||||
|
|
Loading…
Reference in New Issue