nast - not-as-simple terminal ----------------------------- nast is a fork of the suckless simple terminal. libnast is a library designed to provide terminal emulator behavior to arbitrary applications with a well-defined interface. Cool Features ------------- - reflows lines on window or font change - ctrl+scroll to zoom - ctrl+shift+c for copy and ctrl+shift+v for paste - masquerades as xterm, so your terminal works after ssh Project Status -------------- - nast is a barely-usable terminal. - libnast should be a usable library but only has one consumer. System Architecture ------------------- _____________ | | | application | |_____________| v ^ A. v ^ nast terminal emulator .......v...^......................... . ____v___^____ ___________ . . | | C. | | . . | backend |< < <| Term | . . | (GTK app) |> > >| (libnast) | . . |_____________| |___________| . . v ^ . .......v...^......................... B. v ^ _____v___^______ | | | window manager | |________________| A: application/backend interface: - A tty. That's it. - application reads keys from the tty device - application writes keys out to the tty device - application may try to configure the terminal with escape codes (by writing the escape codes to the tty) B: window manager / backend interface: - the backend implements the communication with the window manager - GTK abstracts the window manager, so we just deal with GTK anyway - inputs to the backend are GTK key and mouse events - outputs are that we tell GTK what to draw and when to redraw it C: backend / libnast interface - libnast implements the terminal emulation logic - the backend provides the canvas on which libnast draws the characters - the backend provides a set of THooks for things that must be passed to the desktop environment such as: - the terminal bell - the window title - altering the clipboard and for things that must be passed to the application, such as: - giving bytes that should be written directly to the application Example sequence: pressing the 'q' key: - window manager tells backend 'q' is hit (via B.) - backend sends keypress to libnast for filtering (via C.) - libnast calls THook to tell backend to send 'q' to app (via C.) - backend writes 'q' to the tty (via A.) - application (or tty itself) writes 'q' key back to stdout (via A.) - backend reads 'q' on tty, passes it to libnast (via C.) - libnast updates the terminal state, updates canvas - libnast tells backend canvas is updated - backend notifies window manager to redraw Note that for more complex sequences, what the backend tells the application might not match what the application writes to its stdout. To capture exactly what the application normally receives from a terminal emulator, start up ./raw_inputs and type something. Example sequence: Application calls the Device Status Report - application writes '\x1b[6n' to its stdout (the tty) - backend reads the bytes, passes them to libnast - libnast interprets the DSR request, generates response bytes - libnast calls the THook to tell the backend to write response to tty - backend writes the response bytes to the tty - application reads the response on its stdin (the tty) Alternatives ------------ pyte (pyte.readthedocs.io/en/latest/) pyte is a PYthon Terminal Emulator library. It is very similar in goals to libnast, but it's written in python. I'm interested in a C library. libvterm (github.com/neovim/libvterm) libvterm looks to be neovim's solution to the terminal emulator library problem. I looked at using it, but it has no documentation. Credits ------- Based on the work of literally more people than I can track. See LICENSE for a subset of such people.