2011-09-02 18:51:20 +02:00
|
|
|
#ifndef display_buffer_hh_INCLUDED
|
|
|
|
#define display_buffer_hh_INCLUDED
|
|
|
|
|
|
|
|
#include <vector>
|
|
|
|
|
2012-04-14 03:17:09 +02:00
|
|
|
#include "string.hh"
|
2012-09-17 19:01:13 +02:00
|
|
|
#include "color.hh"
|
2011-10-14 16:29:53 +02:00
|
|
|
#include "line_and_column.hh"
|
2011-09-28 22:54:11 +02:00
|
|
|
#include "buffer.hh"
|
2012-10-11 00:41:48 +02:00
|
|
|
#include "utf8.hh"
|
2011-09-28 22:54:11 +02:00
|
|
|
|
2011-09-02 18:51:20 +02:00
|
|
|
namespace Kakoune
|
|
|
|
{
|
|
|
|
|
2012-10-11 00:41:48 +02:00
|
|
|
struct DisplayCoord : LineAndColumn<DisplayCoord, LineCount, CharCount>
|
2011-10-14 16:29:53 +02:00
|
|
|
{
|
2012-09-04 23:54:10 +02:00
|
|
|
constexpr DisplayCoord(LineCount line = 0, CharCount column = 0)
|
2011-10-14 16:29:53 +02:00
|
|
|
: LineAndColumn(line, column) {}
|
|
|
|
};
|
|
|
|
|
2011-09-02 18:51:20 +02:00
|
|
|
typedef int Attribute;
|
|
|
|
|
|
|
|
enum Attributes
|
|
|
|
{
|
2011-09-26 01:51:12 +02:00
|
|
|
Normal = 0,
|
|
|
|
Underline = 1,
|
|
|
|
Reverse = 2,
|
|
|
|
Blink = 4,
|
2012-07-12 23:19:10 +02:00
|
|
|
Bold = 8
|
2011-09-26 01:51:12 +02:00
|
|
|
};
|
|
|
|
|
2012-10-08 14:28:38 +02:00
|
|
|
class DisplayLine;
|
|
|
|
|
2012-07-12 23:19:10 +02:00
|
|
|
struct AtomContent
|
2011-09-02 18:51:20 +02:00
|
|
|
{
|
2012-07-12 23:19:10 +02:00
|
|
|
public:
|
|
|
|
enum Type { BufferRange, ReplacedBufferRange, Text };
|
|
|
|
|
|
|
|
AtomContent(BufferIterator begin, BufferIterator end)
|
|
|
|
: m_type(BufferRange),
|
|
|
|
m_begin(std::move(begin)),
|
|
|
|
m_end(std::move(end)) {}
|
|
|
|
|
|
|
|
AtomContent(String str)
|
|
|
|
: m_type(Text), m_text(std::move(str)) {}
|
|
|
|
|
|
|
|
String content() const
|
|
|
|
{
|
|
|
|
switch (m_type)
|
|
|
|
{
|
|
|
|
case BufferRange:
|
|
|
|
return m_begin.buffer().string(m_begin, m_end);
|
|
|
|
case Text:
|
|
|
|
case ReplacedBufferRange:
|
|
|
|
return m_text;
|
|
|
|
}
|
2012-10-11 01:17:29 +02:00
|
|
|
assert(false);
|
|
|
|
return 0;
|
2012-07-12 23:19:10 +02:00
|
|
|
}
|
|
|
|
|
2012-09-30 16:21:20 +02:00
|
|
|
CharCount length() const
|
|
|
|
{
|
|
|
|
switch (m_type)
|
|
|
|
{
|
|
|
|
case BufferRange:
|
2012-10-11 00:41:48 +02:00
|
|
|
return utf8::distance(m_begin, m_end);
|
2012-09-30 16:21:20 +02:00
|
|
|
case Text:
|
|
|
|
case ReplacedBufferRange:
|
2012-10-11 00:41:48 +02:00
|
|
|
return m_text.char_length();
|
2012-09-30 16:21:20 +02:00
|
|
|
}
|
2012-10-11 01:17:29 +02:00
|
|
|
assert(false);
|
|
|
|
return 0;
|
2012-09-30 16:21:20 +02:00
|
|
|
}
|
|
|
|
|
2012-10-08 14:28:38 +02:00
|
|
|
const BufferIterator& begin() const
|
2012-07-03 23:23:07 +02:00
|
|
|
{
|
2012-07-12 23:19:10 +02:00
|
|
|
assert(has_buffer_range());
|
|
|
|
return m_begin;
|
|
|
|
}
|
2011-10-15 06:45:49 +02:00
|
|
|
|
2012-10-08 14:28:38 +02:00
|
|
|
const BufferIterator& end() const
|
2012-07-12 23:19:10 +02:00
|
|
|
{
|
|
|
|
assert(has_buffer_range());
|
|
|
|
return m_end;
|
|
|
|
}
|
2011-10-15 06:45:49 +02:00
|
|
|
|
2012-07-12 23:19:10 +02:00
|
|
|
void replace(String text)
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
2011-10-15 06:45:49 +02:00
|
|
|
|
2012-07-12 23:19:10 +02:00
|
|
|
Type type() const { return m_type; }
|
2011-10-17 21:01:04 +02:00
|
|
|
|
2011-10-15 06:45:49 +02:00
|
|
|
private:
|
2012-10-08 14:28:38 +02:00
|
|
|
friend class DisplayLine;
|
|
|
|
|
2012-07-12 23:19:10 +02:00
|
|
|
Type m_type;
|
|
|
|
|
2011-10-15 06:45:49 +02:00
|
|
|
BufferIterator m_begin;
|
|
|
|
BufferIterator m_end;
|
2012-07-12 23:19:10 +02:00
|
|
|
String m_text;
|
2011-09-02 18:51:20 +02:00
|
|
|
};
|
|
|
|
|
2012-07-12 23:19:10 +02:00
|
|
|
struct DisplayAtom
|
2011-09-02 18:51:20 +02:00
|
|
|
{
|
2012-07-12 23:19:10 +02:00
|
|
|
Color fg_color;
|
|
|
|
Color bg_color;
|
|
|
|
Attribute attribute;
|
2011-09-02 18:51:20 +02:00
|
|
|
|
2012-07-12 23:19:10 +02:00
|
|
|
AtomContent content;
|
2011-09-02 18:51:20 +02:00
|
|
|
|
2012-07-12 23:19:10 +02:00
|
|
|
DisplayAtom(AtomContent content)
|
|
|
|
: content(std::move(content)), attribute(Normal),
|
|
|
|
fg_color(Color::Default), bg_color(Color::Default) {}
|
|
|
|
};
|
2011-09-02 18:51:20 +02:00
|
|
|
|
2012-07-12 23:19:10 +02:00
|
|
|
class DisplayLine
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
using AtomList = std::vector<DisplayAtom>;
|
|
|
|
using iterator = AtomList::iterator;
|
|
|
|
using const_iterator = AtomList::const_iterator;
|
|
|
|
|
2012-08-22 23:33:52 +02:00
|
|
|
explicit DisplayLine(LineCount buffer_line) : m_buffer_line(buffer_line) {}
|
2012-07-12 23:19:10 +02:00
|
|
|
|
2012-08-22 23:33:52 +02:00
|
|
|
LineCount buffer_line() const { return m_buffer_line; }
|
2011-10-15 06:45:49 +02:00
|
|
|
|
2011-09-02 18:51:20 +02:00
|
|
|
iterator begin() { return m_atoms.begin(); }
|
2012-07-12 23:19:10 +02:00
|
|
|
iterator end() { return m_atoms.end(); }
|
2011-09-02 18:51:20 +02:00
|
|
|
|
|
|
|
const_iterator begin() const { return m_atoms.begin(); }
|
2012-07-12 23:19:10 +02:00
|
|
|
const_iterator end() const { return m_atoms.end(); }
|
2011-09-29 11:10:27 +02:00
|
|
|
|
2012-07-12 23:19:10 +02:00
|
|
|
// Split atom pointed by it at pos, returns an iterator to the first atom
|
|
|
|
iterator split(iterator it, BufferIterator pos);
|
2011-10-17 21:00:38 +02:00
|
|
|
|
2012-07-12 23:19:10 +02:00
|
|
|
iterator insert(iterator it, DisplayAtom atom) { return m_atoms.insert(it, std::move(atom)); }
|
|
|
|
void push_back(DisplayAtom atom) { m_atoms.push_back(std::move(atom)); }
|
2011-10-15 06:45:49 +02:00
|
|
|
|
2012-10-22 13:20:02 +02:00
|
|
|
void optimize();
|
2011-09-02 18:51:20 +02:00
|
|
|
private:
|
2012-08-22 23:33:52 +02:00
|
|
|
LineCount m_buffer_line;
|
|
|
|
AtomList m_atoms;
|
2011-09-02 18:51:20 +02:00
|
|
|
};
|
|
|
|
|
2012-07-12 23:51:13 +02:00
|
|
|
using BufferRange = std::pair<BufferIterator, BufferIterator>;
|
|
|
|
|
2012-07-12 23:19:10 +02:00
|
|
|
class DisplayBuffer
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
using LineList = std::list<DisplayLine>;
|
|
|
|
DisplayBuffer() {}
|
|
|
|
|
|
|
|
LineList& lines() { return m_lines; }
|
|
|
|
const LineList& lines() const { return m_lines; }
|
2012-07-12 23:51:13 +02:00
|
|
|
|
|
|
|
// returns the smallest BufferIterator range which contains every DisplayAtoms
|
|
|
|
const BufferRange& range() const { return m_range; }
|
2012-10-22 13:20:02 +02:00
|
|
|
void optimize();
|
2012-07-12 23:51:13 +02:00
|
|
|
void compute_range();
|
|
|
|
|
2012-07-12 23:19:10 +02:00
|
|
|
private:
|
|
|
|
LineList m_lines;
|
2012-07-12 23:51:13 +02:00
|
|
|
BufferRange m_range;
|
2012-07-12 23:19:10 +02:00
|
|
|
};
|
|
|
|
|
2011-09-02 18:51:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif // display_buffer_hh_INCLUDED
|