mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-27 05:13:10 +00:00
Support for correctly resizing pager contents.
This commit is contained in:
parent
d9d65577f4
commit
998ce1fe89
2 changed files with 42 additions and 47 deletions
|
@ -937,7 +937,7 @@ void pager_t::update_rendering(page_rendering_t *rendering) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pager_t::pager_t() : term_width(0), term_height(0), selected_completion_idx(-1)
|
pager_t::pager_t() : term_width(0), term_height(0), selected_completion_idx(PAGER_SELECTION_NONE)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -978,7 +978,7 @@ const completion_t *pager_t::select_next_completion_in_direction(selection_direc
|
||||||
if (direction == direction_next)
|
if (direction == direction_next)
|
||||||
{
|
{
|
||||||
new_selected_completion_idx = selected_completion_idx + 1;
|
new_selected_completion_idx = selected_completion_idx + 1;
|
||||||
if (new_selected_completion_idx > completion_infos.size())
|
if (new_selected_completion_idx >= completion_infos.size())
|
||||||
{
|
{
|
||||||
new_selected_completion_idx = 0;
|
new_selected_completion_idx = 0;
|
||||||
}
|
}
|
||||||
|
@ -1128,6 +1128,7 @@ void pager_t::clear()
|
||||||
completions.clear();
|
completions.clear();
|
||||||
completion_infos.clear();
|
completion_infos.clear();
|
||||||
prefix.clear();
|
prefix.clear();
|
||||||
|
selected_completion_idx = PAGER_SELECTION_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
page_rendering_t::page_rendering_t() : term_width(-1), term_height(-1), rows(0), cols(0), selected_completion_idx(-1)
|
page_rendering_t::page_rendering_t() : term_width(-1), term_height(-1), rows(0), cols(0), selected_completion_idx(-1)
|
||||||
|
|
84
reader.cpp
84
reader.cpp
|
@ -199,7 +199,7 @@ public:
|
||||||
wcstring autosuggestion;
|
wcstring autosuggestion;
|
||||||
|
|
||||||
/** Current pager */
|
/** Current pager */
|
||||||
pager_t current_pager;
|
pager_t pager;
|
||||||
|
|
||||||
/** Current page rendering */
|
/** Current page rendering */
|
||||||
page_rendering_t current_page_rendering;
|
page_rendering_t current_page_rendering;
|
||||||
|
@ -543,8 +543,8 @@ static void reader_repaint()
|
||||||
indents.resize(len);
|
indents.resize(len);
|
||||||
|
|
||||||
// Re-render our completions page if necessary
|
// Re-render our completions page if necessary
|
||||||
data->current_pager.set_term_size(common_get_width(), common_get_height());
|
data->pager.set_term_size(common_get_width(), common_get_height());
|
||||||
data->current_pager.update_rendering(&data->current_page_rendering);
|
data->pager.update_rendering(&data->current_page_rendering);
|
||||||
|
|
||||||
s_write(&data->screen,
|
s_write(&data->screen,
|
||||||
data->left_prompt_buff,
|
data->left_prompt_buff,
|
||||||
|
@ -1527,12 +1527,22 @@ static void accept_autosuggestion(bool full)
|
||||||
|
|
||||||
static bool is_navigating_pager_contents()
|
static bool is_navigating_pager_contents()
|
||||||
{
|
{
|
||||||
return data && data->current_pager.selected_completion(data->current_page_rendering) != NULL;
|
return data && data->pager.selected_completion(data->current_page_rendering) != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure we have no pager contents */
|
||||||
|
static void clear_pager()
|
||||||
|
{
|
||||||
|
if (data)
|
||||||
|
{
|
||||||
|
data->pager.clear();
|
||||||
|
data->current_page_rendering = page_rendering_t();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void select_completion_in_direction(enum selection_direction_t dir, const wcstring &cycle_command_line, size_t cycle_cursor_pos)
|
static void select_completion_in_direction(enum selection_direction_t dir, const wcstring &cycle_command_line, size_t cycle_cursor_pos)
|
||||||
{
|
{
|
||||||
const completion_t *next_comp = data->current_pager.select_next_completion_in_direction(dir, data->current_page_rendering);
|
const completion_t *next_comp = data->pager.select_next_completion_in_direction(dir, data->current_page_rendering);
|
||||||
if (next_comp != NULL)
|
if (next_comp != NULL)
|
||||||
{
|
{
|
||||||
size_t cursor_pos = cycle_cursor_pos;
|
size_t cursor_pos = cycle_cursor_pos;
|
||||||
|
@ -1665,40 +1675,6 @@ static void prioritize_completions(std::vector<completion_t> &comp)
|
||||||
sort(comp.begin(), comp.end(), compare_completions_by_match_type);
|
sort(comp.begin(), comp.end(), compare_completions_by_match_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Given a list of completions, get the completion at an index past *inout_idx, and then increment it. inout_idx should be initialized to (size_t)(-1) for the first call. */
|
|
||||||
static const completion_t *cycle_competions(const std::vector<completion_t> &comp, const wcstring &command_line, size_t *inout_idx)
|
|
||||||
{
|
|
||||||
const size_t size = comp.size();
|
|
||||||
if (size == 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
// note start_idx will be set to -1 initially, so that when it gets incremented we start at 0
|
|
||||||
const size_t start_idx = *inout_idx;
|
|
||||||
size_t idx = start_idx;
|
|
||||||
|
|
||||||
const completion_t *result = NULL;
|
|
||||||
size_t remaining = comp.size();
|
|
||||||
while (remaining--)
|
|
||||||
{
|
|
||||||
/* Bump the index */
|
|
||||||
idx = (idx + 1) % size;
|
|
||||||
|
|
||||||
/* Get the completion */
|
|
||||||
const completion_t &c = comp.at(idx);
|
|
||||||
|
|
||||||
/* Try this completion */
|
|
||||||
if (!(c.flags & COMPLETE_REPLACES_TOKEN) || reader_can_replace(command_line, c.flags))
|
|
||||||
{
|
|
||||||
/* Success */
|
|
||||||
result = &c;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*inout_idx = idx;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Handle the list of completions. This means the following:
|
Handle the list of completions. This means the following:
|
||||||
|
|
||||||
|
@ -1887,8 +1863,8 @@ static bool handle_completions(const std::vector<completion_t> &comp)
|
||||||
|
|
||||||
if (1)
|
if (1)
|
||||||
{
|
{
|
||||||
data->current_pager.set_prefix(prefix);
|
data->pager.set_prefix(prefix);
|
||||||
data->current_pager.set_completions(surviving_completions);
|
data->pager.set_completions(surviving_completions);
|
||||||
|
|
||||||
/* Invalidate our rendering */
|
/* Invalidate our rendering */
|
||||||
data->current_page_rendering = page_rendering_t();
|
data->current_page_rendering = page_rendering_t();
|
||||||
|
@ -3083,7 +3059,25 @@ const wchar_t *reader_readline(void)
|
||||||
if (last_char != R_YANK && last_char != R_YANK_POP)
|
if (last_char != R_YANK && last_char != R_YANK_POP)
|
||||||
yank_len=0;
|
yank_len=0;
|
||||||
|
|
||||||
const wchar_t *buff = data->command_line.c_str();
|
/* We clear pager contents for most events, except for a few */
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case R_COMPLETE:
|
||||||
|
case R_BACKWARD_CHAR:
|
||||||
|
case R_FORWARD_CHAR:
|
||||||
|
case R_UP_LINE:
|
||||||
|
case R_DOWN_LINE:
|
||||||
|
case R_NULL:
|
||||||
|
case R_REPAINT:
|
||||||
|
case R_SUPPRESS_AUTOSUGGESTION:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
clear_pager();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const wchar_t * const buff = data->command_line.c_str();
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -3170,7 +3164,7 @@ const wchar_t *reader_readline(void)
|
||||||
if (!data->complete_func)
|
if (!data->complete_func)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (! comp_empty && last_char == R_COMPLETE)
|
if (is_navigating_pager_contents() || (! comp_empty && last_char == R_COMPLETE))
|
||||||
{
|
{
|
||||||
/* The user typed R_COMPLETE more than once in a row. Cycle through our available completions. */
|
/* The user typed R_COMPLETE more than once in a row. Cycle through our available completions. */
|
||||||
select_completion_in_direction(direction_next, cycle_command_line, cycle_cursor_pos);
|
select_completion_in_direction(direction_next, cycle_command_line, cycle_cursor_pos);
|
||||||
|
@ -3852,11 +3846,11 @@ const wchar_t *reader_readline(void)
|
||||||
writestr(L"\n");
|
writestr(L"\n");
|
||||||
|
|
||||||
/* Ensure we have no pager contents when we exit */
|
/* Ensure we have no pager contents when we exit */
|
||||||
if (! data->current_pager.empty())
|
if (! data->pager.empty())
|
||||||
{
|
{
|
||||||
/* Clear to end of screen to erase the pager contents. TODO: this may fail if eos doesn't exist, in which case we should emit newlines */
|
/* Clear to end of screen to erase the pager contents. TODO: this may fail if eos doesn't exist, in which case we should emit newlines */
|
||||||
screen_force_clear_to_end();
|
screen_force_clear_to_end();
|
||||||
data->current_pager.clear();
|
data->pager.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!reader_exit_forced())
|
if (!reader_exit_forced())
|
||||||
|
|
Loading…
Reference in a new issue