diff --git a/src/prompts/fuzzy_select.rs b/src/prompts/fuzzy_select.rs index e17b4908..164bd453 100644 --- a/src/prompts/fuzzy_select.rs +++ b/src/prompts/fuzzy_select.rs @@ -143,11 +143,11 @@ impl FuzzySelect<'_> { let mut render = TermThemeRenderer::new(term, self.theme); let mut sel = self.default; - let mut size_vec = Vec::new(); - for items in self.items.iter().as_slice() { - let size = &items.len(); - size_vec.push(*size); - } + let size_vec: Vec<_> = self.items.iter() + .flat_map(|i| i.split('\n')) + // Formatting each item adds two more characters. + .map(|item| item.len() + 2) + .collect(); // Fuzzy matcher let matcher = fuzzy_matcher::skim::SkimMatcherV2::default(); diff --git a/src/prompts/multi_select.rs b/src/prompts/multi_select.rs index f697c3c2..31f414b6 100644 --- a/src/prompts/multi_select.rs +++ b/src/prompts/multi_select.rs @@ -208,17 +208,11 @@ impl MultiSelect<'_> { let mut render = TermThemeRenderer::new(term, self.theme); let mut sel = 0; - let mut size_vec = Vec::new(); - - for items in self - .items - .iter() + let size_vec: Vec<_> = self.items.iter() .flat_map(|i| i.split('\n')) - .collect::>() - { - let size = &items.len(); - size_vec.push(*size); - } + // Formatting each item adds two more characters. + .map(|item| item.len() + 2) + .collect(); let mut checked: Vec = self.defaults.clone(); diff --git a/src/prompts/select.rs b/src/prompts/select.rs index 5e4335fc..0fca9a5b 100644 --- a/src/prompts/select.rs +++ b/src/prompts/select.rs @@ -247,17 +247,11 @@ impl Select<'_> { let mut render = TermThemeRenderer::new(term, self.theme); let mut sel = self.default; - let mut size_vec = Vec::new(); - - for items in self - .items - .iter() + let size_vec: Vec<_> = self.items.iter() .flat_map(|i| i.split('\n')) - .collect::>() - { - let size = &items.len(); - size_vec.push(*size); - } + // Formatting each item adds two more characters. + .map(|item| item.len() + 2) + .collect(); term.hide_cursor()?; diff --git a/src/prompts/sort.rs b/src/prompts/sort.rs index 03152bf4..ec600a90 100644 --- a/src/prompts/sort.rs +++ b/src/prompts/sort.rs @@ -181,12 +181,11 @@ impl Sort<'_> { let mut render = TermThemeRenderer::new(term, self.theme); let mut sel = 0; - let mut size_vec = Vec::new(); - - for items in self.items.iter().as_slice() { - let size = &items.len(); - size_vec.push(*size); - } + let size_vec: Vec<_> = self.items.iter() + .flat_map(|i| i.split('\n')) + // Formatting each item adds two more characters. + .map(|item| item.len() + 2) + .collect(); let mut order: Vec<_> = (0..self.items.len()).collect(); let mut checked: bool = false; diff --git a/src/theme.rs b/src/theme.rs index 43ea7a01..d0e7f716 100644 --- a/src/theme.rs +++ b/src/theme.rs @@ -846,13 +846,18 @@ impl<'a> TermThemeRenderer<'a> { Ok(()) } + /// Clear all output after the last user prompt; leave the prompt behind. + /// + /// `size_vec` contains the lengths of all lines of output after the prompt. pub fn clear_preserve_prompt(&mut self, size_vec: &[usize]) -> io::Result<()> { + // Printing a selectable item (which should only take up one line) + // can yield several lines in the terminal: if the item is longer than the terminal. + // Take this into account, to fully clear all input after the prompt. let mut new_height = self.height; - //Check each item size, increment on finding an overflow + // Check each item size, increment if it overflows the terminal width. for size in size_vec { - if *size > self.term.size().1 as usize { - new_height += 1; - } + let term_width = self.term.size().1 as usize; + new_height += *size / term_width; } self.term.clear_last_lines(new_height)?;