aboutsummaryrefslogtreecommitdiff
path: root/src/libutil/hilite.cc
blob: e5088230d7c3e6ed008f0d97d897b6feade1ef04 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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;
}

}