This commit is contained in:
2026-09-07 23:01:44 +02:00
parent 9a9a94fc78
commit 6eb796494a
9 changed files with 56 additions and 42 deletions
Generated
+16 -16
View File
@@ -2087,22 +2087,6 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832"
[[package]]
name = "rust-term"
version = "0.1.0"
dependencies = [
"anyhow",
"base64",
"eframe",
"egui",
"libghostty-vt",
"png",
"portable-pty",
"serde",
"toml",
"wgpu",
]
[[package]] [[package]]
name = "rustc-hash" name = "rustc-hash"
version = "1.1.0" version = "1.1.0"
@@ -2283,6 +2267,22 @@ version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5"
[[package]]
name = "slerm"
version = "0.1.0"
dependencies = [
"anyhow",
"base64",
"eframe",
"egui",
"libghostty-vt",
"png",
"portable-pty",
"serde",
"toml",
"wgpu",
]
[[package]] [[package]]
name = "slotmap" name = "slotmap"
version = "1.1.1" version = "1.1.1"
+1 -1
View File
@@ -1,5 +1,5 @@
[package] [package]
name = "rust-term" name = "slerm"
version = "0.1.0" version = "0.1.0"
edition = "2024" edition = "2024"
rust-version = "1.92" rust-version = "1.92"
+1 -1
View File
@@ -1,4 +1,4 @@
# ~/.config/rust-term/config.toml # ~/.config/slerm/config.toml
# Omit shell to use $SHELL. Arguments are separate array entries. # Omit shell to use $SHELL. Arguments are separate array entries.
# shell = ["/bin/bash", "--login"] # shell = ["/bin/bash", "--login"]
# working_directory = "/home/you" # working_directory = "/home/you"
+26 -12
View File
@@ -1,5 +1,5 @@
{ {
description = "Ghostty-powered Rust terminal"; description = "slerm: a Ghostty-powered Rust terminal";
inputs = { inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
@@ -38,7 +38,7 @@
exec ${lib.getExe zig} "$@" exec ${lib.getExe zig} "$@"
''; '';
ghosttyDeps = pkgs.callPackage "${ghostty-src}/build.zig.zon.nix" { ghosttyDeps = pkgs.callPackage "${ghostty-src}/build.zig.zon.nix" {
name = "rust-term-ghostty-zig-deps"; name = "slerm-ghostty-zig-deps";
zig_0_15 = zig; zig_0_15 = zig;
# Zig 0.15's build runner needs real directories, not a symlink farm. # Zig 0.15's build runner needs real directories, not a symlink farm.
linkFarm = linkFarm =
@@ -65,12 +65,25 @@
vulkan-loader vulkan-loader
] ]
); );
# wgpu dlopens the Vulkan loader and libEGL by soname, and those in turn
# dlopen the GPU vendor driver named in the ICD/vendor JSON. Nixpkgs' own
# store paths cover the loaders but never the driver, which lives outside
# /nix/store: under /run/opengl-driver on NixOS, under the distro's library
# directory everywhere else. Without these the loader finds zero drivers and
# wgpu reports "Failed to create surface for any enabled backend: {}".
# They go last so /nix/store still wins for everything else.
driverLibraries = [
"/run/opengl-driver/lib"
"/usr/lib/${pkgs.stdenv.hostPlatform.parsed.cpu.name}-linux-gnu"
"/usr/lib64"
"/usr/lib"
];
ghosttyEnv = { ghosttyEnv = {
GHOSTTY_SOURCE_DIR = "${ghostty-src}"; GHOSTTY_SOURCE_DIR = "${ghostty-src}";
GHOSTTY_ZIG_SYSTEM_DIR = "${ghosttyDeps}"; GHOSTTY_ZIG_SYSTEM_DIR = "${ghosttyDeps}";
LIBGHOSTTY_VT_SYS_OPTIMIZE = "ReleaseFast"; LIBGHOSTTY_VT_SYS_OPTIMIZE = "ReleaseFast";
}; };
rustTerm = pkgs.rustPlatform.buildRustPackage ( slerm = pkgs.rustPlatform.buildRustPackage (
{ {
pname = manifest.package.name; pname = manifest.package.name;
version = manifest.package.version; version = manifest.package.version;
@@ -115,14 +128,15 @@
]; ];
postFixup = lib.optionalString pkgs.stdenv.hostPlatform.isLinux '' postFixup = lib.optionalString pkgs.stdenv.hostPlatform.isLinux ''
wrapProgram "$out/bin/rust-term" \ wrapProgram "$out/bin/slerm" \
--suffix LD_LIBRARY_PATH : ${lib.makeLibraryPath runtimeLibraries} --suffix LD_LIBRARY_PATH : ${lib.makeLibraryPath runtimeLibraries} \
--suffix LD_LIBRARY_PATH : ${lib.concatStringsSep ":" driverLibraries}
''; '';
meta = { meta = {
description = manifest.package.description; description = manifest.package.description;
license = lib.licenses.mit; license = lib.licenses.mit;
mainProgram = "rust-term"; mainProgram = "slerm";
platforms = systems; platforms = systems;
}; };
} }
@@ -131,12 +145,12 @@
in in
{ {
packages = { packages = {
default = rustTerm; default = slerm;
rust-term = rustTerm; slerm = slerm;
}; };
devShells.default = pkgs.mkShell ( devShells.default = pkgs.mkShell (
{ {
inputsFrom = [ rustTerm ]; inputsFrom = [ slerm ];
packages = [ packages = [
pkgs.cargo pkgs.cargo
pkgs.rustc pkgs.rustc
@@ -147,7 +161,7 @@
shellHook = '' shellHook = ''
export ZIG_GLOBAL_CACHE_DIR="$PWD/target/zig-global-cache" export ZIG_GLOBAL_CACHE_DIR="$PWD/target/zig-global-cache"
${lib.optionalString pkgs.stdenv.hostPlatform.isLinux '' ${lib.optionalString pkgs.stdenv.hostPlatform.isLinux ''
export LD_LIBRARY_PATH="${lib.makeLibraryPath runtimeLibraries}''${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" export LD_LIBRARY_PATH="${lib.makeLibraryPath runtimeLibraries}''${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}:${lib.concatStringsSep ":" driverLibraries}"
''} ''}
''; '';
} }
@@ -162,8 +176,8 @@
apps = forAllSystems (system: { apps = forAllSystems (system: {
default = { default = {
type = "app"; type = "app";
program = "${self.packages.${system}.default}/bin/rust-term"; program = "${self.packages.${system}.default}/bin/slerm";
meta.description = "Run rust-term"; meta.description = "Run slerm";
}; };
}); });
formatter = forAllSystems (system: nixpkgs.legacyPackages.${system}.nixfmt); formatter = forAllSystems (system: nixpkgs.legacyPackages.${system}.nixfmt);
+2 -2
View File
@@ -127,11 +127,11 @@ impl Default for Config {
impl Config { impl Config {
pub fn path() -> Result<PathBuf> { pub fn path() -> Result<PathBuf> {
if let Some(dir) = std::env::var_os("XDG_CONFIG_HOME").filter(|p| !p.is_empty()) { if let Some(dir) = std::env::var_os("XDG_CONFIG_HOME").filter(|p| !p.is_empty()) {
return Ok(PathBuf::from(dir).join("rust-term/config.toml")); return Ok(PathBuf::from(dir).join("slerm/config.toml"));
} }
Ok( Ok(
PathBuf::from(std::env::var_os("HOME").context("HOME is not set")?) PathBuf::from(std::env::var_os("HOME").context("HOME is not set")?)
.join(".config/rust-term/config.toml"), .join(".config/slerm/config.toml"),
) )
} }
+6 -6
View File
@@ -21,12 +21,12 @@ fn main() -> Result<()> {
"--check-config" => check = true, "--check-config" => check = true,
"--init-config" => init = true, "--init-config" => init = true,
"--version" => { "--version" => {
println!("rust-term {}", env!("CARGO_PKG_VERSION")); println!("slerm {}", env!("CARGO_PKG_VERSION"));
return Ok(()); return Ok(());
} }
"--help" | "-h" => { "--help" | "-h" => {
println!( println!(
"rust-term [--config PATH] [--check-config | --init-config]\n\nDefault config: {}", "slerm [--config PATH] [--check-config | --init-config]\n\nDefault config: {}",
path.display() path.display()
); );
return Ok(()); return Ok(());
@@ -69,17 +69,17 @@ fn main() -> Result<()> {
libghostty_vt::kitty::graphics::set_png_decoder(Some(Box::new(render::PngDecoder)))?; libghostty_vt::kitty::graphics::set_png_decoder(Some(Box::new(render::PngDecoder)))?;
let options = eframe::NativeOptions { let options = eframe::NativeOptions {
viewport: egui::ViewportBuilder::default() viewport: egui::ViewportBuilder::default()
.with_title("rust-term") .with_title("slerm")
.with_inner_size([config.window_width, config.window_height]) .with_inner_size([config.window_width, config.window_height])
.with_min_inner_size([320.0, 200.0]) .with_min_inner_size([320.0, 200.0])
.with_app_id("rust-term"), .with_app_id("slerm"),
renderer: eframe::Renderer::Wgpu, renderer: eframe::Renderer::Wgpu,
..Default::default() ..Default::default()
}; };
eframe::run_native( eframe::run_native(
"rust-term", "slerm",
options, options,
Box::new(move |cc| Ok(Box::new(app::App::new(cc, config, path)?))), Box::new(move |cc| Ok(Box::new(app::App::new(cc, config, path)?))),
) )
.map_err(|e| anyhow::anyhow!("Cannot start rust-term: {e}")) .map_err(|e| anyhow::anyhow!("Cannot start slerm: {e}"))
} }
+1 -1
View File
@@ -37,7 +37,7 @@ pub fn terminal(config: &Config) -> Result<Terminal<'static, 'static>> {
})?; })?;
term.resize(80, 24, 8, 16)?; term.resize(80, 24, 8, 16)?;
apply_config(&mut term, config)?; apply_config(&mut term, config)?;
term.on_xtversion(|_| Some("rust-term 0.1.0"))?; term.on_xtversion(|_| Some(concat!("slerm ", env!("CARGO_PKG_VERSION"))))?;
term.on_device_attributes(|_| { term.on_device_attributes(|_| {
Some(terminal::DeviceAttributes { Some(terminal::DeviceAttributes {
primary: terminal::PrimaryDeviceAttributes::new( primary: terminal::PrimaryDeviceAttributes::new(
+1 -1
View File
@@ -29,7 +29,7 @@ impl Pty {
cmd.args(&config.shell[1..]); cmd.args(&config.shell[1..]);
cmd.env("TERM", "xterm-256color"); cmd.env("TERM", "xterm-256color");
cmd.env("COLORTERM", "truecolor"); cmd.env("COLORTERM", "truecolor");
cmd.env("TERM_PROGRAM", "rust-term"); cmd.env("TERM_PROGRAM", "slerm");
cmd.env("TERM_PROGRAM_VERSION", env!("CARGO_PKG_VERSION")); cmd.env("TERM_PROGRAM_VERSION", env!("CARGO_PKG_VERSION"));
if let Some(dir) = &config.working_directory { if let Some(dir) = &config.working_directory {
cmd.cwd(dir); cmd.cwd(dir);
+2 -2
View File
@@ -590,7 +590,7 @@ mod tests {
#[ignore = "manual CPU rendering benchmark"] #[ignore = "manual CPU rendering benchmark"]
fn renderer_frame_cost() { fn renderer_frame_cost() {
let config = crate::config::Config { let config = crate::config::Config {
font_path: std::env::var_os("RUST_TERM_TEST_FONT").map(Into::into), font_path: std::env::var_os("SLERM_TEST_FONT").map(Into::into),
..Default::default() ..Default::default()
}; };
let ctx = egui::Context::default(); let ctx = egui::Context::default();
@@ -671,7 +671,7 @@ mod tests {
#[test] #[test]
fn terminal_cells_match_font_line_metrics() { fn terminal_cells_match_font_line_metrics() {
let config = crate::config::Config { let config = crate::config::Config {
font_path: std::env::var_os("RUST_TERM_TEST_FONT").map(Into::into), font_path: std::env::var_os("SLERM_TEST_FONT").map(Into::into),
..Default::default() ..Default::default()
}; };
for scale in [1.0, 1.5, 2.0] { for scale in [1.0, 1.5, 2.0] {