mirror of
https://github.com/dalance/procs.git
synced 2026-10-12 02:12:39 +00:00
Add fancy regex fallback for advanced filters
This commit is contained in:
committed by
Sri Sabbella
parent
fb0f1b2c0b
commit
6cecc6f09f
Generated
+27
@@ -185,6 +185,21 @@ dependencies = [
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bit-set"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3"
|
||||
dependencies = [
|
||||
"bit-vec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bit-vec"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
@@ -700,6 +715,17 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fancy-regex"
|
||||
version = "0.16.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "998b056554fbe42e03ae0e152895cd1a7e1002aec800fdc6635d20270260c46f"
|
||||
dependencies = [
|
||||
"bit-set",
|
||||
"regex-automata",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "filetime"
|
||||
version = "0.2.27"
|
||||
@@ -1589,6 +1615,7 @@ dependencies = [
|
||||
"directories",
|
||||
"dockworker",
|
||||
"errno 0.3.14",
|
||||
"fancy-regex",
|
||||
"getch",
|
||||
"libc",
|
||||
"libproc",
|
||||
|
||||
@@ -54,6 +54,7 @@ tokio = { version = "1.52", optional = true, features = ["rt"] }
|
||||
toml = "1.1"
|
||||
unicode-width = "0.2"
|
||||
regex = "1.12"
|
||||
fancy-regex = "0.16"
|
||||
|
||||
[build-dependencies]
|
||||
anyhow = "1.0"
|
||||
|
||||
@@ -3,6 +3,7 @@ mod columns;
|
||||
mod config;
|
||||
mod opt;
|
||||
mod process;
|
||||
mod search_regex;
|
||||
mod style;
|
||||
mod term_info;
|
||||
mod util;
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
use anyhow::Error;
|
||||
|
||||
pub enum SearchRegex {
|
||||
Fast(regex::Regex),
|
||||
Fancy(fancy_regex::Regex),
|
||||
}
|
||||
|
||||
impl SearchRegex {
|
||||
pub fn new(pattern: &str, ignore_case: bool) -> Result<Self, Error> {
|
||||
if let Ok(regex) = regex::RegexBuilder::new(pattern)
|
||||
.case_insensitive(ignore_case)
|
||||
.build()
|
||||
{
|
||||
return Ok(Self::Fast(regex));
|
||||
}
|
||||
|
||||
let regex = fancy_regex::RegexBuilder::new(pattern)
|
||||
.case_insensitive(ignore_case)
|
||||
.build()?;
|
||||
Ok(Self::Fancy(regex))
|
||||
}
|
||||
|
||||
pub fn is_match(&self, text: &str) -> Result<bool, Error> {
|
||||
match self {
|
||||
Self::Fast(regex) => Ok(regex.is_match(text)),
|
||||
Self::Fancy(regex) => Ok(regex.is_match(text)?),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::SearchRegex;
|
||||
|
||||
#[test]
|
||||
fn uses_fast_engine_for_standard_regex() {
|
||||
let regex = SearchRegex::new("proc.*", false).unwrap();
|
||||
|
||||
assert!(matches!(regex, SearchRegex::Fast(_)));
|
||||
assert!(regex.is_match("procs").unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn falls_back_to_fancy_engine_for_lookahead() {
|
||||
let regex = SearchRegex::new("proc(?=s)", false).unwrap();
|
||||
|
||||
assert!(matches!(regex, SearchRegex::Fancy(_)));
|
||||
assert!(regex.is_match("procs").unwrap());
|
||||
assert!(!regex.is_match("procx").unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn falls_back_to_fancy_engine_for_negative_lookahead() {
|
||||
let regex = SearchRegex::new("proc(?!x)", false).unwrap();
|
||||
|
||||
assert!(matches!(regex, SearchRegex::Fancy(_)));
|
||||
assert!(regex.is_match("procs").unwrap());
|
||||
assert!(!regex.is_match("procx").unwrap());
|
||||
}
|
||||
}
|
||||
+10
-7
@@ -4,6 +4,7 @@ use crate::columns::*;
|
||||
use crate::config::*;
|
||||
use crate::opt::{ArgColorMode, ArgPagerMode};
|
||||
use crate::process::collect_proc;
|
||||
use crate::search_regex::SearchRegex;
|
||||
use crate::style::{apply_color, apply_style, color_to_column_style};
|
||||
use crate::term_info::TermInfo;
|
||||
use crate::util::{
|
||||
@@ -13,7 +14,6 @@ use crate::util::{
|
||||
use anyhow::{Error, bail};
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
use pager::Pager;
|
||||
use regex::RegexBuilder;
|
||||
use std::collections::HashMap;
|
||||
use std::time::Duration;
|
||||
|
||||
@@ -263,9 +263,7 @@ impl View {
|
||||
ConfigSearchCase::Insensitive => true,
|
||||
ConfigSearchCase::Sensitive => false,
|
||||
};
|
||||
let regex = RegexBuilder::new(pattern)
|
||||
.case_insensitive(ignore_case)
|
||||
.build()?;
|
||||
let regex = SearchRegex::new(pattern, ignore_case)?;
|
||||
Some(regex)
|
||||
} else {
|
||||
None
|
||||
@@ -316,7 +314,7 @@ impl View {
|
||||
} else if opt.keyword.is_empty() {
|
||||
true
|
||||
} else if let Some(regex) = ®ex {
|
||||
View::search_regex(*pid, cols_searchable.as_slice(), regex)
|
||||
View::search_regex(*pid, cols_searchable.as_slice(), regex)?
|
||||
} else {
|
||||
View::search(
|
||||
*pid,
|
||||
@@ -714,8 +712,13 @@ impl View {
|
||||
}
|
||||
}
|
||||
|
||||
fn search_regex(pid: i32, cols: &[&dyn Column], regex: ®ex::Regex) -> bool {
|
||||
cols.iter().any(|c| regex.is_match(&c.display_json(pid)))
|
||||
fn search_regex(pid: i32, cols: &[&dyn Column], regex: &SearchRegex) -> Result<bool, Error> {
|
||||
for c in cols {
|
||||
if regex.is_match(&c.display_json(pid))? {
|
||||
return Ok(true);
|
||||
}
|
||||
}
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_os = "windows", any(target_os = "linux", target_os = "android"))))]
|
||||
|
||||
+2
-5
@@ -1,12 +1,12 @@
|
||||
use crate::Opt;
|
||||
use crate::config::*;
|
||||
use crate::search_regex::SearchRegex;
|
||||
use crate::term_info::TermInfo;
|
||||
use crate::util::{get_theme, has_regex_syntax};
|
||||
use crate::view::View;
|
||||
use anyhow::Error;
|
||||
use chrono::offset::Local;
|
||||
use getch::Getch;
|
||||
use regex::RegexBuilder;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::mpsc::{Receiver, Sender, channel};
|
||||
use std::thread;
|
||||
@@ -221,10 +221,7 @@ impl Watcher {
|
||||
ConfigSearchCase::Insensitive => true,
|
||||
ConfigSearchCase::Sensitive => false,
|
||||
};
|
||||
match RegexBuilder::new(&candidate)
|
||||
.case_insensitive(ignore_case)
|
||||
.build()
|
||||
{
|
||||
match SearchRegex::new(&candidate, ignore_case) {
|
||||
Ok(_) => {
|
||||
opt.keyword = vec![candidate];
|
||||
regex_error = None;
|
||||
|
||||
Reference in New Issue
Block a user