summary refs log tree commit diff stats
path: root/doc
diff options
context:
space:
mode:
authorAndrey Makarov <ph.makarov@gmail.com>2022-09-14 19:28:01 +0300
committerGitHub <noreply@github.com>2022-09-14 18:28:01 +0200
commit2140d05f34f7976ed7f7058baa952490ee3fb859 (patch)
tree119f3225f9a255775521fa9b525394d909143af7 /doc
parent08faa04d78aca9e619ba518fb9b4ab4e07635455 (diff)
downloadNim-2140d05f34f7976ed7f7058baa952490ee3fb859.tar.gz
nimgrep: add `--inContext` and `--notinContext` options (#19528)
* nimgrep: add `--matchContext` and `--noMatchContext` options

* Rename options for uniformity

* Revise option names, add `--parentPath` options

* Revert --bin deprecation

* Copy-paste an original test from quantimnot

The origin was:
https://gist.githubusercontent.com/quantimnot/5d23b32fe0936ffc453220d20a87b9e2/raw/96544656d52332118295e55aa73718c389e5d194/tnimgrep.nim

* Change ! to n

* Attempt to fix test

* Fix test on Windows

* Change --contentsFile -> --inFile, add more tests

* Bump

* Change --parentPath to --dirpath
Diffstat (limited to 'doc')
-rw-r--r--doc/nimgrep.md87
-rw-r--r--doc/nimgrep_cmdline.txt48
2 files changed, 103 insertions, 32 deletions
diff --git a/doc/nimgrep.md b/doc/nimgrep.md
index e000efb46..8fb86a9d3 100644
--- a/doc/nimgrep.md
+++ b/doc/nimgrep.md
@@ -34,6 +34,66 @@ Command line switches
 
 .. include:: nimgrep_cmdline.txt
 
+Path filter options
+-------------------
+
+Let us assume we have file `dirA/dirB/dirC/file.nim`.
+Filesystem path options will match for these parts of the path:
+
+| option              | matches for                        |
+| :------------------ | :--------------------------------  |
+| `--[not]extensions` | ``nim``                            |
+| `--[not]filename`   | ``file.nim``                       |
+| `--[not]dirname`    | ``dirA`` and ``dirB`` and ``dirC`` |
+| `--[not]dirpath`    | ``dirA/dirB/dirC``                 |
+
+Combining multiple filter options together and negating them
+------------------------------------------------------------
+
+Options for filtering can be provided multiple times so they form a list,
+which works as:
+* positive filters
+  `--filename`, `--dirname`, `--dirpath`, `--inContext`,
+  `--inFile` accept files/matches if *any* pattern from the list is hit
+* negative filters
+  `--notfilename`, `--notdirname`, `--notdirpath`, `--notinContext`,
+  `--notinFile` accept files/matches if *no* pattern from the list is hit.
+
+In other words the same filtering option repeated many times means logical OR.
+
+.. Important::
+  Different filtering options are related by logical AND: they all must
+  be true for a match to be accepted.
+  E.g. `--filename:F --dirname:D1 --notdirname:D2` means
+  `filename(F) AND dirname(D1) AND (NOT dirname(D2))`.
+
+So negative filtering patterns are effectively related by logical OR also:
+`(NOT PAT1) AND (NOT PAT2) == NOT (PAT1 OR PAT2)`:literal: in pseudo-code.
+
+That means you can always use only 1 such an option with logical OR, e.g.
+`--notdirname:PAT1 --notdirname:PAT2` is fully equivalent to
+`--notdirname:'PAT1|PAT2'`.
+
+.. Note::
+   If you want logical AND on patterns you should compose 1 appropriate pattern,
+   possibly combined with multi-line mode `(?s)`:literal:.
+   E.g. to require that multi-line context of matches has occurences of
+   **both** PAT1 and PAT2 use positive lookaheads (`(?=PAT)`:literal:):
+     ```cmd
+     nimgrep --inContext:'(?s)(?=.*PAT1)(?=.*PAT2)'
+     ```
+
+Meaning of `^`:literal: and `$`:literal:
+========================================
+
+`nimgrep`:cmd: PCRE engine is run in a single-line mode so
+`^`:literal: matches the beginning of whole input *file* and
+`$`:literal: matches the end of *file* (or whole input *string* for
+options like `--filename`).
+
+Add the `(?m)`:literal: modifier to the beginning of your pattern for
+`^`:literal: and `$`:literal: to match the beginnings and ends of *lines*.
+
 Examples
 ========
 
@@ -51,23 +111,18 @@ All examples below use default PCRE Regex patterns:
 
 + To exclude version control directories (Git, Mercurial=hg, Subversion=svn)
   from the search:
-
     ```cmd
-    nimgrep --excludeDir:'^\.git$' --excludeDir:'^\.hg$' --excludeDir:'^\.svn$'
-    # short: --ed:'^\.git$' --ed:'^\.hg$' --ed:'^\.svn$'
+    nimgrep --notdirname:'^\.git$' --notdirname:'^\.hg$' --notdirname:'^\.svn$'
+    # short: --ndi:'^\.git$' --ndi:'^\.hg$' --ndi:'^\.svn$'
     ```
-
-+ To search only in paths containing the `tests` sub-directory recursively:
-
++ To search only in paths containing the `tests`:literal: sub-directory
+  recursively:
     ```cmd
-    nimgrep --recursive --includeDir:'(^|/)tests($|/)'
-    # short: -r --id:'(^|/)tests($|/)'
+    nimgrep --recursive --dirname:'^tests$'
+    # short: -r --di:'^tests$'
+    # or using --dirpath:
+    nimgrep --recursive --dirpath:'(^|/)tests($|/)'
+    # short: -r --pa:'(^|/)tests($|/)'
     ```
-
-  .. Attention:: note the subtle difference between `--excludeDir`:option: and
-    `--includeDir`:option:\: the former is applied to relative directory entries
-    and the latter is applied to the whole paths
-
-+ Nimgrep can search multi-line, e.g. to find files containing `import`
-  and then `strutils` use pattern `'import(.|\n)*?strutils'`:option:.
-
++ Nimgrep can search multi-line, e.g. to find files containing `import`:literal:
+  and then `strutils`:literal: use pattern `'import(.|\n)*?strutils'`:literal:.
diff --git a/doc/nimgrep_cmdline.txt b/doc/nimgrep_cmdline.txt
index 4ec344495..73f29f524 100644
--- a/doc/nimgrep_cmdline.txt
+++ b/doc/nimgrep_cmdline.txt
@@ -46,8 +46,7 @@ Options:
                         nimgrep --filenames               # In current dir
                         nimgrep --filenames "" DIRECTORY
                           # Note empty pattern "", lists all files in DIRECTORY
-
-* Interpret patterns:
+* Interprete patterns:
   --peg               PATTERN and PAT are Peg
   --re                PATTERN and PAT are regular expressions (default)
   --rex, -x           use the "extended" syntax for the regular expression
@@ -62,28 +61,45 @@ Options:
 * File system walk:
   --recursive, -r      process directories recursively
   --follow             follow all symlinks when processing recursively
-  --ext:EX1|EX2|...    only search the files with the given extension(s),
-                       empty one ("--ext") means files with missing extension
-  --noExt:EX1|...      exclude files having given extension(s), use empty one to
-                       skip files with no extension (like some binary files are)
-  --includeFile:PAT    search only files whose names contain pattern PAT
-  --excludeFile:PAT    skip files whose names contain pattern PAT
-  --includeDir:PAT     search only files with their whole directory path
-                       containing PAT
-  --excludeDir:PAT     skip directories whose name (not path)
-                       contain pattern PAT
-  --if,--ef,--id,--ed  abbreviations of the 4 options above
   --sortTime, -s[:asc|desc]
                        order files by the last modification time (default: off):
                        ascending (recent files go last) or descending
 
-* Filter file content:
-  --match:PAT         select files containing a (not displayed) match of PAT
-  --noMatch:PAT       select files not containing any match of PAT
+* Filter files (based on filesystem paths):
+
+  .. Hint:: Instead of `not` you can type just `n` for negative options below.
+
+  --ex[tensions]:EX1|EX2|...
+                       only search the files with the given extension(s),
+                       empty one (`--ex`) means files with missing extension
+  --notex[tensions]:EX1|EX2|...
+                       exclude files having given extension(s), use empty one to
+                       skip files with no extension (like some binary files are)
+  --fi[lename]:PAT     search only files whose name matches pattern PAT
+  --notfi[lename]:PAT  skip files whose name matches pattern PAT
+  --di[rname]:PAT      select files that in their path have a directory name
+                       that matches pattern PAT
+  --notdi[rname]:PAT   do not descend into directories whose name (not path)
+                       matches pattern PAT
+  --dirp[ath]:PAT      select only files whose whole relative directory path
+                       matches pattern PAT
+  --notdirp[ath]:PAT   skip files whose whole relative directory path
+                       matches pattern PAT
+
+* Filter files (based on file contents):
+  --inF[ile]:PAT      select files containing a (not displayed) match of PAT
+  --notinF[ile]:PAT   skip files containing a match of PAT
   --bin:on|off|only   process binary files? (detected by \0 in first 1K bytes)
                       (default: on - binary and text files treated the same way)
   --text, -t          process only text files, the same as `--bin:off`
 
+* Filter matches:
+  --inC[ontext]:PAT   select only matches containing a match of PAT in their
+                      surrounding context (multiline with `-c`, `-a`, `-b`)
+  --notinC[ontext]:PAT
+                      skip matches not containing a match of PAT
+                      in their surrounding context
+
 * Represent results:
   --nocolor           output will be given without any colors
   --color[:on]        force color even if output is redirected (default: auto)