import code, re, string, StringIO, sys, traceback import buffer, color, completer, lex, method, mode, mode.mini, mode.consolemini, window from subprocess import Popen, PIPE, STDOUT from mode.perl import PerlGrammar from point import Point PAD = ' ' LIMIT = 79 class IperlExec(method.Method): def _execute(self, w, **vargs): if w.application.completion_window_is_open(): w.application.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 a = w.application b = w.mode._get_iperl() 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) b.pipe.stdin.write("ENTER:%s\n" % s) b.pipe.stdin.flush() output = w.mode._read() b.insert_string(b.get_buffer_end(), output, force=True) class IperlTab(method.Method): def execute(self, w, **vargs): a = w.application s = w.buffer.make_string() b = w.mode._get_iperl() x2 = w.logical_cursor().x if not s or s[:x2].isspace(): w.insert_string_at_cursor(' ' * w.mode.tabwidth) return r = re.compile('^[a-zA-Z0-9_:$@*&%]$') line = s x1 = x2 while x1 > 0 and r.match(s[x1 - 1]): x1 -= 1 word = line[x1:x2] b.pipe.stdin.write("COMPLETE:%d:%d:%s\n" % (x1, x2, s)) b.pipe.stdin.flush() (typ_, value) = w.mode._readline() assert typ_ == 'COMPLETIONS', '%r %r' % (typ_, value) candidates = [x for x in value.split('|') if x] w.mode._read() if candidates: s = completer.find_common_string(candidates) w.buffer.delete(Point(x1, 0), Point(x2, 0), force=True) w.insert_string_at_cursor(s) mode.mini.use_completion_window(a, s, candidates) class IperlStart(method.Method): '''Evaluate python expressions (for advanced use and debugging only)''' def execute(self, w, **vargs): a = w.application if not a.has_buffer_name('*IPerl*'): b = buffer.IperlBuffer() a.add_buffer(b) window.Window(b, a) b = a.bufferlist.get_buffer_by_name('*IPerl*') if a.window().buffer is not b: a.switch_buffer(b) f = lambda x: None w.application.open_mini_buffer('*** ', f, self, None, 'iperlmini') class IperlPageUp(mode.consolemini.ConsolePageUp): subbuf = '*IPerl*' class IperlPageDown(mode.consolemini.ConsolePageDown): subbuf = '*IPerl*' class IperlGotoBeginning(mode.consolemini.ConsoleGotoBeginning): subbuf = '*IPerl*' class IperlGotoEnd(mode.consolemini.ConsoleGotoEnd): subbuf = '*IPerl*' class IperlMini(mode.Fundamental): modename = 'IperlMini' actions = [IperlExec, IperlTab, IperlStart, IperlPageUp, IperlPageDown, IperlGotoBeginning, IperlGotoEnd] readre = re.compile('^([A-Z]+):(.*)\n$') def _readline(self): b = self._get_iperl() line = b.pipe.stdout.readline() m = self.readre.match(line) if m: return (m.group(1), m.group(2)) else: return ('RAW', line.rstrip()) def _read(self): b = self._get_iperl() output = [] while True: (type_, value) = self._readline() if type_ == 'PROMPT': b.prompt = value.strip() + ' ' self.window.application.set_mini_buffer_prompt(b.prompt) break value.rstrip() if value: output.append(value) if output: return '\n'.join(output) + '\n' else: return '' def _get_iperl(self): a = self.window.application if not a.has_buffer_name('*IPerl*'): raise Exception, "No iperl found!" b = a.bufferlist.get_buffer_by_name('*IPerl*') return b def __init__(self, w): mode.Fundamental.__init__(self, w) self.history = [''] self.hindex = 0 b = self._get_iperl() if hasattr(b, 'pipe'): self.window.application.set_mini_buffer_prompt(b.prompt) else: cmd = ('iperl', '-p') f = open('/dev/null', 'w') b.pipe = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=f) self._read() self.add_bindings('iperl-exec', ('RETURN',)) self.add_bindings('console-clear', ('C-l',)) self.add_bindings('console-cancel', ('C-]',)) self.add_bindings('console-history-prev', ('C-p', 'UP')) self.add_bindings('console-history-next', ('C-n', 'DOWN')) self.add_bindings('iperl-tab', ('TAB',)) self.add_bindings('iperl-page-up', ('M-v',)) self.add_bindings('iperl-page-down', ('C-v',)) self.add_bindings('iperl-goto-beginning', ('M-<',)) self.add_bindings('iperl-goto-end', ('M->',)) for c in string.letters + string.digits + string.punctuation: self.add_binding('insert-string-%s' % c, c) install = IperlMini.install