branch : pmacs2
This commit is contained in:
moculus 2008-05-12 03:37:57 +00:00
parent af1ccc71af
commit dc625d6eb5
7 changed files with 151 additions and 30 deletions

8
IDEAS
View File

@ -1,3 +1,11 @@
2008/05/11:
perl/python "open-module-by-name" command (auto-completing?).
python view help(time)-style documentation in buffer
convert console to user colorbuffer tech
step out of minibuffer support
click on completion support
2008/05/03: 2008/05/03:
use a error-buffer (pop up?) for reporting various errors. use a error-buffer (pop up?) for reporting various errors.

View File

@ -386,8 +386,7 @@ class ConsoleBuffer(Buffer):
def clear(self): def clear(self):
lines = ['Python Console\n', lines = ['Python Console\n',
"Evaluate python expressions in the editor's context (self)\n", "Evaluate python expressions in the editor's context (self)\n",
'Press Control-] to exit\n', 'Press Control-] to exit\n']
'\n']
console.set_data(''.join(lines), force=True) console.set_data(''.join(lines), force=True)
def name(self): def name(self):
return '*Console*' return '*Console*'

View File

@ -1,7 +1,12 @@
import color, mode import color, mode
from lex import Grammar, PatternRule, RegionRule from lex import Grammar, PatternRule, RegionRule
from mode.python import StringGrammar from mode.python import StringGrammar, PythonGrammar
class ReprGrammar(Grammar):
rules = [
RegionRule(r'string', r'"', StringGrammar, r'"'),
RegionRule(r'string', r"'", StringGrammar, r"'"),
]
class ConsoleGrammar(Grammar): class ConsoleGrammar(Grammar):
rules = [ rules = [
PatternRule(r'console_mesg', r'^[A-Za-z].*$'), PatternRule(r'console_mesg', r'^[A-Za-z].*$'),
@ -9,14 +14,24 @@ class ConsoleGrammar(Grammar):
PatternRule(r'console_input', r'^-->.*$'), PatternRule(r'console_input', r'^-->.*$'),
RegionRule(r'string', r'"', StringGrammar, r'"'), RegionRule(r'string', r'"', StringGrammar, r'"'),
RegionRule(r'string', r"'", StringGrammar, r"'"), RegionRule(r'string', r"'", StringGrammar, r"'"),
PatternRule(r'bareword', r'[a-zA-Z_][a-zA-Z0-9_]*'), #RegionRule(r'console_repr', r"<", ReprGrammar, r">"),
PatternRule(r'console_reserved', r'True|False|None'),
PatternRule(r'console_bareword', r'[a-zA-Z_][a-zA-Z0-9_]*'),
] ]
class Console(mode.Fundamental): class Console(mode.Fundamental):
modename = 'Console' modename = 'Console'
grammar = ConsoleGrammar() grammar = ConsoleGrammar()
colors = { colors = {
'console_mesg': ('blue', 'default', 'bold'), 'console_mesg': ('magenta', 'default', 'bold'),
'console_input': ('cyan', 'default', 'bold'), 'console_input': ('cyan', 'default', 'bold'),
'console_reserved': ('magenta', 'default', 'bold'),
'console_bareword': ('default', 'default', 'bold'),
'console_repr.start': ('default', 'default', 'bold'),
'console_repr.null': ('blue', 'default', 'bold'),
'console_repr.string.start': ('cyan', 'default', 'bold'),
'console_repr.string.null': ('cyan', 'default', 'bold'),
'console_repr.string.end': ('cyan', 'default', 'bold'),
'console_repr.end': ('default', 'default', 'bold'),
} }
install = Console.install install = Console.install

View File

