2011-09-02 18:51:20 +02:00
|
|
|
#ifndef display_buffer_hh_INCLUDED
|
|
|
|
#define display_buffer_hh_INCLUDED
|
|
|
|
|
2014-07-11 01:27:04 +02:00
|
|
|
#include "face.hh"
|
2015-04-23 22:38:45 +02:00
|
|
|
#include "hash.hh"
|
2014-05-07 20:51:01 +02:00
|
|
|
#include "coord.hh"
|
2018-10-21 03:10:21 +02:00
|
|
|
#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"
|
2017-03-10 10:06:37 +01:00
|
|
|
#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;
|
2018-10-21 03:10:21 +02:00
|
|
|
using BufferRange = Range<BufferCoord>;
|
2014-11-12 22:27:07 +01:00
|
|
|
|
2017-06-15 19:12:21 +02: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
|
|
|
{
|
2012-07-12 23:19:10 +02:00
|
|
|
public:
|
2016-10-13 20:55:15 +02:00
|
|
|
enum Type { Range, ReplacedRange, Text };
|
2012-07-12 23:19:10 +02:00
|
|
|
|
2016-09-22 21:36:26 +02:00
|
|
|
DisplayAtom(const Buffer& buffer, BufferCoord begin, BufferCoord end)
|
2017-06-09 14:22:32 +02:00
|
|
|
: m_type(Range), m_buffer(&buffer), m_range{begin, end} {}
|
2012-07-12 23:19:10 +02:00
|
|
|
|
2018-04-29 12:33:47 +02:00
|
|
|
DisplayAtom(String str, Face face)
|
2019-02-09 05:41:09 +01:00
|
|
|
: face(face), m_type(Text), m_text(std::move(str)) {}
|
2012-07-12 23:19:10 +02:00
|
|
|
|
2019-09-17 11:06:49 +02:00
|
|
|
explicit DisplayAtom(String str)
|
|
|
|
: DisplayAtom(std::move(str), Face{}) {}
|
|
|
|
|
2014-11-12 22:27:07 +01:00
|
|
|
StringView content() const;
|
2016-09-22 21:36:26 +02:00
|
|
|
ColumnCount length() const;
|
2012-09-30 16:21:20 +02:00
|
|
|
|
2016-09-22 21:36:26 +02:00
|
|
|
const BufferCoord& begin() const
|
2012-07-03 23:23:07 +02:00
|
|
|
{
|
2013-04-09 20:04:11 +02:00
|
|
|
kak_assert(has_buffer_range());
|
2015-04-23 22:38:45 +02:00
|
|
|
return m_range.begin;
|
2012-07-12 23:19:10 +02:00
|
|
|
}
|
2011-10-15 06:45:49 +02:00
|
|
|
|
2016-09-22 21:36:26 +02:00
|
|
|
const BufferCoord& end() const
|
2012-07-12 23:19:10 +02:00
|
|
|
{
|
2013-04-09 20:04:11 +02:00
|
|
|
kak_assert(has_buffer_range());
|
2015-04-23 22:38:45 +02:00
|
|
|
return m_range.end;
|
2012-07-12 23:19:10 +02:00
|
|
|
}
|
2011-10-15 06:45:49 +02:00
|
|
|
|
2012-07-12 23:19:10 +02:00
|
|
|
void replace(String text)
|
|
|
|
{
|
2016-10-13 20:55:15 +02:00
|
|
|
kak_assert(m_type == Range);
|
|
|
|
m_type = ReplacedRange;
|
2012-07-12 23:19:10 +02:00
|
|
|
m_text = std::move(text);
|
|
|
|
}
|
|
|
|
|
2020-04-26 11:27:44 +02:00
|
|
|
void replace(const BufferRange& range)
|
|
|
|
{
|
|
|
|
kak_assert(m_type == Text);
|
|
|
|
m_type = ReplacedRange;
|
|
|
|
m_range = range;
|
|
|
|
}
|
|
|
|
|
2012-07-12 23:19:10 +02:00
|
|
|
bool has_buffer_range() const
|
|
|
|
{
|
2016-10-13 20:55:15 +02:00
|
|
|
return m_type == Range or m_type == ReplacedRange;
|
2012-07-12 23:19:10 +02:00
|
|
|
}
|
2011-10-15 06:45:49 +02:00
|
|
|
|
2014-01-21 19:52:51 +01:00
|
|
|
const Buffer& buffer() const { kak_assert(m_buffer); return *m_buffer; }
|
|
|
|
|
2012-07-12 23:19:10 +02:00
|
|
|
Type type() const { return m_type; }
|
2011-10-17 21:01:04 +02:00
|
|
|
|
2016-09-22 21:36:26 +02:00
|
|
|
void trim_begin(ColumnCount count);
|
|
|
|
void trim_end(ColumnCount count);
|
2013-07-24 14:55:57 +02:00
|
|
|
|
2014-07-07 21:13:08 +02:00
|
|
|
bool operator==(const DisplayAtom& other) const
|
|
|
|
{
|
2015-04-23 22:38:45 +02:00
|
|
|
return face == other.face and type() == other.type() and
|
|
|
|
content() == other.content();
|
2014-07-07 21:13:08 +02:00
|
|
|
}
|
|
|
|
|
2013-07-24 14:55:57 +02:00
|
|
|
public:
|
2014-07-11 01:27:04 +02:00
|
|
|
Face face;
|
2013-07-24 14:55:57 +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;
|
|
|
|
|
2013-05-22 19:53:17 +02:00
|
|
|
const Buffer* m_buffer = nullptr;
|
2016-10-13 20:55:15 +02:00
|
|
|
BufferRange m_range;
|
2012-07-12 23:19:10 +02:00
|
|
|
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>;
|
2013-07-23 20:11:26 +02:00
|
|
|
|
2015-01-21 14:35:46 +01:00
|
|
|
class DisplayLine : public UseMemoryDomain<MemoryDomain::Display>
|
2012-07-12 23:19:10 +02:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
using iterator = AtomList::iterator;
|
|
|
|
using const_iterator = AtomList::const_iterator;
|
2013-12-11 22:38:43 +01:00
|
|
|
using value_type = AtomList::value_type;
|
2012-07-12 23:19:10 +02:00
|
|
|
|
2013-07-23 20:11:26 +02:00
|
|
|
DisplayLine() = default;
|
|
|
|
DisplayLine(AtomList atoms);
|
2018-04-29 12:33:47 +02:00
|
|
|
DisplayLine(String str, Face face)
|
2014-07-11 01:27:04 +02:00
|
|
|
{ push_back({ std::move(str), face }); }
|
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-10-23 22:55:44 +02:00
|
|
|
const AtomList& atoms() const { return m_atoms; }
|
|
|
|
|
2016-09-22 21:36:26 +02:00
|
|
|
ColumnCount length() const;
|
2013-07-23 20:11:26 +02:00
|
|
|
const BufferRange& range() const { return m_range; }
|
2013-04-04 18:50:00 +02:00
|
|
|
|
2015-07-23 14:58:23 +02:00
|
|
|
// Split atom pointed by it at buffer coord pos,
|
|
|
|
// returns an iterator to the first atom
|
2016-09-22 21:36:26 +02:00
|
|
|
iterator split(iterator it, BufferCoord pos);
|
2015-07-23 14:58:23 +02:00
|
|
|
|
2016-09-22 21:36:26 +02:00
|
|
|
// Split atom pointed by it at its pos column,
|
2015-07-23 14:58:23 +02:00
|
|
|
// returns an iterator to the first atom
|
2016-09-22 21:36:26 +02:00
|
|
|
iterator split(iterator it, ColumnCount pos);
|
2011-10-17 21:00:38 +02:00
|
|
|
|
2020-04-27 05:36:12 +02:00
|
|
|
iterator split(BufferCoord pos);
|
|
|
|
|
2013-07-23 20:11:26 +02:00
|
|
|
iterator insert(iterator it, DisplayAtom atom);
|
2020-04-27 05:36:12 +02:00
|
|
|
|
|
|
|
template<typename It>
|
|
|
|
iterator insert(iterator it, It beg, It end)
|
|
|
|
{
|
|
|
|
auto res = m_atoms.insert(it, beg, end);
|
|
|
|
compute_range();
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2013-12-11 22:38:43 +01:00
|
|
|
iterator erase(iterator beg, iterator end);
|
2020-04-27 05:36:12 +02:00
|
|
|
void push_back(DisplayAtom atom);
|
2011-10-15 06:45:49 +02:00
|
|
|
|
2016-09-22 21:36:26 +02:00
|
|
|
// remove first_col from the begining of the line, and make sure
|
|
|
|
// the line is less that col_count character
|
2019-11-24 01:39:33 +01:00
|
|
|
bool trim(ColumnCount first_col, ColumnCount col_count);
|
2013-06-28 00:03:11 +02:00
|
|
|
|
2017-05-26 09:00:15 +02:00
|
|
|
// Merge together consecutive atoms sharing the same display attributes
|
2020-04-27 05:36:12 +02:00
|
|
|
void optimize();
|
2011-09-02 18:51:20 +02:00
|
|
|
private:
|
2013-07-23 20:11:26 +02:00
|
|
|
void compute_range();
|
|
|
|
BufferRange m_range = { { INT_MAX, INT_MAX }, { INT_MIN, INT_MIN } };
|
2012-08-22 23:33:52 +02:00
|
|
|
AtomList m_atoms;
|
2011-09-02 18:51:20 +02:00
|
|
|
};
|
|
|
|
|
2019-11-22 11:48:26 +01:00
|
|
|
using DisplayLineList = Vector<DisplayLine>;
|
2018-04-07 07:36:39 +02:00
|
|
|
class FaceRegistry;
|
|
|
|
|
|
|
|
DisplayLine parse_display_line(StringView line, const FaceRegistry& faces, const HashMap<String, DisplayLine>& builtins = {});
|
2021-08-28 05:53:01 +02:00
|
|
|
DisplayLineList parse_display_line_list(StringView content, const FaceRegistry& faces, const HashMap<String, DisplayLine>& builtins = {});
|
2015-09-19 13:19:17 +02:00
|
|
|
|
2015-01-21 14:35:46 +01:00
|
|
|
class DisplayBuffer : public UseMemoryDomain<MemoryDomain::Display>
|
2012-07-12 23:19:10 +02:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
DisplayBuffer() {}
|
|
|
|
|
2019-11-22 11:48:26 +01:00
|
|
|
DisplayLineList& lines() { return m_lines; }
|
|
|
|
const DisplayLineList& lines() const { return m_lines; }
|
2012-07-12 23:51:13 +02:00
|
|
|
|
2013-05-23 13:59:33 +02:00
|
|
|
// returns the smallest BufferRange which contains every DisplayAtoms
|
2012-07-12 23:51:13 +02:00
|
|
|
const BufferRange& range() const { return m_range; }
|
|
|
|
void compute_range();
|
|
|
|
|
2017-05-26 09:00:15 +02:00
|
|
|
// Optimize all lines, set DisplayLine::optimize
|
|
|
|
void optimize();
|
|
|
|
|
2018-05-08 13:55:15 +02:00
|
|
|
void set_timestamp(size_t timestamp) { m_timestamp = timestamp; }
|
|
|
|
size_t timestamp() const { return m_timestamp; }
|
|
|
|
|
2012-07-12 23:19:10 +02:00
|
|
|
private:
|
2019-11-22 11:48:26 +01:00
|
|
|
DisplayLineList m_lines;
|
2012-07-12 23:51:13 +02:00
|
|
|
BufferRange m_range;
|
2018-06-11 06:44:58 +02:00
|
|
|
size_t m_timestamp = -1;
|
2012-07-12 23:19:10 +02:00
|
|
|
};
|
|
|
|
|
2011-09-02 18:51:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif // display_buffer_hh_INCLUDED
|