Move selection_direction_t to pager.h and make it a class enum

This commit is contained in:
ridiculousfish 2019-04-28 14:06:03 -07:00
parent 3c9f95594a
commit d8ac051f89
5 changed files with 93 additions and 93 deletions

View file

@ -137,24 +137,6 @@ enum {
};
typedef unsigned int escape_flags_t;
// Directions.
enum selection_direction_t {
// Visual directions.
direction_north,
direction_east,
direction_south,
direction_west,
direction_page_north,
direction_page_south,
// Logical directions.
direction_next,
direction_prev,
// Special value that means deselect.
direction_deselect
};
/// Issue a debug message with printf-style string formating and automatic line breaking. The string
/// will begin with the string \c program_name, followed by a colon and a whitespace.
///

View file

@ -1977,47 +1977,47 @@ static void test_pager_navigation() {
// Here are navigation directions and where we expect the selection to be.
const struct {
selection_direction_t dir;
selection_motion_t dir;
size_t sel;
} cmds[] = {
// Tab completion to get into the list.
{direction_next, 0},
{selection_motion_t::next, 0},
// Westward motion in upper left goes to the last filled column in the last row.
{direction_west, 15},
{selection_motion_t::west, 15},
// East goes back.
{direction_east, 0},
{selection_motion_t::east, 0},
// "Next" motion goes down the column.
{direction_next, 1},
{direction_next, 2},
{selection_motion_t::next, 1},
{selection_motion_t::next, 2},
{direction_west, 17},
{direction_east, 2},
{direction_east, 6},
{direction_east, 10},
{direction_east, 14},
{direction_east, 18},
{selection_motion_t::west, 17},
{selection_motion_t::east, 2},
{selection_motion_t::east, 6},
{selection_motion_t::east, 10},
{selection_motion_t::east, 14},
{selection_motion_t::east, 18},
{direction_west, 14},
{direction_east, 18},
{selection_motion_t::west, 14},
{selection_motion_t::east, 18},
// Eastward motion wraps back to the upper left, westward goes to the prior column.
{direction_east, 3},
{direction_east, 7},
{direction_east, 11},
{direction_east, 15},
{selection_motion_t::east, 3},
{selection_motion_t::east, 7},
{selection_motion_t::east, 11},
{selection_motion_t::east, 15},
// 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},
{selection_motion_t::page_north, 12},
{selection_motion_t::page_south, 15},
{selection_motion_t::page_north, 12},
{selection_motion_t::east, 16},
{selection_motion_t::page_south, 18},
{selection_motion_t::east, 3},
{selection_motion_t::north, 2},
{selection_motion_t::page_north, 0},
{selection_motion_t::page_south, 3},
};
for (size_t i = 0; i < sizeof cmds / sizeof *cmds; i++) {

View file

@ -39,24 +39,24 @@ typedef std::vector<comp_t> comp_info_list_t;
/// Text we use for the search field.
#define SEARCH_FIELD_PROMPT _(L"search: ")
inline bool selection_direction_is_cardinal(selection_direction_t dir) {
inline bool selection_direction_is_cardinal(selection_motion_t dir) {
switch (dir) {
case direction_north:
case direction_east:
case direction_south:
case direction_west:
case direction_page_north:
case direction_page_south: {
case selection_motion_t::north:
case selection_motion_t::east:
case selection_motion_t::south:
case selection_motion_t::west:
case selection_motion_t::page_north:
case selection_motion_t::page_south: {
return true;
}
case direction_next:
case direction_prev:
case direction_deselect: {
case selection_motion_t::next:
case selection_motion_t::prev:
case selection_motion_t::deselect: {
return false;
}
}
DIE("should never reach this statement");
DIE("unreachable");
}
/// Returns numer / denom, rounding up. As a "courtesy" 0/0 is 0.
@ -601,7 +601,7 @@ pager_t::pager_t()
bool pager_t::empty() const { return unfiltered_completion_infos.empty(); }
bool pager_t::select_next_completion_in_direction(selection_direction_t direction,
bool pager_t::select_next_completion_in_direction(selection_motion_t direction,
const page_rendering_t &rendering) {
// Must have something to select.
if (this->completion_infos.empty()) {
@ -611,24 +611,24 @@ bool pager_t::select_next_completion_in_direction(selection_direction_t directio
// Handle the case of nothing selected yet.
if (selected_completion_idx == PAGER_SELECTION_NONE) {
switch (direction) {
case direction_south:
case direction_page_south:
case direction_next:
case direction_north:
case direction_prev: {
case selection_motion_t::south:
case selection_motion_t::page_south:
case selection_motion_t::next:
case selection_motion_t::north:
case selection_motion_t::prev: {
// These directions do something sane.
if (direction == direction_prev
|| direction == direction_north) {
if (direction == selection_motion_t::prev ||
direction == selection_motion_t::north) {
selected_completion_idx = completion_infos.size() - 1;
} else {
selected_completion_idx = 0;
}
return true;
}
case direction_page_north:
case direction_east:
case direction_west:
case direction_deselect: {
case selection_motion_t::page_north:
case selection_motion_t::east:
case selection_motion_t::west:
case selection_motion_t::deselect: {
// These do nothing.
return false;
}
@ -639,14 +639,14 @@ bool pager_t::select_next_completion_in_direction(selection_direction_t directio
size_t new_selected_completion_idx;
if (!selection_direction_is_cardinal(direction)) {
// Next, previous, or deselect, all easy.
if (direction == direction_deselect) {
if (direction == selection_motion_t::deselect) {
new_selected_completion_idx = PAGER_SELECTION_NONE;
} else if (direction == direction_next) {
} else if (direction == selection_motion_t::next) {
new_selected_completion_idx = selected_completion_idx + 1;
if (new_selected_completion_idx >= completion_infos.size()) {
new_selected_completion_idx = 0;
}
} else if (direction == direction_prev) {
} else if (direction == selection_motion_t::prev) {
if (selected_completion_idx == 0) {
new_selected_completion_idx = completion_infos.size() - 1;
} else {
@ -662,7 +662,7 @@ bool pager_t::select_next_completion_in_direction(selection_direction_t directio
size_t page_height = std::max(rendering.term_height - 1, (size_t)1);
switch (direction) {
case direction_page_north: {
case selection_motion_t::page_north: {
if (current_row > page_height) {
current_row = current_row - page_height;
} else {
@ -670,7 +670,7 @@ bool pager_t::select_next_completion_in_direction(selection_direction_t directio
}
break;
}
case direction_north: {
case selection_motion_t::north: {
// Go up a whole row. If we cycle, go to the previous column.
if (current_row > 0) {
current_row--;
@ -684,7 +684,7 @@ bool pager_t::select_next_completion_in_direction(selection_direction_t directio
}
break;
}
case direction_page_south: {
case selection_motion_t::page_south: {
if (current_row + page_height < rendering.rows) {
current_row += page_height;
} else {
@ -695,7 +695,7 @@ bool pager_t::select_next_completion_in_direction(selection_direction_t directio
}
break;
}
case direction_south: {
case selection_motion_t::south: {
// Go down, unless we are in the last row.
// If we go over the last element, wrap to the first.
if (current_row + 1 < rendering.rows &&
@ -707,7 +707,7 @@ bool pager_t::select_next_completion_in_direction(selection_direction_t directio
}
break;
}
case direction_east: {
case selection_motion_t::east: {
// Go east, wrapping to the next row. There is no "row memory," so if we run off the
// end, wrap.
if (current_col + 1 < rendering.cols &&
@ -719,7 +719,7 @@ bool pager_t::select_next_completion_in_direction(selection_direction_t directio
}
break;
}
case direction_west: {
case selection_motion_t::west: {
// Go west, wrapping to the previous row.
if (current_col > 0) {
current_col--;

View file

@ -36,6 +36,23 @@ class page_rendering_t {
page_rendering_t();
};
enum class selection_motion_t {
// Visual directions.
north,
east,
south,
west,
page_north,
page_south,
// Logical directions.
next,
prev,
// Special value that means deselect.
deselect
};
// The space between adjacent completions.
#define PAGER_SPACER_STRING L" "
#define PAGER_SPACER_STRING_WIDTH 2
@ -136,7 +153,7 @@ class pager_t {
// Changes the selected completion in the given direction according to the layout of the given
// rendering. Returns true if the selection changed.
bool select_next_completion_in_direction(selection_direction_t direction,
bool select_next_completion_in_direction(selection_motion_t direction,
const page_rendering_t &rendering);
// Returns the currently selected completion for the given rendering.

View file

@ -447,7 +447,7 @@ class reader_data_t : public std::enable_shared_from_this<reader_data_t> {
void handle_readline_command(readline_cmd_t cmd, readline_loop_state_t &rls);
void clear_pager();
void select_completion_in_direction(enum selection_direction_t dir);
void select_completion_in_direction(selection_motion_t dir);
void flash();
void mark_repaint_needed() { repaint_needed = true; }
@ -1410,7 +1410,7 @@ void reader_data_t::clear_pager() {
mark_repaint_needed();
}
void reader_data_t::select_completion_in_direction(enum selection_direction_t dir) {
void reader_data_t::select_completion_in_direction(selection_motion_t dir) {
bool selection_changed = pager.select_next_completion_in_direction(dir, current_page_rendering);
if (selection_changed) {
pager_selection_changed();
@ -2535,8 +2535,8 @@ void reader_data_t::handle_readline_command(readline_cmd_t c, readline_loop_stat
pager.set_fully_disclosed(true);
reader_repaint_needed();
} else {
select_completion_in_direction(c == rl::complete ? direction_next
: direction_prev);
select_completion_in_direction(c == rl::complete ? selection_motion_t::next
: selection_motion_t::prev);
}
} else {
// Either the user hit tab only once, or we had no visible completion list.
@ -2601,7 +2601,7 @@ void reader_data_t::handle_readline_command(readline_cmd_t c, readline_loop_stat
// Show the search field if requested and if we printed a list of completions.
if (c == rl::complete_AND_SEARCH && !rls.comp_empty && !pager.empty()) {
pager.set_search_field_shown(true);
select_completion_in_direction(direction_next);
select_completion_in_direction(selection_motion_t::next);
reader_repaint_needed();
}
}
@ -2614,7 +2614,7 @@ void reader_data_t::handle_readline_command(readline_cmd_t c, readline_loop_stat
pager.set_search_field_shown(!sfs);
pager.set_fully_disclosed(true);
if (pager.is_search_field_shown() && !is_navigating_pager_contents()) {
select_completion_in_direction(direction_south);
select_completion_in_direction(selection_motion_t::south);
}
reader_repaint_needed();
}
@ -2848,7 +2848,7 @@ void reader_data_t::handle_readline_command(readline_cmd_t c, readline_loop_stat
case rl::backward_char: {
editable_line_t *el = active_edit_line();
if (is_navigating_pager_contents()) {
select_completion_in_direction(direction_west);
select_completion_in_direction(selection_motion_t::west);
} else if (el->position > 0) {
update_buff_pos(el, el->position - 1);
reader_repaint_needed();
@ -2858,7 +2858,7 @@ void reader_data_t::handle_readline_command(readline_cmd_t c, readline_loop_stat
case rl::forward_char: {
editable_line_t *el = active_edit_line();
if (is_navigating_pager_contents()) {
select_completion_in_direction(direction_east);
select_completion_in_direction(selection_motion_t::east);
} else if (el->position < el->size()) {
update_buff_pos(el, el->position + 1);
reader_repaint_needed();
@ -2916,7 +2916,8 @@ void reader_data_t::handle_readline_command(readline_cmd_t c, readline_loop_stat
case rl::end_of_history: {
bool up = (c == rl::beginning_of_history);
if (is_navigating_pager_contents()) {
select_completion_in_direction(up ? direction_page_north : direction_page_south);
select_completion_in_direction(up ? selection_motion_t::page_north
: selection_motion_t::page_south);
} else {
if (up) {
history_search.go_to_beginning();
@ -2931,24 +2932,24 @@ void reader_data_t::handle_readline_command(readline_cmd_t c, readline_loop_stat
case rl::down_line: {
if (is_navigating_pager_contents()) {
// We are already navigating pager contents.
selection_direction_t direction;
selection_motion_t direction;
if (c == rl::down_line) {
// Down arrow is always south.
direction = direction_south;
direction = selection_motion_t::south;
} else if (selection_is_at_top()) {
// Up arrow, but we are in the first column and first row. End navigation.
direction = direction_deselect;
direction = selection_motion_t::deselect;
} else {
// Up arrow, go north.
direction = direction_north;
direction = selection_motion_t::north;
}
// Now do the selection.
select_completion_in_direction(direction);
} else if (!pager.empty()) {
// We pressed a direction with a non-empty pager, begin navigation.
select_completion_in_direction(c == rl::down_line ? direction_south
: direction_north);
select_completion_in_direction(c == rl::down_line ? selection_motion_t::south
: selection_motion_t::north);
} else {
// Not navigating the pager contents.
editable_line_t *el = active_edit_line();