kakoune/src/display_buffer.hh

189 lines
4.9 KiB
C++
Raw Normal View History

2011-09-02 18:51:20 +02:00
#ifndef display_buffer_hh_INCLUDED
#define display_buffer_hh_INCLUDED
#include "face.hh"
#include "hash.hh"
#include "coord.hh"
#include "range.hh"
2013-04-09 20:05:40 +02:00
#include "string.hh"
2015-01-12 14:58:41 +01:00
#include "vector.hh"
#include "hash_map.hh"
2013-04-09 20:05:40 +02:00
2011-09-02 18:51:20 +02:00
namespace Kakoune
{
2014-11-12 22:27:07 +01:00
class Buffer;
using BufferRange = Range<BufferCoord>;
2014-11-12 22:27:07 +01:00
class BufferIterator;
// Return a buffer iterator to the coord, tolerating one past end of line coords
BufferIterator get_iterator(const Buffer& buffer, BufferCoord coord);
2015-01-21 14:35:46 +01:00
struct DisplayAtom : public UseMemoryDomain<MemoryDomain::Display>
2011-09-02 18:51:20 +02:00
{
public:
enum Type { Range, ReplacedRange, Text };
DisplayAtom(const Buffer& buffer, BufferCoord begin, BufferCoord end)
: m_type(Range), m_buffer(&buffer), m_range{begin, end} {}
DisplayAtom(String str, Face face)
2019-02-09 05:41:09 +01:00
: face(face), m_type(Text), m_text(std::move(str)) {}
explicit DisplayAtom(String str)
: DisplayAtom(std::move(str), Face{}) {}
2014-11-12 22:27:07 +01:00
StringView content() const;
ColumnCount length() const;
2012-09-30 16:21:20 +02:00
const BufferCoord& begin() const
{
kak_assert(has_buffer_range());
return m_range.begin;
}
const BufferCoord& end() const
{
kak_assert(has_buffer_range());
return m_range.end;
}
void replace(String text)
{
kak_assert(m_type == Range);
m_type = ReplacedRange;
m_text = std::move(text);
}
void replace(const BufferRange& range)
{
kak_assert(m_type == Text);
m_type = ReplacedRange;
m_range = range;
}
bool has_buffer_range() const
{
return m_type == Range or m_type == ReplacedRange;
}
const Buffer& buffer() const { kak_assert(m_buffer); return *m_buffer; }
Type type() const { return m_type; }
2011-10-17 21:01:04 +02:00
void trim_begin(ColumnCount count);
void trim_end(ColumnCount count);
2013-07-24 14:55:57 +02:00
bool operator==(const DisplayAtom& other) const
{
return face == other.face and type() == other.type() and
content() == other.content();
}
2013-07-24 14:55:57 +02:00
public:
Face face;
2013-07-24 14:55:57 +02:00
private:
friend class DisplayLine;
Type m_type;
const Buffer* m_buffer = nullptr;
BufferRange m_range;
String m_text;
2011-09-02 18:51:20 +02:00
};
2015-09-12 11:51:16 +02:00
using AtomList = Vector<DisplayAtom, MemoryDomain::Display>;
2015-01-21 14:35:46 +01:00
class DisplayLine : public UseMemoryDomain<MemoryDomain::Display>
{
public:
using iterator = AtomList::iterator;
using const_iterator = AtomList::const_iterator;
using value_type = AtomList::value_type;
DisplayLine() = default;
DisplayLine(AtomList atoms);
DisplayLine(String str, Face face)
{ push_back({ std::move(str), face }); }
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; }
ColumnCount length() const;
const BufferRange& range() const { return m_range; }
// Split atom pointed by it at buffer coord pos,
// returns an iterator to the first atom
iterator split(iterator it, BufferCoord pos);
// Split atom pointed by it at its pos column,
// returns an iterator to the first atom
iterator split(iterator it, ColumnCount pos);
iterator split(BufferCoord pos);
iterator insert(iterator it, DisplayAtom atom);
template<typename It>
iterator insert(iterator it, It beg, It end)
{
auto res = m_atoms.insert(it, beg, end);
compute_range();
return res;
}
iterator erase(iterator beg, iterator end);
void push_back(DisplayAtom atom);
// remove first_col from the begining of the line, and make sure
// the line is less that col_count character
bool trim(ColumnCount first_col, ColumnCount col_count);
// Merge together consecutive atoms sharing the same display attributes
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
};
using DisplayLineList = Vector<DisplayLine>;
class FaceRegistry;
DisplayLine parse_display_line(StringView line, const FaceRegistry& faces, const HashMap<String, DisplayLine>& builtins = {});
DisplayLineList parse_display_line_list(StringView content, const FaceRegistry& faces, const HashMap<String, DisplayLine>& builtins = {});
2015-01-21 14:35:46 +01:00
class DisplayBuffer : public UseMemoryDomain<MemoryDomain::Display>
{
public:
DisplayBuffer() {}
DisplayLineList& lines() { return m_lines; }
const DisplayLineList& lines() const { return m_lines; }
// returns the smallest BufferRange which contains every DisplayAtoms
const BufferRange& range() const { return m_range; }
void compute_range();
// Optimize all lines, set DisplayLine::optimize
void optimize();
void set_timestamp(size_t timestamp) { m_timestamp = timestamp; }
size_t timestamp() const { return m_timestamp; }
private:
DisplayLineList m_lines;
BufferRange m_range;
size_t m_timestamp = -1;
};
2011-09-02 18:51:20 +02:00
}
#endif // display_buffer_hh_INCLUDED