Window: add a IncrementalInserter class for insert mode
This commit is contained in:
parent
2f093d78b5
commit
9da8fbe630
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue
Block a user