summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCanop <cano.petrole@gmail.com>2020-06-20 17:43:42 +0200
committerCanop <cano.petrole@gmail.com>2020-06-20 17:43:42 +0200
commit249bbd42bcf6df8351c0929c7e749bab9ef148ad (patch)
treec8cb5bd90600753f41016d4841ce99764b3419e4
parent62405df7c20b3cbc11ec16f853227f8ff0bc2ccd (diff)
more subtle rules on pattern combination parsing
For example a closing parenthesis at the very start can only be part of a pattern, not an interpattern token.
-rw-r--r--Cargo.lock2
-rw-r--r--Cargo.toml2
-rw-r--r--README.md2
-rw-r--r--src/command/parts.rs10
-rw-r--r--src/pattern/pattern_parts.rs2
-rw-r--r--src/pattern/search_mode.rs2
-rw-r--r--website/docs/img/20200620-complex-composite.pngbin0 -> 46874 bytes
-rw-r--r--website/docs/img/20200620-composite-notrs.pngbin0 -> 34001 bytes
-rw-r--r--website/docs/img/20200620-content-memm.pngbin0 -> 35627 bytes
-rw-r--r--website/docs/img/20200620-content-search.pngbin0 -> 36140 bytes
-rw-r--r--website/docs/index.md2
-rw-r--r--website/docs/input.md41
-rw-r--r--website/docs/navigation.md22
13 files changed, 65 insertions, 20 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 32e7df2..3f8a731 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -62,8 +62,6 @@ checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
[[package]]
name = "bet"
version = "0.3.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d8cf898b0201ea9ea3da57ec3feafb395c153ee8d063912ee79ddb645c276d31"
[[package]]
name = "bitflags"
diff --git a/Cargo.toml b/Cargo.toml
index ad4a480..f20964f 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -14,7 +14,7 @@ build = "build.rs"
exclude = ["website", "broot*.zip"]
[dependencies]
-bet = "0.3.3"
+bet = "0.3.4"
clap = { version="2.33", default-features=false, features=["suggestions"] }
chrono = "0.4"
crossbeam = "0.7"
diff --git a/README.md b/README.md
index e9c1c94..e78970c 100644
--- a/README.md
+++ b/README.md
@@ -74,7 +74,7 @@ You may also search with a regular expression. To do this, add a `/` before the
And you have other types of searches, for example searching on file content (start with `c/`):
-![content search](website/docs/img/20200608-content-search.png)
+![content search](website/docs/img/20200620-content-memm.png)
You may also apply logical operators or combine patterns, for example searching `test` in all files except txt ones could be `!/txt$/&c/test` and searching `carg` both in file names and file contents would be `carg|c/carg`.
diff --git a/src/command/parts.rs b/src/command/parts.rs
index a6a98ea..839eeb8 100644
--- a/src/command/parts.rs
+++ b/src/command/parts.rs
@@ -58,23 +58,23 @@ impl CommandParts {
};
if allow_inter_pattern_token {
match c {
- '|' => {
+ '|' if pt.accept_binary_operator() => {
pt.push_operator(PatternOperator::Or);
continue;
}
- '&' => {
+ '&' if pt.accept_binary_operator() => {
pt.push_operator(PatternOperator::And);
continue;
}
- '!' => {
+ '!' if pt.accept_unary_operator() => {
pt.push_operator(PatternOperator::Not);
continue;
}
- '(' => {
+ '(' if pt.accept_opening_par() => {
pt.open_par();
continue;
}
- ')' => {
+ ')' if pt.accept_closing_par() => {
pt.close_par();
continue;
}
diff --git a/src/pattern/pattern_parts.rs b/src/pattern/pattern_parts.rs
index c4808a1..e0d233d 100644
--- a/src/pattern/pattern_parts.rs
+++ b/src/pattern/pattern_parts.rs
@@ -33,7 +33,7 @@ impl PatternParts {
self.parts.push(String::new());
}
pub fn allow_inter_pattern_token(&self) -> bool {
- self.parts.len() != 2 || self.parts.last().unwrap().is_empty()
+ self.parts.len() != 2
}
pub fn is_empty(&self) -> bool {
self.core().is_empty()
diff --git a/src/pattern/search_mode.rs b/src/pattern/search_mode.rs
index 1b51388..95a95f1 100644
--- a/src/pattern/search_mode.rs
+++ b/src/pattern/search_mode.rs
@@ -95,7 +95,7 @@ impl Default for SearchModeMap {
entries: Vec::new(),
};
// the last keys are prefered
- smm.setm(&["nf", "fn", "n"], SearchMode::NameFuzzy);
+ smm.setm(&["nf", "fn", "n", "f"], SearchMode::NameFuzzy);
smm.setm(&["r", "nr", "rn", ""], SearchMode::NameRegex);
smm.setm(&["pf", "fp", "p"], SearchMode::PathFuzzy);
smm.setm(&["pr", "rp"], SearchMode::PathRegex);
diff --git a/website/docs/img/20200620-complex-composite.png b/website/docs/img/20200620-complex-composite.png
new file mode 100644
index 0000000..6c87a5d
--- /dev/null
+++ b/website/docs/img/20200620-complex-composite.png
Binary files differ
diff --git a/website/docs/img/20200620-composite-notrs.png b/website/docs/img/20200620-composite-notrs.png
new file mode 100644
index 0000000..e28db1f
--- /dev/null
+++ b/website/docs/img/20200620-composite-notrs.png
Binary files differ
diff --git a/website/docs/img/20200620-content-memm.png b/website/docs/img/20200620-content-memm.png
new file mode 100644
index 0000000..12723bb
--- /dev/null
+++ b/website/docs/img/20200620-content-memm.png
Binary files differ
diff --git a/website/docs/img/20200620-content-search.png b/website/docs/img/20200620-content-search.png
new file mode 100644
index 0000000..45e5e79
--- /dev/null
+++ b/website/docs/img/20200620-content-search.png
Binary files differ
diff --git a/website/docs/index.md b/website/docs/index.md
index b76ce83..b61db43 100644
--- a/website/docs/index.md
+++ b/website/docs/index.md
@@ -42,7 +42,7 @@ You may also search with a regular expression. To do this, add a `/` before the
And you have other types of searches, for example searching on file content (start with `c/`):
-![content search](img/20200608-content-search.png)
+![content search](img/20200620-content-memm.png)
You may also apply logical operators or combine patterns, for example searching `test` in all files except json ones could be `!/json$/&c/test` and searching `carg` both in file names and file contents would be `carg|c/carg`.
diff --git a/website/docs/input.md b/website/docs/input.md
index 2cc7047..e0990fc 100644
--- a/website/docs/input.md
+++ b/website/docs/input.md
@@ -13,7 +13,9 @@ Both parts are optional.
## The filtering pattern
-The search syntax is globally
+A search pattern is made of 1 to 3 parts separated by the `/` character but you rarely need the two `/`.
+
+The syntax is globally
<mode><pattern>[/<flags>]
@@ -21,18 +23,36 @@ The mode is either nothing (fuzzy name), just a slash (regex name) or some lette
mode | example query | example match | explanation
-|-|-|-
-fuzzy name | `abc` | `abac.txt` | search for "abc" in a fuzzy way in filenames
-regex name | `/abc` | `abc.txt` | search for the regular expression `abc` in filenames ("exact search")
-regex name | `/[yz]{3}` | `fuzzy.rs` | search for the regular expression `[yz]{3}` in filenames
+fuzzy name | `abc` or `nf/abc` | `abac.txt` | search for "abc" in a fuzzy way in filenames
+regex name | `/abc` or `/abc/` | `abc.txt` | search for the regular expression `abc` in filenames ("exact search")
+regex name | `/[yz]{3}` or `/[yz]{3}/` | `fuzzy.rs` | search for the regular expression `[yz]{3}` in filenames
+regex name | `/(json|xml)$/i` | `thing.XML` | find files whose name ends in `json` or `xml`, case insensitive
regex name | `/abc/i` | `aBc.txt` | search for the regular expression `abc` with flag `i` in filenames
-fuzzy path | `p/abc` | `a/bac.txt` | search for "abc" in a fuzzy way in sub-paths from current tree root
+fuzzy path | `p/abc` or `p/abc/` | `a/bac.txt` | search for "abc" in a fuzzy way in sub-paths from current tree root
regex path | `rp/abc` | `e/abac.txt` | search for the "abc" regex in sub-paths from current tree root
-content | `c/mask` | `umask = "1.0"` | search for the "mask" string in file contents
+content | `c/mask` or `c/mask/` | `umask = "1.0"` | search for the "mask" string in file contents
It's also possible to [redefine those mode mappings](../conf_file/#search-modes).
To escape characters (for example the space, colon or slash) in the pattern, use a `\` (an antislash is `\\`).
+## Combining filtering patterns
+
+Patterns can be combined with the `!` (not), `&` (and) and `|` (or) operators, and parentheses if necessary.
+
+You can for example display non `json` files containing either `isize` or `i32` with
+
+ !/json$/&(c/isize/|c/i32/)
+
+### Subtleties
+
+The caracters you use as operators and the parenthesis can be useful in patterns too, either because you want to search for them in fuzzy patterns or in file contents, or because you write non trivial regular expressions.
+
+Most often you'll just type what feels natural and broot will select the interpretation which makes sense but you might be interested in a few rules:
+
+* parenthesis and operators in the second pattern part (parts being separated by `/`) are part of the patternC, which explains why `/(json|xml)` is interpreted as a regular expression. If you want to do a fuzzy search for a `|` in the name of your files, you'll need to have an explicit pattern mode : `nf/a|b` because `a|b` would search for files whose name contains either `a` or `b`. And to ensure an operator or closing parenthesis isn't interpreted as part of your pattern, just close it with a `/`.
+* broot interprets the left operand before the right one and don't interpret the second one if it looks useless. So if you want to search your whole disk for json files containing `abcd`, it will be faster to use `/json$/&c/abcd` rather than `c/abcd/&/json$/` which would look at the file name only after having scanned the content.
+
## The verb invocation
The verb invocation is
@@ -89,3 +109,12 @@ In this case with an escaped space:
![content search](img/20200608-content-search.png)
+### A complex composite search
+
+Here we search for `"carg"` both in file names and file contents, and we exclude `"lock"` files:
+
+`!lock&(carg|c/carg/)`
+
+![complex composite](img/20200620-complex-composite.png)
+
+note: the `/` at the end of `c/carg/` is necessary to tell broot that the following parenthesis isn't part of the pattern.
diff --git a/website/docs/navigation.md b/website/docs/navigation.md
index e7b7940..17b3caa 100644
--- a/website/docs/navigation.md
+++ b/website/docs/navigation.md
@@ -48,9 +48,27 @@ For example `/pat+ern` would match `"patern.zip"` or `"some_patttern.rar"` but n
If you want the regex to be case insensitive, add the `i` flag: `/pat+ern/i`.
-# Other kinds of searches
+# File content searches
-Other types of searches are possible, see [reference](../input/#the-filtering-pattern).
+To display only files containing `"memmap"`, type `c/memmap`:
+
+![content](../img/20200620-content-search.png)
+
+(as the search is displayed in real time you'll usually stop as soon as you have the right matches)
+
+# Composite patterns
+
+Simple patterns can be composed with the `!`, `&` and `|` operators.
+
+For example, if you don't want to see files whose name ends in `"rs"`, you may type `!/rs$` (it's the negation of the `/rs$` regular expression).
+
+And if you want to see all files containing `"pattern"` but not the rust ones, you'll type `!rs&c/pattern`:
+
+![composite](../img/20200620-composite-notrs.png)
+
+# More about searches
+
+If you want to know more about the exact pattern syntax, see [reference](../input/#the-filtering-pattern).
# Total Search