github Gaurav-Gosain/tuios v0.10.0

4 hours ago

tuios 0.10.0 is a feature release. On Omarchy, tuios now uses the Omarchy theme when you set no theme, and it changes its colours when you switch the Omarchy theme. You do not restart tuios.
The terminal emulator of tuios is now a Go library of its own, tuios.dev/vt. A second library, tuios.dev/swatch, reads the colour theme of a desktop. Host links reconnect after a laptop wakes from sleep. Read Upgrading before you update: the theme on Omarchy, the TERM of new sessions, some terminal mode keys and Option characters on macOS changed.

The full list is at tuios.dev/releases.

Install

brew install tuios                     # Homebrew (macOS, Linux)
yay -S tuios-bin                       # AUR (tuios-web-bin for the web server)
nix run github:Gaurav-Gosain/tuios     # Nix
curl -fsSL https://raw.githubusercontent.com/Gaurav-Gosain/tuios/main/install.sh | bash
go install github.com/Gaurav-Gosain/tuios/cmd/tuios@v0.10.0
docker run -it --rm ghcr.io/gaurav-gosain/tuios:v0.10.0

A binary installed by the script or from an archive updates with tuios update.

Omarchy

  • The Omarchy theme by default. On a machine with Omarchy, tuios uses the applied Omarchy theme when appearance.theme is empty. The panes, the chrome, the rail and the dock take its colours. The panes get the colours that Omarchy gives kitty, ghostty and foot (#734).
  • Live follow. When you switch the Omarchy theme, tuios changes its colours at the same moment as your terminal. You do not restart tuios and you do not press a key (#738).
    • tuios watches the theme folder with one file watch. No timer runs. A machine without Omarchy watches nothing.
    • A theme that you pick by hand stays. A theme in a picker preview stays.
  • Theme ids. theme = "omarchy" uses the Omarchy theme, and shows a warning on a machine without Omarchy. theme = "none" uses the colours of your terminal. Each installed Omarchy theme is also in the theme list as omarchy/NAME, such as omarchy/gruvbox. Such an id is fixed. It does not change with the Omarchy theme.
  • tuios list-themes shows the Omarchy theme that it found, and whether tuios uses it.
  • Theme colours in a pane. A program in a pane of a daemon session now gets the theme's colours when it asks with OSC 10, 11 and 4. Before, under any theme, it got black, white and the xterm colours. Neovim, Claude Code and other programs use this answer to pick a light or a dark look (#730).
  • Light and dark reports. A program that turns on mode 2031 gets a report when the background changes between light and dark. This also works when your terminal changes its own colour scheme. tuios sends no SIGWINCH (#738).

See Omarchy for the keys that tuios reads.

  • Theme switch animation. appearance.theme_transition shows a change of theme as an animation. circle grows the new theme from the middle of the screen, and fade changes every cell from the old colours to the new colours. The default, none, changes the theme in one frame. It runs for the theme picker, set-config, a config reload and the Omarchy live follow. appearance.theme_transition_duration sets the time, 450 ms by default, from 100 to 2000. animation_speed scales it. motion = "none" and --no-animations turn it off. fade needs a truecolor terminal (#757).

  • CharmTone themes. Two new built-in themes, charmtone (dark) and charmtone-light, use the colours of CharmTone, the colour system of Charm (#755).

Go libraries

  • tuios.dev/vt, the terminal emulator of tuios, is now its own Go module (#725). It keeps the screen that a program draws: cells, colours, the cursor, scrollback with reflow, kitty graphics and sixel. The default build is pure Go. The ghostty build tag uses libghostty-vt.
    • v0.1.0 is the first release, with a documented API and a Screen interface.
    • v0.2.0 adds TakeResponses, a read of the replies to the program that never blocks. It also adds the mode 2031 report, the ConPTY kitty keyboard switch and two calls that give back memory. The vtgen input generator now shrinks a failing input all the way down (#740).
    • tuitest now uses tuios.dev/vt in place of its own copy of the emulator (tuitest#8).
  • tuios.dev/swatch v0.1.0 reads the colour theme of a desktop as one palette with named roles, such as background, accent and error (#731, #732, #739).
    • swatch/omarchy reads the Omarchy theme. Its colours match the output of omarchy-theme-color for every shipped theme.
    • swatch.Watch follows a theme and sends each new palette.
    • swatch/teaswatch connects a watch to a Bubble Tea program, and follows the colours of the terminal.
    • swatch/termconfig reads kitty, ghostty, alacritty and wezterm colour files. tuios import-theme now uses it.

The library pages are at tuios.dev/docs/libraries.

Hosts

  • Reconnect after sleep. After a laptop wakes, a host link now reconnects. Before, the link stayed on a dead connection, and a click on a remote session did nothing or froze the screen (#728, fixes #720).
    • A link that carried nothing for 15 seconds sends a check to its host. Two missed answers end the link, and tuios dials again.
    • After this machine wakes, one missed answer ends the link, and a link that waits to dial again dials at once.
    • The first dial after a dead link opens its own ssh connection, so an ssh master that did not survive the sleep does not block it.
  • Remote sessions open in every link state. Each remote session on the rail is a click target. A click on a host that is up says "Connecting to HOST". A click on a host that is down says "Reconnecting to HOST", and the session opens when the link comes up. The wait ends after one minute, and tuios says why.

Sessions

  • Spaces. A space is a named group of related sessions (#708, part of #681). Thanks to @abhijit-s.
    • tuios new NAME --space SPACE makes a session in a space. tuios set-session-space SPACE -s SESSION files a session that exists. With no space, it takes the session out of its space.
    • tuios ls shows one table for each space. A daemon restart keeps the space of each session.
    • A global session cannot be in a space.
  • Move a window to another session. tuios move-window --to-session NAME moves a window and its program to another session. The program keeps running, and the scrollback stays (#660).
    • The tmux shim's join-pane and move-pane, and herdr's pane.move, now move a pane to another session too.
  • Split toward a side. tuios split-window left, right, up and down put the new pane on that side. The tape Split command takes the same words (#707).
  • Merged worktrees. tuios worktree ls has a MERGED column. It shows into <ref> when the base of the branch holds its work. A merge commit, a fast-forward, a rebase and a squash merge all count. tuios does not fetch, and it does not remove a worktree (#657).
  • Daemon sessions in the rail. [appearance.sidebar.left] session = "NAME" and the same key under right show the panes of a daemon session in that rail, one on top of the other. You type in them as in other panes. session_workspace shows the rail only on one workspace. Detach does not stop the programs (#741, from #626). Thanks to @drawde-nadroj.

Panes and the mouse

  • Links to a window. A program can print an OSC 8 link to tuios://window/<id>. A Ctrl+click on it goes to that window. A tuios://window/<id>/close link asks first, and the confirmation names the pane (#609). Thanks to @davidreuss.
  • Page scroll and middle-click paste. In terminal mode, Shift+PageUp and Shift+PageDown now scroll one page of the pane's history. The middle mouse button pastes from the clipboard. A program that uses the full screen or the mouse still gets these keys and the middle button. You can rebind or unbind all three in [keybindings.terminal_mode] (#679). Thanks to @stevegt.
  • The drop preview. While you drag a pane in BSP, the preview is a pane frame in the accent colour over one even tint. The text under it fades into the tint (#705, #714). The preview follows the layout when it changes under a held drag (#721). Thanks to @abhijit-s.
  • Cancel a drag. A press of another mouse button during a pane drag now cancels the drag. Before, a right click left the pane floating over the tiles (#713).

Keys and settings

  • List keys. The new [keybindings.lists] section sets the keys that move the cursor in every list: the palette, the launcher, the pickers, the menus and the settings page. The actions are list_up, list_down, list_page_up, list_page_down, list_first and list_last. The defaults are the old keys (#745). Thanks to @ural89.

  • Animation speed. appearance.animation_speed sets the speed of the window animations, in percent. 200 runs them in half the time. The range is 25 to 400 (#747). Thanks to @adilw3nomad.

  • Option characters on macOS. On macOS, tuios now reads the keyboard layout at startup. On a US or ABC layout, Option+N switches the workspace as before. On any other layout, a character that the keyboard composes, such as £ on a UK Mac or the AZERTY characters, goes to the pane as text. Before, tuios read these characters as Option key bindings. On a UK Mac, Shift+3 types £, and tuios switched to workspace 3. keybindings.option_glyphs has a new default, auto. See Upgrading (#753, fixes #746 and #575).

  • tmux-style actions. New actions with no default key, so you can write a tmux keymap in config.toml (#718). Thanks to @SugarHashira.

    • mark_pane marks a pane, and join_marked_left, _right, _up and _down move the marked pane next to the focused one.
    • resize_pane_left_5 and the other resize_pane_*_5 and resize_pane_*_20 actions move an edge of the pane by 5 or 20 cells.
    • new_workspace, move_workspace_left, move_workspace_right and send_to_workspace_1 to send_to_workspace_9 work on workspaces.
    • reload_config reads config.toml again. toggle_mouse lets the terminal select text. cycle_layout goes through BSP, master-stack and scrolling.
  • Workspace tab style. [dock.tabs] style = "flat" draws the workspace strip of the dock as text with a separator, as a tmux status line does. The tab format also takes {icon} and {zoom}. With no [dock.tabs] table the strip does not change (#715). Thanks to @SugarHashira.

  • Dim only the background. appearance.dim_foreground = false makes dim_unfocused dim the background of a pane you are not in, and keeps its text at full strength (#717). Thanks to @SugarHashira.

  • A steady dock. A clock or another component in the centre of the dock no longer moves when a notification shows, changes or goes away (#752, fixes #751). Thanks to @syz51.

  • A session cell in the dock. The new session dock component shows the session and the position of the pane, such as main 2:1. [dock.session] and each [dock.custom.NAME] take colours and caps (#716). Thanks to @SugarHashira.

Terminal

  • The caller's terminal. A session that a command makes now gives its panes the TERM and COLORTERM of the terminal you ran the command in. Before, these sessions got xterm-256color. This holds for tuios call new-session, tuios switch-session --create (#700, fixes #697), tuios new from an attached client (#727), start-agent (#729), and new-worktree and fan (#749). Thanks to @abhijit-s. See Upgrading.
  • Kitty images by number. An image that a program sends by number (I=) now shows. Each placement of an image stays, so one sprite can show at many places. tuios answers uploads as kitty does (#646, #651, fixes #644).
  • Wide text at the edge of the screen. A pane that the left edge of the screen cuts keeps its border in place when the cut part has CJK text or emoji (#744, fixes #743).

Windows

  • No kitty keyboard protocol in ConPTY panes. A pane on Windows no longer offers the kitty keyboard protocol, because older conhost versions drop its keys. Programs such as pi and neovim then use the legacy keys, and Escape works again (#596). Thanks to @chexxor.

The rail

  • A steady peek. When the terminals section is above the sessions section, a hover on a session row no longer changes the height of the terminals section. The row under the pointer stays in place (#699, fixes #698). Thanks to @abhijit-s.

Daemon verbs

These verbs and events are for scripts and for a GUI client. The protocol is in protocol.md.

  • search-panes finds text in the history and the screen of every pane. command-history lists the commands that shells in panes ran. list-ports lists the TCP ports that the programs in a pane listen on (#666).
  • Each window has started_by, the pane whose call made it.
  • review-stage stages and unstages a change by file, by hunk or by line, and each call gives an undo. review-diff marks the changed words (#662).
  • file-preview makes a preview of a file on this machine or on a host. It keeps the read rules of file-read (#659).
  • set-session-space files a session under a space. move-window takes to_session.
  • A layout-changed event names a workspace whose panes moved. list-windows marks a floating window (#707).
  • hello takes term and color_term (#700).
  • tuios gui-bridge serves a session to a native renderer over stdin and stdout. The [keybindings.gui] section holds its keys. The desktop app that uses it is not released yet (#658, #661).

Performance and binary size

  • Less memory in the daemon. The cleanup sweep of the daemon, every 30 seconds, now frees the resize buffers of each pane, and the alternate screen of each pane that left it. That is about 1.7 MB each for a pane of 171x83. On a load of 25 panes, the first change takes the live heap from 42.3 MB to 34.9 MB, and the second from 42.3 MB to 37.0 MB (#735, #736). Thanks to @abhijit-s.
  • A faster clip. To cut a pane of 42 rows at the left screen edge, tuios now makes 45 allocations in place of 259 (#744).
  • Fewer wakeups while a message shows. A client with a message on the dock now sleeps until the rule under the message changes. Before, it woke at the frame rate. Client CPU on an idle screen with a message went from 0.77% to 0.27% (#763).
  • Binary size. The size budget is now 36,620,000 bytes on linux/amd64 and 34,465,000 bytes on darwin/arm64. In v0.9.3 it was 35,560,000 and 33,500,000. The GUI bridge, file previews, the new verbs, the rail sessions, the Omarchy theme, the tmux-style actions and the theme transition take the difference (#759). The ceiling stays at 40 MB.

Fixes

  • ssh sockets on macOS. On macOS, tuios refused every ssh socket under /var, because /var is a symlink there. A split of a pane that runs ssh, and the SSH agent of a pane, can use these sockets again (#617, fixes #615). Thanks to @abhijit-s.
  • Theme reload. A config reload that removes the theme line now puts the default theme back (#734).
  • Settings from config.toml in the daemon. tuios get-config, list-themes, list-glyphs and the screenshot settings of the daemon now read config.toml. Before, they gave the built-in default for a key that only config.toml set. A set-config value still wins. A call over a host link does not read the file. On Omarchy with no theme set, they report omarchy (#758).
  • A split that is too small. In BSP, tuios refuses a split that leaves a pane smaller than 20 columns by 5 rows, and says why (#658).

Maintenance

  • The release workflow uses goreleaser-action 7.3.0 (#754).

Upgrading

The daemon

The daemon protocol did not change, so a v0.9.3 daemon works with a v0.10.0 client, and the reverse. The new fields are optional in both directions. The sleep reconnect, the theme colours in panes, spaces, window moves and the memory fixes are in the daemon. To get them, restart the daemon:

tuios kill-server

This closes every pane in every session, so save your work first.

The theme on Omarchy

On a machine with Omarchy, an empty appearance.theme now means the Omarchy theme. Before, it meant the colours of your terminal. To keep the colours of your terminal, set:

[appearance]
theme = "none"

A machine without Omarchy does not change. A theme that you set does not change.

Theme colours in daemon panes

A program in a daemon pane now gets the theme's colours from OSC 10, 11 and 4. A program that picks a light or a dark look from the background can change its look after the update. With no theme set, nothing changes.

The TERM of new sessions

A session made by tuios call new-session, tuios switch-session --create, an attached tuios new, start-agent, new-worktree or fan now gets your TERM and COLORTERM. Before, it got xterm-256color. tuios gives a pane your TERM only when the machine that runs the pane has a terminfo entry for it. Otherwise the pane gets xterm-256color, as before. A program in the pane that runs ssh to a machine with no entry for your TERM can show wrong keys or colours there. Install the entry on that machine, for example with infocmp -x xterm-kitty | ssh HOST tic -x -. The SSH server, tuios-web and the GUI bridge do not send a TERM. Their sessions still get xterm-256color.

Terminal mode keys

Shift+PageUp and Shift+PageDown now scroll the pane's history, and the middle mouse button pastes from the clipboard. A program that uses the full screen or the mouse still gets them. To give the keys and the button back to every program, remove them from the bindings:

[keybindings.terminal_mode]
terminal_scroll_page_up = []
terminal_scroll_page_down = []
terminal_paste_host = ["ctrl+shift+v", "super+v", "shift+super+v"]

Option characters on macOS

This is a change in behaviour on a keyboard layout other than US. keybindings.option_glyphs now defaults to auto. On macOS, tuios reads the keyboard layout when it starts:

  • On a US or ABC layout, nothing changes. Option+N switches the workspace.
  • On any other layout, such as UK or AZERTY, a character that the keyboard composes, such as £ or ©, goes to the pane as text. In Terminal.app and iTerm2 as they ship, Option+N then types its character. It does not switch the workspace.

keyboard_layout in [keybindings] overrides the layout that tuios reads. To get the Option bindings on any layout, set the Option key of the terminal to send Alt. In Terminal.app, tick "Use Option as Meta Key". In iTerm2, set the Option key to "Esc+". To keep the old behaviour, set option_glyphs = "bind". Ghostty, and kitty with the kitty keyboard protocol, report Alt, so they do not change.

New config keys

The defaults keep the old behaviour. The session lines are examples.

[appearance]
animation_speed = 100            # 25 to 400, 0 is 100
dim_foreground = true            # false dims only the background
theme_transition = "none"        # none, circle, fade
theme_transition_duration = 450  # milliseconds, 100 to 2000

[appearance.sidebar.left]
session = "side-left"            # a daemon session to show in this rail
session_workspace = 0            # 0 is every workspace, or 1 to 9

[appearance.sidebar.right]
session = "side-right"
session_workspace = 0

[keybindings.lists]
list_up = ["up", "ctrl+p", "k"]
list_down = ["down", "ctrl+n", "j"]
list_page_up = ["pgup"]
list_page_down = ["pgdown"]
list_first = ["home", "g"]
list_last = ["end", "G"]

[keybindings.terminal_mode]
terminal_scroll_page_up = ["shift+pgup"]
terminal_scroll_page_down = ["shift+pgdown"]

[dock.tabs]
style = "pill"                   # pill, flat

[dock.session]
format = "{session} {workspace}:{pane}"   # add "session" to a [dock] list to draw it

[dock.tabs] also takes separator, separator_fg, the active_ and inactive_ colours, number_glyphs, zoom_marker and show_add. The tmux-style actions have no default key.

appearance.theme also takes omarchy, omarchy/NAME, charmtone and charmtone-light. See CONFIGURATION.md.

For developers

  • tuios.dev/vt needs Go 1.26. tuios.dev/swatch needs Go 1.25. tuios itself still builds with the Go version in go.mod.
  • The emulator moved from internal/vt to vt/, the tuios.dev/vt module. The snapshot of a terminal moved to tuios.dev/vt/snapshot (#724). go.work holds the app, progstatus, vt and swatch. To build tuios as go install does, use GOWORK=off.
  • The binary size budgets went up in commits of their own. See docs/perf.md.

Contributors

Thank you to everyone who sent a pull request for this release:

And thanks to everyone who reported bugs and asked for features: @Brookke for the £ key and its analysis (#746), @florian-guily for the AZERTY keys (#575), @syz51 for the dock clock (#751), @fonnesbeck for the reconnect after sleep (#720), @pshickeydev for the kitty images (#644), @lost-melody for the wide text at the screen edge (#743), @abhi-easygo for the ssh sockets on macOS (#615), and @abhijit-s for spaces (#681), the TERM of new sessions (#697) and the rail peek (#698).


Full Changelog: v0.9.3...v0.10.0


Full Changelog: v0.9.3...v0.10.0

Don't miss a new tuios release

NewReleases is sending notifications on new releases.