Rio: Terminal app built over WebGPU, WebAssembly and Rust
github.com
github.com
There was a real push, which must be approaching a decade ago at this point, to get all terminal emulators able to understand the ITU-T T.416 control sequences for direct 24-bit RGB colour. Even if they implement it really badly, and some do, almost everyone tries to support this colour system now.
See the screenshot of the old syscons FreeBSD kernel built-in terminal emulator at https://tty0.social/@JdeBP/110424206935120790 for what I mean by really badly. It still does understand the control sequences, though.
Since eMacs and vi has been two color for a lot of its life, I’d say it’s more like writing code with pretty bog standard code editing tools.
I still stubbornly use it as my daily driver for some probably terrible reason.
It's a 96 GiB of RAM machine, for chrissake! That ought to be enough for everybody!
The parent ran out of memory with iTerm not because of the infinite scrolling buffer but because of iTerm having memory leaks. The memory leaks in iTerm used to be a big issue, and it appears they still have not fully fixed. Other terminal apps can swell up to over 1Gb of the RSS, yet they do not crash. Provided there is sufficient RAM available, the inifinte scrolling can prove to be benefecial.
I have a fairly trivial bodge for them in mine. Kovid Goyal over a period of 7 years has built up an extensive system for overriding the glyphs for block and line drawing characters that are supplied in fonts and replacing them with ones that Kitty constructs itself, all started because they just didn't line up when using what the fonts supplied.
* https://github.com/kovidgoyal/kitty/issues/16
* https://github.com/kovidgoyal/kitty/blob/28b84a2d5b2720b88fd...
However, it could use some love from Apple. Better keyboard-only text selection, horizontal and vertical splitting, True Color (not Cyndi Lauper style)…
(That's the big push that I mentioned. Going since January 2014.)
Microsoft Terminal has a whole open GitHub issues system to itself.
Apple seems to have forgotten we exist.
* https://github.com/rust-lang/rust/blob/master/compiler/rustc...
fn foo<'bla>(...)
According to cat -v, <'bla> is preceded by ^[[38;5;10m, which, according to [1], "applies extended color value to the foreground", and further that 38;5;<s> sets "foreground color to <s> index in 88 or 256 color table".[1]: <https://learn.microsoft.com/en-us/windows/console/console-vi...>
I've checked and the 10th colour is set to #000000 in my Terminal.app settings.
If the app doesn’t check for support and simply spills the control characters, there may be garbled output.
There's a demo program that comes with libcaca, called cacademo. It can either output text to standard output with ECMA-48 control sequences, or crank up a built-in X client that displays a very simple text window.
I SSHed into a remote machine with it from a local machine that had an X server. Tunnelled over the SSH connection, the X version of the demo was a little slower than running directly on the remote machine's own display, but mostly didn't drop frames. The mode where it sent ECMA-48 control sequences over the SSH connection to a local terminal emulator was woefully slower, to the point that it was displaying less than 1 frame a second sometimes, and visibly tearing the display. I tried it with both Microsoft Terminal and MobaXTerm to see whether it was the terminal emulator. It wasn't.
Sending colour information as ITU-T T.416 RGB control sequences, or even as AIXTerm 16-colour control sequences, to be interpreted by a control sequence state machine in the terminal emulator and turned into a display buffer and graphics drawing commands, turns out not to be as efficient over SSH as the X protocol over SSH. Yes, X11.
The X path was going through an X client library to the X server. It was probably using the old X11 primitives for text, rather than doing client-end rendering. The terminal emulator path was going through ncurses, then probably wasn't being batched up very much over the SSH connection, and then was going through a decoder that had to (amongst other things) parse numbers from human-readable to machine-readable thousands of times per frame because ECMA-48 uses decimal-character-encoded values in control sequences, and the cacademo program outputs lots of colour changes, frequently a colour change for each successive cell.
I think that part of the problem lies with SSH: the lack of batching as I mentioned, which might also be at ncurses' door too. Of course one wants terminal output to go over the wire as soon as possible, and not wait "until we have a buffer-ful". But not in this case.
Rather, batching up the control sequences to change colour, cursor position, and then output the relevant character into a single exchange over the wire would be better. That would be equivalent to a an X primitive to write character X at position Y with attributes Z, which presumably goes as a single message over the wire.
But a combination of whatever output buffering ncurses and libcaca are doing, what happens in the pseudo-terminal and sshd at the remote end, and then what happens at the local end when ssh is outputting to its pseudo-terminal, are all almost certainly strongly militating against that.
... In addition to converting lots of numbers from machine-readable to human-readable, then back to machine-readable again. (-:
I should mention that at one point I was transcoding from AIXTerm to ITU T.416 colour control sequences. The latter are about 4 times as long as the former, and that noticeably slowed things down even further. Yes, I'm in favour of 24-bit colour like the other terminal emulator authors, but it does come at a measurable price.
- Alacritty minimal and blazingly fast
- Wezterm with batteries included
- Warp even batteries included
Host *
SetEnv TERM=xterm-256colorKitty is, unsurprisingly:
https://invisible-island.net/ncurses/terminfo.src.html#tic-k...
The problem that people have is different anyway. When they're doing things correctly, and setting the correct terminal type, they then face "But my terminfo on that Linux distribution DVD that I got isn't up to date!", or "But my termcap on FreeBSD isn't up to date!".
The answer to that problem is to point out that terminfo supports a local ~/.terminfo/ if one needs one, and FreeBSD termcap has a TERMPATH environment variable that one can point at a ~/.termcap.db file, or indeed one placed anywhere else, if the system termcap database isn't up to date.
Most machines I've SSHed into didn't have kitty's terminfo installed, which results in many things not working. Using xterm-256color as a safe fallback has always worked for me however. It would always be possible to define the TERM variable per host and use TERM=kitty for hosts that have the correct terminfo installed. Is there a drawback to that apart from not being technically correct?
Yes, you have misunderstood what xterm+256colour is. It's not xterm-256color. Notice the plus sign. What entries with plus signs in are is actually explained in commentary in the terminfo source file itself.
The full difference between the two entries is obtainable with infocmp, but that's just details. The simple fact is that for anything that isn't XTerm the xterm entries in terminfo/termcap are wrong. The few terminals that are close enough to XTerm to be for practical purposes compatible are the ones that were actually branches of actual XTerm at one point. All of the others, especially the recent ones like Alacritty, Kitty, and the like, are markedly and intentionally different.
The drawbacks in general are various and range from the subtle (e.g. some supposedly compatible terminal emulators mix up the home/end key codes with the find/select key codes, or they'll use different codes for higher numbered function keys, or for keys with modifiers) to the blatant (e.g. there are stark differences in indexed and direct colour support amongst terminal emulators). There's plenty of just plain odd along the way. I used the wrong TERM value for something the other day, and suddenly the Z shell's line editor was putting the cursor in column 80 all of the time.
The thing to remember is that one isn't helpless with respect to getting a proper terminfo/termcap entry installed on systems that don't have it. It's 2023, and not only has terminfo had the ability for users to supply extra terminfo entries for a long while, but historical termcap has gone away, and the few remaining systems such as FreeBSD that still use termcap can also just plonk in user-supplied termcap entries. They, too, nowadays have a mechanism for this. There's really zero excuse for not just copying the proper entry over and using it if it isn't there, nowadays. Indeed, Kitty even reportedly has a helper utility for hand-holding one through the process.
It's really a shame that more terminals don't support this protocol, because we could have a lot more sophisticated terminal applications.
I have to take a moment to just evangelize WezTerm a bit. I switched over from iTerm in the last few months and IMO WezTerm's absolute killer feature is its Lua-based configuration. You can do so much with it, down to running scripts on key binds, and the API is powerful enough to do virtually anything you want. For example I have some key binds that act differently when the active pane is running emacs vs. a shell.
GPU rendering is really cool, but I don't really understand what might people be doing where CPU rendering in terminal is anywhere close to being a bottleneck. People lose ability to comprehend way before that, why would I want gibberish to be printed even faster? Redirecting output to a file (or /dev/null) is almost always what I would want?
1. I wouldn't say there really is much that would be "just not possible" in urxvt. If you drop down to Perl level, you can do almost everything (albeit you would have to write Perl).
2. The reason urxvt doesn't have majority of those selling points is because they arguably aren't the concern of terminal emulator at all. Things like better autocomplete menu, command editing, history browsing etc. historically fell under purview of the shell. You can have all these things with say zsh and a few chose plugins.
Perhaps, on Mac, you badly need an alternate terminal app , because the default one is unbearably slow.
https://danluu.com/images/term-latency/loaded-terminal-laten...
Also, which terminal emulator would you recommend?
I use Terminology, from the Enlightenment WM team. It's fast, supports unicode, is easily configurable, and behaves how I, personally, prefer. But if you don't really have a preference, I don't think fancy different terminals are going to be that important.
https://github.com/microsoft/terminal/issues/10362
It really highlighted how crappy software gets written in large corporations. They told him rendering monospaced fonts on the GPU would involve a multi year PHD research project.
Apparently they then went on to infiltrate his discord server so they could ask questions. Then write up a blog post calling the change "trivial".
I hate that what was definitely intended as a joke originally turned into this massive miscommunication and flame war. Admittedly tone is hard to convey on the internet, and italics is no replacement for a good old fashioned ":P". But this could have been a good place for everyone to work together, rather than flame one another.
It's certainly an experience that everyone can learn from.
I use JetBrains IDEs and honestly their built in terminal emulators are embarrassingly slow. VSCode is buttery smooth in comparison. Sad state of things.
edit: found the reference at https://twitter.com/nathansobo/status/1619398212712022017
Also- VSCode is literally an example of a use-case where you might do this in WebGPU, they just didn't
I've sort of been looking into it and it doesn't seem there are cross platform libraries for handling IMEs and not many people talk about even the platform-specific APIs.
[1]: https://wasmer.io/
edit: seems like most of the wasm stuff is some tests within this lib: https://github.com/raphamorim/rio/tree/main/sugarloaf
[0]: https://src.chromium.org/viewvc/chrome/trunk/src/net/base/ne...
> Is it really the fastest terminal emulator?
Benchmarking terminal emulators is complicated. Alacritty uses vtebench to quantify terminal emulator throughput and manages to consistently score better than the competition using it. If you have found an example where this is not the case, please report a bug.
Other aspects like latency or framerate and frame consistency are more difficult to quantify. Some terminal emulators also intentionally slow down to save resources, which might be preferred by some users.
If you have doubts about Alacritty's performance or usability, the best way to quantify terminal emulators is always to test them with your specific usecases.
Couldn't you just use Rust + OpenGL/SDL2/.. or even AppKit if macOS is the only supported OS?
JavaScript doesn’t belong anywhere in anyone’s tech stack, and unless you’re making a web page neither do HTML or CSS.
Rio uses none of these things?