From fbbe741c073e3c8c432c8d60f9c17a6ae3959d78 Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Thu, 14 Aug 2014 00:31:39 +0100 Subject: [PATCH] Add support for and for word moves in the line editor This might go away later if we find a better way of handling line edition, but seems like a good compromise for now. Fixes #168 --- src/input_handler.cc | 87 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 85 insertions(+), 2 deletions(-) diff --git a/src/input_handler.cc b/src/input_handler.cc index 1ece72b6..0402f2ea 100644 --- a/src/input_handler.cc +++ b/src/input_handler.cc @@ -143,17 +143,87 @@ private: Timer m_fs_check_timer; }; +template +void to_next_word_begin(CharCount& pos, StringView line) +{ + const CharCount len = line.char_length(); + if (pos == len) + return; + if (word_type == Word and is_punctuation(line[pos])) + { + while (pos != len and is_punctuation(line[pos])) + ++pos; + } + else if (is_word(line[pos])) + { + while (pos != len and is_word(line[pos])) + ++pos; + } + while (pos != len and is_blank(line[pos])) + ++pos; +} + +template +void to_next_word_end(CharCount& pos, StringView line) +{ + const CharCount len = line.char_length(); + if (pos + 1 >= len) + return; + ++pos; + + while (pos != len and is_blank(line[pos])) + ++pos; + + if (word_type == Word and is_punctuation(line[pos])) + { + while (pos != len and is_punctuation(line[pos])) + ++pos; + } + else if (is_word(line[pos])) + { + while (pos != len and is_word(line[pos])) + ++pos; + } + --pos; +} + +template +void to_prev_word_begin(CharCount& pos, StringView line) +{ + if (pos == 0_char) + return; + --pos; + + while (pos != 0_char and is_blank(line[pos])) + --pos; + + if (word_type == Word and is_punctuation(line[pos])) + { + while (pos != 0_char and is_punctuation(line[pos])) + --pos; + if (!is_punctuation(line[pos])) + ++pos; + } + else if (is_word(line[pos])) + { + while (pos != 0_char and is_word(line[pos])) + --pos; + if (!is_word(line[pos])) + ++pos; + } +} + class LineEditor { public: void handle_key(Key key) { - if (key == Key::Left or key == ctrl('b')) + if (key == Key::Left) { if (m_cursor_pos > 0) --m_cursor_pos; } - else if (key == Key::Right or key == ctrl('f')) + else if (key == Key::Right) { if (m_cursor_pos < m_line.char_length()) ++m_cursor_pos; @@ -178,6 +248,18 @@ public: m_line = m_line.substr(0, m_cursor_pos) + m_line.substr(m_cursor_pos+1); } + else if (key == ctrl('w')) + to_next_word_begin(m_cursor_pos, m_line); + else if (key == ctrlalt('w')) + to_next_word_begin(m_cursor_pos, m_line); + else if (key == ctrl('b')) + to_prev_word_begin(m_cursor_pos, m_line); + else if (key == ctrlalt('b')) + to_prev_word_begin(m_cursor_pos, m_line); + else if (key == ctrl('e')) + to_next_word_end(m_cursor_pos, m_line); + else if (key == ctrlalt('e')) + to_next_word_end(m_cursor_pos, m_line); else { m_line = m_line.substr(0, m_cursor_pos) + codepoint_to_str(key.key) @@ -227,6 +309,7 @@ public: private: CharCount m_cursor_pos = 0; CharCount m_display_pos = 0; + String m_line; };