pmacs3/mode/consolemini.py

184 lines
6.7 KiB
Python

import code, string, StringIO, sys, traceback
import color, completer, method, mode2
from lex import Grammar, PatternRule
from point import Point
class ConsoleMini(mode2.Fundamental):
modename = 'ConsoleMini'
def __init__(self, w):
mode2.Fundamental.__init__(self, w)
self.bindings = {}
self.globals = dict(w.application.globals())
self.locals = dict(w.application.locals())
self.saved_input = ""
self.history = ['']
self.hindex = 0
self.add_bindings('start-of-line', ('C-a', 'HOME',))
self.add_bindings('end-of-line', ('C-e', 'END',))
self.add_bindings('backward', ('C-b', 'L_ARROW',))
self.add_bindings('forward', ('C-f', 'R_ARROW',))
self.add_bindings('delete-left', ('DELETE', 'BACKSPACE',))
self.add_bindings('delete-left-word', ('M-DELETE', 'M-BACKSPACE',))
self.add_bindings('delete-right', ('C-d',))
self.add_bindings('delete-right-word', ('M-d',))
self.add_bindings('kill-region', ('C-w',))
self.add_bindings('copy-region', ('M-w',))
self.add_bindings('kill', ('C-k',))
self.add_bindings('copy', ('M-k',))
self.add_bindings('yank', ('C-y',))
self.add_bindings('pop-kill', ('M-y',))
self.add_bindings('right-word', ('M-f',))
self.add_bindings('left-word', ('M-b',))
self.add_bindings('set-mark', ('C-@',))
self.add_bindings('switch-mark', ('C-x C-x',))
self.add_bindings('undo', ('C-/', 'C-x u',))
self.add_bindings('redo', ('M-/', 'M-_', 'C-x r',))
self.add_bindings('toggle-margins', ('M-m',))
self.add_bindings('transpose-words', ('M-t',))
self.add_bindings('delete-left-whitespace', ('C-c DELETE', 'C-c BACKSPACE',))
self.add_bindings('delete-right-whitespace', ('C-c d',))
self.add_bindings('insert-space', ('SPACE',))
self.add_bindings('insert-tab', ('TAB',))
self.add_action_and_bindings(ConsoleExec(), ('RETURN',))
self.add_action_and_bindings(ConsoleClear(), ('C-l',))
self.add_action_and_bindings(ConsoleCancel(), ('C-]',))
self.add_action_and_bindings(ConsoleHistoryPrev(), ('C-p',))
self.add_action_and_bindings(ConsoleHistoryNext(), ('C-n',))
#self.add_action_and_bindings(ConsoleTab(), ('TAB',))
for c in string.letters + string.digits + string.punctuation:
self.add_binding('insert-string-%s' % c, c)
class ConsoleExec(method.Method):
def _execute(self, w, **vargs):
s = w.buffer.make_string()
w.mode.history[-1] = s
w.mode.history.append('')
w.buffer.set_data('')
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*')
if a.window().buffer is not b:
a.switch_buffer(b)
p = a.get_mini_buffer_prompt()
b.insert_string(b.get_buffer_end(), p + s + '\n', force=True)
if w.mode.saved_input:
s = w.mode.saved_input + '\n' + s
try:
code_obj = code.compile_command(s)
if code_obj is None:
w.mode.saved_input = s
a.set_mini_buffer_prompt('--> ')
output = None
else:
w.mode.saved_input = ''
a.set_mini_buffer_prompt('>>> ')
sys.stdout = code_out = StringIO.StringIO()
sys.stderr = code_err = StringIO.StringIO()
ok = True
try:
exec code_obj in w.mode.globals, w.mode.locals
except Exception, e:
ok = False
output = str(e) + '\n'
sys.stdout = sys.__stdout__
sys.stdout = sys.__stderr__
if ok:
output = code_out.getvalue()
code_out.close()
code_err.close()
except (SyntaxError, OverflowError, ValueError), e:
a.set_mini_buffer_prompt('>>> ')
t = sys.exc_traceback
output = str(e) + traceback.format_exc()
if output:
newlines = [' %s' % x for x in output.split('\n')]
assert newlines[-1] == ' '
newlines[-1] = ''
b.insert_lines(b.get_buffer_end(), newlines, force=True)
for w2 in b.windows:
w2.goto_end()
class ConsoleCancel(method.Method):
def execute(self, w, **vargs):
w.application.close_mini_buffer()
class ConsoleClear(method.Method):
def execute(self, w, **vargs):
a = w.application
if not a.has_buffer_name('*Console*'):
raise Exception, "No console found!"
b = a.bufferlist.get_buffer_by_name('*Console*')
b.clear()
class ConsoleHistoryPrev(method.Method):
def execute(self, w, **vargs):
if w.mode.hindex <= 0:
w.mode.hindex = 0
return
elif w.mode.hindex == len(w.mode.history) - 1:
w.mode.history[-1] = w.buffer.make_string()
w.mode.hindex -= 1
w.buffer.set_data(w.mode.history[w.mode.hindex])
class ConsoleHistoryNext(method.Method):
def execute(self, w, **vargs):
if w.mode.hindex == len(w.mode.history) - 1:
return
w.mode.hindex += 1
w.buffer.set_data(w.mode.history[w.mode.hindex])
#class ConsoleTab(method.Method):
# def execute(self, w, **vargs):
# a = w.application
# s = w.buffer.make_string()
#
# if '"' in s or "'" in s or "(" in s or ")" in s or "[" in s or "]" in s:
# return
#
# parts = s.split(".")
# if len(parts) == 0:
# return
#
# v = a.globals()
# v.update(a.locals())
# obj = None
# for part in parts[:-1]:
# if obj is None:
# if part in v:
# obj = v[part]
# else:
# return
# else:
# if hasattr(obj, part):
# obj = getattr(obj, part)
# else:
# return
#
# if obj is None:
# pool = v.keys()
# else:
# pool = dir(obj)
# candidates = [x for x in pool if x.startswith(parts[-1])]
#
# if len(candidates) == 0:
# return
#
# common = completer.find_common_string(candidates)
# s2 = '.'.join(parts[:-1]) + '.' + common
#
# w.buffer.set_data(s2)
#
# if len(candidates) > 1:
# if not a.has_buffer_name('*Console*'):
# a.add_buffer(buffer.ConsoleBuffer())
# b = a.bufferlist.get_buffer_by_name('*Console*')
# b.insert_string(b.get_buffer_end(), repr(candidates) + '\n', force=True)
install = ConsoleMini.install