make display buffers and highlighters handle better longer than display lines
still work in progress, I think the whole display system will in fact need a rewrite.
This commit is contained in:
parent
d092afead9
commit
5cbded8221
|
@ -95,10 +95,20 @@ DisplayBuffer::DisplayBuffer()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
DisplayBuffer::iterator DisplayBuffer::insert(iterator where, const DisplayAtom& atom)
|
DisplayBuffer::iterator DisplayBuffer::append(BufferIterator begin, BufferIterator end)
|
||||||
{
|
{
|
||||||
iterator res = m_atoms.insert(where, atom);
|
DisplayCoord coord;
|
||||||
// check_invariant();
|
if (not m_atoms.empty())
|
||||||
|
coord = m_atoms.back().end_coord();
|
||||||
|
m_atoms.push_back(DisplayAtom(std::move(coord), std::move(begin), std::move(end)));
|
||||||
|
return --(this->end());
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayBuffer::iterator DisplayBuffer::insert_empty_atom_before(iterator where)
|
||||||
|
{
|
||||||
|
assert(where != end());
|
||||||
|
iterator res = m_atoms.insert(
|
||||||
|
where, DisplayAtom(where->coord(), where->begin(), where->begin()));
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,6 +134,7 @@ DisplayBuffer::iterator DisplayBuffer::atom_containing(const BufferIterator& whe
|
||||||
|
|
||||||
DisplayBuffer::iterator DisplayBuffer::split(iterator atom, const BufferIterator& pos)
|
DisplayBuffer::iterator DisplayBuffer::split(iterator atom, const BufferIterator& pos)
|
||||||
{
|
{
|
||||||
|
assert(atom->splitable());
|
||||||
assert(pos > atom->begin());
|
assert(pos > atom->begin());
|
||||||
assert(pos < atom->end());
|
assert(pos < atom->end());
|
||||||
|
|
||||||
|
@ -136,7 +147,7 @@ DisplayBuffer::iterator DisplayBuffer::split(iterator atom, const BufferIterator
|
||||||
iterator insert_pos = atom;
|
iterator insert_pos = atom;
|
||||||
++insert_pos;
|
++insert_pos;
|
||||||
m_atoms.insert(insert_pos, std::move(new_atom));
|
m_atoms.insert(insert_pos, std::move(new_atom));
|
||||||
// check_invariant();
|
check_invariant();
|
||||||
return atom;
|
return atom;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,7 +158,10 @@ void DisplayBuffer::check_invariant() const
|
||||||
{
|
{
|
||||||
assert(it->end() >= it->begin());
|
assert(it->end() >= it->begin());
|
||||||
if (it != begin())
|
if (it != begin())
|
||||||
|
{
|
||||||
assert(prev_it->end() == it->begin());
|
assert(prev_it->end() == it->begin());
|
||||||
|
assert(prev_it->end_coord() == it->coord());
|
||||||
|
}
|
||||||
prev_it = it;
|
prev_it = it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,19 +52,6 @@ enum class Color
|
||||||
// text stored in the replacement_string field.
|
// text stored in the replacement_string field.
|
||||||
struct DisplayAtom
|
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_content_mode(BufferText),
|
|
||||||
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 DisplayCoord& coord() const { return m_coord; }
|
||||||
const BufferIterator& begin() const { return m_begin; }
|
const BufferIterator& begin() const { return m_begin; }
|
||||||
const BufferIterator& end() const { return m_end; }
|
const BufferIterator& end() const { return m_end; }
|
||||||
|
@ -72,6 +59,12 @@ struct DisplayAtom
|
||||||
const Color& bg_color() const { return m_bg_color; }
|
const Color& bg_color() const { return m_bg_color; }
|
||||||
const Attribute& attribute() const { return m_attribute; }
|
const Attribute& attribute() const { return m_attribute; }
|
||||||
|
|
||||||
|
enum ContentMode
|
||||||
|
{
|
||||||
|
BufferText,
|
||||||
|
ReplacementText
|
||||||
|
};
|
||||||
|
ContentMode content_mode() const { return m_content_mode; }
|
||||||
|
|
||||||
Color& fg_color() { return m_fg_color; }
|
Color& fg_color() { return m_fg_color; }
|
||||||
Color& bg_color() { return m_bg_color; }
|
Color& bg_color() { return m_bg_color; }
|
||||||
|
@ -82,16 +75,23 @@ struct DisplayAtom
|
||||||
BufferIterator iterator_at(const DisplayCoord& coord) const;
|
BufferIterator iterator_at(const DisplayCoord& coord) const;
|
||||||
DisplayCoord line_and_column_at(const BufferIterator& iterator) const;
|
DisplayCoord line_and_column_at(const BufferIterator& iterator) const;
|
||||||
|
|
||||||
bool splitable() const { return m_replacement_text.empty(); }
|
bool splitable() const { return m_content_mode != ReplacementText; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class DisplayBuffer;
|
friend class DisplayBuffer;
|
||||||
|
DisplayAtom(DisplayCoord coord,
|
||||||
|
BufferIterator begin, BufferIterator end,
|
||||||
|
Color fg_color = Color::Default,
|
||||||
|
Color bg_color = Color::Default,
|
||||||
|
Attribute attribute = Attributes::Normal)
|
||||||
|
: m_content_mode(BufferText),
|
||||||
|
m_coord(std::move(coord)),
|
||||||
|
m_begin(std::move(begin)), m_end(std::move(end)),
|
||||||
|
m_fg_color(fg_color),
|
||||||
|
m_bg_color(bg_color),
|
||||||
|
m_attribute(attribute)
|
||||||
|
{}
|
||||||
|
|
||||||
enum ContentMode
|
|
||||||
{
|
|
||||||
BufferText,
|
|
||||||
ReplacementText
|
|
||||||
};
|
|
||||||
ContentMode m_content_mode;
|
ContentMode m_content_mode;
|
||||||
|
|
||||||
DisplayCoord m_coord;
|
DisplayCoord m_coord;
|
||||||
|
@ -117,8 +117,8 @@ public:
|
||||||
DisplayBuffer();
|
DisplayBuffer();
|
||||||
|
|
||||||
void clear() { m_atoms.clear(); }
|
void clear() { m_atoms.clear(); }
|
||||||
void append(const DisplayAtom& atom) { m_atoms.push_back(atom); }
|
iterator append(BufferIterator begin, BufferIterator end);
|
||||||
iterator insert(iterator where, const DisplayAtom& atom);
|
iterator insert_empty_atom_before(iterator where);
|
||||||
iterator split(iterator atom, const BufferIterator& pos);
|
iterator split(iterator atom, const BufferIterator& pos);
|
||||||
|
|
||||||
void replace_atom_content(iterator atom, const String& replacement);
|
void replace_atom_content(iterator atom, const String& replacement);
|
||||||
|
|
|
@ -43,15 +43,18 @@ void colorize_regex_range(DisplayBuffer& display_buffer,
|
||||||
auto begin_atom_it = display_buffer.atom_containing(begin, atom_it);
|
auto begin_atom_it = display_buffer.atom_containing(begin, atom_it);
|
||||||
assert(begin_atom_it != display_buffer.end());
|
assert(begin_atom_it != display_buffer.end());
|
||||||
if (begin_atom_it->begin() != begin)
|
if (begin_atom_it->begin() != begin)
|
||||||
begin_atom_it = ++display_buffer.split(begin_atom_it, begin);
|
{
|
||||||
|
if (begin_atom_it->splitable())
|
||||||
|
begin_atom_it = ++display_buffer.split(begin_atom_it, begin);
|
||||||
|
else
|
||||||
|
++begin_atom_it;
|
||||||
|
}
|
||||||
|
|
||||||
auto end_atom_it = display_buffer.atom_containing(end, begin_atom_it);
|
auto end_atom_it = display_buffer.atom_containing(end, begin_atom_it);
|
||||||
if (end_atom_it != display_buffer.end() and
|
if (end_atom_it != display_buffer.end() and
|
||||||
end_atom_it->begin() != end)
|
end_atom_it->begin() != end and end_atom_it->splitable())
|
||||||
end_atom_it = ++display_buffer.split(end_atom_it, end);
|
end_atom_it = ++display_buffer.split(end_atom_it, end);
|
||||||
|
|
||||||
assert(begin_atom_it != end_atom_it);
|
|
||||||
|
|
||||||
for (auto it = begin_atom_it; it != end_atom_it; ++it)
|
for (auto it = begin_atom_it; it != end_atom_it; ++it)
|
||||||
{
|
{
|
||||||
if (it->attribute() & Attributes::Final)
|
if (it->attribute() & Attributes::Final)
|
||||||
|
@ -169,12 +172,10 @@ void show_line_numbers(DisplayBuffer& display_buffer)
|
||||||
|
|
||||||
atom_it = ++display_buffer.split(atom_it, line_start);
|
atom_it = ++display_buffer.split(atom_it, line_start);
|
||||||
}
|
}
|
||||||
atom_it = display_buffer.insert(
|
atom_it = display_buffer.insert_empty_atom_before(atom_it);
|
||||||
atom_it,
|
atom_it->fg_color() = Color::Black;
|
||||||
DisplayAtom(atom_it->coord(),
|
atom_it->bg_color() = Color::White;
|
||||||
atom_it->begin(), atom_it->begin(),
|
atom_it->attribute() = Attributes::Final;
|
||||||
Color::Black, Color::White,
|
|
||||||
Attributes::Final));
|
|
||||||
|
|
||||||
char buffer[10];
|
char buffer[10];
|
||||||
snprintf(buffer, 10, format, coord.line + 1);
|
snprintf(buffer, 10, format, coord.line + 1);
|
||||||
|
@ -257,7 +258,7 @@ void highlight_selections(Window& window, DisplayBuffer& display_buffer)
|
||||||
const BufferIterator& last = sel.last();
|
const BufferIterator& last = sel.last();
|
||||||
|
|
||||||
DisplayBuffer::iterator atom_it = display_buffer.atom_containing(last);
|
DisplayBuffer::iterator atom_it = display_buffer.atom_containing(last);
|
||||||
if (atom_it == display_buffer.end())
|
if (atom_it == display_buffer.end() or not atom_it->splitable())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (atom_it->begin() < last)
|
if (atom_it->begin() < last)
|
||||||
|
|
|
@ -83,13 +83,22 @@ void Window::update_display_buffer()
|
||||||
|
|
||||||
m_display_buffer.clear();
|
m_display_buffer.clear();
|
||||||
|
|
||||||
BufferIterator begin = buffer().iterator_at(m_position);
|
for (auto line = 0; line < m_dimensions.line; ++line)
|
||||||
BufferIterator end = buffer().iterator_at(m_position +
|
{
|
||||||
BufferCoord(m_dimensions.line, m_dimensions.column))+2;
|
auto buffer_line = m_position.line + line;
|
||||||
if (begin == end)
|
if (buffer_line >= buffer().line_count())
|
||||||
return;
|
break;
|
||||||
|
BufferIterator pos = buffer().iterator_at({ buffer_line, m_position.column });
|
||||||
|
BufferIterator line_begin = buffer().iterator_at_line_begin(pos);
|
||||||
|
BufferIterator line_end = buffer().iterator_at_line_end(pos);
|
||||||
|
|
||||||
m_display_buffer.append(DisplayAtom(DisplayCoord(0,0), begin, end));
|
if (line_begin != pos)
|
||||||
|
{
|
||||||
|
auto atom_it = m_display_buffer.append(line_begin, pos);
|
||||||
|
m_display_buffer.replace_atom_content(atom_it, "");
|
||||||
|
}
|
||||||
|
m_display_buffer.append(pos, line_end);
|
||||||
|
}
|
||||||
|
|
||||||
m_highlighters(m_display_buffer);
|
m_highlighters(m_display_buffer);
|
||||||
m_display_buffer.check_invariant();
|
m_display_buffer.check_invariant();
|
||||||
|
@ -141,5 +150,4 @@ void Window::on_option_changed(const String& name, const Option& option)
|
||||||
m_hook_manager.run_hook("WinSetOption", desc, Context(*this));
|
m_hook_manager.run_hook("WinSetOption", desc, Context(*this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user