Window: refactor DisplayBuffer generation
This commit is contained in:
parent
7746c78ccc
commit
ba2800ddac
|
@ -4,6 +4,8 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "buffer.hh"
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
||||
|
@ -33,13 +35,19 @@ enum class Color
|
|||
|
||||
struct DisplayAtom
|
||||
{
|
||||
std::string content;
|
||||
Color fg_color;
|
||||
Color bg_color;
|
||||
Attribute attribute;
|
||||
std::string content;
|
||||
BufferIterator begin;
|
||||
BufferIterator end;
|
||||
Color fg_color;
|
||||
Color bg_color;
|
||||
Attribute attribute;
|
||||
|
||||
DisplayAtom()
|
||||
: fg_color(Color::Default),
|
||||
DisplayAtom(BufferIterator begin, BufferIterator end,
|
||||
const std::string& content)
|
||||
: content(content),
|
||||
begin(begin),
|
||||
end(end),
|
||||
fg_color(Color::Default),
|
||||
bg_color(Color::Default),
|
||||
attribute(Attributes::Normal)
|
||||
{}
|
||||
|
@ -48,7 +56,7 @@ struct DisplayAtom
|
|||
class DisplayBuffer
|
||||
{
|
||||
public:
|
||||
typedef std::vector<DisplayAtom> AtomList;
|
||||
typedef std::vector<DisplayAtom> AtomList;
|
||||
typedef AtomList::iterator iterator;
|
||||
typedef AtomList::const_iterator const_iterator;
|
||||
|
||||
|
@ -56,6 +64,7 @@ public:
|
|||
|
||||
void clear() { m_atoms.clear(); }
|
||||
void append(const DisplayAtom& atom) { m_atoms.push_back(atom); }
|
||||
iterator insert(iterator where, const DisplayAtom& atom) { return m_atoms.insert(where, atom); }
|
||||
|
||||
iterator begin() { return m_atoms.begin(); }
|
||||
iterator end() { return m_atoms.end(); }
|
||||
|
|
120
src/window.cc
120
src/window.cc
|
@ -33,6 +33,90 @@ private:
|
|||
Buffer& m_buffer;
|
||||
};
|
||||
|
||||
class HighlightSelections
|
||||
{
|
||||
public:
|
||||
HighlightSelections(Window& window)
|
||||
: m_window(window)
|
||||
{
|
||||
}
|
||||
|
||||
void operator()(DisplayBuffer& display_buffer)
|
||||
{
|
||||
SelectionList sorted_selections = m_window.m_selections;
|
||||
|
||||
std::sort(sorted_selections.begin(), sorted_selections.end(),
|
||||
[](const Selection& lhs, const Selection& rhs) { return lhs.begin() < rhs.begin(); });
|
||||
|
||||
auto atom_it = display_buffer.begin();
|
||||
auto sel_it = sorted_selections.begin();
|
||||
|
||||
while (atom_it != display_buffer.end()
|
||||
and sel_it != sorted_selections.end())
|
||||
{
|
||||
Selection& sel = *sel_it;
|
||||
DisplayAtom& atom = *atom_it;
|
||||
|
||||
// [###------]
|
||||
if (atom.begin >= sel.begin() and atom.begin < sel.end() and atom.end > sel.end())
|
||||
{
|
||||
size_t length = sel.end() - atom.begin;
|
||||
DisplayAtom selected(atom.begin, sel.end(),
|
||||
atom.content.substr(0, length));
|
||||
selected.attribute = Attributes::Underline;
|
||||
atom.content = atom.content.substr(length);
|
||||
atom.begin = sel.end();
|
||||
atom_it = display_buffer.insert(atom_it, selected) + 1;
|
||||
++sel_it;
|
||||
}
|
||||
// [---###---]
|
||||
else if (atom.begin < sel.begin() and atom.end > sel.end())
|
||||
{
|
||||
size_t prefix_length = sel.begin() - atom.begin;
|
||||
DisplayAtom prefix(atom.begin, sel.begin(),
|
||||
atom.content.substr(0, prefix_length));
|
||||
size_t sel_length = sel.end() - sel.begin();
|
||||
DisplayAtom selected(sel.begin(), sel.end(),
|
||||
atom.content.substr(prefix_length, sel_length));
|
||||
selected.attribute = Attributes::Underline;
|
||||
atom.content = atom.content.substr(prefix_length + sel_length);
|
||||
atom_it = display_buffer.insert(atom_it, selected);
|
||||
atom_it = display_buffer.insert(atom_it, prefix);
|
||||
atom_it += 2;
|
||||
++sel_it;
|
||||
}
|
||||
// [------###]
|
||||
else if (atom.begin < sel.begin() and atom.end > sel.begin())
|
||||
{
|
||||
size_t length = sel.end() - atom.begin;
|
||||
DisplayAtom prefix(atom.begin, sel.end(),
|
||||
atom.content.substr(0, length));
|
||||
atom.content = atom.content.substr(length);
|
||||
atom.begin = sel.end();
|
||||
atom.attribute = Attributes::Underline;
|
||||
atom_it = display_buffer.insert(atom_it, prefix) + 2;
|
||||
}
|
||||
// [#########]
|
||||
else if (atom.begin >= sel.begin() and atom.end <= sel.end())
|
||||
{
|
||||
atom.attribute = Attributes::Underline;
|
||||
++atom_it;
|
||||
}
|
||||
// [---------]
|
||||
else if (atom.begin >= sel.end())
|
||||
++sel_it;
|
||||
// [---------]
|
||||
else if (atom.end <= sel.begin())
|
||||
++atom_it;
|
||||
else
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
const Window& m_window;
|
||||
};
|
||||
|
||||
Window::Window(Buffer& buffer)
|
||||
: m_buffer(buffer),
|
||||
m_position(0, 0),
|
||||
|
@ -41,6 +125,7 @@ Window::Window(Buffer& buffer)
|
|||
m_current_inserter(nullptr)
|
||||
{
|
||||
m_selections.push_back(Selection(buffer.begin(), buffer.begin()));
|
||||
m_filters.push_back(HighlightSelections(*this));
|
||||
}
|
||||
|
||||
void Window::check_invariant() const
|
||||
|
@ -210,36 +295,13 @@ void Window::update_display_buffer()
|
|||
{
|
||||
m_display_buffer.clear();
|
||||
|
||||
SelectionList sorted_selections = m_selections;
|
||||
BufferIterator begin = m_buffer.iterator_at(m_position);
|
||||
BufferIterator end = m_buffer.iterator_at(m_position +
|
||||
BufferCoord(m_dimensions.line, m_dimensions.column+1));
|
||||
m_display_buffer.append(DisplayAtom(begin, end, m_buffer.string(begin, end)));
|
||||
|
||||
std::sort(sorted_selections.begin(), sorted_selections.end(),
|
||||
[](const Selection& lhs, const Selection& rhs) { return lhs.begin() < rhs.begin(); });
|
||||
|
||||
BufferIterator current_position = m_buffer.iterator_at(m_position);
|
||||
|
||||
for (Selection& sel : sorted_selections)
|
||||
{
|
||||
if (current_position != sel.begin())
|
||||
{
|
||||
DisplayAtom atom;
|
||||
atom.content = m_buffer.string(current_position, sel.begin());
|
||||
m_display_buffer.append(atom);
|
||||
}
|
||||
if (sel.begin() != sel.end())
|
||||
{
|
||||
DisplayAtom atom;
|
||||
atom.content = m_buffer.string(sel.begin(), sel.end());
|
||||
atom.attribute = Underline;
|
||||
m_display_buffer.append(atom);
|
||||
}
|
||||
current_position = sel.end();
|
||||
}
|
||||
if (current_position != m_buffer.end())
|
||||
{
|
||||
DisplayAtom atom;
|
||||
atom.content = m_buffer.string(current_position, m_buffer.end());
|
||||
m_display_buffer.append(atom);
|
||||
}
|
||||
for (auto& filter : m_filters)
|
||||
filter(m_display_buffer);
|
||||
}
|
||||
|
||||
void Window::set_dimensions(const WindowCoord& dimensions)
|
||||
|
|
|
@ -102,12 +102,17 @@ private:
|
|||
friend class IncrementalInserter;
|
||||
IncrementalInserter* m_current_inserter;
|
||||
|
||||
friend class HighlightSelections;
|
||||
|
||||
SelectMode m_select_mode;
|
||||
Buffer& m_buffer;
|
||||
BufferCoord m_position;
|
||||
WindowCoord m_dimensions;
|
||||
SelectionList m_selections;
|
||||
DisplayBuffer m_display_buffer;
|
||||
|
||||
typedef std::vector<std::function<void (DisplayBuffer&)>> FilterList;
|
||||
FilterList m_filters;
|
||||
};
|
||||
|
||||
class IncrementalInserter
|
||||
|
|
Loading…
Reference in New Issue
Block a user