Window: add a IncrementalInserter class for insert mode

This commit is contained in:
Maxime Coste 2011-09-19 21:56:29 +00:00
parent 2f093d78b5
commit 9da8fbe630
2 changed files with 88 additions and 3 deletions

View File

@ -1,5 +1,7 @@
#include "window.hh" #include "window.hh"
#include "assert.hh"
#include <algorithm> #include <algorithm>
namespace Kakoune namespace Kakoune
@ -9,7 +11,8 @@ Window::Window(Buffer& buffer)
: m_buffer(buffer), : m_buffer(buffer),
m_position(0, 0), m_position(0, 0),
m_cursor(0, 0), m_cursor(0, 0),
m_dimensions(0, 0) m_dimensions(0, 0),
m_current_inserter(nullptr)
{ {
} }
@ -215,4 +218,64 @@ void Window::scroll_to_keep_cursor_visible_ifn()
} }
} }
IncrementalInserter::IncrementalInserter(Window& window, bool append)
: m_window(window)
{
assert(not m_window.m_current_inserter);
m_window.m_current_inserter = this;
if (m_window.m_selections.empty())
{
WindowCoord pos = m_window.m_cursor;
if (append)
pos += WindowCoord(0, 1);
m_cursors.push_back(pos);
}
else
{
for (auto& sel : m_window.m_selections)
{
const BufferIterator& pos = append ? sel.end() : sel.begin();
m_cursors.push_back(m_window.line_and_column_at(pos));
}
}
m_window.m_buffer.begin_undo_group();
}
IncrementalInserter::~IncrementalInserter()
{
assert(m_window.m_current_inserter == this);
m_window.m_current_inserter = nullptr;
m_window.m_buffer.end_undo_group();
}
void IncrementalInserter::insert(const Window::String& string)
{
for (auto& cursor : m_cursors)
{
m_window.m_buffer.insert(m_window.iterator_at(cursor), string);
move_cursor(measure_string(string));
}
}
void IncrementalInserter::erase()
{
for (auto& cursor : m_cursors)
{
BufferIterator pos = m_window.iterator_at(cursor);
m_window.m_buffer.erase(pos - 1, pos);
move_cursor(WindowCoord(0, -1));
}
}
void IncrementalInserter::move_cursor(const WindowCoord& offset)
{
for (auto& cursor : m_cursors)
{
BufferCoord target = m_window.window_to_buffer(cursor + offset);
cursor = m_window.buffer_to_window(m_window.m_buffer.clamp(target));
}
}
} }

View File

@ -44,6 +44,8 @@ private:
typedef std::vector<Selection> SelectionList; typedef std::vector<Selection> SelectionList;
class IncrementalInserter;
class Window class Window
{ {
public: public:
@ -67,8 +69,6 @@ public:
void move_cursor(const WindowCoord& offset); void move_cursor(const WindowCoord& offset);
const SelectionList& selections() const { return m_selections; }
void empty_selections(); void empty_selections();
void select(bool append, const Selector& selector); void select(bool append, const Selector& selector);
@ -89,6 +89,9 @@ private:
void scroll_to_keep_cursor_visible_ifn(); void scroll_to_keep_cursor_visible_ifn();
friend class IncrementalInserter;
IncrementalInserter* m_current_inserter;
Buffer& m_buffer; Buffer& m_buffer;
BufferCoord m_position; BufferCoord m_position;
WindowCoord m_cursor; WindowCoord m_cursor;
@ -97,6 +100,25 @@ private:
DisplayBuffer m_display_buffer; DisplayBuffer m_display_buffer;
}; };
class IncrementalInserter
{
public:
typedef std::vector<WindowCoord> CursorList;
IncrementalInserter(Window& window, bool append = false);
~IncrementalInserter();
void insert(const Window::String& string);
void erase();
void move_cursor(const WindowCoord& offset);
const CursorList& cursors() const { return m_cursors; }
private:
Window& m_window;
std::vector<WindowCoord> m_cursors;
};
} }
#endif // window_hh_INCLUDED #endif // window_hh_INCLUDED