From fd844a0d5a96313a7d70b7a1f6a6aa9bf4071b7b Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Sat, 25 Apr 2020 08:48:01 +1000 Subject: [PATCH] add w: shortcut for searching on word boundaries --- rslib/src/search/parser.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/rslib/src/search/parser.rs b/rslib/src/search/parser.rs index fb6963c8a..f1f87f7f2 100644 --- a/rslib/src/search/parser.rs +++ b/rslib/src/search/parser.rs @@ -277,6 +277,7 @@ fn search_node_for_text_with_argument<'a>( "prop" => parse_prop(val.as_ref())?, "re" => SearchNode::Regex(val), "nc" => SearchNode::NoCombining(val), + "w" => parse_word(val.as_ref()), // anything else is a field search _ => parse_single_field(key.as_ref(), val.as_ref()), }) @@ -409,6 +410,13 @@ fn parse_single_field(key: &str, mut val: &str) -> SearchNode<'static> { } } +fn parse_word(val: &str) -> SearchNode<'static> { + let front_boundary = if val.starts_with('*') { "" } else { r"\b" }; + let end_boundary = if val.ends_with('*') { "" } else { r"\b" }; + let escaped = regex::escape(val.trim_matches('*')); + SearchNode::Regex(format!("{}{}{}", front_boundary, escaped, end_boundary).into()) +} + #[cfg(test)] mod test { use super::*; @@ -523,6 +531,11 @@ mod test { })] ); + assert_eq!(parse("w:foo")?, vec![Search(Regex(r"\bfoo\b".into()))]); + assert_eq!(parse("w:*foo")?, vec![Search(Regex(r"foo\b".into()))]); + assert_eq!(parse("w:foo*")?, vec![Search(Regex(r"\bfoo".into()))]); + assert_eq!(parse("w:*fo.*o*")?, vec![Search(Regex(r"fo\.\*o".into()))]); + Ok(()) } }