commit pik for openSUSE:Factory
Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package pik for openSUSE:Factory checked in at 2024-10-07 21:52:00 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/pik (Old) and /work/SRC/openSUSE:Factory/.pik.new.19354 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "pik" Mon Oct 7 21:52:00 2024 rev:5 rq:1206028 version:0.8.0 Changes: -------- --- /work/SRC/openSUSE:Factory/pik/pik.changes 2024-09-24 17:34:58.609350631 +0200 +++ /work/SRC/openSUSE:Factory/.pik.new.19354/pik.changes 2024-10-07 21:52:13.222225728 +0200 @@ -1,0 +2,11 @@ +Sat Oct 5 17:34:29 UTC 2024 - Muhammad Akbar Yanuar Mantari <mantarimay@pm.me> + +- Update to version 0.8.0 + + Bugs fixes + - fixed failing tests - removed fuzzy search from args + + New Features + - Add fuzzy search for Path type of queries + - Add configuration + - Add fuzzy search for Cmd, Ports, and Args + +------------------------------------------------------------------- Old: ---- pik-0.7.0.tar.gz New: ---- pik-0.8.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ pik.spec ++++++ --- /var/tmp/diff_new_pack.xB6h1I/_old 2024-10-07 21:52:14.370273521 +0200 +++ /var/tmp/diff_new_pack.xB6h1I/_new 2024-10-07 21:52:14.374273688 +0200 @@ -18,7 +18,7 @@ %bcond_without test Name: pik -Version: 0.7.0 +Version: 0.8.0 Release: 0 Summary: Process Interactive Kill License: MIT ++++++ pik-0.7.0.tar.gz -> pik-0.8.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pik-0.7.0/Cargo.lock new/pik-0.8.0/Cargo.lock --- old/pik-0.7.0/Cargo.lock 2024-09-24 08:37:58.000000000 +0200 +++ new/pik-0.8.0/Cargo.lock 2024-10-05 13:27:16.000000000 +0200 @@ -80,7 +80,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" dependencies = [ - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -90,7 +90,7 @@ checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" dependencies = [ "anstyle", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -287,19 +287,66 @@ ] [[package]] +name = "directories" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.48.0", +] + +[[package]] name = "either" version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" [[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] name = "errno" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "fuzzy-matcher" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54614a3312934d066701a80f20f15fa3b56d67ac7722b39eea5b4c9dd1d66c94" +dependencies = [ + "thread_local", +] + +[[package]] +name = "getrandom" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" +dependencies = [ + "cfg-if", + "libc", + "wasi", ] [[package]] @@ -357,6 +404,16 @@ ] [[package]] +name = "indexmap" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] name = "instability" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -403,6 +460,16 @@ checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags 2.4.2", + "libc", +] + +[[package]] name = "linux-raw-sys" version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -461,7 +528,7 @@ "libc", "log", "wasi", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -489,6 +556,12 @@ checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] name = "parking_lot" version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -519,16 +592,20 @@ [[package]] name = "pik" -version = "0.7.0" +version = "0.8.0" dependencies = [ "anyhow", "chrono", "clap", "crossterm", + "directories", + "fuzzy-matcher", "http-test-server", "listeners", "ratatui", + "serde", "sysinfo", + "toml", "tui-textarea", ] @@ -601,6 +678,17 @@ ] [[package]] +name = "redox_users" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" +dependencies = [ + "getrandom", + "libredox", + "thiserror", +] + +[[package]] name = "regex" version = "1.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -639,7 +727,7 @@ "errno", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -661,6 +749,35 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] +name = "serde" +version = "1.0.210" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.210" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_spanned" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" +dependencies = [ + "serde", +] + +[[package]] name = "signal-hook" version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -756,6 +873,70 @@ ] [[package]] +name = "thiserror" +version = "1.0.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "toml" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + +[[package]] name = "tui-textarea" version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1017,6 +1198,15 @@ [[package]] name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" @@ -1146,6 +1336,15 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] +name = "winnow" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" +dependencies = [ + "memchr", +] + +[[package]] name = "zerocopy" version = "0.7.32" source = "registry+https://github.com/rust-lang/crates.io-index" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pik-0.7.0/Cargo.toml new/pik-0.8.0/Cargo.toml --- old/pik-0.7.0/Cargo.toml 2024-09-24 08:37:58.000000000 +0200 +++ new/pik-0.8.0/Cargo.toml 2024-10-05 13:27:16.000000000 +0200 @@ -1,6 +1,6 @@ [package] name = "pik" -version = "0.7.0" +version = "0.8.0" edition = "2021" authors = ["Jacek Kurlit"] keywords = ["terminal", "process", "linux", "system", "kill"] @@ -20,6 +20,10 @@ listeners = "0.2.1" chrono = "0.4" clap = { version = "4.5", features = ["derive"] } +directories = "5.0" +toml = "0.8" +serde = { version = "1.0", features = ["derive"] } +fuzzy-matcher = "0.3.7" [dev-dependencies] http-test-server = "2.1.1" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pik-0.7.0/README.md new/pik-0.8.0/README.md --- old/pik-0.7.0/README.md 2024-09-24 08:37:58.000000000 +0200 +++ new/pik-0.8.0/README.md 2024-10-05 13:27:16.000000000 +0200 @@ -29,7 +29,7 @@ ## Features -Pik allows to search processes by: +Pik allows to **fuzzy** search processes by: - Name - No prefix is required, just type process name, for example 'firefox' ![Example search by name](docs/search_by_name.gif) @@ -67,7 +67,7 @@ sudo zypper install pik ``` -With **[dra](https://github.com/devmatteini/dra)** +With **[dra](https://github.com/devmatteini/dra)** ```sh dra download --install jacek-kurlit/pik @@ -88,6 +88,12 @@ ## Configuration +### Application configuration + +You may set your preferences in `pik.toml` file located in `~/.config/pik` directory. +All options are optional, if skipped default values will be used. +Example configuration with default settings can be found at [example config](example_config.toml) + ### Key maps - Esc | Ctrl + C - Quit @@ -101,9 +107,17 @@ - Process name on linux system it is not always exe name also it is limited to 15 chars - In linux process may appear on list but you are not allowed to get information about ports it uses. In such situations you need to run pik with root privileges +- Currently fuzzy search for args is not supported due to weird behavior - some processes pass all arguments as single causing them to always appear on list. Due to this fact args search is done by **contains** method ## Development +### Supported Systems + +In theory pik is using coross compliant lib that allows to run it on all major platforms. +In pratice I'm using linux and development is performed based on this OS. +Pik will probably work on MacOs and Windows but that must be tested by community since I don't own computers with these OS'es. +If you are able to test it on windows or macos please create issue to let me know. + ### Setup - Rust 1.79+ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pik-0.7.0/example_config.toml new/pik-0.8.0/example_config.toml --- old/pik-0.7.0/example_config.toml 1970-01-01 01:00:00.000000000 +0100 +++ new/pik-0.8.0/example_config.toml 2024-10-05 13:27:16.000000000 +0200 @@ -0,0 +1,3 @@ +# Size of the viewport +screen_size = { height = 20 } # run pik in 20 lines of the terminal +# screen_size = "fullscreen" # run pik in fullscreen diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pik-0.7.0/pik.spec new/pik-0.8.0/pik.spec --- old/pik-0.7.0/pik.spec 2024-09-24 08:37:58.000000000 +0200 +++ new/pik-0.8.0/pik.spec 2024-10-05 13:27:16.000000000 +0200 @@ -1,5 +1,5 @@ Name: pik -Version: 0.7.0 +Version: 0.8.0 Release: 1%{?dist} License: MIT Summary: Process Interactive Kill is a tool that helps to find and kill process diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pik-0.7.0/src/args.rs new/pik-0.8.0/src/args.rs --- old/pik-0.7.0/src/args.rs 2024-09-24 08:37:58.000000000 +0200 +++ new/pik-0.8.0/src/args.rs 2024-10-05 13:27:16.000000000 +0200 @@ -1,11 +1,13 @@ -use clap::Parser; +use clap::{Args, Parser}; + +use crate::config; #[derive(Parser, Debug)] #[command(version, about, long_about = Some("Pik is a simple TUI tool for searching and killing processes in interactive way."))] -pub struct Args { +pub struct CliArgs { #[clap( default_value = "", - help = r#"Query string for searching processes. By default, all processes are searched. + help = r#"Query string for searching processes. You may use special prefix for different kind of search: - :<port> - search by port, i.e ':8080' - /<path> - search by command path, i.e. '/home/user/bin' @@ -17,10 +19,19 @@ #[arg(short = 't', long, default_value_t = false)] pub include_threads_processes: bool, /// By default pik shows only proceseses owned by current user. This flag allows to show all processes - #[arg(short, long, default_value_t = false)] - pub all_processes: bool, + #[arg(short = 'a', long, default_value_t = false)] + pub include_other_users_processes: bool, + #[command(flatten)] + pub screen_size: Option<ScreenSizeOptions>, +} + +#[derive(Args, Debug, Clone, Copy)] +#[group(required = false, multiple = false)] +pub struct ScreenSizeOptions { + /// Start pik in fullscreen mode #[arg(short = 'F', long, default_value_t = false)] pub fullscreen: bool, - #[arg(short = 'H', long, default_value_t = 20)] + /// Number of lines of the screen pik will use + #[arg(short = 'H', long, default_value_t = config::DEFAULT_SCREEN_SIZE)] pub height: u16, } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pik-0.7.0/src/config.rs new/pik-0.8.0/src/config.rs --- old/pik-0.7.0/src/config.rs 1970-01-01 01:00:00.000000000 +0100 +++ new/pik-0.8.0/src/config.rs 2024-10-05 13:27:16.000000000 +0200 @@ -0,0 +1,70 @@ +use anyhow::{Context, Result}; + +pub fn load_app_config() -> Result<AppConfig> { + let config_path = directories::ProjectDirs::from("", "", "pik") + .map(|dirs| dirs.config_dir().join("config.toml")) + .filter(|path| path.exists()); + + match config_path { + Some(path) => load_config_from_file(&path), + None => Ok(AppConfig::default()), + } +} + +fn load_config_from_file(path: &std::path::PathBuf) -> Result<AppConfig> { + let raw_toml = std::fs::read_to_string(path) + .with_context(|| format!("Failed to load config from file: {:?}", path))?; + toml::from_str(&raw_toml) + .with_context(|| format!("Failed to deserialize config from file: {:?}", path)) +} + +use serde::Deserialize; + +#[derive(Debug, Default, PartialEq, Eq, Deserialize)] +pub struct AppConfig { + #[serde(default)] + pub screen_size: ScreenSize, +} + +#[derive(Debug, Eq, PartialEq, Deserialize, Clone, Copy)] +#[serde(rename_all = "camelCase")] +pub enum ScreenSize { + Fullscreen, + Height(u16), +} + +pub const DEFAULT_SCREEN_SIZE: u16 = 25; + +impl Default for ScreenSize { + fn default() -> Self { + ScreenSize::Height(DEFAULT_SCREEN_SIZE) + } +} + +#[cfg(test)] +mod tests { + + use super::*; + + #[test] + fn should_deserialize_empty_configuration() { + let default_settings = toml::from_str(""); + assert_eq!(default_settings, Ok(AppConfig::default())); + } + + #[test] + fn should_allow_to_override_defaults() { + let default_settings: AppConfig = toml::from_str( + r#" + screen_size = "fullscreen" + "#, + ) + .unwrap(); + assert_eq!( + default_settings, + AppConfig { + screen_size: ScreenSize::Fullscreen + } + ); + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pik-0.7.0/src/lib.rs new/pik-0.8.0/src/lib.rs --- old/pik-0.7.0/src/lib.rs 2024-09-24 08:37:58.000000000 +0200 +++ new/pik-0.8.0/src/lib.rs 2024-10-05 13:27:16.000000000 +0200 @@ -1,3 +1,5 @@ pub mod args; +pub mod config; pub mod processes; +pub mod settings; pub mod tui; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pik-0.7.0/src/main.rs new/pik-0.8.0/src/main.rs --- old/pik-0.7.0/src/main.rs 2024-09-24 08:37:58.000000000 +0200 +++ new/pik-0.8.0/src/main.rs 2024-10-05 13:27:16.000000000 +0200 @@ -1,18 +1,13 @@ use anyhow::Result; use clap::Parser; -use pik::args::Args; -use pik::processes::FilterOptions; +use pik::args::CliArgs; +use pik::settings::AppSettings; use pik::tui::start_app; fn main() -> Result<()> { - let args = Args::parse(); - start_app( - args.query, - FilterOptions { - ignore_threads: !args.include_threads_processes, - include_all_processes: args.all_processes, - }, - args.height, - args.fullscreen, - ) + let config = pik::config::load_app_config()?; + let args = CliArgs::parse(); + + let settings = AppSettings::from(config, &args); + start_app(args.query, settings) } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pik-0.7.0/src/processes/filters.rs new/pik-0.8.0/src/processes/filters.rs --- old/pik-0.7.0/src/processes/filters.rs 2024-09-24 08:37:58.000000000 +0200 +++ new/pik-0.8.0/src/processes/filters.rs 2024-10-05 13:27:16.000000000 +0200 @@ -1,3 +1,4 @@ +use fuzzy_matcher::{skim::SkimMatcherV2, FuzzyMatcher}; use sysinfo::Uid; use super::{utils::get_process_args, ProcessInfo}; @@ -5,6 +6,7 @@ pub(super) struct QueryFilter { query: String, pub(super) search_by: SearchBy, + matcher: SkimMatcherV2, } #[derive(PartialEq, Eq, Debug)] @@ -31,40 +33,44 @@ Some(_) => (SearchBy::Cmd, query), None => (SearchBy::None, query), }; + let matcher = SkimMatcherV2::default(); Self { query: query.to_lowercase(), search_by, + matcher, } } pub(super) fn accept(&self, prc: &impl ProcessInfo, ports: Option<&str>) -> bool { match self.search_by { - SearchBy::Cmd => self.query_matches_str(prc.cmd()), + SearchBy::Cmd => self.query_match_str(prc.cmd()), SearchBy::Path => self.query_matches_opt(prc.cmd_path()), - SearchBy::Args => self.query_matches_vec(get_process_args(prc)), + SearchBy::Args => self.query_contains_vec(get_process_args(prc)), SearchBy::Port => self.query_matches_opt(ports), SearchBy::Pid => self.query_eq_u32(prc.pid()), SearchBy::ProcessFamily => self.query_matches_process_family(prc), SearchBy::Everywhere => { - self.query_matches_str(prc.cmd()) + self.query_match_str(prc.cmd()) || self.query_matches_opt(prc.cmd_path()) || self.query_matches_opt(ports) - || self.query_matches_vec(get_process_args(prc)) + || self.query_contains_vec(get_process_args(prc)) } SearchBy::None => true, } } - fn query_matches_str(&self, s: &str) -> bool { - s.to_lowercase().contains(&self.query) + fn query_match_str(&self, s: &str) -> bool { + let score = self.matcher.fuzzy_match(s, self.query.as_str()); + // TODO: fine-tune the score threshold or make it configurable? + score.map(|s| s >= 0).unwrap_or(false) } fn query_matches_opt(&self, s: Option<&str>) -> bool { - s.map(|v| self.query_matches_str(v)).unwrap_or(false) + s.map(|s| self.query_match_str(s)).unwrap_or(false) } - fn query_matches_vec(&self, s: Vec<&str>) -> bool { - s.iter().any(|a| self.query_matches_str(a)) + fn query_contains_vec(&self, s: Vec<&str>) -> bool { + s.iter().any(|a| a.to_lowercase().contains(&self.query)) } fn query_eq_u32(&self, s: u32) -> bool { @@ -80,13 +86,22 @@ } } -#[derive(Copy, Clone, Default)] +#[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct FilterOptions { //NOTE: On linux threads can be listed as processes and thus needs filtering pub ignore_threads: bool, pub include_all_processes: bool, } +impl Default for FilterOptions { + fn default() -> Self { + Self { + ignore_threads: true, + include_all_processes: false, + } + } +} + pub(super) struct OptionsFilter<'a> { opt: FilterOptions, current_user_id: &'a Uid, @@ -191,6 +206,10 @@ }; assert!(filter.accept(&process, None)); + // tests that fuzzy search works + process.cmd_path = Some("/taest".to_string()); + assert!(filter.accept(&process, None)); + process.cmd_path = Some("/test".to_string()); assert!(filter.accept(&process, None)); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pik-0.7.0/src/settings.rs new/pik-0.8.0/src/settings.rs --- old/pik-0.7.0/src/settings.rs 1970-01-01 01:00:00.000000000 +0100 +++ new/pik-0.8.0/src/settings.rs 2024-10-05 13:27:16.000000000 +0200 @@ -0,0 +1,131 @@ +use ratatui::Viewport; + +use crate::{ + args::{CliArgs, ScreenSizeOptions}, + config::{AppConfig, ScreenSize}, + processes::FilterOptions, +}; + +#[derive(Debug, PartialEq, Eq)] +pub struct AppSettings { + pub viewport: Viewport, + pub filter_opions: FilterOptions, +} + +impl AppSettings { + pub fn from(config: AppConfig, cli_args: &CliArgs) -> Self { + Self { + viewport: prefer_override(config.screen_size, cli_args.screen_size), + filter_opions: FilterOptions { + ignore_threads: !cli_args.include_threads_processes, + include_all_processes: cli_args.include_other_users_processes, + }, + } + } +} + +fn prefer_override<V, C, A>(config_value: C, override_opt: Option<A>) -> V +where + C: Into<V>, + A: Into<V>, +{ + match override_opt { + Some(overidden_value) => overidden_value.into(), + None => config_value.into(), + } +} + +impl From<ScreenSize> for Viewport { + fn from(ss: ScreenSize) -> Self { + match ss { + ScreenSize::Fullscreen => Viewport::Fullscreen, + ScreenSize::Height(height) => Viewport::Inline(height), + } + } +} + +impl From<ScreenSizeOptions> for Viewport { + fn from(ss: ScreenSizeOptions) -> Self { + match (ss.fullscreen, ss.height) { + (true, _) => Viewport::Fullscreen, + (_, height) => Viewport::Inline(height), + } + } +} + +#[cfg(test)] +mod tests { + + use super::*; + + #[test] + fn should_convert_screen_size_to_viewport() { + assert_eq!(Viewport::from(ScreenSize::Fullscreen), Viewport::Fullscreen); + assert_eq!(Viewport::from(ScreenSize::Height(25)), Viewport::Inline(25)); + } + + #[test] + fn should_convert_screen_size_options_to_viewport() { + assert_eq!( + Viewport::from(ScreenSizeOptions { + fullscreen: true, + height: 25 + }), + Viewport::Fullscreen + ); + assert_eq!( + Viewport::from(ScreenSizeOptions { + fullscreen: false, + height: 25 + }), + Viewport::Inline(25) + ); + } + + #[test] + fn should_create_settings() { + let config = AppConfig::default(); + let cli_args = CliArgs { + query: "".to_string(), + include_threads_processes: true, + include_other_users_processes: true, + screen_size: None, + }; + let settings = AppSettings::from(config, &cli_args); + assert_eq!( + settings, + AppSettings { + viewport: Viewport::Inline(25), + filter_opions: FilterOptions { + ignore_threads: false, + include_all_processes: true + } + } + ); + } + + #[test] + fn should_prefer_cli_args_screen_size() { + let config = AppConfig { + screen_size: ScreenSize::Height(40), + }; + let cli_args = CliArgs { + screen_size: Some(ScreenSizeOptions { + fullscreen: true, + height: 25, + }), + ..some_cli_args() + }; + let settings = AppSettings::from(config, &cli_args); + assert_eq!(settings.viewport, Viewport::Fullscreen); + } + + fn some_cli_args() -> CliArgs { + CliArgs { + query: "".to_string(), + include_threads_processes: true, + include_other_users_processes: true, + screen_size: None, + } + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pik-0.7.0/src/tui.rs new/pik-0.8.0/src/tui.rs --- old/pik-0.7.0/src/tui.rs 2024-09-24 08:37:58.000000000 +0200 +++ new/pik-0.8.0/src/tui.rs 2024-10-05 13:27:16.000000000 +0200 @@ -5,11 +5,14 @@ event::{self, Event, KeyCode, KeyEventKind, KeyModifiers}, terminal::{disable_raw_mode, enable_raw_mode}, }; -use ratatui::{prelude::*, TerminalOptions, Viewport}; +use ratatui::{prelude::*, TerminalOptions}; mod rendering; -use crate::processes::{FilterOptions, ProcessManager, ProcessSearchResults}; +use crate::{ + processes::{FilterOptions, ProcessManager, ProcessSearchResults}, + settings::AppSettings, +}; use self::rendering::Tui; @@ -21,11 +24,11 @@ } impl App { - fn new(search_criteria: String, filter_options: FilterOptions) -> Result<App> { + fn new(search_criteria: String, app_settings: AppSettings) -> Result<App> { let mut app = App { process_manager: ProcessManager::new()?, search_results: ProcessSearchResults::empty(), - filter_options, + filter_options: app_settings.filter_opions, tui: Tui::new(search_criteria), }; app.search_for_processess(); @@ -73,23 +76,15 @@ } } -pub fn start_app( - search_criteria: String, - filter_options: FilterOptions, - viewport_height: u16, - viewport_fullscreen: bool, -) -> Result<()> { +pub fn start_app(search_criteria: String, app_settings: AppSettings) -> Result<()> { // setup terminal enable_raw_mode()?; let backend = CrosstermBackend::new(io::stdout()); - let viewport = match (viewport_height, viewport_fullscreen) { - (_, true) => Viewport::Fullscreen, - (h, false) => Viewport::Inline(h), - }; + let viewport = app_settings.viewport.clone(); let mut terminal = Terminal::with_options(backend, TerminalOptions { viewport })?; // create app and run it - let app = App::new(search_criteria, filter_options)?; + let app = App::new(search_criteria, app_settings)?; let res = run_app(&mut terminal, app); // restore terminal diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pik-0.7.0/tests/processes_search.rs new/pik-0.8.0/tests/processes_search.rs --- old/pik-0.7.0/tests/processes_search.rs 2024-09-24 08:37:58.000000000 +0200 +++ new/pik-0.8.0/tests/processes_search.rs 2024-10-05 13:27:16.000000000 +0200 @@ -2,12 +2,14 @@ use pik::processes::{FilterOptions, ProcessManager}; +use fuzzy_matcher::{skim::SkimMatcherV2, FuzzyMatcher}; + #[test] fn should_find_cargo_process_by_cmd_name() { let mut process_manager = ProcessManager::new().unwrap(); let results = process_manager.find_processes("cargo", FilterOptions::default()); assert!(!results.is_empty()); - assert!(results.iter().all(|p| p.cmd.contains("cargo"))); + assert!(results.iter().all(|p| fuzzy_matches(&p.cmd, "cargo"))); } #[test] @@ -17,7 +19,7 @@ assert!(!results.is_empty()); assert!(results .iter() - .all(|p| p.cmd_path.as_ref().unwrap().contains("cargo"))); + .all(|p| fuzzy_matches(p.cmd_path.as_ref().unwrap(), "cargo"))); } #[test] @@ -27,9 +29,9 @@ assert!(!results.is_empty()); assert!(results .iter() - .all(|p| p.cmd_path.as_ref().unwrap().contains("cargo") + .all(|p| fuzzy_matches(p.cmd_path.as_ref().unwrap(), "cargo") || p.args.contains("cargo") - || p.cmd.contains("cargo"))); + || fuzzy_matches(&p.cmd, "cargo"))); } #[test] @@ -37,7 +39,7 @@ let mut process_manager = ProcessManager::new().unwrap(); let results = process_manager.find_processes("-test", FilterOptions::default()); assert!(!results.is_empty()); - assert!(results.iter().all(|p| p.args.contains("test"))); + assert!(results.iter().all(|p| fuzzy_matches(&p.args, "test"))); } use http_test_server::TestServer; @@ -78,3 +80,10 @@ .iter() .all(|p| p.pid == cargo_process_pid || p.parent_pid == Some(cargo_process_pid))); } + +fn fuzzy_matches(value: &str, pattern: &str) -> bool { + SkimMatcherV2::default() + .fuzzy_match(value, pattern) + .unwrap_or(0) + > 0 +} ++++++ vendor.tar.zst ++++++ /work/SRC/openSUSE:Factory/pik/vendor.tar.zst /work/SRC/openSUSE:Factory/.pik.new.19354/vendor.tar.zst differ: char 268996, line 1132
participants (1)
-
Source-Sync