aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/manual/rl-next/empty-search-regex.md8
-rw-r--r--src/nix/search.cc6
-rw-r--r--src/nix/search.md15
-rw-r--r--tests/functional/search.sh17
4 files changed, 30 insertions, 16 deletions
diff --git a/doc/manual/rl-next/empty-search-regex.md b/doc/manual/rl-next/empty-search-regex.md
new file mode 100644
index 000000000..b193f9456
--- /dev/null
+++ b/doc/manual/rl-next/empty-search-regex.md
@@ -0,0 +1,8 @@
+synopsis: Disallow empty search regex in `nix search`
+prs: #9481
+description: {
+
+[`nix search`](@docroot@/command-ref/new-cli/nix3-search.md) now requires a search regex to be passed. To show all packages, use `^`.
+
+}
+
diff --git a/src/nix/search.cc b/src/nix/search.cc
index ef0139e09..97ef1375e 100644
--- a/src/nix/search.cc
+++ b/src/nix/search.cc
@@ -67,11 +67,9 @@ struct CmdSearch : InstallableValueCommand, MixJSON
settings.readOnlyMode = true;
evalSettings.enableImportFromDerivation.setDefault(false);
- // Empty search string should match all packages
- // Use "^" here instead of ".*" due to differences in resulting highlighting
- // (see #1893 -- libc++ claims empty search string is not in POSIX grammar)
+ // Recommend "^" here instead of ".*" due to differences in resulting highlighting
if (res.empty())
- res.push_back("^");
+ throw UsageError("Must provide at least one regex! To match all packages, use '%s'.", "nix search <installable> ^");
std::vector<std::regex> regexes;
std::vector<std::regex> excludeRegexes;
diff --git a/src/nix/search.md b/src/nix/search.md
index 0c5d22549..f65ac9b17 100644
--- a/src/nix/search.md
+++ b/src/nix/search.md
@@ -5,7 +5,7 @@ R""(
* Show all packages in the `nixpkgs` flake:
```console
- # nix search nixpkgs
+ # nix search nixpkgs ^
* legacyPackages.x86_64-linux.AMB-plugins (0.8.1)
A set of ambisonics ladspa plugins
@@ -34,7 +34,7 @@ R""(
* Show all packages in the flake in the current directory:
```console
- # nix search
+ # nix search . ^
```
* Search for Firefox or Chromium:
@@ -64,11 +64,16 @@ R""(
`nix search` searches [*installable*](./nix.md#installables) (which can be evaluated, that is, a
flake or Nix expression, but not a store path or store derivation path) for packages whose name or description matches all of the
-regular expressions *regex*. For each matching package, It prints the
+regular expressions *regex*. For each matching package, It prints the
full attribute name (from the root of the [installable](./nix.md#installables)), the version
and the `meta.description` field, highlighting the substrings that
-were matched by the regular expressions. If no regular expressions are
-specified, all packages are shown.
+were matched by the regular expressions.
+
+To show all packages, use the regular expression `^`. In contrast to `.*`,
+it avoids highlighting the entire name and description of every package.
+
+> Note that in this context, `^` is the regex character to match the beginning of a string, *not* the delimiter for
+> [selecting a derivation output](@docroot@/command-ref/new-cli/nix.md#derivation-output-selection).
# Flake output attributes
diff --git a/tests/functional/search.sh b/tests/functional/search.sh
index 8742f8736..d9c7a75da 100644
--- a/tests/functional/search.sh
+++ b/tests/functional/search.sh
@@ -17,12 +17,15 @@ clearCache
# Multiple arguments will not exist
(( $(nix search -f search.nix '' hello broken | wc -l) == 0 ))
+# No regex should return an error
+(( $(nix search -f search.nix '' | wc -l) == 0 ))
+
## Search expressions
# Check that empty search string matches all
-nix search -f search.nix '' |grepQuiet foo
-nix search -f search.nix '' |grepQuiet bar
-nix search -f search.nix '' |grepQuiet hello
+nix search -f search.nix '' ^ | grepQuiet foo
+nix search -f search.nix '' ^ | grepQuiet bar
+nix search -f search.nix '' ^ | grepQuiet hello
## Tests for multiple regex/match highlighting
@@ -39,8 +42,8 @@ e=$'\x1b' # grep doesn't support \e, \033 or even \x1b
(( $(nix search -f search.nix '' 'b' | grep -Eo "$e\[32;1mb$e\[(0|0;1)m" | wc -l) == 3 ))
## Tests for --exclude
-(( $(nix search -f search.nix -e hello | grep -c hello) == 0 ))
+(( $(nix search -f search.nix ^ -e hello | grep -c hello) == 0 ))
-(( $(nix search -f search.nix foo --exclude 'foo|bar' | grep -Ec 'foo|bar') == 0 ))
-(( $(nix search -f search.nix foo -e foo --exclude bar | grep -Ec 'foo|bar') == 0 ))
-[[ $(nix search -f search.nix -e bar --json | jq -c 'keys') == '["foo","hello"]' ]]
+(( $(nix search -f search.nix foo ^ --exclude 'foo|bar' | grep -Ec 'foo|bar') == 0 ))
+(( $(nix search -f search.nix foo ^ -e foo --exclude bar | grep -Ec 'foo|bar') == 0 ))
+[[ $(nix search -f search.nix '' ^ -e bar --json | jq -c 'keys') == '["foo","hello"]' ]]