summaryrefslogtreecommitdiff
path: root/src/display_buffer.hh
blob: c351c219aee8935124084cdcdad218c88293e09d (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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#ifndef display_buffer_hh_INCLUDED
#define display_buffer_hh_INCLUDED

#include <string>
#include <vector>

#include "line_and_column.hh"

#include "buffer.hh"

namespace Kakoune
{

struct DisplayCoord : LineAndColumn<DisplayCoord>
{
    DisplayCoord(int line = 0, int column = 0)
        : LineAndColumn(line, column) {}

    template<typename T>
    explicit DisplayCoord(const LineAndColumn<T>& other)
        : LineAndColumn(other.line, other.column) {}
};

typedef int Attribute;

enum Attributes
{
    Normal = 0,
    Underline = 1,
    Reverse = 2,
    Blink = 4,
    Bold = 8,
};

enum class Color
{
    Default,
    Black,
    Red,
    Green,
    Yellow,
    Blue,
    Magenta,
    Cyan,
    White
};

struct DisplayAtom
{
    DisplayAtom(const DisplayCoord& coord,
                const BufferIterator& begin, const BufferIterator& end,
                Color fg_color = Color::Default,
                Color bg_color = Color::Default,
                Attribute attribute = Attributes::Normal)
        : m_coord(coord),
          m_begin(begin), m_end(end),
          m_fg_color(fg_color),
          m_bg_color(bg_color),
          m_attribute(attribute)
    {}

    const DisplayCoord&   coord()     const { return m_coord; }
    const BufferIterator& begin()     const { return m_begin; }
    const BufferIterator& end()       const { return m_end; }
    const Color&          fg_color()  const { return m_fg_color; }
    const Color&          bg_color()  const { return m_bg_color; }
    const Attribute&      attribute() const { return m_attribute; }


    Color&         fg_color()  { return m_fg_color; }
    Color&         bg_color()  { return m_bg_color; }
    Attribute&     attribute() { return m_attribute; }

    BufferString   content()    const;
    DisplayCoord   end_coord()  const;
    BufferIterator iterator_at(const DisplayCoord& coord) const;
    DisplayCoord   line_and_column_at(const BufferIterator& iterator) const;

    bool           splitable() const { return m_replacement_text.empty(); }

private:
    friend class DisplayBuffer;

    DisplayCoord   m_coord;
    BufferIterator m_begin;
    BufferIterator m_end;
    Color          m_fg_color;
    Color          m_bg_color;
    Attribute      m_attribute;
    BufferString   m_replacement_text;
};

class DisplayBuffer
{
public:
    typedef std::list<DisplayAtom> AtomList;
    typedef AtomList::iterator iterator;
    typedef AtomList::const_iterator const_iterator;

    DisplayBuffer();

    void clear() { m_atoms.clear(); }
    void append(const DisplayAtom& atom) { m_atoms.push_back(atom); }
    iterator insert(iterator where, const DisplayAtom& atom);
    iterator split(iterator atom, const BufferIterator& pos);

    void replace_atom_content(iterator atom, const BufferString& replacement);

    iterator begin() { return m_atoms.begin(); }
    iterator end()   { return m_atoms.end(); }

    const_iterator begin() const { return m_atoms.begin(); }
    const_iterator end()   const { return m_atoms.end(); }

    iterator atom_containing(const BufferIterator& where);

    const DisplayAtom& front() const { return m_atoms.front(); }
    const DisplayAtom& back()  const { return m_atoms.back(); }

    void check_invariant() const;
private:
    AtomList m_atoms;
};

}

#endif // display_buffer_hh_INCLUDED