@ -4,6 +4,7 @@ from lex import Grammar, PatternRule
from mode.python import PythonGrammar from mode.python import PythonGrammar
from point import Point from point import Point
PAD = ' '
LIMIT = 79 LIMIT = 79
class ConsoleExec(method.Method): class ConsoleExec(method.Method):
@ -15,7 +16,6 @@ class ConsoleExec(method.Method):
w.mode.hindex = len(w.mode.history) - 1 w.mode.hindex = len(w.mode.history) - 1
a = w.application a = w.application
if not a.has_buffer_name('*Console*'): if not a.has_buffer_name('*Console*'):
raise Exception, "No console found!" raise Exception, "No console found!"
b = a.bufferlist.get_buffer_by_name('*Console*') b = a.bufferlist.get_buffer_by_name('*Console*')
@ -55,27 +55,33 @@ class ConsoleExec(method.Method):
t = sys.exc_traceback t = sys.exc_traceback
output = str(e) + traceback.format_exc() output = str(e) + traceback.format_exc()
limit = 1000
for w2 in b.windows:
limit = min(w.width, limit)
if limit == 1000:
limit = LIMIT
limit -= len(PAD)
if output: if output:
newlines = [' %s' % x for x in output.split('\n')] newlines = []
assert newlines[-1] == ' ' for line in output.split('\n'):
newlines[-1] = ''
newlines2 = []
for line in newlines:
i = 0 i = 0
while i + LIMIT < len(line): while i + limit < len(line):
j = LIMIT j = limit
while j > 0 and line[i + j] != ' ': while j > 0 and line[i + j] != ' ':
j -= 1 j -= 1
if j == 0: if j == 0:
newlines2.append(line[i:i + LIMIT]) newlines.append(PAD + line[i:i + limit])
i += j i += j
else: else:
newlines2.append(line[i:i + j]) newlines.append(PAD + line[i:i + j])
i += j + 1 i += j + 1
newlines2.append(line[i:]) newlines.append(PAD + line[i:])
b.insert_lines(b.get_buffer_end(), newlines2, force=True) assert newlines[-1] == PAD
newlines[-1] = ''
b.insert_lines(b.get_buffer_end(), newlines, force=True)
for w2 in b.windows: for w2 in b.windows:
w2.goto_end() w2.goto_end(force=True)
class ConsoleCancel(method.Method): class ConsoleCancel(method.Method):
def execute(self, w, **vargs): def execute(self, w, **vargs):
@ -178,11 +184,33 @@ class ConsoleTab(method.Method):
s = candidates[0][len(name):] s = candidates[0][len(name):]
w.insert_string_at_cursor(s) w.insert_string_at_cursor(s)
class ConsoleBaseMethod(method.Method):
subcls = method.Method
def __init__(self):
method.Method.__init__(self)
self.submethod = self.subcls()
def _execute(self, w, **vargs):
a = w.application
if not a.has_buffer_name('*Console*'):
raise Exception, "No console found!"
w2 = a.bufferlist.get_buffer_by_name('*Console*').windows[0]
self.submethod.execute(w2, **vargs)
class ConsolePageUp(ConsoleBaseMethod):
subcls = method.move.PageUp
class ConsolePageDown(ConsoleBaseMethod):
subcls = method.move.PageDown
class ConsoleGotoBeginning(ConsoleBaseMethod):
subcls = method.move.GotoBeginning
class ConsoleGotoEnd(ConsoleBaseMethod):
subcls = method.move.GotoEnd
class ConsoleMini(mode.Fundamental): class ConsoleMini(mode.Fundamental):
modename = 'ConsoleMini' modename = 'ConsoleMini'
grammar = PythonGrammar grammar = PythonGrammar
actions = [ConsoleExec, ConsoleClear, ConsoleCancel, ConsoleHistoryPrev, actions = [ConsoleExec, ConsoleClear, ConsoleCancel, ConsoleHistoryPrev,
ConsoleHistoryNext, ConsoleTab] ConsoleHistoryNext, ConsoleTab,
ConsolePageUp, ConsolePageDown, ConsoleGotoBeginning, ConsoleGotoEnd]
def __init__(self, w): def __init__(self, w):
mode.Fundamental.__init__(self, w) mode.Fundamental.__init__(self, w)
self.bindings = {} self.bindings = {}
@ -225,6 +253,10 @@ class ConsoleMini(mode.Fundamental):
self.add_bindings('console-history-prev', ('C-p',)) self.add_bindings('console-history-prev', ('C-p',))
self.add_bindings('console-history-next', ('C-n',)) self.add_bindings('console-history-next', ('C-n',))
self.add_bindings('console-tab', ('TAB',)) self.add_bindings('console-tab', ('TAB',))
self.add_bindings('console-page-up', ('M-v',))
self.add_bindings('console-page-down', ('C-v',))
self.add_bindings('console-goto-beginning', ('M-<',))
self.add_bindings('console-goto-end', ('M->',))
for c in string.letters + string.digits + string.punctuation: for c in string.letters + string.digits + string.punctuation:
self.add_binding('insert-string-%s' % c, c) self.add_binding('insert-string-%s' % c, c)

View File

