summaryrefslogtreecommitdiff
path: root/src/display_buffer.cc
blob: c656410cb04b0299e3ab27b215e0578bb016c3fc (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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include "display_buffer.hh"

#include "assert.hh"

namespace Kakoune
{

DisplayLine::iterator DisplayLine::split(iterator it, BufferCoord pos)
{
    kak_assert(it->content.type() == AtomContent::BufferRange);
    kak_assert(it->content.begin() < pos);
    kak_assert(it->content.end() > pos);

    DisplayAtom atom = *it;
    atom.content.m_end = pos;
    it->content.m_begin = pos;
    return m_atoms.insert(it, std::move(atom));
}

void DisplayLine::optimize()
{
    if (m_atoms.empty())
        return;

    auto atom_it = m_atoms.begin();
    auto next_atom_it = atom_it + 1;
    while (next_atom_it != m_atoms.end())
    {
        auto& atom = *atom_it;
        auto& next_atom = *next_atom_it;
        bool merged = false;

        if (atom.colors == next_atom.colors and
            atom.attribute == next_atom.attribute and
            atom.content.type() ==  next_atom.content.type())
        {
            auto type = atom.content.type();
            if ((type == AtomContent::BufferRange or
                 type == AtomContent::ReplacedBufferRange) and
                next_atom.content.begin() == atom.content.end())
            {
                atom.content.m_end = next_atom.content.end();
                if (type == AtomContent::ReplacedBufferRange)
                    atom.content.m_text += next_atom.content.m_text;
                merged = true;
            }
            if (type == AtomContent::Text)
            {
                atom.content.m_text += next_atom.content.m_text;
                merged = true;
            }
        }
        if (merged)
            next_atom_it = m_atoms.erase(next_atom_it);
        else
            atom_it = next_atom_it++;
    }
}

CharCount DisplayLine::length() const
{
    CharCount len = 0;
    for (auto& atom : m_atoms)
        len += atom.content.length();
    return len;
}

void DisplayBuffer::compute_range()
{
    m_range.first  = {INT_MAX,INT_MAX};
    m_range.second = {0,0};
    for (auto& line : m_lines)
    {
        for (auto& atom : line)
        {
            if (not atom.content.has_buffer_range())
                continue;

            if (m_range.first > atom.content.begin())
                m_range.first = atom.content.begin();

            if (m_range.second < atom.content.end())
                m_range.second = atom.content.end();
        }
    }
    kak_assert(m_range.first <= m_range.second);
}

void DisplayBuffer::optimize()
{
    for (auto& line : m_lines)
        line.optimize();
}
}