diff options
-rw-r--r-- | saneterm/pty.py (renamed from saneterm/ptyparser.py) | 57 | ||||
-rw-r--r-- | saneterm/terminal.py | 47 |
2 files changed, 54 insertions, 50 deletions
diff --git a/saneterm/ptyparser.py b/saneterm/pty.py index 2a0d4bd..90bcf34 100644 --- a/saneterm/ptyparser.py +++ b/saneterm/pty.py @@ -1,16 +1,55 @@ +import os + +from pty import fork from enum import Enum, auto +from gi.repository import GLib + +TERM = "dumb" + +class Source(GLib.Source): + master = -1 + + def __init__(self, cmd): + GLib.Source.__init__(self) + self.cmd = cmd + self.tag = None + + def prepare(self): + if self.master != -1: + return False, -1 + + pid, self.master = fork() + if pid == 0: + # Terminal options enforced by saneterm. + # Most importantly, local echo is disabled. Instead we show + # characters on input directly in the GTK termview/TextBuffer. + os.system("stty -onlcr -echo") + + os.environ["TERM"] = TERM + os.execvp(self.cmd[0], self.cmd) + + events = GLib.IOCondition.IN|GLib.IOCondition.HUP + self.tag = self.add_unix_fd(self.master, events) + + return False, -1 + + def check(self): + return False + + def dispatch(self, callback, args): + return callback(self, self.tag, self.master) -class PtyEventType(Enum): +class EventType(Enum): TEXT = auto() BELL = auto() -class PtyParser(object): +class Parser(object): """ Parses a subset of special control sequences read from a pty device. It is somewhat high level: Given a decoded, proper Python string it will emit a series of events which just need to be reflected in the UI while any state - is tracked in the PtyParser object. + is tracked in the Parser object. """ def __init__(self): # no state, yet @@ -18,15 +57,15 @@ class PtyParser(object): def parse(self, input): """ - Main interface of PtyParser. Given a proper decoded + Main interface of Parser. Given a proper decoded Python string , it yields a series of tuples of the - form (PtyEventType, payload) which the caller can + form (EventType, payload) which the caller can iterate through. Valid events are: - * PtyEventType.TEXT has a string slice as its payload + * EventType.TEXT has a string slice as its payload which should be appended to the terminal buffer as is. - * PtyEventType.BELL has no payload and indicates that + * EventType.BELL has no payload and indicates that the bell character '\a' was in the terminal input. This usually should trigger the machine to beep and/or the window to set the urgent flag. @@ -56,7 +95,7 @@ class PtyParser(object): # relying of gtk's default behavior. if code == '\a': flush_until = pos - special_ev = (PtyEventType.BELL, None) + special_ev = (EventType.BELL, None) pos += 1 @@ -66,7 +105,7 @@ class PtyParser(object): # only generate text event if it is non empty, … if flush_until != None and flush_until > start: - yield (PtyEventType.TEXT, input[start:flush_until]) + yield (EventType.TEXT, input[start:flush_until]) # … but advance as if we had flushed if flush_until != None: diff --git a/saneterm/terminal.py b/saneterm/terminal.py index 70f538c..f0c5e4d 100644 --- a/saneterm/terminal.py +++ b/saneterm/terminal.py @@ -1,5 +1,4 @@ import sys -import pty import os import codecs import termios @@ -8,10 +7,10 @@ import struct from . import keys from . import proc +from . import pty from .search import SearchBar from .history import History from .termview import * -from .ptyparser import PtyParser, PtyEventType from gi.repository import Gtk from gi.repository import Gdk @@ -19,40 +18,6 @@ from gi.repository import GLib from gi.repository import Pango NAME = "saneterm" -TERM = "dumb" - -class PtySource(GLib.Source): - master = -1 - - def __init__(self, cmd): - GLib.Source.__init__(self) - self.cmd = cmd - self.tag = None - - def prepare(self): - if self.master != -1: - return False, -1 - - pid, self.master = pty.fork() - if pid == pty.CHILD: - # Terminal options enforced by saneterm. - # Most importantly, local echo is disabled. Instead we show - # characters on input directly in the GTK termview/TextBuffer. - os.system("stty -onlcr -echo") - - os.environ["TERM"] = TERM - os.execvp(self.cmd[0], self.cmd) - - events = GLib.IOCondition.IN|GLib.IOCondition.HUP - self.tag = self.add_unix_fd(self.master, events) - - return False, -1 - - def check(self): - return False - - def dispatch(self, callback, args): - return callback(self, self.tag, self.master) class Terminal(Gtk.Window): config = { @@ -67,12 +32,12 @@ class Terminal(Gtk.Window): self.hist = History() self.reset_history_index() - self.pty = PtySource(cmd) + self.pty = pty.Source(cmd) self.pty.set_priority(GLib.PRIORITY_LOW) self.pty.set_callback(self.handle_pty) self.pty.attach(None) - self.pty_parser = PtyParser() + self.pty_parser = pty.Parser() self.termview = TermView(self.complete, limit) @@ -201,13 +166,13 @@ class Terminal(Gtk.Window): decoded = self.decoder.decode(data) for (ev, data) in self.pty_parser.parse(decoded): - if ev is PtyEventType.TEXT: + if ev is pty.EventType.TEXT: self.termview.insert_data(data) - elif ev is PtyEventType.BELL: + elif ev is pty.EventType.BELL: self.termview.error_bell() self.set_urgency_hint(True) else: - raise AssertionError("unknown PtyEventType") + raise AssertionError("unknown pty.EventType") return GLib.SOURCE_CONTINUE |