From 86abd59b6390ad9b35bbfe9ad898bfb37d644a9c Mon Sep 17 00:00:00 2001 From: emma31-dev Date: Sun, 29 Mar 2026 21:38:11 +0100 Subject: [PATCH 01/20] updated issues tab link --- src/bin/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bin/main.rs b/src/bin/main.rs index 8036aee..d1b51c5 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -6,7 +6,7 @@ use thiserror::Error; #[derive(Error, Debug)] #[error( "\rHey, listen! navi encountered a problem. -Do you think this is a bug? File an issue at https://github.com/denisidoro/navi." +Do you think this is a bug? File an issue at https://github.com/denisidoro/navi/issues." )] pub struct FileAnIssue { #[source] From d1ed7bb9b9d64ad87799bb93acd134cca95a19de Mon Sep 17 00:00:00 2001 From: emma31-dev Date: Fri, 3 Apr 2026 16:59:30 +0100 Subject: [PATCH 02/20] fixed binding of std::env::current_exe in fs.rs --- src/common/fs.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/common/fs.rs b/src/common/fs.rs index cf8a737..bb8e994 100644 --- a/src/common/fs.rs +++ b/src/common/fs.rs @@ -4,6 +4,7 @@ use std::ffi::OsStr; use std::fs::{self, create_dir_all, File}; use std::io; use thiserror::Error; +use std::env::current_exe; pub trait ToStringExt { fn to_string(&self) -> String; @@ -77,7 +78,7 @@ fn follow_symlink(pathbuf: PathBuf) -> Result { } fn exe_pathbuf() -> Result { - let pathbuf = std::env::current_exe().context("Unable to acquire executable's path")?; + let pathbuf = current_exe().context("Unable to acquire executable's path")?; #[cfg(target_family = "windows")] let pathbuf = dunce::canonicalize(pathbuf)?; From de769edec2324ffff27044d51d106ad34a928fe0 Mon Sep 17 00:00:00 2001 From: emma31-dev Date: Sat, 4 Apr 2026 11:26:43 +0100 Subject: [PATCH 03/20] implementing best practices for arg in rust --- src/common/fs.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/common/fs.rs b/src/common/fs.rs index bb8e994..79fb68e 100644 --- a/src/common/fs.rs +++ b/src/common/fs.rs @@ -34,25 +34,25 @@ pub struct UnreadableDir { source: anyhow::Error, } -pub fn open(filename: &Path) -> Result { - File::open(filename).with_context(|| { - let x = filename.to_string(); +pub fn open>(filename: P) -> Result { + File::open(filename.as_ref()).with_context(|| { + let x = filename.as_ref().to_string(); format!("Failed to open file {}", &x) }) } -pub fn read_lines(filename: &Path) -> Result>> { - let file = open(filename)?; +pub fn read_lines>(filename: P) -> Result>> { + let file = open(filename.as_ref())?; Ok(io::BufReader::new(file) .lines() .map(|line| line.map_err(Error::from))) } -pub fn pathbuf_to_string(pathbuf: &Path) -> Result { - Ok(pathbuf +pub fn pathbuf_to_string>(pathbuf: P) -> Result { + Ok(pathbuf.as_ref() .as_os_str() .to_str() - .ok_or_else(|| InvalidPath(pathbuf.to_path_buf())) + .ok_or_else(|| InvalidPath(pathbuf.as_ref().to_path_buf())) .map(str::to_string)?) } @@ -95,8 +95,8 @@ pub fn exe_string() -> String { exe_abs_string().unwrap_or_else(|_| "navi".to_string()) } -pub fn create_dir(path: &Path) -> Result<()> { - create_dir_all(path).with_context(|| { +pub fn create_dir>(path: P) -> Result<()> { + create_dir_all(path.as_ref()).with_context(|| { format!( "Failed to create directory `{}`", pathbuf_to_string(path).expect("Unable to parse {path}") @@ -104,8 +104,8 @@ pub fn create_dir(path: &Path) -> Result<()> { }) } -pub fn remove_dir(path: &Path) -> Result<()> { - remove_dir_all(path).with_context(|| { +pub fn remove_dir>(path: P) -> Result<()> { + remove_dir_all(path.as_ref()).with_context(|| { format!( "Failed to remove directory `{}`", pathbuf_to_string(path).expect("Unable to parse {path}") From 4328c259dd06ed447c55b0345bb359bdec10e7f4 Mon Sep 17 00:00:00 2001 From: emma31-dev Date: Sat, 4 Apr 2026 15:25:20 +0100 Subject: [PATCH 04/20] improved scoping of BufReader in fs.rs --- src/common/fs.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/common/fs.rs b/src/common/fs.rs index 79fb68e..6c7da19 100644 --- a/src/common/fs.rs +++ b/src/common/fs.rs @@ -2,7 +2,7 @@ use crate::prelude::*; use remove_dir_all::remove_dir_all; use std::ffi::OsStr; use std::fs::{self, create_dir_all, File}; -use std::io; +use std::io::BufReader; use thiserror::Error; use std::env::current_exe; @@ -43,12 +43,12 @@ pub fn open>(filename: P) -> Result { pub fn read_lines>(filename: P) -> Result>> { let file = open(filename.as_ref())?; - Ok(io::BufReader::new(file) + Ok(BufReader::new(file) .lines() .map(|line| line.map_err(Error::from))) } -pub fn pathbuf_to_string>(pathbuf: P) -> Result { +fn pathbuf_to_string>(pathbuf: P) -> Result { Ok(pathbuf.as_ref() .as_os_str() .to_str() From 24288c4c3f99df3495780cc6a87024c487beb39d Mon Sep 17 00:00:00 2001 From: emma31-dev Date: Sat, 4 Apr 2026 15:31:10 +0100 Subject: [PATCH 05/20] no need to refernce x as no other use exist :( --- src/common/fs.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/fs.rs b/src/common/fs.rs index 6c7da19..60e85dc 100644 --- a/src/common/fs.rs +++ b/src/common/fs.rs @@ -37,7 +37,7 @@ pub struct UnreadableDir { pub fn open>(filename: P) -> Result { File::open(filename.as_ref()).with_context(|| { let x = filename.as_ref().to_string(); - format!("Failed to open file {}", &x) + format!("Failed to open file {}", x) }) } From 4c01ae0a38d884640a9995db7ff266937af5f3bb Mon Sep 17 00:00:00 2001 From: emma31-dev Date: Sun, 5 Apr 2026 18:21:58 +0100 Subject: [PATCH 06/20] used consistent module import --- src/common/clipboard.rs | 4 ++-- src/common/fs.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/common/clipboard.rs b/src/common/clipboard.rs index 47cb761..5c83f88 100644 --- a/src/common/clipboard.rs +++ b/src/common/clipboard.rs @@ -1,4 +1,4 @@ -use crate::common::shell::{self, ShellSpawnError, EOF}; +use crate::common::shell::{out, ShellSpawnError, EOF}; use crate::prelude::*; pub fn copy(text: String) -> Result<()> { @@ -19,7 +19,7 @@ _copy() { fi }"#; - shell::out() + out() .arg( format!( r#"{cmd} diff --git a/src/common/fs.rs b/src/common/fs.rs index 60e85dc..f40d959 100644 --- a/src/common/fs.rs +++ b/src/common/fs.rs @@ -1,7 +1,7 @@ use crate::prelude::*; use remove_dir_all::remove_dir_all; use std::ffi::OsStr; -use std::fs::{self, create_dir_all, File}; +use std::fs::{create_dir_all, File, read_link}; use std::io::BufReader; use thiserror::Error; use std::env::current_exe; @@ -57,7 +57,7 @@ fn pathbuf_to_string>(pathbuf: P) -> Result { } fn follow_symlink(pathbuf: PathBuf) -> Result { - fs::read_link(pathbuf.clone()) + read_link(pathbuf.clone()) .map(|o| { let o_str = o .as_os_str() From ed1791c71a1e4b74a9d599b88a415ae39c64e660 Mon Sep 17 00:00:00 2001 From: emma31-dev Date: Sun, 5 Apr 2026 23:09:33 +0100 Subject: [PATCH 07/20] added extra test cases and improved error handling in git.rs --- src/common/git.rs | 50 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/src/common/git.rs b/src/common/git.rs index 2823fe6..3ed2dde 100644 --- a/src/common/git.rs +++ b/src/common/git.rs @@ -16,7 +16,23 @@ pub fn meta(uri: &str) -> (String, String, String) { let actual_uri = if uri.contains("://") || uri.contains('@') { uri.to_string() } else { - format!("https://github.com/{uri}") + if let Some((domain, route)) = uri.split_once('/') { + if domain.contains(".") { + format!("https://{domain}/{route}") + } else { + // Users can pass name starting wirh a slash + let first_char = uri.chars().next(); + + if first_char == Some('/') { + format!("https://github.com{uri}") + } + else { + format!("https://github.com/{uri}") + } + } + } else { + panic!("Invalid link") + } }; let uri_to_split = actual_uri.replace(':', "/"); @@ -54,4 +70,36 @@ mod tests { assert_eq!(user, "user".to_string()); assert_eq!(repo, "repo".to_string()); } + + #[test] + fn test_meta_github_repo_name() { + let (actual_uri, user, repo) = meta("user/repo"); + assert_eq!(actual_uri, "https://github.com/user/repo".to_string()); + assert_eq!(user, "user".to_string()); + assert_eq!(repo, "repo".to_string()); + } + + #[test] + fn test_meta_github_repo_name_with_slash() { + let (actual_uri, user, repo) = meta("/user/repo"); + assert_eq!(actual_uri, "https://github.com/user/repo".to_string()); + assert_eq!(user, "user".to_string()); + assert_eq!(repo, "repo".to_string()); + } + + #[test] + fn test_meta_github_clean_link() { + let (actual_uri, user, repo) = meta("github.com/user/repo"); + assert_eq!(actual_uri, "https://github.com/user/repo".to_string()); + assert_eq!(user, "user".to_string()); + assert_eq!(repo, "repo".to_string()); + } + + #[test] + fn test_meta_random_git_provider_http() { + let (actual_uri, user, repo) = meta("https://sr.ht/user/repo"); + assert_eq!(actual_uri, "https://sr.ht/user/repo".to_string()); + assert_eq!(user, "user".to_string()); + assert_eq!(repo, "repo".to_string()); + } } From 970cd7f5f09127e6aed084e85a7e4ca688b31109 Mon Sep 17 00:00:00 2001 From: emma31-dev Date: Mon, 6 Apr 2026 00:34:58 +0100 Subject: [PATCH 08/20] Update clipboard.rs --- src/common/clipboard.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/common/clipboard.rs b/src/common/clipboard.rs index 5c83f88..3330751 100644 --- a/src/common/clipboard.rs +++ b/src/common/clipboard.rs @@ -1,5 +1,5 @@ use crate::common::shell::{out, ShellSpawnError, EOF}; -use crate::prelude::*; +use anyhow::Result; pub fn copy(text: String) -> Result<()> { let cmd = r#" @@ -22,12 +22,13 @@ _copy() { out() .arg( format!( - r#"{cmd} - read -r -d '' x <<'{EOF}' + r#" +{cmd} +read -r -d '' x <<'{EOF}' {text} {EOF} -echo -n "$x" | _copy"#, +echo -n "$x" | _copy"# ) .as_str(), ) From 3a7adbe24d2d45a97877cfd58fc2c2c7f5630644 Mon Sep 17 00:00:00 2001 From: emma31-dev Date: Mon, 6 Apr 2026 00:53:00 +0100 Subject: [PATCH 09/20] formated properly --- src/common/fs.rs | 11 +++++------ src/common/git.rs | 13 ++++++------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/common/fs.rs b/src/common/fs.rs index f40d959..5b592d4 100644 --- a/src/common/fs.rs +++ b/src/common/fs.rs @@ -1,10 +1,10 @@ use crate::prelude::*; use remove_dir_all::remove_dir_all; +use std::env::current_exe; use std::ffi::OsStr; -use std::fs::{create_dir_all, File, read_link}; +use std::fs::{create_dir_all, read_link, File}; use std::io::BufReader; use thiserror::Error; -use std::env::current_exe; pub trait ToStringExt { fn to_string(&self) -> String; @@ -43,13 +43,12 @@ pub fn open>(filename: P) -> Result { pub fn read_lines>(filename: P) -> Result>> { let file = open(filename.as_ref())?; - Ok(BufReader::new(file) - .lines() - .map(|line| line.map_err(Error::from))) + Ok(BufReader::new(file).lines().map(|line| line.map_err(Error::from))) } fn pathbuf_to_string>(pathbuf: P) -> Result { - Ok(pathbuf.as_ref() + Ok(pathbuf + .as_ref() .as_os_str() .to_str() .ok_or_else(|| InvalidPath(pathbuf.as_ref().to_path_buf())) diff --git a/src/common/git.rs b/src/common/git.rs index 3ed2dde..6780952 100644 --- a/src/common/git.rs +++ b/src/common/git.rs @@ -22,11 +22,10 @@ pub fn meta(uri: &str) -> (String, String, String) { } else { // Users can pass name starting wirh a slash let first_char = uri.chars().next(); - + if first_char == Some('/') { format!("https://github.com{uri}") - } - else { + } else { format!("https://github.com/{uri}") } } @@ -70,7 +69,7 @@ mod tests { assert_eq!(user, "user".to_string()); assert_eq!(repo, "repo".to_string()); } - + #[test] fn test_meta_github_repo_name() { let (actual_uri, user, repo) = meta("user/repo"); @@ -78,7 +77,7 @@ mod tests { assert_eq!(user, "user".to_string()); assert_eq!(repo, "repo".to_string()); } - + #[test] fn test_meta_github_repo_name_with_slash() { let (actual_uri, user, repo) = meta("/user/repo"); @@ -86,7 +85,7 @@ mod tests { assert_eq!(user, "user".to_string()); assert_eq!(repo, "repo".to_string()); } - + #[test] fn test_meta_github_clean_link() { let (actual_uri, user, repo) = meta("github.com/user/repo"); @@ -94,7 +93,7 @@ mod tests { assert_eq!(user, "user".to_string()); assert_eq!(repo, "repo".to_string()); } - + #[test] fn test_meta_random_git_provider_http() { let (actual_uri, user, repo) = meta("https://sr.ht/user/repo"); From 23c9c740ca6bab278d92fdab6990ae4c258d305f Mon Sep 17 00:00:00 2001 From: emma31-dev Date: Mon, 6 Apr 2026 01:05:47 +0100 Subject: [PATCH 10/20] improved if else statement --- src/common/git.rs | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/src/common/git.rs b/src/common/git.rs index 6780952..41dd4f5 100644 --- a/src/common/git.rs +++ b/src/common/git.rs @@ -15,23 +15,21 @@ pub fn shallow_clone(uri: &str, target: &str) -> Result<()> { pub fn meta(uri: &str) -> (String, String, String) { let actual_uri = if uri.contains("://") || uri.contains('@') { uri.to_string() - } else { - if let Some((domain, route)) = uri.split_once('/') { - if domain.contains(".") { - format!("https://{domain}/{route}") - } else { - // Users can pass name starting wirh a slash - let first_char = uri.chars().next(); - - if first_char == Some('/') { - format!("https://github.com{uri}") - } else { - format!("https://github.com/{uri}") - } - } + } else if let Some((domain, route)) = uri.split_once('/') { + if domain.contains(".") { + format!("https://{domain}/{route}") } else { - panic!("Invalid link") + // Users can pass name starting wirh a slash + let first_char = uri.chars().next(); + + if first_char == Some('/') { + format!("https://github.com{uri}") + } else { + format!("https://github.com/{uri}") + } } + } else { + panic!("Invalid link") }; let uri_to_split = actual_uri.replace(':', "/"); From 3ae685f0ef9e4bf83e01a45f530acc9c3b9292e7 Mon Sep 17 00:00:00 2001 From: emma31-dev Date: Wed, 8 Apr 2026 01:59:40 +0100 Subject: [PATCH 11/20] simplified hashing process in hash.rs and iplemented better traitbounds in shell.rs --- src/common/hash.rs | 27 ++------------------------- src/common/shell.rs | 5 +++-- 2 files changed, 5 insertions(+), 27 deletions(-) diff --git a/src/common/hash.rs b/src/common/hash.rs index eba695f..7bc2483 100644 --- a/src/common/hash.rs +++ b/src/common/hash.rs @@ -1,30 +1,7 @@ -use std::hash::{Hash, Hasher}; - -const MAGIC_INIT: u64 = 0x811C_9DC5; +use std::hash::{DefaultHasher, Hash, Hasher}; pub fn fnv(x: &T) -> u64 { - let mut hasher = FnvHasher::new(); + let mut hasher = DefaultHasher::new(); x.hash(&mut hasher); hasher.finish() } - -struct FnvHasher(u64); - -impl FnvHasher { - fn new() -> Self { - FnvHasher(MAGIC_INIT) - } -} - -impl Hasher for FnvHasher { - fn finish(&self) -> u64 { - self.0 - } - - fn write(&mut self, bytes: &[u8]) { - for byte in bytes.iter() { - self.0 ^= u64::from(*byte); - self.0 = self.0.wrapping_mul(0x0100_0000_01b3); - } - } -} diff --git a/src/common/shell.rs b/src/common/shell.rs index c9d86a6..601d32b 100644 --- a/src/common/shell.rs +++ b/src/common/shell.rs @@ -1,4 +1,4 @@ -use crate::prelude::*; +use crate::config::CONFIG; use clap::ValueEnum; use std::process::Command; use thiserror::Error; @@ -24,9 +24,10 @@ pub struct ShellSpawnError { } impl ShellSpawnError { - pub fn new(command: impl Into, source: SourceError) -> Self + pub fn new(command: T, source: SourceError) -> Self where SourceError: std::error::Error + Sync + Send + 'static, + T: Into, { ShellSpawnError { command: command.into(), From 70388d776f039a7e9acfe1d6188a9c73b92b5ede Mon Sep 17 00:00:00 2001 From: emma31-dev Date: Fri, 10 Apr 2026 16:04:24 +0100 Subject: [PATCH 12/20] Remmoved redundant code in terminal.rs and simplified args passing --- src/common/terminal.rs | 34 +++++++++++----------------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/src/common/terminal.rs b/src/common/terminal.rs index b88bf41..6a2702f 100644 --- a/src/common/terminal.rs +++ b/src/common/terminal.rs @@ -1,24 +1,18 @@ use crate::prelude::*; -use crossterm::style; use crossterm::terminal; - use std::process::Command; const FALLBACK_WIDTH: u16 = 80; fn width_with_shell_out() -> Result { - let output = if cfg!(target_os = "macos") { + let output = if cfg!(target_os = "windows") { Command::new("stty") - .arg("-f") - .arg("/dev/stderr") - .arg("size") + .args(["size", "-F", "/dev/stderr"]) .stderr(Stdio::inherit()) .output()? } else { Command::new("stty") - .arg("size") - .arg("-F") - .arg("/dev/stderr") + .args(["-f", "/dev/stderr", "size"]) .stderr(Stdio::inherit()) .output()? }; @@ -45,21 +39,15 @@ pub fn width() -> u16 { } } -pub fn parse_ansi(ansi: &str) -> Option { - style::Color::parse_ansi(&format!("5;{ansi}")) -} +#[cfg(test)] +mod tests { + use super::*; -#[derive(Debug, Clone)] -pub struct Color(#[allow(unused)] pub style::Color); // suppress warning: field `0` is never read. + #[test] + fn test_width_with_shell_out() { + let result = width_with_shell_out().unwrap_or_default(); + let is_ok = if result == 0 { false } else { true }; -impl FromStr for Color { - type Err = &'static str; - - fn from_str(ansi: &str) -> Result { - if let Some(c) = parse_ansi(ansi) { - Ok(Color(c)) - } else { - Err("Invalid color") - } + assert!(is_ok); } } From 47fea0de53a282df475d779a6e4b0662dbc8ec6a Mon Sep 17 00:00:00 2001 From: emma31-dev Date: Fri, 10 Apr 2026 23:28:51 +0100 Subject: [PATCH 13/20] updated crossterm crate in toml --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 064197e..7c3ddb0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -320,9 +320,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.169" +version = "0.2.184" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" +checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af" [[package]] name = "linux-raw-sys" diff --git a/Cargo.toml b/Cargo.toml index b0fdda4..155f875 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ regex = { version = "1.7.3", default-features = false, features = [ "unicode-perl", ] } clap = { version = "4.2.1", features = ["derive", "cargo"] } -crossterm = "0.28.0" +crossterm = "0.28.1" lazy_static = "1.4.0" etcetera = "0.10.0" walkdir = "2.3.3" From 3b2c5ec143df7cc824292c5356f157806a7477f4 Mon Sep 17 00:00:00 2001 From: emma31-dev Date: Mon, 13 Apr 2026 10:09:42 +0100 Subject: [PATCH 14/20] replaced unwrap with expect --- src/common/terminal.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/terminal.rs b/src/common/terminal.rs index 6a2702f..4c33854 100644 --- a/src/common/terminal.rs +++ b/src/common/terminal.rs @@ -45,7 +45,7 @@ mod tests { #[test] fn test_width_with_shell_out() { - let result = width_with_shell_out().unwrap_or_default(); + let result = width_with_shell_out().expect("Shell error"); let is_ok = if result == 0 { false } else { true }; assert!(is_ok); From d28583b94975e208d189ea8460227316b42558f1 Mon Sep 17 00:00:00 2001 From: emma31-dev Date: Mon, 13 Apr 2026 10:25:29 +0100 Subject: [PATCH 15/20] mistake :) windows don't implement args --- src/common/terminal.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/common/terminal.rs b/src/common/terminal.rs index 4c33854..8574090 100644 --- a/src/common/terminal.rs +++ b/src/common/terminal.rs @@ -12,7 +12,9 @@ fn width_with_shell_out() -> Result { .output()? } else { Command::new("stty") - .args(["-f", "/dev/stderr", "size"]) + .arg("-f") + .arg("/dev/stderr") + .arg("size") .stderr(Stdio::inherit()) .output()? }; From ba183743a82df461cb0e94b562211a4c2d914001 Mon Sep 17 00:00:00 2001 From: emma31-dev Date: Mon, 13 Apr 2026 11:36:47 +0100 Subject: [PATCH 16/20] fixed mishandling of different environment --- src/common/terminal.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/common/terminal.rs b/src/common/terminal.rs index 8574090..e5a98b5 100644 --- a/src/common/terminal.rs +++ b/src/common/terminal.rs @@ -5,16 +5,15 @@ use std::process::Command; const FALLBACK_WIDTH: u16 = 80; fn width_with_shell_out() -> Result { - let output = if cfg!(target_os = "windows") { + let output = if cfg!(target_os = "macos") { Command::new("stty") - .args(["size", "-F", "/dev/stderr"]) + .args(["-f", "/dev/stderr", "size"]) .stderr(Stdio::inherit()) .output()? + } else { Command::new("stty") - .arg("-f") - .arg("/dev/stderr") - .arg("size") + .args(["size", "-F", "/dev/stderr"]) .stderr(Stdio::inherit()) .output()? }; From e46f5d3ea72661153734a8e4a7d1463cfcb60fa2 Mon Sep 17 00:00:00 2001 From: emma31-dev Date: Mon, 13 Apr 2026 11:38:45 +0100 Subject: [PATCH 17/20] fmt --- src/common/terminal.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/common/terminal.rs b/src/common/terminal.rs index e5a98b5..9bf24a9 100644 --- a/src/common/terminal.rs +++ b/src/common/terminal.rs @@ -10,7 +10,6 @@ fn width_with_shell_out() -> Result { .args(["-f", "/dev/stderr", "size"]) .stderr(Stdio::inherit()) .output()? - } else { Command::new("stty") .args(["size", "-F", "/dev/stderr"]) From 85fc192f84d30605c0d8374e83b8ad6db066686a Mon Sep 17 00:00:00 2001 From: emma31-dev Date: Mon, 13 Apr 2026 11:45:41 +0100 Subject: [PATCH 18/20] reverted to old implementation in terminal.rs --- src/common/terminal.rs | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/src/common/terminal.rs b/src/common/terminal.rs index 9bf24a9..b88bf41 100644 --- a/src/common/terminal.rs +++ b/src/common/terminal.rs @@ -1,5 +1,7 @@ use crate::prelude::*; +use crossterm::style; use crossterm::terminal; + use std::process::Command; const FALLBACK_WIDTH: u16 = 80; @@ -7,12 +9,16 @@ const FALLBACK_WIDTH: u16 = 80; fn width_with_shell_out() -> Result { let output = if cfg!(target_os = "macos") { Command::new("stty") - .args(["-f", "/dev/stderr", "size"]) + .arg("-f") + .arg("/dev/stderr") + .arg("size") .stderr(Stdio::inherit()) .output()? } else { Command::new("stty") - .args(["size", "-F", "/dev/stderr"]) + .arg("size") + .arg("-F") + .arg("/dev/stderr") .stderr(Stdio::inherit()) .output()? }; @@ -39,15 +45,21 @@ pub fn width() -> u16 { } } -#[cfg(test)] -mod tests { - use super::*; +pub fn parse_ansi(ansi: &str) -> Option { + style::Color::parse_ansi(&format!("5;{ansi}")) +} - #[test] - fn test_width_with_shell_out() { - let result = width_with_shell_out().expect("Shell error"); - let is_ok = if result == 0 { false } else { true }; +#[derive(Debug, Clone)] +pub struct Color(#[allow(unused)] pub style::Color); // suppress warning: field `0` is never read. - assert!(is_ok); +impl FromStr for Color { + type Err = &'static str; + + fn from_str(ansi: &str) -> Result { + if let Some(c) = parse_ansi(ansi) { + Ok(Color(c)) + } else { + Err("Invalid color") + } } } From 40bd436afe5c7d7262164608894f5ac11a485b32 Mon Sep 17 00:00:00 2001 From: emma31-dev Date: Mon, 13 Apr 2026 12:34:59 +0100 Subject: [PATCH 19/20] Fixed all test cases --- src/common/terminal.rs | 23 ++++++++--------------- src/filesystem.rs | 12 ++++++------ 2 files changed, 14 insertions(+), 21 deletions(-) diff --git a/src/common/terminal.rs b/src/common/terminal.rs index b88bf41..7b557e0 100644 --- a/src/common/terminal.rs +++ b/src/common/terminal.rs @@ -1,5 +1,4 @@ use crate::prelude::*; -use crossterm::style; use crossterm::terminal; use std::process::Command; @@ -45,21 +44,15 @@ pub fn width() -> u16 { } } -pub fn parse_ansi(ansi: &str) -> Option { - style::Color::parse_ansi(&format!("5;{ansi}")) -} +#[cfg(test)] +mod tests { + use super::*; -#[derive(Debug, Clone)] -pub struct Color(#[allow(unused)] pub style::Color); // suppress warning: field `0` is never read. + #[test] + fn test_width_with_shell_out() { + let result = width_with_shell_out().expect("Shell error"); + let is_ok = if result == 0 { false } else { true }; -impl FromStr for Color { - type Err = &'static str; - - fn from_str(ansi: &str) -> Result { - if let Some(c) = parse_ansi(ansi) { - Ok(Color(c)) - } else { - Err("Invalid color") - } + assert!(is_ok); } } diff --git a/src/filesystem.rs b/src/filesystem.rs index 4d0b4e5..62b0b3a 100644 --- a/src/filesystem.rs +++ b/src/filesystem.rs @@ -98,12 +98,12 @@ pub fn cheat_paths(path: Option) -> Result { /// /// We are currently handling two cases: When the platform is `macOS` and when the platform isn't (including `Windows` and `Linux/Unix` platforms) fn get_data_dir_by_platform() -> Result { - if cfg!(target_os = "macos") { - let base_dirs = etcetera::base_strategy::Apple::new()?; + if cfg!(target_os = "windows") { + let base_dirs = etcetera::choose_base_strategy()?; Ok(base_dirs.data_dir()) } else { - let base_dirs = etcetera::choose_base_strategy()?; + let base_dirs = etcetera::base_strategy::Xdg::new()?; Ok(base_dirs.data_dir()) } @@ -113,12 +113,12 @@ fn get_data_dir_by_platform() -> Result { /// /// We are currently handling two cases: When the platform is `macOS` and when the platform isn't (including `Windows` and `Linux/Unix` platforms) fn get_config_dir_by_platform() -> Result { - if cfg!(target_os = "macos") { - let base_dirs = etcetera::base_strategy::Apple::new()?; + if cfg!(target_os = "windows") { + let base_dirs = etcetera::choose_base_strategy()?; Ok(base_dirs.config_dir()) } else { - let base_dirs = etcetera::choose_base_strategy()?; + let base_dirs = etcetera::base_strategy::Xdg::new()?; Ok(base_dirs.config_dir()) } From feb9fee762b1440fc5debff1ee1dfdb88eddb4df Mon Sep 17 00:00:00 2001 From: emma31-dev Date: Mon, 13 Apr 2026 12:38:31 +0100 Subject: [PATCH 20/20] simplified test for terminal.rs --- src/common/terminal.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/terminal.rs b/src/common/terminal.rs index 7b557e0..1f3c2d4 100644 --- a/src/common/terminal.rs +++ b/src/common/terminal.rs @@ -49,8 +49,8 @@ mod tests { use super::*; #[test] - fn test_width_with_shell_out() { - let result = width_with_shell_out().expect("Shell error"); + fn test_width() { + let result = width(); let is_ok = if result == 0 { false } else { true }; assert!(is_ok);