- Zig 96%
- Makefile 2.2%
- Roff 1.1%
- C 0.7%
On Guix, glibc's headers include <linux/errno.h> and <asm/...>, which come from the separate linux-libre-headers package and are listed only in C_INCLUDE_PATH. Zig doesn't read that variable, so translate-c failed with "'linux/errno.h' not found". Pass every directory in CPATH and C_INCLUDE_PATH to translate-c. |
||
|---|---|---|
| patches | ||
| .gitignore | ||
| actions.zig | ||
| build.zig | ||
| c.h | ||
| config.def.zig | ||
| LICENSE | ||
| main.zig | ||
| Makefile | ||
| pty.zig | ||
| README.md | ||
| term.zig | ||
| util.zig | ||
| x.zig | ||
| zst.1 | ||
zst: zig simple terminal
A terminal emulator for X in the spirit of suckless st: a small base
(~2.6k lines of Zig), configured by editing source, extended by patches you
pick from patches/. Same libraries as st (X11, Xft, fontconfig).
base zst 175 KB (stock st 0.9.3: 96 KB)
all patches 203 KB + the optional zst-img image helper
Requirements
- Zig 0.15, 0.16 or 0.17
- libX11, libXft, libXrender, fontconfig, freetype2 headers, pkg-config
Arch: pacman -S zig libxft fontconfig pkgconf
Guix: packages zst (no patches) and zst-full (every patch) are in the
PIL channel.
Build
make # copies config.def.zig -> config.zig on first run
sudo make install
make OPT=ReleaseFast trades some binary size for speed;
make ZIGFLAGS=-Dcpu=baseline builds a binary that runs on any x86-64 CPU
(the default is tuned to the build machine).
Patches
The base is deliberately plain. Everything else is a patch in patches/:
| patch | adds |
|---|---|
scrollback |
history, Shift+PgUp/PgDn, mouse-wheel scrolling |
themes |
pywal colors.json/colors.yml, live reload |
alpha |
transparent background, opacity keys, -A, dim unfocused |
images |
PNG/JPEG/GIF/WebP/AVIF/JXL/video frames, fzf previews (+ Go helper) |
kbselect |
copy without the mouse: vim keys, search, yank |
anysize |
fill the whole dwm tile instead of cell-sized steps |
hidecursor |
hide the mouse pointer while typing |
make patch P="scrollback themes" # apply any set, in any order
make
Every combination of these patches applies cleanly in any order and builds.
See patches/README for what each one does, how to use it, and how to
remove or write patches.
Configuration
Edit config.zig and rebuild: exactly like st's config.h.
Shortcuts are { modifier, keysym, function, argument }; keysyms are matched
unshifted, so Ctrl+Shift+K is written TERMMOD, c.XK_k. The function can
be anything in actions.zig or a function you write in config.zig:
fn hello(_: a.Arg) void { @import("pty.zig").write("echo hi\r"); }
pub const shortcuts = [_]a.Shortcut{
.{ .mod = TERMMOD, .key = c.XK_h, .func = hello },
...
A function no shortcut points at is never compiled, so deleting a shortcut line removes its code from the binary too.
Default shortcuts (base)
| keys | action |
|---|---|
| Ctrl+Shift+K / Ctrl+Shift+J | zoom in / out (also Ctrl+wheel) |
| Ctrl+Shift+Home | reset zoom |
| Ctrl+Shift+C / Ctrl+Shift+V | copy / paste CLIPBOARD |
| Shift+Insert, Ctrl+Shift+Y, middle click | paste PRIMARY |
| Ctrl+Shift+I | invert colors |
| Ctrl+Shift+Return | new zst in the current directory |
| Ctrl+Shift+U | pick a URL on screen with dmenu, open it |
| Ctrl+Shift+E | open the screen contents in $EDITOR |
| double / triple click | select word / line |
| Shift + mouse | select even when an app grabs the mouse (htop, vim with mouse=a, tmux) |
What the base does
- xterm-compatible escape handling (
TERM=xterm-256color, no terminfo to install): 16/256/truecolor, bold/italic/underline/strike/reverse, alternate screen, scroll regions, DEC line drawing, bracketed paste, focus events, SGR mouse reporting, OSC 52 clipboard, window title. - Colors from
config.zig; applications (and pywal'swal) can still change them live with the standard OSC 4/10/11/12 escapes. - Xft rendering with automatic fontconfig fallback for CJK, symbols, emoji.
- Zoom with font-size steps, CLIPBOARD and PRIMARY selections.
- st's latency-based drawing (
minlatency/maxlatency).
Layout
| file | job |
|---|---|
main.zig |
arguments, event loop |
term.zig |
grid, VT/xterm parser, selection |
x.zig |
window, Xft drawing, fonts + fallback, keyboard, mouse, clipboard |
pty.zig |
spawn the shell, read/write |
actions.zig |
functions bindable to keys |
util.zig |
small shared helpers |
config.def.zig |
defaults |
patches/ |
optional features + the patch guide |
Not done
Ligatures, sixel, bidi, blinking text, the kitty keyboard protocol, and reflow on resize (st doesn't reflow either).