mirror of
https://github.com/nushell/reedline.git
synced 2024-10-05 21:38:16 +03:00
Typed text style (#730)
* add match style to MenuTextStyle * cargo fmt * fix external style
This commit is contained in:
parent
c8a52a85f1
commit
34af84ebe0
@ -36,10 +36,27 @@ fn main() -> io::Result<()> {
|
||||
|
||||
let commands = vec![
|
||||
"test".into(),
|
||||
"clear".into(),
|
||||
"exit".into(),
|
||||
"history 1".into(),
|
||||
"history 2".into(),
|
||||
"logout".into(),
|
||||
"login".into(),
|
||||
"hello world".into(),
|
||||
"hello world reedline".into(),
|
||||
"hello world something".into(),
|
||||
"hello world another".into(),
|
||||
"hello world 1".into(),
|
||||
"hello world 2".into(),
|
||||
"hello another very large option for hello word that will force one column".into(),
|
||||
"this is the reedline crate".into(),
|
||||
"abaaabas".into(),
|
||||
"abaaacas".into(),
|
||||
"ababac".into(),
|
||||
"abacaxyc".into(),
|
||||
"abadarabc".into(),
|
||||
];
|
||||
|
||||
let completer = Box::new(DefaultCompleter::new_with_wordlen(commands, 2));
|
||||
|
||||
// Use the interactive menu to select options from the completer
|
||||
|
@ -37,6 +37,8 @@ struct ColumnDetails {
|
||||
pub columns: u16,
|
||||
/// Column width
|
||||
pub col_width: usize,
|
||||
/// The shortest of the strings, which the suggestions are based on
|
||||
pub shortest_base_string: String,
|
||||
}
|
||||
|
||||
/// Menu to present suggestions in a columnar fashion
|
||||
@ -296,18 +298,29 @@ impl ColumnarMenu {
|
||||
use_ansi_coloring: bool,
|
||||
) -> String {
|
||||
if use_ansi_coloring {
|
||||
let match_len = self.working_details.shortest_base_string.len();
|
||||
|
||||
// Split string so the match text can be styled
|
||||
let (match_str, remaining_str) = suggestion.value.split_at(match_len);
|
||||
|
||||
let suggestion_style_prefix = suggestion
|
||||
.style
|
||||
.unwrap_or(self.settings.color.text_style)
|
||||
.prefix();
|
||||
|
||||
if index == self.index() {
|
||||
if let Some(description) = &suggestion.description {
|
||||
let left_text_size = self.longest_suggestion + self.default_details.col_padding;
|
||||
let right_text_size = self.get_width().saturating_sub(left_text_size);
|
||||
format!(
|
||||
"{}{}{:max$}{}{}{}{}{}{}",
|
||||
suggestion
|
||||
.style
|
||||
.unwrap_or(self.settings.color.text_style)
|
||||
.prefix(),
|
||||
"{}{}{}{}{}{}{:max$}{}{}{}{}{}{}",
|
||||
suggestion_style_prefix,
|
||||
self.settings.color.selected_match_style.prefix(),
|
||||
match_str,
|
||||
RESET,
|
||||
suggestion_style_prefix,
|
||||
self.settings.color.selected_text_style.prefix(),
|
||||
&suggestion.value,
|
||||
&remaining_str,
|
||||
RESET,
|
||||
self.settings.color.description_style.prefix(),
|
||||
self.settings.color.selected_text_style.prefix(),
|
||||
@ -322,13 +335,14 @@ impl ColumnarMenu {
|
||||
)
|
||||
} else {
|
||||
format!(
|
||||
"{}{}{}{}{:>empty$}{}",
|
||||
suggestion
|
||||
.style
|
||||
.unwrap_or(self.settings.color.text_style)
|
||||
.prefix(),
|
||||
"{}{}{}{}{}{}{}{}{:>empty$}{}",
|
||||
suggestion_style_prefix,
|
||||
self.settings.color.selected_match_style.prefix(),
|
||||
match_str,
|
||||
RESET,
|
||||
suggestion_style_prefix,
|
||||
self.settings.color.selected_text_style.prefix(),
|
||||
&suggestion.value,
|
||||
remaining_str,
|
||||
RESET,
|
||||
"",
|
||||
self.end_of_line(column),
|
||||
@ -339,12 +353,13 @@ impl ColumnarMenu {
|
||||
let left_text_size = self.longest_suggestion + self.default_details.col_padding;
|
||||
let right_text_size = self.get_width().saturating_sub(left_text_size);
|
||||
format!(
|
||||
"{}{:max$}{}{}{}{}{}",
|
||||
suggestion
|
||||
.style
|
||||
.unwrap_or(self.settings.color.text_style)
|
||||
.prefix(),
|
||||
&suggestion.value,
|
||||
"{}{}{}{}{}{:max$}{}{}{}{}{}",
|
||||
suggestion_style_prefix,
|
||||
self.settings.color.match_style.prefix(),
|
||||
match_str,
|
||||
RESET,
|
||||
suggestion_style_prefix,
|
||||
remaining_str,
|
||||
RESET,
|
||||
self.settings.color.description_style.prefix(),
|
||||
description
|
||||
@ -358,12 +373,13 @@ impl ColumnarMenu {
|
||||
)
|
||||
} else {
|
||||
format!(
|
||||
"{}{}{}{}{:>empty$}{}{}",
|
||||
suggestion
|
||||
.style
|
||||
.unwrap_or(self.settings.color.text_style)
|
||||
.prefix(),
|
||||
&suggestion.value,
|
||||
"{}{}{}{}{}{}{}{}{:>empty$}{}{}",
|
||||
suggestion_style_prefix,
|
||||
self.settings.color.match_style.prefix(),
|
||||
match_str,
|
||||
RESET,
|
||||
suggestion_style_prefix,
|
||||
remaining_str,
|
||||
RESET,
|
||||
self.settings.color.description_style.prefix(),
|
||||
"",
|
||||
@ -476,7 +492,15 @@ impl Menu for ColumnarMenu {
|
||||
self.input.as_deref(),
|
||||
self.settings.only_buffer_difference,
|
||||
);
|
||||
self.values = completer.complete(&input, pos);
|
||||
|
||||
let (values, base_ranges) = completer.complete_with_base_ranges(&input, pos);
|
||||
|
||||
self.values = values;
|
||||
self.working_details.shortest_base_string = base_ranges
|
||||
.iter()
|
||||
.map(|range| editor.get_buffer()[range.clone()].to_string())
|
||||
.min_by_key(|s| s.len())
|
||||
.unwrap_or_default();
|
||||
|
||||
self.reset_position();
|
||||
}
|
||||
|
@ -125,9 +125,8 @@ struct IdeMenuDetails {
|
||||
pub space_right: u16,
|
||||
/// Corrected description offset, based on the available space
|
||||
pub description_offset: u16,
|
||||
/// The ranges of the strings, the suggestions are based on (ranges in [`Editor::get_buffer`])
|
||||
/// This is required to adjust the suggestion boxes position, when `correct_cursor_pos` in [`DefaultIdeMenuDetails`] is true
|
||||
pub base_strings: Vec<String>,
|
||||
/// The shortest of the strings, which the suggestions are based on
|
||||
pub shortest_base_string: String,
|
||||
}
|
||||
|
||||
/// Menu to present suggestions like similar to Ide completion menus
|
||||
@ -513,31 +512,43 @@ impl IdeMenu {
|
||||
};
|
||||
|
||||
if use_ansi_coloring {
|
||||
let match_len = self.working_details.shortest_base_string.len();
|
||||
|
||||
// Split string so the match text can be styled
|
||||
let (match_str, remaining_str) = string.split_at(match_len);
|
||||
|
||||
let suggestion_style_prefix = suggestion
|
||||
.style
|
||||
.unwrap_or(self.settings.color.text_style)
|
||||
.prefix();
|
||||
|
||||
if index == self.index() {
|
||||
format!(
|
||||
"{}{}{}{}{}{}{}{}",
|
||||
"{}{}{}{}{}{}{}{}{}{}{}{}",
|
||||
vertical_border,
|
||||
suggestion
|
||||
.style
|
||||
.unwrap_or(self.settings.color.text_style)
|
||||
.prefix(),
|
||||
self.settings.color.selected_text_style.prefix(),
|
||||
suggestion_style_prefix,
|
||||
" ".repeat(padding),
|
||||
string,
|
||||
self.settings.color.selected_match_style.prefix(),
|
||||
match_str,
|
||||
RESET,
|
||||
suggestion_style_prefix,
|
||||
self.settings.color.selected_text_style.prefix(),
|
||||
remaining_str,
|
||||
" ".repeat(padding_right),
|
||||
RESET,
|
||||
vertical_border,
|
||||
)
|
||||
} else {
|
||||
format!(
|
||||
"{}{}{}{}{}{}{}",
|
||||
"{}{}{}{}{}{}{}{}{}{}{}",
|
||||
vertical_border,
|
||||
suggestion
|
||||
.style
|
||||
.unwrap_or(self.settings.color.text_style)
|
||||
.prefix(),
|
||||
suggestion_style_prefix,
|
||||
" ".repeat(padding),
|
||||
string,
|
||||
self.settings.color.match_style.prefix(),
|
||||
match_str,
|
||||
RESET,
|
||||
suggestion_style_prefix,
|
||||
remaining_str,
|
||||
" ".repeat(padding_right),
|
||||
RESET,
|
||||
vertical_border,
|
||||
@ -623,10 +634,11 @@ impl Menu for IdeMenu {
|
||||
let (values, base_ranges) = completer.complete_with_base_ranges(&input, pos);
|
||||
|
||||
self.values = values;
|
||||
self.working_details.base_strings = base_ranges
|
||||
self.working_details.shortest_base_string = base_ranges
|
||||
.iter()
|
||||
.map(|range| editor.get_buffer()[range.clone()].to_string())
|
||||
.collect::<Vec<String>>();
|
||||
.min_by_key(|s| s.len())
|
||||
.unwrap_or_default();
|
||||
|
||||
self.reset_position();
|
||||
}
|
||||
@ -684,13 +696,8 @@ impl Menu for IdeMenu {
|
||||
let mut cursor_pos = self.working_details.cursor_col;
|
||||
|
||||
if self.default_details.correct_cursor_pos {
|
||||
let base_string = self
|
||||
.working_details
|
||||
.base_strings
|
||||
.iter()
|
||||
.min_by_key(|s| s.len())
|
||||
.cloned()
|
||||
.unwrap_or_default();
|
||||
let base_string = &self.working_details.shortest_base_string;
|
||||
|
||||
cursor_pos = cursor_pos.saturating_sub(base_string.width() as u16);
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,12 @@ pub struct MenuTextStyle {
|
||||
pub text_style: Style,
|
||||
/// Text style for the item description
|
||||
pub description_style: Style,
|
||||
/// Text style of the parts of the suggestions that match the
|
||||
/// typed text when the suggestion is selected
|
||||
pub selected_match_style: Style,
|
||||
/// Text style of the parts of the suggestions that match the
|
||||
/// typed text
|
||||
pub match_style: Style,
|
||||
}
|
||||
|
||||
impl Default for MenuTextStyle {
|
||||
@ -30,6 +36,8 @@ impl Default for MenuTextStyle {
|
||||
selected_text_style: Color::Green.bold().reverse(),
|
||||
text_style: Color::DarkGray.normal(),
|
||||
description_style: Color::Yellow.normal(),
|
||||
selected_match_style: Color::Green.bold().reverse().underline(),
|
||||
match_style: Style::default().underline(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user