diff options
-rw-r--r-- | common.h | 4 | ||||
-rw-r--r-- | fish_tests.cpp | 14 | ||||
-rw-r--r-- | pager.cpp | 26 | ||||
-rw-r--r-- | reader.cpp | 29 |
4 files changed, 62 insertions, 11 deletions
@@ -98,6 +98,8 @@ enum selection_direction_t direction_east, direction_south, direction_west, + direction_page_north, + direction_page_south, /* logical directions */ direction_next, @@ -112,7 +114,9 @@ inline bool selection_direction_is_cardinal(selection_direction_t dir) switch (dir) { case direction_north: + case direction_page_north: case direction_east: + case direction_page_south: case direction_south: case direction_west: return true; diff --git a/fish_tests.cpp b/fish_tests.cpp index 6cab5a66..c51ea8ab 100644 --- a/fish_tests.cpp +++ b/fish_tests.cpp @@ -1664,7 +1664,19 @@ static void test_pager_navigation() {direction_north, 18}, {direction_west, 14}, {direction_south, 15}, - {direction_north, 14} + {direction_north, 14}, + + /* pages */ + {direction_page_north, 12}, + {direction_page_south, 15}, + {direction_page_north, 12}, + {direction_east, 16}, + {direction_page_south, 18}, + {direction_east, 3}, + {direction_north, 2}, + {direction_page_north, 0}, + {direction_page_south, 3}, + }; for (size_t i=0; i < sizeof cmds / sizeof *cmds; i++) { @@ -684,6 +684,7 @@ bool pager_t::select_next_completion_in_direction(selection_direction_t directio { /* These directions do something sane */ case direction_south: + case direction_page_south: case direction_next: case direction_prev: if (direction == direction_prev) @@ -698,6 +699,7 @@ bool pager_t::select_next_completion_in_direction(selection_direction_t directio /* These do nothing */ case direction_north: + case direction_page_north: case direction_east: case direction_west: case direction_deselect: @@ -744,9 +746,18 @@ bool pager_t::select_next_completion_in_direction(selection_direction_t directio /* Cardinal directions. We have a completion index; we wish to compute its row and column. */ size_t current_row = this->get_selected_row(rendering); size_t current_col = this->get_selected_column(rendering); + size_t page_height = maxi(rendering.term_height - 1, 1); switch (direction) { + case direction_page_north: + { + if (current_row > page_height) + current_row = current_row - page_height; + else + current_row = 0; + break; + } case direction_north: { /* Go up a whole row. If we cycle, go to the previous column. */ @@ -763,6 +774,21 @@ bool pager_t::select_next_completion_in_direction(selection_direction_t directio break; } + case direction_page_south: + { + if (current_row + page_height < rendering.rows) + { + current_row += page_height; + } + else + { + current_row = rendering.rows - 1; + if (current_col * rendering.rows + current_row >= completion_infos.size()) { + current_row = (completion_infos.size() - 1) % rendering.rows; + } + } + break; + } case direction_south: { /* Go down, unless we are in the last row. Note that this means that we may set selected_completion_idx to an out-of-bounds value if the last row is incomplete; this is a feature (it allows "last column memory"). */ @@ -1142,8 +1142,6 @@ static bool command_ends_paging(wchar_t c, bool focused_on_search_field) /* These commands always end paging */ case R_HISTORY_SEARCH_BACKWARD: case R_HISTORY_SEARCH_FORWARD: - case R_BEGINNING_OF_HISTORY: - case R_END_OF_HISTORY: case R_HISTORY_TOKEN_SEARCH_BACKWARD: case R_HISTORY_TOKEN_SEARCH_FORWARD: case R_ACCEPT_AUTOSUGGESTION: @@ -1160,6 +1158,8 @@ static bool command_ends_paging(wchar_t c, bool focused_on_search_field) case R_NULL: case R_REPAINT: case R_SUPPRESS_AUTOSUGGESTION: + case R_BEGINNING_OF_HISTORY: + case R_END_OF_HISTORY: default: return false; @@ -3780,21 +3780,30 @@ const wchar_t *reader_readline(int nchars) case R_BEGINNING_OF_HISTORY: { - const editable_line_t *el = &data->command_line; - data->history_search = history_search_t(*data->history, el->text, HISTORY_SEARCH_TYPE_PREFIX); - data->history_search.go_to_beginning(); - if (! data->history_search.is_at_end()) + if (data->is_navigating_pager_contents()) { - wcstring new_text = data->history_search.current_string(); - set_command_line_and_position(&data->command_line, new_text, new_text.size()); + select_completion_in_direction(direction_page_north); + } else { + const editable_line_t *el = &data->command_line; + data->history_search = history_search_t(*data->history, el->text, HISTORY_SEARCH_TYPE_PREFIX); + data->history_search.go_to_beginning(); + if (! data->history_search.is_at_end()) + { + wcstring new_text = data->history_search.current_string(); + set_command_line_and_position(&data->command_line, new_text, new_text.size()); + } } - break; } case R_END_OF_HISTORY: { - data->history_search.go_to_end(); + if (data->is_navigating_pager_contents()) + { + select_completion_in_direction(direction_page_south); + } else { + data->history_search.go_to_end(); + } break; } |