diff options
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..e5088230d --- /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 extra work 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; +} + +} |