@ -13,6 +13,9 @@ class ErlangGrammar(Grammar):
PatternRule(r'comment', r'%.*$'), PatternRule(r'comment', r'%.*$'),
PatternRule(r'erl_attribute', r'-[a-z][a-zA-Z0-9_@]+'), PatternRule(r'erl_attribute', r'-[a-z][a-zA-Z0-9_@]+'),
PatternRule(r'erl_reserved', r"(?:xor|when|try|rem|receive|query|orelse|or|of|not|let|if|fun|end|div|cond|catch|case|bxor|bsr|bsl|bor|bnot|begin|band|andalso|and|after)(?![a-zA-Z0-9_'])"), PatternRule(r'erl_reserved', r"(?:xor|when|try|rem|receive|query|orelse|or|of|not|let|if|fun|end|div|cond|catch|case|bxor|bsr|bsl|bor|bnot|begin|band|andalso|and|after)(?![a-zA-Z0-9_'])"),
PatternRule(r'erl_arity', r'[a-z][a-zA-Z0-9_@]*/[1-9][0-9]*'),
PatternRule(r'erl_function', r'[a-z][a-zA-Z0-9_@]*(?= *\()'),
PatternRule(r'erl_namespace', r'[a-z][a-zA-Z0-9_@]*(?=:)'),
PatternRule(r'erl_builtin', r"whereis|unregister|unlink|tuple_to_list|tuple_size|trunc|tl|time|throw|term_to_binary|term_to_binary|statistics|split_binary|spawn_opt|spawn_opt|spawn_opt|spawn_opt|spawn_monitor|spawn_monitor|spawn_link|spawn_link|spawn_link|spawn_link|spawn|spawn|spawn|spawn|size|setelement|self|round|registered|register|put|purge_module|process_info|process_info|process_flag|process_flag|processes|pre_loaded|port_control|port_connect|port_command|port_close|pid_to_list|open_port|now|nodes|nodes|node|node|monitor_node|module_loaded|make_ref|load_module|list_to_tuple|list_to_pid|list_to_integer|list_to_float|list_to_existing_atom|list_to_bitstring|list_to_binary|list_to_atom|link|length|is_tuple|is_reference|is_record|is_record|is_process_alive|is_port|is_pid|is_number|is_list|is_integer|is_function|is_function|is_float|is_boolean|is_bitstring|is_binary|is_atom|is_alive|iolist_to_binary|iolist_size|iolist|iodata|integer_to_list|hd|halt|halt|group_leader|group_leader|get_keys|get|get|garbage_collect|garbage_collect|float_to_list|float|ext_binary|exit|exit|erase|erase|ence|element|disconnect_node|delete_module|date|concat_binary|check_process_code|byte_size|bitstring_to_list|bit_size|binary_to_term|binary_to_list|binary_to_list|atom_to_list|atom_to_list|apply|apply|apply|abs"), PatternRule(r'erl_builtin', r"whereis|unregister|unlink|tuple_to_list|tuple_size|trunc|tl|time|throw|term_to_binary|term_to_binary|statistics|split_binary|spawn_opt|spawn_opt|spawn_opt|spawn_opt|spawn_monitor|spawn_monitor|spawn_link|spawn_link|spawn_link|spawn_link|spawn|spawn|spawn|spawn|size|setelement|self|round|registered|register|put|purge_module|process_info|process_info|process_flag|process_flag|processes|pre_loaded|port_control|port_connect|port_command|port_close|pid_to_list|open_port|now|nodes|nodes|node|node|monitor_node|module_loaded|make_ref|load_module|list_to_tuple|list_to_pid|list_to_integer|list_to_float|list_to_existing_atom|list_to_bitstring|list_to_binary|list_to_atom|link|length|is_tuple|is_reference|is_record|is_record|is_process_alive|is_port|is_pid|is_number|is_list|is_integer|is_function|is_function|is_float|is_boolean|is_bitstring|is_binary|is_atom|is_alive|iolist_to_binary|iolist_size|iolist|iodata|integer_to_list|hd|halt|halt|group_leader|group_leader|get_keys|get|get|garbage_collect|garbage_collect|float_to_list|float|ext_binary|exit|exit|erase|erase|ence|element|disconnect_node|delete_module|date|concat_binary|check_process_code|byte_size|bitstring_to_list|bit_size|binary_to_term|binary_to_list|binary_to_list|atom_to_list|atom_to_list|apply|apply|apply|abs"),
RegionRule(r'string', r'"', StringGrammar, r'"'), RegionRule(r'string', r'"', StringGrammar, r'"'),
RegionRule(r'erl_atom', r"'", StringGrammar, r"'"), RegionRule(r'erl_atom', r"'", StringGrammar, r"'"),
@ -27,7 +30,7 @@ class Erlang(mode.Fundamental):
modename = 'Erlang' modename = 'Erlang'
extensions = ['.erl'] extensions = ['.erl']
tabwidth = 4 tabwidth = 4
#tabbercls = mode.lisp.LispTabber #tabbercls = ErlangTabber
grammar = ErlangGrammar grammar = ErlangGrammar
opentokens = ('delimiter',) opentokens = ('delimiter',)
opentags = {'(': ')', '[': ']', '{': '}'} opentags = {'(': ')', '[': ']', '{': '}'}
@ -36,10 +39,16 @@ class Erlang(mode.Fundamental):
colors = { colors = {
'erl_attribute': ('cyan', 'default', 'bold'), 'erl_attribute': ('cyan', 'default', 'bold'),
'erl_reserved': ('cyan', 'default', 'bold'), 'erl_reserved': ('cyan', 'default', 'bold'),
'erl_arity': ('magenta', 'default', 'bold'),
'erl_namespace': ('magenta', 'default', 'bold'),
'erl_function': ('blue', 'default', 'bold'),
'erl_builtin': ('magenta', 'default', 'bold'), 'erl_builtin': ('magenta', 'default', 'bold'),
'erl_atom': ('blue', 'default', 'bold'),
'erl_variable': ('yellow', 'default', 'bold'), 'erl_variable': ('yellow', 'default', 'bold'),
'erl_operator': ('default', 'default', 'bold'), 'erl_operator': ('default', 'default', 'bold'),
'erl_atom': ('magenta', 'default', 'bold'),
'erl_atom.start': ('magenta', 'default', 'bold'),
'erl_atom.null': ('magenta', 'default', 'bold'),
'erl_atom.end': ('magenta', 'default', 'bold'),
} }
def __init__(self, w): def __init__(self, w):
mode.Fundamental.__init__(self, w) mode.Fundamental.__init__(self, w)

