import code, os, sets, string, StringIO, sys, traceback import color, completer, default, highlight, method, mode, point class Console(mode.Fundamental): def __init__(self, w): mode.Fundamental.__init__(self, w) self.actions = {} self.bindings = {} self.globals = dict(w.application.globals()) self.locals = dict(w.application.locals()) self.saved_input = "" 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(ConsoleCancel(), ('C-]',)) #self.add_action_and_bindings(ConsoleTab(), ('TAB',)) # create all the insert actions for the character ranges we like for c in string.letters + string.digits + string.punctuation: self.add_binding('insert-string-%s' % c, c) # get mode name def name(self): return "Console" class ConsoleExec(method.Method): def _execute(self, w, **vargs): s = w.buffer.make_string() w.buffer.set_data('') a = w.application if not a.has_buffer_name('*Console*'): a.add_buffer(buffer.ConsoleBuffer()) 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 a.globals(), a.locals() 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.last_traceback t = sys.exc_traceback output = str(e) + traceback.format_exc() #try: # output = a.eval(s) #except Exception, e: # output = str(e) if output: b.insert_string(b.get_buffer_end(), output, force=True) w.goto_end() class ConsoleCancel(method.Method): def execute(self, w, **vargs): w.application.close_mini_buffer() #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)