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 <mantari...@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

Reply via email to