home/src/display_buffer.hh

188 lines
4.4 KiB
C++
Raw Normal View History

2011-09-02 18:51:20 +02:00
#ifndef display_buffer_hh_INCLUDED
#define display_buffer_hh_INCLUDED
2013-04-09 20:05:40 +02:00
#include "buffer.hh"
#include "color.hh"
#include "line_and_column.hh"
2013-04-09 20:05:40 +02:00
#include "string.hh"
#include "utf8.hh"
2013-04-09 20:05:40 +02:00
#include <vector>
2011-09-02 18:51:20 +02:00
namespace Kakoune
{
struct DisplayCoord : LineAndColumn<DisplayCoord, LineCount, CharCount>
{
2012-09-04 23:54:10 +02:00
constexpr DisplayCoord(LineCount line = 0, CharCount column = 0)
: LineAndColumn(line, column) {}
};
2012-10-23 22:43:12 +02:00
typedef char Attribute;
2011-09-02 18:51:20 +02:00
enum Attributes
{
2011-09-26 01:51:12 +02:00
Normal = 0,
Underline = 1,
Reverse = 2,
Blink = 4,
Bold = 8
2011-09-26 01:51:12 +02:00
};
struct AtomContent
2011-09-02 18:51:20 +02:00
{
public:
enum Type { BufferRange, ReplacedBufferRange, Text };
AtomContent(const Buffer& buffer, BufferCoord begin, BufferCoord end)
: m_type(BufferRange), m_buffer(&buffer), m_begin(begin), m_end(end) {}
AtomContent(String str)
: m_type(Text), m_text(std::move(str)) {}
String content() const
{
switch (m_type)
{
case BufferRange:
return m_buffer->string(m_begin, m_end);
case Text:
case ReplacedBufferRange:
return m_text;
}
kak_assert(false);
2012-10-11 01:17:29 +02:00
return 0;
}
2012-09-30 16:21:20 +02:00
CharCount length() const
{
switch (m_type)
{
case BufferRange:
return utf8::distance(m_buffer->iterator_at(m_begin),
m_buffer->iterator_at(m_end));
2012-09-30 16:21:20 +02:00
case Text:
case ReplacedBufferRange:
return m_text.char_length();
2012-09-30 16:21:20 +02:00
}
kak_assert(false);
2012-10-11 01:17:29 +02:00
return 0;
2012-09-30 16:21:20 +02:00
}
const BufferCoord& begin() const
{
kak_assert(has_buffer_range());
return m_begin;
}
const BufferCoord& end() const
{
kak_assert(has_buffer_range());
return m_end;
}
void replace(String text)
{
kak_assert(m_type == BufferRange);
m_type = ReplacedBufferRange;
m_text = std::move(text);
}
bool has_buffer_range() const
{
return m_type == BufferRange or m_type == ReplacedBufferRange;
}
Type type() const { return m_type; }
2011-10-17 21:01:04 +02:00
void trim_begin(CharCount count);
void trim_end(CharCount count);
private:
friend class DisplayLine;
Type m_type;
const Buffer* m_buffer = nullptr;
BufferCoord m_begin;
BufferCoord m_end;
String m_text;
2011-09-02 18:51:20 +02:00
};
struct DisplayAtom
2011-09-02 18:51:20 +02:00
{
ColorPair colors;
Attribute attribute;
AtomContent content;
2011-09-02 18:51:20 +02:00
DisplayAtom(AtomContent content,
ColorPair colors = {Colors::Default, Colors::Default},
Attribute attribute = Normal)
: content{std::move(content)}, colors{colors}, attribute{attribute}
{}
};
2011-09-02 18:51:20 +02:00
using BufferRange = std::pair<BufferCoord, BufferCoord>;
using AtomList = std::vector<DisplayAtom>;
class DisplayLine
{
public:
using iterator = AtomList::iterator;
using const_iterator = AtomList::const_iterator;
DisplayLine() = default;
DisplayLine(AtomList atoms);
DisplayLine(String str, ColorPair color)
{ push_back({ std::move(str), color }); }
2011-09-02 18:51:20 +02:00
iterator begin() { return m_atoms.begin(); }
iterator end() { return m_atoms.end(); }
2011-09-02 18:51:20 +02:00
const_iterator begin() const { return m_atoms.begin(); }
const_iterator end() const { return m_atoms.end(); }
const AtomList& atoms() const { return m_atoms; }
CharCount length() const;
const BufferRange& range() const { return m_range; }
// Split atom pointed by it at pos, returns an iterator to the first atom
iterator split(iterator it, BufferCoord pos);
iterator insert(iterator it, DisplayAtom atom);
void push_back(DisplayAtom atom);
// remove first_char from the begining of the line, and make sure
// the line is less that char_count character
void trim(CharCount first_char, CharCount char_count);
void optimize();
2011-09-02 18:51:20 +02:00
private:
void compute_range();
BufferRange m_range = { { INT_MAX, INT_MAX }, { INT_MIN, INT_MIN } };
AtomList m_atoms;
2011-09-02 18:51:20 +02:00
};
class DisplayBuffer
{
public:
using LineList = std::vector<DisplayLine>;
DisplayBuffer() {}
LineList& lines() { return m_lines; }
const LineList& lines() const { return m_lines; }
// returns the smallest BufferRange which contains every DisplayAtoms
const BufferRange& range() const { return m_range; }
void optimize();
void compute_range();
private:
LineList m_lines;
BufferRange m_range;
};
2011-09-02 18:51:20 +02:00
}
#endif // display_buffer_hh_INCLUDED