View File

@ -1,5 +1,5 @@
import re, sets, string, sys import re, sets, string, sys
import color, commands, completer, default, method, mode, regex, tab import color, commands, completer, context, 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
@ -578,6 +578,64 @@ class PerlFunctionCompleter(completer.Completer):
functions = old_window.mode.get_functions() functions = old_window.mode.get_functions()
return [n for n in functions if n.startswith(s)] return [n for n in functions if n.startswith(s)]
class PerlContext(context.Context):
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
while i < y2:
g = highlights.tokens[i]
if (len(g) == 1 and g[0].name == 'eol' or
len(g) == 2 and g[0].name == 'null' and g[1].name == 'eol'):
if last is None:
last = i
i += 1
if i == y2 and y2 < blen:
y2 += 1
continue
if g[0].name == 'null':
j, lvl = 1, len(g[0].string)
else:
j, lvl = 0, 0
while stack and lvl <= stack[-1][0]:
stack.pop(-1)
if last is not None:
curr = '.'.join([x[1] for x in stack])
if curr:
for k in range(last, i):
self.namelines[k] = curr
last = None
if len(g[j:]) > 3:
d, found = None, False
if g[j].name == 'python_keyword' and g[j].string == 'class':
d, found = self.classes, True
elif g[j].name == 'python_keyword' and g[j].string == 'def':
d, found = self.functions, True
if found:
stack.append([lvl, g[j+2].string])
curr = '.'.join([x[1] for x in stack])
d[curr] = i
self.names[curr] = i
else:
curr = '.'.join([x[1] for x in stack])
if i == y2 - 1 and curr != self.namelines[i] and y2 < blen:
y2 += 1
if curr:
self.namelines[i] = curr
i += 1
if last is not None and y2 < len(self.namelines):
if self.namelines[y2]:
n = len(self.namelines[y2].split('.'))
curr = '.'.join([x[1] for x in stack[:n]])
if curr:
for k in range(last, y2):
self.namelines[k] = curr
class Perl(mode.Fundamental): class Perl(mode.Fundamental):
modename = 'Perl' modename = 'Perl'
extensions = ['.pl', '.pm'] extensions = ['.pl', '.pm']

View File

@ -438,7 +438,7 @@ class Window(object):
def goto_beginning(self): def goto_beginning(self):
self.cursor = Point(0, 0) self.cursor = Point(0, 0)
self.assure_visible_cursor() self.assure_visible_cursor()
def goto_end(self): def goto_end(self, force=False):
self.cursor = self.buffer.get_buffer_end() self.cursor = self.buffer.get_buffer_end()
(x, y) = self.logical_cursor().xy() (x, y) = self.logical_cursor().xy()
if x == 0: if x == 0:
@ -458,7 +458,7 @@ class Window(object):
break break
counter += 1 counter += 1
if not self.cursor_is_visible(): if force or not self.cursor_is_visible():
self.first = Point(x - (x % self.width), y) self.first = Point(x - (x % self.width), y)
self.redraw() self.redraw()