Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,8 +291,9 @@ pub use validator::{DefaultValidator, ValidationResult, Validator};

mod menu;
pub use menu::{
menu_functions, ColumnarMenu, DescriptionMenu, DescriptionMode, IdeMenu, ListMenu, Menu,
MenuBuilder, MenuEvent, MenuSettings, MenuTextStyle, ReedlineMenu, TraversalDirection,
menu_functions, ColumnarMenu, DescriptionMenu, DescriptionMode, DescriptionPosition, IdeMenu,
ListMenu, Menu, MenuBuilder, MenuEvent, MenuSettings, MenuTextStyle, ReedlineMenu,
TraversalDirection,
};

mod terminal_extensions;
Expand Down
129 changes: 97 additions & 32 deletions src/menu/list_menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,19 @@ use {

const SELECTION_CHAR: char = '!';

/// Controls where the description is rendered relative to the completion value
/// in a [`ListMenu`] row.
#[derive(Clone, Default, Debug, PartialEq, Eq)]
pub enum DescriptionPosition {
/// Description is shown **before** the value, wrapped in parentheses:
/// `(description) value` — the original behaviour.
#[default]
Before,
/// Description is shown **after** the value with a leading space:
/// `value description`
After,
}

struct Page {
size: usize,
full: bool,
Expand Down Expand Up @@ -67,6 +80,8 @@ pub struct ListMenu {
event: Option<MenuEvent>,
/// String collected after the menu is activated
input: Option<String>,
/// Controls where the description is rendered relative to the completion value
description_position: DescriptionPosition,
}

impl Default for ListMenu {
Expand All @@ -87,6 +102,7 @@ impl Default for ListMenu {
pages: Vec::new(),
event: None,
input: None,
description_position: DescriptionPosition::default(),
}
}
}
Expand All @@ -113,6 +129,15 @@ impl ListMenu {
self.max_lines = max_lines;
self
}

/// Menu builder to set where descriptions are rendered relative to the
/// completion value. Defaults to [`DescriptionPosition::Before`] for
/// backwards compatibility.
#[must_use]
pub fn with_description_position(mut self, position: DescriptionPosition) -> Self {
self.description_position = position;
self
}
}

// Menu functionality
Expand Down Expand Up @@ -265,40 +290,80 @@ impl ListMenu {
row_number: &str,
use_ansi_coloring: bool,
) -> String {
let description = description.map_or("".to_string(), |desc| {
if use_ansi_coloring {
format!(
"{}({}) {}",
self.settings.color.description_style.prefix(),
desc,
RESET
)
} else {
format!("({desc}) ")
}
});
match self.description_position {
DescriptionPosition::Before => {
let description = description.map_or("".to_string(), |desc| {
if use_ansi_coloring {
format!(
"{}({}) ",
self.settings.color.description_style.prefix(),
desc,
)
} else {
format!("({desc}) ")
}
});

if use_ansi_coloring {
format!(
"{}{}{}{}{}{}",
row_number,
description,
self.text_style(index),
&line,
RESET,
Self::end_of_line(),
)
} else {
// If no ansi coloring is found, then the selection word is
// the line in uppercase
let line_str = if index == self.index() {
format!("{}{}>{}", row_number, description, line.to_uppercase())
} else {
format!("{row_number}{description}{line}")
};

if use_ansi_coloring {
format!(
"{}{}{}{}{}{}",
row_number,
description,
self.text_style(index),
&line,
RESET,
Self::end_of_line(),
)
} else {
// If no ansi coloring is found, then the selection word is
// the line in uppercase
let line_str = if index == self.index() {
format!("{}{}>{}", row_number, description, line.to_uppercase())
} else {
format!("{row_number}{description}{line}")
};
// Final string with formatting
format!("{}{}", line_str, Self::end_of_line())
}
}
DescriptionPosition::After => {
let description = description.map_or("".to_string(), |desc| {
if use_ansi_coloring {
format!(
" {}{}{}",
self.settings.color.description_style.prefix(),
desc,
RESET
)
} else {
format!(" {desc}")
}
});

if use_ansi_coloring {
format!(
"{}{}{}{}{}{}",
row_number,
self.text_style(index),
&line,
RESET,
description,
Self::end_of_line(),
)
} else {
// If no ansi coloring is found, then the selection word is
// the line in uppercase
let line_str = if index == self.index() {
format!("{}>{}{}", row_number, line.to_uppercase(), description)
} else {
format!("{row_number}{line}{description}")
};

// Final string with formatting
format!("{}{}", line_str, Self::end_of_line())
// Final string with formatting
format!("{}{}", line_str, Self::end_of_line())
}
}
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/menu/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pub use columnar_menu::TraversalDirection;
pub use description_menu::DescriptionMenu;
pub use ide_menu::DescriptionMode;
pub use ide_menu::IdeMenu;
pub use list_menu::DescriptionPosition;
pub use list_menu::ListMenu;
use nu_ansi_term::{Color, Style};

Expand Down