Window: selection behaviour now depends on a window state
more vi-like behaviour, hit the v key to toggle append selection mode, this means much more keys become available for mapping, as caps are now longer reserved to append mode.
This commit is contained in:
parent
309b722df9
commit
43fb64a913
45
src/main.cc
45
src/main.cc
|
@ -370,7 +370,7 @@ void do_search(Window& window)
|
||||||
else
|
else
|
||||||
RegisterManager::instance()['/'] = ex;
|
RegisterManager::instance()['/'] = ex;
|
||||||
|
|
||||||
window.select(false, RegexSelector(ex));
|
window.select(RegexSelector(ex));
|
||||||
}
|
}
|
||||||
catch (prompt_aborted&) {}
|
catch (prompt_aborted&) {}
|
||||||
}
|
}
|
||||||
|
@ -379,7 +379,7 @@ void do_search_next(Window& window)
|
||||||
{
|
{
|
||||||
std::string& ex = RegisterManager::instance()['/'];
|
std::string& ex = RegisterManager::instance()['/'];
|
||||||
if (not ex.empty())
|
if (not ex.empty())
|
||||||
window.select(false, RegexSelector(ex));
|
window.select(RegexSelector(ex));
|
||||||
else
|
else
|
||||||
print_status("no search pattern");
|
print_status("no search pattern");
|
||||||
}
|
}
|
||||||
|
@ -414,28 +414,18 @@ void do_paste(Window& window, int count)
|
||||||
|
|
||||||
std::unordered_map<char, std::function<void (Window& window, int count)>> keymap =
|
std::unordered_map<char, std::function<void (Window& window, int count)>> keymap =
|
||||||
{
|
{
|
||||||
{ 'h', [](Window& window, int count) { window.move_cursor(WindowCoord(0, -std::max(count,1))); window.empty_selections(); } },
|
{ 'h', [](Window& window, int count) { window.move_cursor(WindowCoord(0, -std::max(count,1))); } },
|
||||||
{ 'j', [](Window& window, int count) { window.move_cursor(WindowCoord( std::max(count,1), 0)); window.empty_selections(); } },
|
{ 'j', [](Window& window, int count) { window.move_cursor(WindowCoord( std::max(count,1), 0)); } },
|
||||||
{ 'k', [](Window& window, int count) { window.move_cursor(WindowCoord(-std::max(count,1), 0)); window.empty_selections(); } },
|
{ 'k', [](Window& window, int count) { window.move_cursor(WindowCoord(-std::max(count,1), 0)); } },
|
||||||
{ 'l', [](Window& window, int count) { window.move_cursor(WindowCoord(0, std::max(count,1))); window.empty_selections(); } },
|
{ 'l', [](Window& window, int count) { window.move_cursor(WindowCoord(0, std::max(count,1))); } },
|
||||||
|
|
||||||
{ 'H', [](Window& window, int count) { window.select(true, std::bind(move_select, std::ref(window), _1,
|
{ 't', [](Window& window, int count) { window.select(std::bind(select_to, _1, getch(), count, false)); } },
|
||||||
WindowCoord(0, -std::max(count,1)))); } },
|
{ 'f', [](Window& window, int count) { window.select(std::bind(select_to, _1, getch(), count, true)); } },
|
||||||
{ 'J', [](Window& window, int count) { window.select(true, std::bind(move_select, std::ref(window), _1,
|
|
||||||
WindowCoord( std::max(count,1), 0))); } },
|
|
||||||
{ 'K', [](Window& window, int count) { window.select(true, std::bind(move_select, std::ref(window), _1,
|
|
||||||
WindowCoord(-std::max(count,1), 0))); } },
|
|
||||||
{ 'L', [](Window& window, int count) { window.select(true, std::bind(move_select, std::ref(window), _1,
|
|
||||||
WindowCoord(0, std::max(count,1)))); } },
|
|
||||||
|
|
||||||
{ 't', [](Window& window, int count) { window.select(false, std::bind(select_to, _1, getch(), count, false)); } },
|
|
||||||
{ 'f', [](Window& window, int count) { window.select(false, std::bind(select_to, _1, getch(), count, true)); } },
|
|
||||||
|
|
||||||
{ 'd', do_erase },
|
{ 'd', do_erase },
|
||||||
{ 'c', do_change },
|
{ 'c', do_change },
|
||||||
{ 'i', [](Window& window, int count) { do_insert(window); } },
|
{ 'i', [](Window& window, int count) { do_insert(window); } },
|
||||||
{ 'a', [](Window& window, int count) { do_insert(window, true); } },
|
{ 'a', [](Window& window, int count) { do_insert(window, true); } },
|
||||||
{ 'o', [](Window& window, int count) { window.select(true, select_line); window.append("\n"); do_insert(window, true); } },
|
|
||||||
|
|
||||||
{ 'g', do_go },
|
{ 'g', do_go },
|
||||||
|
|
||||||
|
@ -443,20 +433,19 @@ std::unordered_map<char, std::function<void (Window& window, int count)>> keymap
|
||||||
{ 'p', do_paste<true> },
|
{ 'p', do_paste<true> },
|
||||||
{ 'P', do_paste<false> },
|
{ 'P', do_paste<false> },
|
||||||
|
|
||||||
{ '%', [](Window& window, int count) { window.select(false, [](const BufferIterator& cursor)
|
{ 'v', [](Window& window, int count) { window.set_select_mode(window.select_mode() == Window::SelectMode::Append ?
|
||||||
|
Window::SelectMode::Normal : Window::SelectMode::Append); } },
|
||||||
|
|
||||||
|
{ '%', [](Window& window, int count) { window.select([](const BufferIterator& cursor)
|
||||||
{ return Selection(cursor.buffer().begin(), cursor.buffer().end()-1); }); } },
|
{ return Selection(cursor.buffer().begin(), cursor.buffer().end()-1); }); } },
|
||||||
|
|
||||||
{ ':', [](Window& window, int count) { do_command(); } },
|
{ ':', [](Window& window, int count) { do_command(); } },
|
||||||
{ ' ', [](Window& window, int count) { window.empty_selections(); } },
|
{ ' ', [](Window& window, int count) { window.empty_selections(); } },
|
||||||
{ 'w', [](Window& window, int count) { do { window.select(false, select_to_next_word); } while(--count > 0); } },
|
{ 'w', [](Window& window, int count) { do { window.select(select_to_next_word); } while(--count > 0); } },
|
||||||
{ 'W', [](Window& window, int count) { do { window.select(true, select_to_next_word); } while(--count > 0); } },
|
{ 'e', [](Window& window, int count) { do { window.select(select_to_next_word_end); } while(--count > 0); } },
|
||||||
{ 'e', [](Window& window, int count) { do { window.select(false, select_to_next_word_end); } while(--count > 0); } },
|
{ 'b', [](Window& window, int count) { do { window.select(select_to_previous_word); } while(--count > 0); } },
|
||||||
{ 'E', [](Window& window, int count) { do { window.select(true, select_to_next_word_end); } while(--count > 0); } },
|
{ '.', [](Window& window, int count) { do { window.select(select_line); } while(--count > 0); } },
|
||||||
{ 'b', [](Window& window, int count) { do { window.select(false, select_to_previous_word); } while(--count > 0); } },
|
{ 'm', [](Window& window, int count) { window.select(select_matching); } },
|
||||||
{ 'B', [](Window& window, int count) { do { window.select(true, select_to_previous_word); } while(--count > 0); } },
|
|
||||||
{ '.', [](Window& window, int count) { do { window.select(false, select_line); } while(--count > 0); } },
|
|
||||||
{ 'm', [](Window& window, int count) { window.select(false, select_matching); } },
|
|
||||||
{ 'M', [](Window& window, int count) { window.select(true, select_matching); } },
|
|
||||||
{ '/', [](Window& window, int count) { do_search(window); } },
|
{ '/', [](Window& window, int count) { do_search(window); } },
|
||||||
{ 'n', [](Window& window, int count) { do_search_next(window); } },
|
{ 'n', [](Window& window, int count) { do_search_next(window); } },
|
||||||
{ 'u', [](Window& window, int count) { do { if (not window.undo()) { print_status("nothing left to undo"); break; } } while(--count > 0); } },
|
{ 'u', [](Window& window, int count) { do { if (not window.undo()) { print_status("nothing left to undo"); break; } } while(--count > 0); } },
|
||||||
|
|
|
@ -37,6 +37,7 @@ Window::Window(Buffer& buffer)
|
||||||
: m_buffer(buffer),
|
: m_buffer(buffer),
|
||||||
m_position(0, 0),
|
m_position(0, 0),
|
||||||
m_dimensions(0, 0),
|
m_dimensions(0, 0),
|
||||||
|
m_select_mode(SelectMode::Normal),
|
||||||
m_current_inserter(nullptr)
|
m_current_inserter(nullptr)
|
||||||
{
|
{
|
||||||
m_selections.push_back(Selection(buffer.begin(), buffer.begin()));
|
m_selections.push_back(Selection(buffer.begin(), buffer.begin()));
|
||||||
|
@ -153,11 +154,11 @@ void Window::empty_selections()
|
||||||
m_selections.push_back(std::move(sel));
|
m_selections.push_back(std::move(sel));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::select(bool append, const Selector& selector)
|
void Window::select(const Selector& selector)
|
||||||
{
|
{
|
||||||
check_invariant();
|
check_invariant();
|
||||||
|
|
||||||
if (not append)
|
if (m_select_mode == SelectMode::Normal)
|
||||||
{
|
{
|
||||||
Selection sel = selector(m_selections.back().last());
|
Selection sel = selector(m_selections.back().last());
|
||||||
m_selections.clear();
|
m_selections.clear();
|
||||||
|
@ -183,7 +184,16 @@ BufferString Window::selection_content() const
|
||||||
|
|
||||||
void Window::move_cursor(const WindowCoord& offset)
|
void Window::move_cursor(const WindowCoord& offset)
|
||||||
{
|
{
|
||||||
|
if (m_select_mode == SelectMode::Normal)
|
||||||
move_cursor_to(cursor_position() + offset);
|
move_cursor_to(cursor_position() + offset);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (auto& sel : m_selections)
|
||||||
|
{
|
||||||
|
WindowCoord pos = line_and_column_at(sel.last());
|
||||||
|
sel = Selection(sel.first(), iterator_at(pos + offset));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::move_cursor_to(const WindowCoord& new_pos)
|
void Window::move_cursor_to(const WindowCoord& new_pos)
|
||||||
|
|
|
@ -45,6 +45,13 @@ public:
|
||||||
typedef BufferString String;
|
typedef BufferString String;
|
||||||
typedef std::function<Selection (const BufferIterator&)> Selector;
|
typedef std::function<Selection (const BufferIterator&)> Selector;
|
||||||
|
|
||||||
|
enum class SelectMode
|
||||||
|
{
|
||||||
|
Normal,
|
||||||
|
Append,
|
||||||
|
LineAppend,
|
||||||
|
};
|
||||||
|
|
||||||
void erase();
|
void erase();
|
||||||
void insert(const String& string);
|
void insert(const String& string);
|
||||||
void append(const String& string);
|
void append(const String& string);
|
||||||
|
@ -64,7 +71,7 @@ public:
|
||||||
void move_cursor_to(const WindowCoord& new_pos);
|
void move_cursor_to(const WindowCoord& new_pos);
|
||||||
|
|
||||||
void empty_selections();
|
void empty_selections();
|
||||||
void select(bool append, const Selector& selector);
|
void select(const Selector& selector);
|
||||||
BufferString selection_content() const;
|
BufferString selection_content() const;
|
||||||
|
|
||||||
void set_dimensions(const WindowCoord& dimensions);
|
void set_dimensions(const WindowCoord& dimensions);
|
||||||
|
@ -76,6 +83,9 @@ public:
|
||||||
bool undo();
|
bool undo();
|
||||||
bool redo();
|
bool redo();
|
||||||
|
|
||||||
|
SelectMode select_mode() const { return m_select_mode; }
|
||||||
|
void set_select_mode(SelectMode select_mode) { m_select_mode = select_mode; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class Buffer;
|
friend class Buffer;
|
||||||
|
|
||||||
|
@ -92,6 +102,7 @@ private:
|
||||||
friend class IncrementalInserter;
|
friend class IncrementalInserter;
|
||||||
IncrementalInserter* m_current_inserter;
|
IncrementalInserter* m_current_inserter;
|
||||||
|
|
||||||
|
SelectMode m_select_mode;
|
||||||
Buffer& m_buffer;
|
Buffer& m_buffer;
|
||||||
BufferCoord m_position;
|
BufferCoord m_position;
|
||||||
WindowCoord m_dimensions;
|
WindowCoord m_dimensions;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user