diff options
author | Eelco Dolstra <edolstra@gmail.com> | 2022-04-21 11:58:40 +0200 |
---|---|---|
committer | Eelco Dolstra <edolstra@gmail.com> | 2022-04-21 12:06:29 +0200 |
commit | f05e1f6fbb8a760f23a7af16b065078df6588acf (patch) | |
tree | 618d7ce614dcbabb8170a8c397fe6f68a8badf4e /src/libutil/hilite.cc | |
parent | 684e679e07d3a8d9da1449347e5e07da2d718916 (diff) |
Move hiliteMatches into a separate header
This is mostly so that we don't #include <regex> everywhere (which
adds quite a bit of compilation time).
Diffstat (limited to 'src/libutil/hilite.cc')
-rw-r--r-- | src/libutil/hilite.cc | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/src/libutil/hilite.cc b/src/libutil/hilite.cc new file mode 100644 index 000000000..a5991ca39 --- /dev/null +++ b/src/libutil/hilite.cc @@ -0,0 +1,44 @@ +#include "hilite.hh" + +namespace nix { + +std::string hiliteMatches( + std::string_view s, + std::vector<std::smatch> matches, + std::string_view prefix, + std::string_view postfix) +{ + // Avoid copy on zero matches + if (matches.size() == 0) + return (std::string) s; + + std::sort(matches.begin(), matches.end(), [](const auto & a, const auto & b) { + return a.position() < b.position(); + }); + + std::string out; + ssize_t last_end = 0; + + for (auto it = matches.begin(); it != matches.end();) { + auto m = *it; + size_t start = m.position(); + out.append(s.substr(last_end, m.position() - last_end)); + // Merge continous matches + ssize_t end = start + m.length(); + while (++it != matches.end() && (*it).position() <= end) { + auto n = *it; + ssize_t nend = start + (n.position() - start + n.length()); + if (nend > end) + end = nend; + } + out.append(prefix); + out.append(s.substr(start, end - start)); + out.append(postfix); + last_end = end; + } + + out.append(s.substr(last_end)); + return out; +} + +} |