saneterm

Modern line-oriented terminal emulator without support for TUIs

git clone https://git.8pit.net/saneterm.git

  1# saneterm
  2
  3Modern line-oriented terminal emulator without support for TUIs.
  4
  5![saneterm demo](https://gist.githubusercontent.com/nmeum/51d89900c9c7beef49cace24ebc605ec/raw/14b9eeb25483c82fa3672875bb24ff33dbdf932a/saneterm.gif)
  6
  7## Motivation
  8
  9Mainstream terminal emulators (urxvt, xterm, alacritty, …) support a
 10standard known as [ANSI escape sequences][wikipedia ansi]. This standard
 11defines several byte sequences to provide special control
 12functions for terminals emulators. This includes control of the cursor,
 13support for different colors, et cetera. They are often used to
 14implement TUIs, e.g. using the [ncurses][ncurses web] library.
 15
 16Many of these escape sequences operate on rows and columns and therefore
 17require terminal emulators to be built around a character grid were
 18individual cells can be modified. Historically, this was very useful to
 19implement UIs on physical terminals like the VT100. Nowadays this
 20approach feels dated and causes a variety of problems. For instance, the
 21concept of grapheme cluster as used in [Unicode][unicode web] is largely
 22incompatible with fixed-size columns. For this reason, terminal
 23emulator supporting the aforementioned escape sequences can never fully
 24support Unicode [\[1\]][variable-width glyphs].
 25
 26On the other hand, a terminal emulator not supporting ANSI escape
 27sequences can never support existing TUIs. However, the idea behind
 28`saneterm` is that terminals shouldn't be used to implement TUIs anyhow,
 29instead they should focus on line-based CLIs. By doing so, a variety of
 30features normally implemented in CLI programs themselves (like
 31[readline][readline web]-keybindings) can be implemented directly in the
 32terminal emulator.
 33
 34## Status
 35
 36Silly, buggy, and incomplete prototype implementation.
 37
 38## Features
 39
 40By focusing on line-based input in the terminal emulator a variety of
 41things can be simplified and improved. `saneterm` is presently just a
 42prototype and provides basic implementations of the following features:
 43
 44* Full Unicode support
 45* Support for readline-like line editing keybindings
 46* Editing history support directly in the terminal emulator
 47* File name completions
 48* Pager-like text handling (scrolling, searching, …)
 49* Basic support for SGR escape sequences (colors, font modifiers, …)
 50
 51## Installation
 52
 53This software has the following dependencies:
 54
 55* [python3][python web]
 56* [PyGObject][PyGObject web] and [gtk+3.0][gtk web]
 57* [setuptools][setuptools web]
 58
 59If these are installed run the following command to install `saneterm`:
 60
 61	$ python3 setup.py install --optimize=1
 62
 63You can also run saneterm's tests (with limited coverage at the moment):
 64
 65	$ python3 tests.py
 66
 67For development setups just run `python3 -msaneterm`.
 68
 69## Usage
 70
 71Since many modern day shells use ANSI escape sequences heavily for
 72providing editing features, your favorite shell might not directly work
 73with `saneterm`. Simple shells like [dash][dash web] are known to work
 74well though. You might also want to consider using a clean environment,
 75to do so run the following command to start `saneterm`:
 76
 77	$ saneterm -- env -i dash
 78
 79## Configuration
 80
 81The terminal appearance can be configured using [Gtk's CSS][gtk css]
 82feature. The `saneterm` window widget can be selected using the CSS
 83selector `#saneterm`.
 84
 85For example, to change the color scheme and employed font. Add the
 86following to your `gtk.css` configuration file located at
 87`$XDG_CONFIG_HOME/gtk-3.0/gtk.css`:
 88
 89	#saneterm textview {
 90		font-family: Terminus;
 91		font-size: 16px;
 92	}
 93
 94	#saneterm textview text {
 95		background-color: #181818;
 96		color: #d8d8d8;
 97
 98		/* change cursor color too */
 99		caret-color: #d8d8d8;
100	}
101
102Keybindings can be configured using the same mechanism, see `keys.py`
103for the default keybindings.
104
105## FAQ
106
107**Q:** How do I edit text on remote machines over SSH if my terminal
108emulator doesn't support visual editors?
109
110**A:** This is an interesting problem since a lot of software
111relies on TUIs to be used over PTYs and SSH on remote machines. This is
112mostly also an inherit flaw of Unix as it hasn't been designed with
113networking and GUIs in mind. Plan 9 solves this problem through 9P file
114servers, but unfortunately it has not been widely adopted and we are
115stuck with Unix. In the Unix world potential solutions include
116CLI-based editors (e.g. [ed][wikipedia ed]) or network protocols
117tunneled over SSH connections (e.g.  [Emacs Tramp Mode][emacs tramp mode]).
118
119**Q:** How do I use pagers (e.g. `less(1)`) without support for TUIs?
120
121**A:** With `saneterm` pagers are not needed as paging functionality is
122implemented in the terminal emulator itself. For this reason, `saneterm`
123offers a scrollback buffer in which autoscrolling can be configured
124using the Gtk context menu. Furthermore, word wrapping can also be
125disabled using the same mechanism. A search feature is also implemented
126and can be activated using ctrl+f.
127
128**Q:** How do I paste the primary clipboard when clicking the middle
129mouse button?
130
131**A:** Configure [gtk-enable-primary-paste][gtk primary paste] in
132`$XDG_CONFIG_HOME/gtk-3.0/settings.ini`. Since most terminal emulator do
133it this way, this may become the default in future `saneterm` versions.
134
135**Q:** Why is this written in Python and not X?
136
137**A:** This software is presently just a silly prototype, Python is good
138for prototyping. Furthermore, Python has decent, somewhat well-documented
139bindings for Gtk.
140
141## Related Work
142
143This work is heavily inspired by the Plan 9 terminal emulator, usage of
144which is further described in the [`rio(1)`][rio man page] man page.
145This terminal emulator was also [ported to Unix][9term man page] as part
146of [plan9port][plan9port web]. An (unmaintained) reimplementation using
147Ruby and the Tk GUI toolkit, named [tt], is also available.
148
149There are also a few projects which seem to share the problem statement
150outlined in the Motivation but propose different solution. Most of
151which include continued support for TUIs and therefore don't benefit
152from other line-based editing features. Non-complete list:
153
154* https://github.com/withoutboats/notty
155* https://github.com/christianparpart/contour
156* https://notcurses.com/
157
158## License
159
160This program is free software: you can redistribute it and/or modify it
161under the terms of the GNU General Public License as published by the
162Free Software Foundation, either version 3 of the License, or (at your
163option) any later version.
164
165This program is distributed in the hope that it will be useful, but
166WITHOUT ANY WARRANTY; without even the implied warranty of
167MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
168Public License for more details.
169
170You should have received a copy of the GNU General Public License along
171with this program. If not, see <http://www.gnu.org/licenses/>.
172
173[ncurses web]: https://invisible-island.net/ncurses/
174[wikipedia ansi]: https://en.wikipedia.org/wiki/ANSI_escape_code
175[wikipedia zwj]: https://en.wikipedia.org/wiki/Zero-width_joiner
176[unicode web]: https://www.unicode.org/
177[readline web]: https://tiswww.case.edu/php/chet/readline/rltop.html
178[python web]: https://www.python.org/
179[PyGObject web]: https://pygobject.readthedocs.io/en/latest/
180[gtk web]: https://gtk.org/
181[setuptools web]: https://pypi.python.org/pypi/setuptools
182[wikipedia ed]: https://en.wikipedia.org/wiki/Ed_(text_editor)
183[emacs tramp mode]: https://www.emacswiki.org/emacs/TrampMode
184[variable-width glyphs]: https://gitlab.freedesktop.org/terminal-wg/specifications/-/issues/21
185[rio man page]: https://9p.io/magic/man2html/1/rio
186[9term man page]: https://9fans.github.io/plan9port/man/man1/9term.html
187[plan9port web]: https://9fans.github.io/plan9port/
188[gtk css]: https://developer.gnome.org/gtk3/stable/chap-css-overview.html
189[dash web]: http://gondor.apana.org.au/~herbert/dash/
190[gtk primary paste]: https://developer.gnome.org/gtk3/stable/GtkSettings.html#GtkSettings--gtk-enable-primary-paste
191[tt]: https://github.com/leahneukirchen/tt