diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/libutil/hilite.cc | 4 | ||||
-rw-r--r-- | src/nix/search.cc | 29 | ||||
-rw-r--r-- | src/nix/search.md | 13 |
3 files changed, 39 insertions, 7 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(); diff --git a/src/nix/search.cc b/src/nix/search.cc index 87dc1c0de..f1f5f9641 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<std::string> res; + std::vector<std::string> 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<std::regex> regexes; + std::vector<std::regex> 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<JSONObject>(std::cout) : nullptr; @@ -106,6 +119,14 @@ struct CmdSearch : InstallableCommand, MixJSON std::vector<std::smatch> 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<std::smatch> & vec) { @@ -133,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)); } } } 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 |