From 4ad5cba821a701ee2145dfc4ef829a182c41e8c4 Mon Sep 17 00:00:00 2001 From: moculus Date: Wed, 4 Mar 2009 02:10:32 +0000 Subject: [PATCH] interact is awesome --HG-- branch : pmacs2 --- application.py | 3 +++ buffer/emul.py | 11 ++++++++--- method/shell.py | 18 ++++++++++++++++++ mode/haskell.py | 31 ++++++++++++++++++++++++++----- mode/shellmini.py | 31 ++++++++----------------------- 5 files changed, 63 insertions(+), 31 deletions(-) diff --git a/application.py b/application.py index 8fafc97..aff53da 100755 --- a/application.py +++ b/application.py @@ -331,6 +331,9 @@ class Application(object): else: blist.set_slot(i, active_slot.window.buffer) assert blist.slots[i].window is not None + def close_buffer_by_name(self, name): + if self.has_buffer_name(name): + self.close_buffer(self.get_buffer_by_name(name)) def open_path(self, path, binary=False, cipher=None, password=None): path = os.path.abspath(os.path.realpath(util.expand_tilde(path))) diff --git a/buffer/emul.py b/buffer/emul.py index 49739e4..0159805 100644 --- a/buffer/emul.py +++ b/buffer/emul.py @@ -1,4 +1,4 @@ -import fcntl, os, select, pty, threading +import fcntl, os, select, pty, threading, time from buffer import Buffer, ACT_NORM, ACT_NONE from term import XTerm @@ -18,7 +18,7 @@ class XTermBuffer(Buffer, XTerm): self._pid, self._pty = pty.fork() if self._pid == 0: # child process - os.execve(cmd, [cmd] + args, {'TERM': self.termtype}) + os.execvpe(cmd, [cmd] + args, {'TERM': self.termtype}) self._lock = threading.Lock() self._towrite = '' @@ -28,7 +28,6 @@ class XTermBuffer(Buffer, XTerm): self._thread.setDaemon(True) self._thread.start() - def _w(self): return self.windows[0] def _get_height(self): @@ -109,6 +108,12 @@ class XTermBuffer(Buffer, XTerm): def pipe_read(self): fd = self._pty + + # wait until we are hooked up and ready to go + while not self.windows: + time.sleep(0.1) + + # ok, so start reading stuff! try: while not self._done: if self._towrite: diff --git a/method/shell.py b/method/shell.py index 91c8789..471ba35 100644 --- a/method/shell.py +++ b/method/shell.py @@ -134,3 +134,21 @@ class Sed(Pipe): args = [Argument('expression', datatype="str", prompt="Expression: ")] def _parse(self, w, **vargs): return ('grep', ('sed', '-r', '-e', vargs['expression']), False) + +class Interact(Method): + '''Interact with a program via a PTY''' + args = [Argument('bname', datatype="str", prompt="Buffer Name: ", + default=default.build_constant('*Interact*')), + Argument('cmd', datatype="str", prompt="Command: ", + default=default.build_constant('bash'))] + def _execute(self, w, **vargs): + bname = vargs['bname'] + cmd = vargs['cmd'] + + a = w.application + a.close_buffer_by_name(bname) + b = buffer.emul.XTermBuffer(a, cmd, [], name=bname) + a.add_buffer(b) + window.Window(b, a) + if a.window().buffer is not b: + a.switch_buffer(b) diff --git a/mode/haskell.py b/mode/haskell.py index 7089906..99aa325 100644 --- a/mode/haskell.py +++ b/mode/haskell.py @@ -1,5 +1,7 @@ import commands, os.path, string, sys, traceback import color, completer, default, mode, method, regex, tab +import buffer.emul +import window from point import Point from lex import Grammar, PatternRule, RegionRule, OverridePatternRule, NocasePatternRule @@ -39,6 +41,23 @@ class HaskellGrammar(Grammar): PatternRule(r'operator', r'@|!|>@>|>>=|>>|=>|::|->|;|<-|\\\\|\.\.|!!|:|\+\+|\||\.|\\|>=|>|/=|==|<=|<|\|\||&&|\^\^|\*\*|##|\^|/|\*|-|\+|='), ] +#class HaskellOpenHugs(method.Method): +# '''Evaluate haskell expressions''' +# bname = '*Hugs*' +# def _execute(self, w, **vargs): +# a = w.application +# if not a.has_buffer_name(self.bname): +# b = buffer.emul.XTermBuffer(a, '/usr/bin/hugs', [], name=self.bname) +# a.add_buffer(b) +# window.Window(b, a) +# b = a.bufferlist.get_buffer_by_name(self.bname) +# if a.window().buffer is not b: +# a.switch_buffer(b) +class HaskellOpenHugs(method.shell.Interact): + args = [] + def _execute(self, w, **vargs): + method.shell.Interact._execute(self, w, bname='*Hugs', cmd='hugs') + class HaskellTabber(tab.Tabber): pass @@ -62,10 +81,12 @@ class Haskell(mode.Fundamental): 'string.gap.null': ('red', 'default', 'bold'), 'string.gap.end': ('red', 'default', 'bold'), } - def __init__(self, w): - mode.Fundamental.__init__(self, w) - self.add_bindings('close-paren', (')',)) - self.add_bindings('close-brace', ('}',)) - self.add_bindings('close-bracket', (']',)) + _bindings = { + 'close-paren': (')',), + 'close-brace': ('}',), + 'close-bracket': (']',), + } + actions = [HaskellOpenHugs] + install = Haskell.install diff --git a/mode/shellmini.py b/mode/shellmini.py index 0898faa..c9949b7 100644 --- a/mode/shellmini.py +++ b/mode/shellmini.py @@ -117,32 +117,17 @@ class ShellGotoBeginning(ShellBaseMethod): class ShellGotoEnd(ShellBaseMethod): subcls = method.move.GotoEnd -class OpenShell(Method): +class OpenShellRaw(method.shell.Interact): '''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(a, '/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) + args = [] + def _execute(self, w, **vargs): + method.shell.Interact._execute(self, w, bname='*Shell*', cmd='bash') +class OpenShell(OpenShellRaw): + '''Evaluate sh expressions''' + def _execute(self, w, **vargs): + OpenShellRaw._execute(self, w) f = lambda x: None w.application.open_mini_buffer('>>> ', f, self, None, 'shellmini') -class OpenShellRaw(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(a, '/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) class ShellMini(mode.Fundamental): modename = 'ShellMini'