summaryrefslogtreecommitdiff
path: root/src/display_buffer.cc
blob: bdd7d68a3179c2060c151ebc2c4583a08a6948db (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
#include "display_buffer.hh"

#include "assert.hh"
#include "utf8.hh"

namespace Kakoune
{

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

    assert(utf8::is_character_start(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()
{
    for (auto atom_it = m_atoms.begin(); atom_it != m_atoms.end(); ++atom_it)
    {
        decltype(atom_it) next_atom_it;
        while ((next_atom_it = atom_it + 1) != m_atoms.end())
        {
            auto& atom = *atom_it;
            auto& next_atom = *next_atom_it;

            if (atom.fg_color == next_atom.fg_color and
                atom.bg_color == next_atom.bg_color and
                atom.attribute == next_atom.attribute and
                atom.content.type() == AtomContent::BufferRange and
                next_atom.content.type() == AtomContent::BufferRange and
                next_atom.content.begin() == atom.content.end())
            {
                atom.content.m_end = next_atom.content.end();
                atom_it = m_atoms.erase(next_atom_it) - 1;
            }
            else
                break;
        }
    }
}

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

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

            if (not m_range.second.is_valid() or m_range.second < atom.content.end())
                m_range.second = atom.content.end();
        }
    }
    assert(m_range.first.is_valid() and m_range.second.is_valid());
    assert(m_range.first <= m_range.second);
}

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