aboutsummaryrefslogtreecommitdiff
path: root/src/libutil/hilite.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libutil/hilite.cc')
-rw-r--r--src/libutil/hilite.cc44
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;
+}
+
+}