From dc625d6eb577156b13102a81b92e9e29992e931f Mon Sep 17 00:00:00 2001 From: moculus Date: Mon, 12 May 2008 03:37:57 +0000 Subject: [PATCH] --HG-- branch : pmacs2 --- IDEAS | 8 ++++++ buffer.py | 3 +-- mode/console.py | 23 ++++++++++++++--- mode/consolemini.py | 60 ++++++++++++++++++++++++++++++++++----------- mode/erlang.py | 23 +++++++++++------ mode/perl.py | 60 ++++++++++++++++++++++++++++++++++++++++++++- window.py | 4 +-- 7 files changed, 151 insertions(+), 30 deletions(-) diff --git a/IDEAS b/IDEAS index 84bf572..40d98cc 100644 --- a/IDEAS +++ b/IDEAS @@ -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: use a error-buffer (pop up?) for reporting various errors. diff --git a/buffer.py b/buffer.py index c573117..0a22e20 100644 --- a/buffer.py +++ b/buffer.py @@ -386,8 +386,7 @@ class ConsoleBuffer(Buffer): def clear(self): lines = ['Python Console\n', "Evaluate python expressions in the editor's context (self)\n", - 'Press Control-] to exit\n', - '\n'] + 'Press Control-] to exit\n'] console.set_data(''.join(lines), force=True) def name(self): return '*Console*' diff --git a/mode/console.py b/mode/console.py index f9ceba9..ded13d2 100644 --- a/mode/console.py +++ b/mode/console.py @@ -1,7 +1,12 @@ import color, mode 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): rules = [ PatternRule(r'console_mesg', r'^[A-Za-z].*$'), @@ -9,14 +14,24 @@ class ConsoleGrammar(Grammar): PatternRule(r'console_input', 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): modename = 'Console' grammar = ConsoleGrammar() colors = { - 'console_mesg': ('blue', 'default', 'bold'), - 'console_input': ('cyan', 'default', 'bold'), + 'console_mesg': ('magenta', '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 diff --git a/mode/consolemini.py b/mode/consolemini.py index 5b90fc2..0eba718 100644 --- a/mode/consolemini.py +++ b/mode/consolemini.py @@ -4,6 +4,7 @@ from lex import Grammar, PatternRule from mode.python import PythonGrammar from point import Point +PAD = ' ' LIMIT = 79 class ConsoleExec(method.Method): @@ -15,7 +16,6 @@ class ConsoleExec(method.Method): w.mode.hindex = len(w.mode.history) - 1 a = w.application - if not a.has_buffer_name('*Console*'): raise Exception, "No console found!" b = a.bufferlist.get_buffer_by_name('*Console*') @@ -55,27 +55,33 @@ class ConsoleExec(method.Method): t = sys.exc_traceback 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: - newlines = [' %s' % x for x in output.split('\n')] - assert newlines[-1] == ' ' - newlines[-1] = '' - newlines2 = [] - for line in newlines: + newlines = [] + for line in output.split('\n'): i = 0 - while i + LIMIT < len(line): - j = LIMIT + while i + limit < len(line): + j = limit while j > 0 and line[i + j] != ' ': j -= 1 if j == 0: - newlines2.append(line[i:i + LIMIT]) + newlines.append(PAD + line[i:i + limit]) i += j else: - newlines2.append(line[i:i + j]) + newlines.append(PAD + line[i:i + j]) i += j + 1 - newlines2.append(line[i:]) - b.insert_lines(b.get_buffer_end(), newlines2, force=True) + newlines.append(PAD + line[i:]) + assert newlines[-1] == PAD + newlines[-1] = '' + b.insert_lines(b.get_buffer_end(), newlines, force=True) for w2 in b.windows: - w2.goto_end() + w2.goto_end(force=True) class ConsoleCancel(method.Method): def execute(self, w, **vargs): @@ -178,11 +184,33 @@ class ConsoleTab(method.Method): s = candidates[0][len(name):] 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): modename = 'ConsoleMini' grammar = PythonGrammar actions = [ConsoleExec, ConsoleClear, ConsoleCancel, ConsoleHistoryPrev, - ConsoleHistoryNext, ConsoleTab] + ConsoleHistoryNext, ConsoleTab, + ConsolePageUp, ConsolePageDown, ConsoleGotoBeginning, ConsoleGotoEnd] def __init__(self, w): mode.Fundamental.__init__(self, w) self.bindings = {} @@ -225,6 +253,10 @@ class ConsoleMini(mode.Fundamental): self.add_bindings('console-history-prev', ('C-p',)) self.add_bindings('console-history-next', ('C-n',)) 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: self.add_binding('insert-string-%s' % c, c) diff --git a/mode/erlang.py b/mode/erlang.py index 5c60aaf..acd1fbc 100644 --- a/mode/erlang.py +++ b/mode/erlang.py @@ -13,6 +13,9 @@ class ErlangGrammar(Grammar): PatternRule(r'comment', r'%.*$'), 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_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"), RegionRule(r'string', r'"', StringGrammar, r'"'), RegionRule(r'erl_atom', r"'", StringGrammar, r"'"), @@ -27,19 +30,25 @@ class Erlang(mode.Fundamental): modename = 'Erlang' extensions = ['.erl'] tabwidth = 4 - #tabbercls = mode.lisp.LispTabber + #tabbercls = ErlangTabber grammar = ErlangGrammar opentokens = ('delimiter',) opentags = {'(': ')', '[': ']', '{': '}'} closetokens = ('delimiter',) closetags = {')': '(', ']': '[', '}': '{'} colors = { - 'erl_attribute': ('cyan', 'default', 'bold'), - 'erl_reserved': ('cyan', 'default', 'bold'), - 'erl_builtin': ('magenta', 'default', 'bold'), - 'erl_atom': ('blue', 'default', 'bold'), - 'erl_variable': ('yellow', 'default', 'bold'), - 'erl_operator': ('default', 'default', 'bold'), + 'erl_attribute': ('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_variable': ('yellow', '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): mode.Fundamental.__init__(self, w) diff --git a/mode/perl.py b/mode/perl.py index 513318c..2b61ae9 100644 --- a/mode/perl.py +++ b/mode/perl.py @@ -1,5 +1,5 @@ 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 lex import Grammar, PatternRule, ContextPatternRule, RegionRule, OverridePatternRule, PatternGroupRule from method import Argument, Method, WrapParagraph @@ -578,6 +578,64 @@ class PerlFunctionCompleter(completer.Completer): functions = old_window.mode.get_functions() 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): modename = 'Perl' extensions = ['.pl', '.pm'] diff --git a/window.py b/window.py index 4d724fd..2af1a57 100644 --- a/window.py +++ b/window.py @@ -438,7 +438,7 @@ class Window(object): def goto_beginning(self): self.cursor = Point(0, 0) self.assure_visible_cursor() - def goto_end(self): + def goto_end(self, force=False): self.cursor = self.buffer.get_buffer_end() (x, y) = self.logical_cursor().xy() if x == 0: @@ -458,7 +458,7 @@ class Window(object): break 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.redraw()