1# saneterm23Modern line-oriented terminal emulator without support for TUIs.4567## Motivation89Mainstream terminal emulators (urxvt, xterm, alacritty, …) support a10standard known as [ANSI escape sequences][wikipedia ansi]. This standard11defines several byte sequences to provide special control12functions for terminals emulators. This includes control of the cursor,13support for different colors, et cetera. They are often used to14implement TUIs, e.g. using the [ncurses][ncurses web] library.1516Many of these escape sequences operate on rows and columns and therefore17require terminal emulators to be built around a character grid were18individual cells can be modified. Historically, this was very useful to19implement UIs on physical terminals like the VT100. Nowadays this20approach feels dated and causes a variety of problems. For instance, the21concept of grapheme cluster as used in [Unicode][unicode web] is largely22incompatible with fixed-size columns. For this reason, terminal23emulator supporting the aforementioned escape sequences can never fully24support Unicode [\[1\]][variable-width glyphs].2526On the other hand, a terminal emulator not supporting ANSI escape27sequences can never support existing TUIs. However, the idea behind28`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 of30features normally implemented in CLI programs themselves (like31[readline][readline web]-keybindings) can be implemented directly in the32terminal emulator.3334## Status3536Silly, buggy, and incomplete prototype implementation.3738## Features3940By focusing on line-based input in the terminal emulator a variety of41things can be simplified and improved. `saneterm` is presently just a42prototype and provides basic implementations of the following features:4344* Full Unicode support45* Support for readline-like line editing keybindings46* Editing history support directly in the terminal emulator47* File name completions48* Pager-like text handling (scrolling, searching, …)49* Basic support for SGR escape sequences (colors, font modifiers, …)5051## Installation5253This software has the following dependencies:5455* [python3][python web]56* [PyGObject][PyGObject web] and [gtk+3.0][gtk web]57* [setuptools][setuptools web]5859If these are installed run the following command to install `saneterm`:6061 $ python3 setup.py install --optimize=16263You can also run saneterm's tests (with limited coverage at the moment):6465 $ python3 tests.py6667For development setups just run `python3 -msaneterm`.6869## Usage7071Since many modern day shells use ANSI escape sequences heavily for72providing editing features, your favorite shell might not directly work73with `saneterm`. Simple shells like [dash][dash web] are known to work74well though. You might also want to consider using a clean environment,75to do so run the following command to start `saneterm`:7677 $ saneterm -- env -i dash7879## Configuration8081The terminal appearance can be configured using [Gtk's CSS][gtk css]82feature. The `saneterm` window widget can be selected using the CSS83selector `#saneterm`.8485For example, to change the color scheme and employed font. Add the86following to your `gtk.css` configuration file located at87`$XDG_CONFIG_HOME/gtk-3.0/gtk.css`:8889 #saneterm textview {90 font-family: Terminus;91 font-size: 16px;92 }9394 #saneterm textview text {95 background-color: #181818;96 color: #d8d8d8;9798 /* change cursor color too */99 caret-color: #d8d8d8;100 }101102Keybindings can be configured using the same mechanism, see `keys.py`103for the default keybindings.104105## FAQ106107**Q:** How do I edit text on remote machines over SSH if my terminal108emulator doesn't support visual editors?109110**A:** This is an interesting problem since a lot of software111relies on TUIs to be used over PTYs and SSH on remote machines. This is112mostly also an inherit flaw of Unix as it hasn't been designed with113networking and GUIs in mind. Plan 9 solves this problem through 9P file114servers, but unfortunately it has not been widely adopted and we are115stuck with Unix. In the Unix world potential solutions include116CLI-based editors (e.g. [ed][wikipedia ed]) or network protocols117tunneled over SSH connections (e.g. [Emacs Tramp Mode][emacs tramp mode]).118119**Q:** How do I use pagers (e.g. `less(1)`) without support for TUIs?120121**A:** With `saneterm` pagers are not needed as paging functionality is122implemented in the terminal emulator itself. For this reason, `saneterm`123offers a scrollback buffer in which autoscrolling can be configured124using the Gtk context menu. Furthermore, word wrapping can also be125disabled using the same mechanism. A search feature is also implemented126and can be activated using ctrl+f.127128**Q:** How do I paste the primary clipboard when clicking the middle129mouse button?130131**A:** Configure [gtk-enable-primary-paste][gtk primary paste] in132`$XDG_CONFIG_HOME/gtk-3.0/settings.ini`. Since most terminal emulator do133it this way, this may become the default in future `saneterm` versions.134135**Q:** Why is this written in Python and not X?136137**A:** This software is presently just a silly prototype, Python is good138for prototyping. Furthermore, Python has decent, somewhat well-documented139bindings for Gtk.140141## Related Work142143This work is heavily inspired by the Plan 9 terminal emulator, usage of144which is further described in the [`rio(1)`][rio man page] man page.145This terminal emulator was also [ported to Unix][9term man page] as part146of [plan9port][plan9port web]. An (unmaintained) reimplementation using147Ruby and the Tk GUI toolkit, named [tt], is also available.148149There are also a few projects which seem to share the problem statement150outlined in the Motivation but propose different solution. Most of151which include continued support for TUIs and therefore don't benefit152from other line-based editing features. Non-complete list:153154* https://github.com/withoutboats/notty155* https://github.com/christianparpart/contour156* https://notcurses.com/157158## License159160This program is free software: you can redistribute it and/or modify it161under the terms of the GNU General Public License as published by the162Free Software Foundation, either version 3 of the License, or (at your163option) any later version.164165This program is distributed in the hope that it will be useful, but166WITHOUT ANY WARRANTY; without even the implied warranty of167MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General168Public License for more details.169170You should have received a copy of the GNU General Public License along171with this program. If not, see <http://www.gnu.org/licenses/>.172173[ncurses web]: https://invisible-island.net/ncurses/174[wikipedia ansi]: https://en.wikipedia.org/wiki/ANSI_escape_code175[wikipedia zwj]: https://en.wikipedia.org/wiki/Zero-width_joiner176[unicode web]: https://www.unicode.org/177[readline web]: https://tiswww.case.edu/php/chet/readline/rltop.html178[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/setuptools182[wikipedia ed]: https://en.wikipedia.org/wiki/Ed_(text_editor)183[emacs tramp mode]: https://www.emacswiki.org/emacs/TrampMode184[variable-width glyphs]: https://gitlab.freedesktop.org/terminal-wg/specifications/-/issues/21185[rio man page]: https://9p.io/magic/man2html/1/rio186[9term man page]: https://9fans.github.io/plan9port/man/man1/9term.html187[plan9port web]: https://9fans.github.io/plan9port/188[gtk css]: https://developer.gnome.org/gtk3/stable/chap-css-overview.html189[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-paste191[tt]: https://github.com/leahneukirchen/tt