import code, os, re, string, StringIO, sys, traceback import buffer, buffer.pipe, buffer.emul 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 ShellMiniGrammar(Grammar): rules = [ PatternRule('word', r'(?:(?:\\.|[^\n\\\'" ])+|"(?:\\.|[^\\\"])*"|\'(?:\\.|[^\\\'])*\')+'), PatternRule('spaces', r' +'), PatternRule('eol', r'\n'), ] 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 s1 = curr_t.string if(curr_i == 0) and '/' not in s1: completer = method.DATATYPES['command'] else: completer = method.DATATYPES['path'] s2, exists, complete = completer.tab_string(s1, w) w.delete(Point(curr_t.x, curr_t.y), Point(curr_t.end_x(), curr_t.y)) w.insert_string_at_cursor(s2) candidates = completer.get_candidates(s1, w) mode.mini.use_completion_window(a, s2, 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') b = buffer.emul.XTermBuffer('/bin/bash', [], name="*Shell*") 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