about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSören Tempel <soeren+git@soeren-tempel.net>2021-05-29 12:01:32 +0200
committerSören Tempel <soeren+git@soeren-tempel.net>2021-05-29 12:01:32 +0200
commitb6db98ffd7b1d9aee64b8c5fa52dafc332aacfd1 (patch)
tree626fd2d87ccf6536451ca03ca77ff0dac9516af0
parent43ba599e7b1ed13f2594b41dfbbb173ac7bc1bf2 (diff)
parentc007f1197e2b030e22fbaf1635315b0d5a58aa66 (diff)
Merge branch 'limit-scroll-buffer'
-rw-r--r--TODO.txt3
-rw-r--r--saneterm/__main__.py4
-rw-r--r--saneterm/terminal.py4
-rw-r--r--saneterm/termview.py40
4 files changed, 41 insertions, 10 deletions
diff --git a/TODO.txt b/TODO.txt
index 525704a..c6b1ed3 100644
--- a/TODO.txt
+++ b/TODO.txt
@@ -7,6 +7,3 @@
 * 9term-like file name completions using ctrl+f
 * Support of a ctrl+l screen clear feature and/or
   scrolling beyond th end of the buffer like 9term supports
-* Limit total amount of lines stored in buffer, should also fix
-  issue with GtkTextView going black if too many lines have
-  accumulated
diff --git a/saneterm/__main__.py b/saneterm/__main__.py
index ee71ca3..9764bb5 100644
--- a/saneterm/__main__.py
+++ b/saneterm/__main__.py
@@ -8,6 +8,8 @@ def get_parser():
     default_cmd = os.environ["SHELL"] if "SHELL" in os.environ else "sh"
 
     parser = argparse.ArgumentParser()
+    parser.add_argument('-l', metavar='LIMIT', type=int,
+                        default=5000, help='Amount of lines to store in scroback buffer')
     parser.add_argument('command', metavar='CMD', type=str, nargs='*',
                         default=[default_cmd], help='Command to execute (defaults to $SHELL)')
 
@@ -17,7 +19,7 @@ def main():
     parser = get_parser()
     args = parser.parse_args()
 
-    win = Terminal(args.command)
+    win = Terminal(args.command, args.l)
     win.connect("destroy", Gtk.main_quit)
     win.show_all()
     Gtk.main()
diff --git a/saneterm/terminal.py b/saneterm/terminal.py
index 2fc92b2..7ff85ac 100644
--- a/saneterm/terminal.py
+++ b/saneterm/terminal.py
@@ -60,7 +60,7 @@ class Terminal(Gtk.Window):
         'wordwrap': True,
     }
 
-    def __init__(self, cmd):
+    def __init__(self, cmd, limit):
         Gtk.Window.__init__(self, title=NAME)
         self.set_name(NAME)
 
@@ -71,7 +71,7 @@ class Terminal(Gtk.Window):
         self.pty.set_callback(self.handle_pty)
         self.pty.attach(None)
 
-        self.termview = TermView()
+        self.termview = TermView(limit)
 
         # Block-wise reading from the PTY requires an incremental decoder.
         self.decoder = codecs.getincrementaldecoder('UTF-8')()
diff --git a/saneterm/termview.py b/saneterm/termview.py
index ef2af57..2bfa9f8 100644
--- a/saneterm/termview.py
+++ b/saneterm/termview.py
@@ -4,6 +4,37 @@ gi.require_version("Gtk", "3.0")
 from gi.repository import Gtk
 from gi.repository import GObject
 
+class LimitTextBuffer(Gtk.TextBuffer):
+    """
+    Buffer which stores a limit amount of lines. If the limit is -1
+    an unlimited amount of lines is stored. Old lines are deleted
+    automatically if the limit is exceeded.
+    """
+
+    def __init__(self, limit):
+        Gtk.TextBuffer.__init__(self)
+
+        if limit == -1:
+            return # unlimited
+
+        self.limit = limit
+        self.connect_after("insert-text", self.__insert_text)
+
+    def __insert_text(self, buffer, loc, text, len):
+        lines = buffer.get_line_count()
+        diff = lines - self.limit
+        if diff <= 0:
+            return
+
+        end = buffer.get_start_iter()
+        end.forward_lines(diff)
+
+        start = buffer.get_start_iter()
+        buffer.delete(start, end)
+
+        # Revalide the given iterator
+        loc.assign(buffer.get_end_iter())
+
 class TermView(Gtk.TextView):
     """
     TextView-based widget for line-based terminal emulators. The widget
@@ -27,17 +58,18 @@ class TermView(Gtk.TextView):
     to the application via the termios-ctrlkey signal.
     """
 
-    def __init__(self):
+    def __init__(self, limit=-1):
         # TODO: set insert-hypens to false in GTK 4
         # https://docs.gtk.org/gtk4/property.TextTag.insert-hyphens.html
         Gtk.TextView.__init__(self)
 
+        self._textbuffer = LimitTextBuffer(limit)
+        self._textbuffer.connect("end-user-action", self.__end_user_action)
+        self.set_buffer(self._textbuffer)
+
         self.set_monospace(True)
         self.set_input_hints(Gtk.InputHints.NO_SPELLCHECK | Gtk.InputHints.EMOJI)
 
-        self._textbuffer = self.get_buffer()
-        self._textbuffer.connect("end-user-action", self.__end_user_action)
-
         self._last_mark = self._textbuffer.create_mark(None,
                 self._textbuffer.get_end_iter(), True)
         self._last_output_mark = self._last_mark