summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2011-09-28 20:54:11 +0000
committerMaxime Coste <frrrwww@gmail.com>2011-09-28 20:54:11 +0000
commitba2800ddacf69f3f9cc8389b1f1aa415cdd3fac1 (patch)
tree784dcba32110ed847fe9291dea8da04aed134a7b /src
parent7746c78cccef6cb35e193c85182a496b33bb0c7a (diff)
Window: refactor DisplayBuffer generation
Diffstat (limited to 'src')
-rw-r--r--src/display_buffer.hh23
-rw-r--r--src/window.cc120
-rw-r--r--src/window.hh5
3 files changed, 112 insertions, 36 deletions
diff --git a/src/display_buffer.hh b/src/display_buffer.hh
index fd609134..d1a1eebb 100644
--- a/src/display_buffer.hh
+++ b/src/display_buffer.hh
@@ -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(); }
diff --git a/src/window.cc b/src/window.cc
index 33042a72..314a31c7 100644
--- a/src/window.cc
+++ b/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;
-
- std::sort(sorted_selections.begin(), sorted_selections.end(),
- [](const Selection& lhs, const Selection& rhs) { return lhs.begin() < rhs.begin(); });
+ 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)));
- 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)
diff --git a/src/window.hh b/src/window.hh
index db244db4..cba50167 100644
--- a/src/window.hh
+++ b/src/window.hh
@@ -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