Correct pager size when command line soft-wraps

When selectiong a large completion entry in the pager, it would clobber the
prompt. To reproduce, first run this command

	complete -c : -xa '(
		# completion entries that,  when applied to the commandline
		# need one, two, or three lines respectively
		echo 1
		echo 2(string repeat -n (math $COLUMNS - 5) x)
		echo 3(string repeat -n $COLUMNS x)
		printf %s\n n(seq $LINES)
	)'

then type ": " and hit Tab repeatedly. When cycling through completion
entries, observe that fish always tries to render the pager with the same
size, even though the number of lines occupied by the command line buffer
changes due to soft wrapping.

Fix this by rendering the pager after the command line has been rendered, so
we know how many lines we have left.
This commit is contained in:
Johannes Altmanninger
2020-07-05 08:38:03 +02:00
parent 826db22dbf
commit ada03d3509
3 changed files with 24 additions and 21 deletions

View File

@@ -820,21 +820,12 @@ void reader_data_t::repaint() {
std::vector<int> indents = this->indents;
indents.resize(len);
// Re-render our completions page if necessary. Limit the term size of the pager to the true
// term size, minus the number of lines consumed by our string. (Note this doesn't yet consider
// wrapping).
int full_line_count = 1 + std::count(full_line.cbegin(), full_line.cend(), L'\n');
termsize_t curr_termsize = termsize_last();
pager.set_term_size(termsize_t{std::max(1, curr_termsize.width),
std::max(1, curr_termsize.height - full_line_count)});
pager.update_rendering(&current_page_rendering);
bool focused_on_pager = active_edit_line() == &pager.search_field_line;
size_t cursor_position = focused_on_pager ? pager.cursor_position() : cmd_line->position();
// Prepend the mode prompt to the left prompt.
s_write(&screen, termsize_last().width, mode_prompt_buff + left_prompt_buff, right_prompt_buff,
full_line, cmd_line->size(), colors, indents, cursor_position, current_page_rendering,
s_write(&screen, mode_prompt_buff + left_prompt_buff, right_prompt_buff, full_line,
cmd_line->size(), colors, indents, cursor_position, pager, current_page_rendering,
focused_on_pager);
repaint_needed = false;
@@ -2690,7 +2681,8 @@ void reader_data_t::handle_readline_command(readline_cmd_t c, readline_loop_stat
auto fish_color_cancel = vars.get(L"fish_color_cancel");
if (fish_color_cancel) {
outp.set_color(parse_color(*fish_color_cancel, false), parse_color(*fish_color_cancel, true));
outp.set_color(parse_color(*fish_color_cancel, false),
parse_color(*fish_color_cancel, true));
}
outp.writestr(L"^C");
outp.set_color(rgb_color_t::reset(), rgb_color_t::reset());