From fedc2f09518597b04923fe77130ccf69192f01f5 Mon Sep 17 00:00:00 2001 From: Chen Mulong Date: Sat, 3 May 2025 16:38:04 +0800 Subject: [PATCH] Add foot as a newly supported backend See https://codeberg.org/dnkl/foot --- Cargo.lock | 74 +++++++++++++++++++++++++++++++++- Cargo.toml | 1 + src/backend/foot.rs | 98 +++++++++++++++++++++++++++++++++++++++++++++ src/backend/mod.rs | 2 + src/config.rs | 1 + 5 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 src/backend/foot.rs diff --git a/Cargo.lock b/Cargo.lock index 72ea598..30b4e55 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "aho-corasick" @@ -35,6 +35,26 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "const-random" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359" +dependencies = [ + "const-random-macro", +] + +[[package]] +name = "const-random-macro" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" +dependencies = [ + "getrandom", + "once_cell", + "tiny-keccak", +] + [[package]] name = "core-foundation-sys" version = "0.8.4" @@ -74,6 +94,12 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crunchy" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" + [[package]] name = "dirs" version = "4.0.0" @@ -94,6 +120,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "dlv-list" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "442039f5147480ba31067cb00ada1adae6892028e40e45fc5de7b7df6dcc1b5f" +dependencies = [ + "const-random", +] + [[package]] name = "either" version = "1.9.0" @@ -153,6 +188,7 @@ dependencies = [ "dirs", "env_logger", "log", + "rust-ini", "serde", "serde_yaml", "shellexpand", @@ -272,6 +308,16 @@ version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +[[package]] +name = "ordered-multimap" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49203cdcae0030493bad186b28da2fa25645fa276a51b6fec8010d281e02ef79" +dependencies = [ + "dlv-list", + "hashbrown", +] + [[package]] name = "proc-macro2" version = "1.0.86" @@ -347,6 +393,17 @@ version = "0.6.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" +[[package]] +name = "rust-ini" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e310ef0e1b6eeb79169a1171daf9abcb87a2e17c03bee2c4bb100b55c75409f" +dependencies = [ + "cfg-if", + "ordered-multimap", + "trim-in-place", +] + [[package]] name = "rustix" version = "0.38.25" @@ -482,6 +539,15 @@ dependencies = [ "syn", ] +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + [[package]] name = "toml_datetime" version = "0.6.5" @@ -499,6 +565,12 @@ dependencies = [ "winnow", ] +[[package]] +name = "trim-in-place" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "343e926fc669bc8cde4fa3129ab681c63671bae288b1f1081ceee6d9d37904fc" + [[package]] name = "unicode-ident" version = "1.0.12" diff --git a/Cargo.toml b/Cargo.toml index aab3186..41da357 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,7 @@ shellexpand = "2.1.*" log = "0.4.*" env_logger = "0.10.*" sysinfo = "0.22.*" +rust-ini = "0.21" [package.metadata.deb] maintainer = "beeender " diff --git a/src/backend/foot.rs b/src/backend/foot.rs new file mode 100644 index 0000000..1a193c3 --- /dev/null +++ b/src/backend/foot.rs @@ -0,0 +1,98 @@ +use super::Functions; +use crate::config::Config; +use crate::error::GlrnvimError; +use ini::Ini; +use std::io::Write; +use std::path::PathBuf; +use tempfile::NamedTempFile; + +pub const FOOT_NAME: &str = "foot"; + +struct Foot { + exe_path: PathBuf, + temp_file: Option, +} + +pub fn init(config: &Config) -> Result, GlrnvimError> { + let exe_path = super::exe_path(&config.term_exe_path, FOOT_NAME)?; + + Ok(Box::new(Foot { + exe_path, + temp_file: None, + })) +} + +impl Foot { + fn create_conf_file(&mut self, config: &Config) { + let mut foot_conf = if config.load_term_conf { + let conf_files = Foot::find_default_confs(); + if conf_files.is_empty() { + Ini::new() + } else { + let path = conf_files.first().unwrap(); + Ini::load_from_file(path).expect("Failed to load default config file") + } + } else { + Ini::new() + }; + + let mut font_str = String::new(); + for f in &config.fonts { + if !font_str.is_empty() { + font_str += ","; + } + font_str += f; + if config.font_size != 0 { + font_str += &format!(":size={}", config.font_size).to_string(); + } + } + if !font_str.is_empty() { + foot_conf.with_section(Some("main")).set("font", font_str); + } + // Note: The ctrl-z seems to be no-op so we don't have to disable it. Other default + // key bindings are quite harmless for now. If needed, just disable them in the config file + // here. + + let mut file = tempfile::NamedTempFile::new().expect("Failed to create temporary file"); + foot_conf + .write_to_file(&file) + .expect("Failed to write to temporary file"); + file.flush().unwrap(); + + file.path(); + self.temp_file = Some(file); + } + + fn find_default_confs() -> Vec { + let base_confs: [String; 0] = []; + let pri_confs: [String; 3] = [ + "$XDG_CONFIG_HOME/foot/foot.conf".to_string(), + "$HOME/.config/foot/foot.conf".to_string(), + "$XDG_CONFIG_DIRS/foot/foot.conf".to_string(), + ]; + super::find_term_conf_files(&base_confs, &pri_confs) + } +} + +impl Functions for Foot { + fn create_command(&mut self, config: &Config) -> std::process::Command { + let mut command = std::process::Command::new(&self.exe_path); + + command.arg("--config"); + if let Some(config_path) = config.term_config_path.as_ref() { + command.arg(config_path.as_str()); + } else { + self.create_conf_file(config); + // Overwrite the config with the generated settings from glrnvim.yml + command.arg(self.temp_file.as_ref().unwrap().path()); + } + + command.arg("--app-id"); + command.arg("glrnvim"); + + command.arg(&config.nvim_exe_path); + command.args(super::COMMON_ARGS); + + command + } +} diff --git a/src/backend/mod.rs b/src/backend/mod.rs index 72bb84f..806b551 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -2,6 +2,7 @@ mod alacritty; mod kitty; mod urxvt; mod wezterm; +mod foot; use super::config::Config; use crate::config::Backend; use crate::error::GlrnvimError; @@ -42,6 +43,7 @@ pub fn init(config: &Config) -> Result, GlrnvimError> { Backend::Urxvt => urxvt::init(config), Backend::Kitty => kitty::init(config), Backend::Wezterm => wezterm::init(config), + Backend::Foot => foot::init(config), }, None => { for init_func in &[alacritty::init, urxvt::init, kitty::init, wezterm::init] { diff --git a/src/config.rs b/src/config.rs index ca3ca02..9308c06 100644 --- a/src/config.rs +++ b/src/config.rs @@ -13,6 +13,7 @@ pub enum Backend { Urxvt, Kitty, Wezterm, + Foot, } #[derive(Debug, PartialEq, Eq, Deserialize)]