mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-27 05:13:10 +00:00
Also handle overflown screens if editing pager search field
As mentioned in 04c913427
(Limit command line rendering to $LINES
lines, 2024-10-25) our rendering breaks when the command line overflows
the screen and we have a pager search field.
Let's also apply the overflow logic in this case.
Note that the search field still works, it's just not visible.
In future we should maybe show a small search field (~4 lines) in
this case (removing 4 screen lines worth of command line). But again,
this is not really important.
This commit is contained in:
parent
adfa87d141
commit
f89909ae31
3 changed files with 43 additions and 38 deletions
|
@ -71,7 +71,7 @@ const PAGER_UNDISCLOSED_MAX_ROWS: usize = 4;
|
||||||
const PAGER_MIN_WIDTH: usize = 16;
|
const PAGER_MIN_WIDTH: usize = 16;
|
||||||
|
|
||||||
/// Minimum height to show completions
|
/// Minimum height to show completions
|
||||||
const PAGER_MIN_HEIGHT: usize = 4;
|
pub const PAGER_MIN_HEIGHT: usize = 4;
|
||||||
|
|
||||||
/// The maximum number of columns of completion to attempt to fit onto the screen.
|
/// The maximum number of columns of completion to attempt to fit onto the screen.
|
||||||
const PAGER_MAX_COLS: usize = 6;
|
const PAGER_MAX_COLS: usize = 6;
|
||||||
|
|
|
@ -427,8 +427,8 @@ struct LayoutData {
|
||||||
/// Position of the cursor in the command line.
|
/// Position of the cursor in the command line.
|
||||||
position: usize,
|
position: usize,
|
||||||
|
|
||||||
/// Whether the cursor is focused on the pager or not.
|
/// The cursor position in the pager search field.
|
||||||
focused_on_pager: bool,
|
pager_search_field_position: Option<usize>,
|
||||||
|
|
||||||
/// Visual selection of the command line, or none if none.
|
/// Visual selection of the command line, or none if none.
|
||||||
selection: Option<SelectionData>,
|
selection: Option<SelectionData>,
|
||||||
|
@ -1386,6 +1386,7 @@ impl<'a> Reader<'a> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let focused_on_pager = self.active_edit_line_tag() == EditableLineTag::SearchField;
|
let focused_on_pager = self.active_edit_line_tag() == EditableLineTag::SearchField;
|
||||||
|
let pager_search_field_position = focused_on_pager.then_some(self.pager.cursor_position());
|
||||||
let last = &self.rendered_layout;
|
let last = &self.rendered_layout;
|
||||||
check(self.force_exec_prompt_and_repaint, "forced")
|
check(self.force_exec_prompt_and_repaint, "forced")
|
||||||
|| check(self.command_line.text() != last.text, "text")
|
|| check(self.command_line.text() != last.text, "text")
|
||||||
|
@ -1394,8 +1395,11 @@ impl<'a> Reader<'a> {
|
||||||
"highlight",
|
"highlight",
|
||||||
)
|
)
|
||||||
|| check(self.selection != last.selection, "selection")
|
|| check(self.selection != last.selection, "selection")
|
||||||
|| check(focused_on_pager != last.focused_on_pager, "focus")
|
|
||||||
|| check(self.command_line.position() != last.position, "position")
|
|| check(self.command_line.position() != last.position, "position")
|
||||||
|
|| check(
|
||||||
|
pager_search_field_position != last.pager_search_field_position,
|
||||||
|
"pager_search_field_position",
|
||||||
|
)
|
||||||
|| check(
|
|| check(
|
||||||
self.history_search.search_range_if_active() != last.history_search_range,
|
self.history_search.search_range_if_active() != last.history_search_range,
|
||||||
"history search",
|
"history search",
|
||||||
|
@ -1431,13 +1435,10 @@ impl<'a> Reader<'a> {
|
||||||
result.text = self.command_line.text().to_owned();
|
result.text = self.command_line.text().to_owned();
|
||||||
result.colors = self.command_line.colors().to_vec();
|
result.colors = self.command_line.colors().to_vec();
|
||||||
assert!(result.text.len() == result.colors.len());
|
assert!(result.text.len() == result.colors.len());
|
||||||
result.position = if focused_on_pager {
|
result.position = self.command_line.position();
|
||||||
self.pager.cursor_position()
|
result.pager_search_field_position =
|
||||||
} else {
|
focused_on_pager.then_some(self.pager.cursor_position());
|
||||||
self.command_line.position()
|
|
||||||
};
|
|
||||||
result.selection = self.selection;
|
result.selection = self.selection;
|
||||||
result.focused_on_pager = focused_on_pager;
|
|
||||||
result.history_search_range = self.history_search.search_range_if_active();
|
result.history_search_range = self.history_search.search_range_if_active();
|
||||||
result.autosuggestion = self.autosuggestion.text.clone();
|
result.autosuggestion = self.autosuggestion.text.clone();
|
||||||
result.left_prompt_buff = self.left_prompt_buff.clone();
|
result.left_prompt_buff = self.left_prompt_buff.clone();
|
||||||
|
@ -1516,10 +1517,10 @@ impl<'a> Reader<'a> {
|
||||||
&colors,
|
&colors,
|
||||||
&indents,
|
&indents,
|
||||||
data.position,
|
data.position,
|
||||||
|
data.pager_search_field_position,
|
||||||
self.parser.vars(),
|
self.parser.vars(),
|
||||||
pager,
|
pager,
|
||||||
current_page_rendering,
|
current_page_rendering,
|
||||||
data.focused_on_pager,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
//! The current implementation is less smart than ncurses allows and can not for example move blocks
|
//! The current implementation is less smart than ncurses allows and can not for example move blocks
|
||||||
//! of text around to handle text insertion.
|
//! of text around to handle text insertion.
|
||||||
|
|
||||||
use crate::pager::{PageRendering, Pager};
|
use crate::pager::{PageRendering, Pager, PAGER_MIN_HEIGHT};
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::collections::LinkedList;
|
use std::collections::LinkedList;
|
||||||
use std::ffi::{CStr, CString};
|
use std::ffi::{CStr, CString};
|
||||||
|
@ -237,7 +237,6 @@ impl Screen {
|
||||||
/// of the command line \param colors the colors to use for the commanad line \param indent the
|
/// of the command line \param colors the colors to use for the commanad line \param indent the
|
||||||
/// indent to use for the command line \param cursor_pos where the cursor is \param pager the
|
/// indent to use for the command line \param cursor_pos where the cursor is \param pager the
|
||||||
/// pager to render below the command line \param page_rendering to cache the current pager view
|
/// pager to render below the command line \param page_rendering to cache the current pager view
|
||||||
/// \param cursor_is_within_pager whether the position is within the pager line (first line)
|
|
||||||
pub fn write(
|
pub fn write(
|
||||||
&mut self,
|
&mut self,
|
||||||
left_prompt: &wstr,
|
left_prompt: &wstr,
|
||||||
|
@ -247,10 +246,10 @@ impl Screen {
|
||||||
colors: &[HighlightSpec],
|
colors: &[HighlightSpec],
|
||||||
indent: &[i32],
|
indent: &[i32],
|
||||||
cursor_pos: usize,
|
cursor_pos: usize,
|
||||||
|
pager_search_field_position: Option<usize>,
|
||||||
vars: &dyn Environment,
|
vars: &dyn Environment,
|
||||||
pager: &mut Pager,
|
pager: &mut Pager,
|
||||||
page_rendering: &mut PageRendering,
|
page_rendering: &mut PageRendering,
|
||||||
cursor_is_within_pager: bool,
|
|
||||||
) {
|
) {
|
||||||
let curr_termsize = termsize_last();
|
let curr_termsize = termsize_last();
|
||||||
let screen_width = curr_termsize.width;
|
let screen_width = curr_termsize.width;
|
||||||
|
@ -337,7 +336,7 @@ impl Screen {
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
loop {
|
loop {
|
||||||
// Grab the current cursor's x,y position if this character matches the cursor's offset.
|
// Grab the current cursor's x,y position if this character matches the cursor's offset.
|
||||||
if !cursor_is_within_pager && i == cursor_pos {
|
if i == cursor_pos {
|
||||||
cursor_arr = Some(ScrolledCursor {
|
cursor_arr = Some(ScrolledCursor {
|
||||||
cursor: self.desired.cursor,
|
cursor: self.desired.cursor,
|
||||||
scroll_amount: (self.desired.line_count()
|
scroll_amount: (self.desired.line_count()
|
||||||
|
@ -379,39 +378,44 @@ impl Screen {
|
||||||
}
|
}
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
cursor_arr.as_mut().map(
|
|
||||||
|ScrolledCursor {
|
|
||||||
ref mut cursor,
|
|
||||||
scroll_amount,
|
|
||||||
}| {
|
|
||||||
if *scroll_amount != 0 {
|
|
||||||
self.desired.line_datas = self.desired.line_datas.split_off(*scroll_amount);
|
|
||||||
cursor.y -= *scroll_amount;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
let full_line_count = self.desired.cursor.y + 1;
|
let full_line_count = self.desired.cursor.y + 1;
|
||||||
|
let pager_available_height = std::cmp::max(
|
||||||
|
1,
|
||||||
|
curr_termsize
|
||||||
|
.height
|
||||||
|
.saturating_sub_unsigned(full_line_count),
|
||||||
|
);
|
||||||
|
|
||||||
// Now that we've output everything, set the cursor to the position that we saved in the loop
|
// Now that we've output everything, set the cursor to the position that we saved in the loop
|
||||||
// above.
|
// above.
|
||||||
self.desired.cursor = cursor_arr.as_ref().map(|sc| sc.cursor).unwrap_or_default();
|
self.desired.cursor = match pager_search_field_position {
|
||||||
|
Some(pager_cursor_pos)
|
||||||
if cursor_is_within_pager {
|
if pager_available_height >= isize::try_from(PAGER_MIN_HEIGHT).unwrap() =>
|
||||||
self.desired.cursor.x = cursor_pos;
|
{
|
||||||
self.desired.cursor.y = self.desired.line_count();
|
Cursor {
|
||||||
}
|
x: pager_cursor_pos,
|
||||||
|
y: self.desired.line_count(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
let ScrolledCursor {
|
||||||
|
mut cursor,
|
||||||
|
scroll_amount,
|
||||||
|
} = cursor_arr.unwrap();
|
||||||
|
if scroll_amount != 0 {
|
||||||
|
self.desired.line_datas = self.desired.line_datas.split_off(scroll_amount);
|
||||||
|
cursor.y -= scroll_amount;
|
||||||
|
}
|
||||||
|
cursor
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Re-render our completions page if necessary. Limit the term size of the pager to the true
|
// 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.
|
// term size, minus the number of lines consumed by our string.
|
||||||
pager.set_term_size(&Termsize::new(
|
pager.set_term_size(&Termsize::new(
|
||||||
std::cmp::max(1, curr_termsize.width),
|
std::cmp::max(1, curr_termsize.width),
|
||||||
std::cmp::max(
|
pager_available_height,
|
||||||
1,
|
|
||||||
curr_termsize
|
|
||||||
.height
|
|
||||||
.saturating_sub_unsigned(full_line_count),
|
|
||||||
),
|
|
||||||
));
|
));
|
||||||
|
|
||||||
pager.update_rendering(page_rendering);
|
pager.update_rendering(page_rendering);
|
||||||
|
|
Loading…
Reference in a new issue