diff --git a/README.rst b/README.rst index 35a0149..5f7c77b 100644 --- a/README.rst +++ b/README.rst @@ -106,10 +106,14 @@ SELECTION MODE +-----------------------------------+-----------------------------------------------------------+ | ``w`` or ``shift-right`` | forward word | +-----------------------------------+-----------------------------------------------------------+ +| ``e`` | forward to end of word | ++-----------------------------------+-----------------------------------------------------------+ | ``b`` or ``shift-left`` | backward word | +-----------------------------------+-----------------------------------------------------------+ | ``W`` or ``ctrl-right`` | forward WORD (non-whitespace) | +-----------------------------------+-----------------------------------------------------------+ +| ``E`` | forward to end of WORD (non-whitespace) | ++-----------------------------------+-----------------------------------------------------------+ | ``B`` or ``ctrl-left`` | backward WORD (non-whitespace) | +-----------------------------------+-----------------------------------------------------------+ | ``0`` or ``home`` | move cursor to the first column in the row | diff --git a/termite.cc b/termite.cc index 916228f..9abd5ff 100644 --- a/termite.cc +++ b/termite.cc @@ -675,7 +675,7 @@ static void move_to_eol(VteTerminal *vte, select_info *select) { } template -static void move_forward(VteTerminal *vte, select_info *select, F is_word) { +static void move_forward(VteTerminal *vte, select_info *select, F is_word, bool goto_word_end) { long cursor_col, cursor_row; vte_terminal_get_cursor_position(vte, &cursor_col, &cursor_row); @@ -701,15 +701,24 @@ static void move_forward(VteTerminal *vte, select_info *select, F is_word) { bool end_of_word = false; - for (long i = 1; i < length; i++) { - if (is_word(codepoints[i - 1])) { - if (end_of_word) { + if (!goto_word_end) { + for (long i = 1; i < length; i++) { + if (is_word(codepoints[i - 1])) { + if (end_of_word) { + break; + } + } else { + end_of_word = true; + } + cursor_col++; + } + } else { + for (long i = 2; i <= length; i++) { + cursor_col++; + if (is_word(codepoints[i - 1]) && !is_word(codepoints[i])) { break; } - } else { - end_of_word = true; } - cursor_col++; } vte_terminal_set_cursor_position(vte, cursor_col, cursor_row); update_selection(vte, select); @@ -717,12 +726,20 @@ static void move_forward(VteTerminal *vte, select_info *select, F is_word) { g_free(codepoints); } +static void move_forward_end_word(VteTerminal *vte, select_info *select) { + move_forward(vte, select, is_word_char, true); +} + +static void move_forward_end_blank_word(VteTerminal *vte, select_info *select) { + move_forward(vte, select, std::not1(std::ref(g_unichar_isspace)), true); +} + static void move_forward_word(VteTerminal *vte, select_info *select) { - move_forward(vte, select, is_word_char); + move_forward(vte, select, is_word_char, false); } static void move_forward_blank_word(VteTerminal *vte, select_info *select) { - move_forward(vte, select, std::not1(std::ref(g_unichar_isspace))); + move_forward(vte, select, std::not1(std::ref(g_unichar_isspace)), false); } /* {{{ CALLBACKS */ @@ -853,6 +870,12 @@ gboolean key_press_cb(VteTerminal *vte, GdkEventKey *event, keybind_info *info) case GDK_KEY_W: move_forward_blank_word(vte, &info->select); break; + case GDK_KEY_e: + move_forward_end_word(vte, &info->select); + break; + case GDK_KEY_E: + move_forward_end_blank_word(vte, &info->select); + break; case GDK_KEY_0: case GDK_KEY_Home: set_cursor_column(vte, &info->select, 0);