From d137ceccefe08250106dcede1f30c270b0f9cf19 Mon Sep 17 00:00:00 2001 From: Fishhh Date: Sun, 5 Jun 2022 18:44:37 +0200 Subject: [PATCH 1/5] Fix incorrect comment in `hiliteMatches` --- src/libutil/hilite.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libutil/hilite.cc b/src/libutil/hilite.cc index a5991ca39..e5088230d 100644 --- a/src/libutil/hilite.cc +++ b/src/libutil/hilite.cc @@ -8,9 +8,9 @@ std::string hiliteMatches( std::string_view prefix, std::string_view postfix) { - // Avoid copy on zero matches + // Avoid extra work on zero matches if (matches.size() == 0) - return (std::string) s; + return std::string(s); std::sort(matches.begin(), matches.end(), [](const auto & a, const auto & b) { return a.position() < b.position(); From b42358b9bec12dfdc419136f32ded2a4f7d7dea7 Mon Sep 17 00:00:00 2001 From: Fishhh Date: Sun, 5 Jun 2022 18:45:58 +0200 Subject: [PATCH 2/5] Add `--exclude` flag to `nix search` If a package's attribute path, description or name contains matches for any of the regexes specified via `-e` or `--exclude` that package is excluded from the final output. --- src/nix/search.cc | 23 ++++++++++++++++++++++- src/nix/search.md | 13 ++++++++++++- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/nix/search.cc b/src/nix/search.cc index 87dc1c0de..62ad98999 100644 --- a/src/nix/search.cc +++ b/src/nix/search.cc @@ -18,16 +18,24 @@ using namespace nix; std::string wrap(std::string prefix, std::string s) { - return prefix + s + ANSI_NORMAL; + return concatStrings(prefix, s, ANSI_NORMAL); } struct CmdSearch : InstallableCommand, MixJSON { std::vector res; + std::vector excludeRes; CmdSearch() { expectArgs("regex", &res); + addFlag(Flag { + .longName = "exclude", + .shortName = 'e', + .description = "Hide packages whose attribute path, name or description contain *regex*.", + .labels = {"regex"}, + .handler = Handler(&excludeRes), + }); } std::string description() override @@ -62,11 +70,16 @@ struct CmdSearch : InstallableCommand, MixJSON res.push_back("^"); std::vector regexes; + std::vector excludeRegexes; regexes.reserve(res.size()); + excludeRegexes.reserve(excludeRes.size()); for (auto & re : res) regexes.push_back(std::regex(re, std::regex::extended | std::regex::icase)); + for (auto & re : excludeRes) + excludeRegexes.emplace_back(re, std::regex::extended | std::regex::icase); + auto state = getEvalState(); auto jsonOut = json ? std::make_unique(std::cout) : nullptr; @@ -106,6 +119,14 @@ struct CmdSearch : InstallableCommand, MixJSON std::vector nameMatches; bool found = false; + for (auto & regex : excludeRegexes) { + if ( + std::regex_search(attrPath2, regex) + || std::regex_search(name.name, regex) + || std::regex_search(description, regex)) + return; + } + for (auto & regex : regexes) { found = false; auto addAll = [&found](std::sregex_iterator it, std::vector & vec) { diff --git a/src/nix/search.md b/src/nix/search.md index d182788a6..5a5b5ae05 100644 --- a/src/nix/search.md +++ b/src/nix/search.md @@ -43,12 +43,23 @@ R""( # nix search nixpkgs 'firefox|chromium' ``` -* Search for packages containing `git'`and either `frontend` or `gui`: +* Search for packages containing `git` and either `frontend` or `gui`: ```console # nix search nixpkgs git 'frontend|gui' ``` +* Search for packages containing `neovim` but hide ones containing either `gui` or `python`: + + ```console + # nix search nixpkgs neovim -e 'python|gui' + ``` + or + + ```console + # nix search nixpkgs neovim -e 'python' -e 'gui' + ``` + # Description `nix search` searches *installable* (which must be evaluatable, e.g. a From e009367c8d4523bfe3a1bc20583b27d06948a390 Mon Sep 17 00:00:00 2001 From: Fishhh Date: Sun, 5 Jun 2022 18:48:48 +0200 Subject: [PATCH 3/5] Remove redundant `std::move`s in calls to `hiliteMatches` --- src/nix/search.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/nix/search.cc b/src/nix/search.cc index 62ad98999..f1f5f9641 100644 --- a/src/nix/search.cc +++ b/src/nix/search.cc @@ -154,15 +154,15 @@ struct CmdSearch : InstallableCommand, MixJSON jsonElem.attr("version", name.version); jsonElem.attr("description", description); } else { - auto name2 = hiliteMatches(name.name, std::move(nameMatches), ANSI_GREEN, "\e[0;2m"); + auto name2 = hiliteMatches(name.name, nameMatches, ANSI_GREEN, "\e[0;2m"); if (results > 1) logger->cout(""); logger->cout( "* %s%s", - wrap("\e[0;1m", hiliteMatches(attrPath2, std::move(attrPathMatches), ANSI_GREEN, "\e[0;1m")), + wrap("\e[0;1m", hiliteMatches(attrPath2, attrPathMatches, ANSI_GREEN, "\e[0;1m")), name.version != "" ? " (" + name.version + ")" : ""); if (description != "") logger->cout( - " %s", hiliteMatches(description, std::move(descriptionMatches), ANSI_GREEN, ANSI_NORMAL)); + " %s", hiliteMatches(description, descriptionMatches, ANSI_GREEN, ANSI_NORMAL)); } } } From 0338cf55395feb3aedabc535858263d95d235f72 Mon Sep 17 00:00:00 2001 From: Fishhh Date: Sun, 5 Jun 2022 19:44:42 +0200 Subject: [PATCH 4/5] Add tests for `--exclude` flag in `nix search` --- tests/search.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/search.sh b/tests/search.sh index 52e12f381..f320e0ec1 100644 --- a/tests/search.sh +++ b/tests/search.sh @@ -36,3 +36,9 @@ e=$'\x1b' # grep doesn't support \e, \033 or even \x1b (( $(nix search -f search.nix '' 'o' | grep -Eo "$e\[32;1mo{1,2}$e\[(0|0;1)m" | wc -l) == 3 )) # Searching for 'b' should yield the 'b' in bar and the two 'b's in 'broken bar' (( $(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 foo --exclude 'foo|bar' | grep -Ec 'foo|bar') == 0 )) +(( $(nix search -f search.nix foo -e foo --exclude bar | grep -Ec 'foo|bar') == 0 )) From 9ae22b1fdeaf6cc7541a66d981ecf7b6038739cc Mon Sep 17 00:00:00 2001 From: Fishhh Date: Sun, 5 Jun 2022 19:45:21 +0200 Subject: [PATCH 5/5] Use `grep -c` instead of `grep|wc -l` in some `nix search` tests --- tests/search.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/search.sh b/tests/search.sh index f320e0ec1..41b706ac6 100644 --- a/tests/search.sh +++ b/tests/search.sh @@ -28,13 +28,14 @@ nix search -f search.nix '' |grep -q hello e=$'\x1b' # grep doesn't support \e, \033 or even \x1b # Multiple overlapping regexes -(( $(nix search -f search.nix '' 'oo' 'foo' 'oo' | grep "$e\[32;1mfoo$e\\[0;1m" | wc -l) == 1 )) -(( $(nix search -f search.nix '' 'broken b' 'en bar' | grep "$e\[32;1mbroken bar$e\\[0m" | wc -l) == 1 )) +(( $(nix search -f search.nix '' 'oo' 'foo' 'oo' | grep -c "$e\[32;1mfoo$e\\[0;1m") == 1 )) +(( $(nix search -f search.nix '' 'broken b' 'en bar' | grep -c "$e\[32;1mbroken bar$e\\[0m") == 1 )) # Multiple matches # Searching for 'o' should yield the 'o' in 'broken bar', the 'oo' in foo and 'o' in hello -(( $(nix search -f search.nix '' 'o' | grep -Eo "$e\[32;1mo{1,2}$e\[(0|0;1)m" | wc -l) == 3 )) +(( $(nix search -f search.nix '' 'o' | grep -Eoc "$e\[32;1mo{1,2}$e\[(0|0;1)m") == 3 )) # Searching for 'b' should yield the 'b' in bar and the two 'b's in 'broken bar' +# NOTE: This does not work with `grep -c` because it counts the two 'b's in 'broken bar' as one matched line (( $(nix search -f search.nix '' 'b' | grep -Eo "$e\[32;1mb$e\[(0|0;1)m" | wc -l) == 3 )) ## Tests for --exclude