import code, os, re, string, StringIO, sys, traceback import buffer, buffer.pipe import color, completer, lex, method, mode, window from lex import Grammar, PatternRule, RegionRule from point import Point from method import Method from subprocess import Popen, PIPE, STDOUT class ShellExec(Method): def _execute(self, w, **vargs): a = w.application if a.completion_window_is_open(): a.close_completion_buffer() 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 if not a.has_buffer_name('*Shell*'): raise Exception, "No shell found!" b = a.bufferlist.get_buffer_by_name('*Shell*') if a.window().buffer is not b: a.switch_buffer(b) b.pipe_write(s + "\n") class ShellCancel(Method): def execute(self, w, **vargs): w.application.close_mini_buffer() if w.application.completion_window_is_open(): w.application.close_completion_buffer() class ShellClear(Method): def execute(self, w, **vargs): a = w.application if not a.has_buffer_name('*Shell*'): raise Exception, "No shell found!" b = a.bufferlist.get_buffer_by_name('*Shell*') class ShellHistoryPrev(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 ShellHistoryNext(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 ShellTab(Method): def execute(self, w, **vargs): a = w.application s = w.buffer.make_string() x = w.logical_cursor().x if not s or s[:x].isspace(): w.insert_string_at_cursor(' ' * w.mode.tabwidth) return l = lex.Lexer(w.mode, ShellMiniGrammar) tokens = list(l.lex([s])) curr_t = None curr_i = None for i in range(0, len(tokens)): t = tokens[i] if t.x < x and t.end_x() >= x: curr_i = i curr_t = t if curr_t is None: return if(i == 0) and '/' not in curr_t.string: # we are completing a command candidates = [] else: # we are completing a path cwd = os.getcwd() if not cwd.endswith('/'): cwd += '/' path = cwd + curr_t.string (d, name) = os.path.split(path) names = [] for x in os.listdir(d): if os.path.isdir(os.path.join(d, x)): names.append(x + '/') else: names.append(x) candidates = [x for x in names if x.startswith(name)] s = completer.find_common_string(candidates)[len(name):] w.insert_string_at_cursor(s) mode.mini.use_completion_window(a, name, candidates) class ShellBaseMethod(Method): subcls = Method subbuf = '*Shell*' def __init__(self): Method.__init__(self) self.submethod = self.subcls() def _execute(self, w, **vargs): a = w.application if not a.has_buffer_name(self.subbuf): raise Exception, "No shell found!" w2 = a.bufferlist.get_buffer_by_name(self.subbuf).windows[0] self.submethod.execute(w2, **vargs) class ShellPageUp(ShellBaseMethod): subcls = method.move.PageUp class ShellPageDown(ShellBaseMethod): subcls = method.move.PageDown class ShellGotoBeginning(ShellBaseMethod): subcls = method.move.GotoBeginning class ShellGotoEnd(ShellBaseMethod): subcls = method.move.GotoEnd class OpenShell(Method): '''Evaluate sh expressions''' def execute(self, w, **vargs): a = w.application if not a.has_buffer_name('*Shell*'): b = buffer.pipe.PipeBuffer('/bin/bash', [], name="*Shell*", term='xterm') a.add_buffer(b) window.Window(b, a) b = a.bufferlist.get_buffer_by_name('*Shell*') if a.window().buffer is not b: a.switch_buffer(b) f = lambda x: None w.application.open_mini_buffer('>>> ', f, self, None, 'shellmini') class ShellMini(mode.Fundamental): modename = 'ShellMini' actions = [ShellExec, ShellClear, ShellCancel, ShellHistoryPrev, ShellHistoryNext, ShellTab, ShellPageUp, ShellPageDown, ShellGotoBeginning, ShellGotoEnd, OpenShell] def __init__(self, w): mode.Fundamental.__init__(self, w) self.saved_input = "" self.history = [''] self.hindex = 0 self.add_bindings('shell-exec', ('RETURN',)) self.add_bindings('shell-clear', ('C-l',)) self.add_bindings('shell-cancel', ('C-]', 'C-g')) self.add_bindings('shell-history-prev', ('C-p', 'UP')) self.add_bindings('shell-history-next', ('C-n', 'DOWN')) self.add_bindings('shell-tab', ('TAB',)) self.add_bindings('shell-page-up', ('M-v',)) self.add_bindings('shell-page-down', ('C-v',)) self.add_bindings('shell-goto-beginning', ('M-<',)) self.add_bindings('shell-goto-end', ('M->',)) install = ShellMini.install