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:
Maxime Coste 2011-09-28 14:23:43 +00:00
parent 309b722df9
commit 43fb64a913
3 changed files with 42 additions and 32 deletions

View File

@ -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); } },

View File

@ -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)

View File

@ -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;