Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

respect windows newline in update_values #709

Merged
merged 1 commit into from
Jan 20, 2024
Merged
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
2 changes: 1 addition & 1 deletion src/menu/columnar_menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -543,7 +543,7 @@
// editing a multiline buffer.
// Also, by replacing the new line character with a space, the insert
// position is maintain in the line buffer.
let trimmed_buffer = editor.get_buffer().replace('\n', " ");
let trimmed_buffer = editor.get_buffer().replace("\r\n", " ").replace('\n', " ");
completer.complete(
&trimmed_buffer[..editor.insertion_point()],
editor.insertion_point(),
Expand Down Expand Up @@ -729,9 +729,9 @@
}
}

fn set_cursor_pos(&mut self, _pos: (u16, u16)) {
// The columnar menu does not need the cursor position
}

Check warning on line 734 in src/menu/columnar_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/columnar_menu.rs#L732-L734

Added lines #L732 - L734 were not covered by tests
}

#[cfg(test)]
Expand Down
2 changes: 1 addition & 1 deletion src/menu/ide_menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,16 @@
}

impl Default for BorderSymbols {
fn default() -> Self {
Self {
top_left: '╭',
top_right: '╮',
bottom_left: '╰',
bottom_right: '╯',
horizontal: '─',
vertical: '│',
}
}

Check warning on line 44 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L35-L44

Added lines #L35 - L44 were not covered by tests
}

/// Default values used as reference for the menu. These values are set during
Expand Down Expand Up @@ -174,156 +174,156 @@

/// Menu builder with new value for text style
#[must_use]
pub fn with_text_style(mut self, text_style: Style) -> Self {
self.color.text_style = text_style;
self
}

Check warning on line 180 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L177-L180

Added lines #L177 - L180 were not covered by tests

/// Menu builder with new value for text style
#[must_use]
pub fn with_selected_text_style(mut self, selected_text_style: Style) -> Self {
self.color.selected_text_style = selected_text_style;
self
}

Check warning on line 187 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L184-L187

Added lines #L184 - L187 were not covered by tests

/// Menu builder with new value for text style
#[must_use]
pub fn with_description_text_style(mut self, description_text_style: Style) -> Self {
self.color.description_style = description_text_style;
self
}

Check warning on line 194 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L191-L194

Added lines #L191 - L194 were not covered by tests

/// Menu builder with new value for min completion width value
#[must_use]
pub fn with_min_completion_width(mut self, width: u16) -> Self {
self.default_details.min_completion_width = width;
self
}

Check warning on line 201 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L198-L201

Added lines #L198 - L201 were not covered by tests

/// Menu builder with new value for max completion width value
#[must_use]
pub fn with_max_completion_width(mut self, width: u16) -> Self {
self.default_details.max_completion_width = width;
self
}

Check warning on line 208 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L205-L208

Added lines #L205 - L208 were not covered by tests

/// Menu builder with new value for max completion height value
#[must_use]
pub fn with_max_completion_height(mut self, height: u16) -> Self {
self.default_details.max_completion_height = height;
self
}

Check warning on line 215 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L212-L215

Added lines #L212 - L215 were not covered by tests

/// Menu builder with new value for padding value
#[must_use]
pub fn with_padding(mut self, padding: u16) -> Self {
self.default_details.padding = padding;
self
}

Check warning on line 222 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L219-L222

Added lines #L219 - L222 were not covered by tests

/// Menu builder with the default border value
#[must_use]
pub fn with_default_border(mut self) -> Self {
self.default_details.border = Some(BorderSymbols::default());
self
}

Check warning on line 229 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L226-L229

Added lines #L226 - L229 were not covered by tests

/// Menu builder with new value for border value
#[must_use]
pub fn with_border(
mut self,
top_right: char,
top_left: char,
bottom_right: char,
bottom_left: char,
horizontal: char,
vertical: char,
) -> Self {
self.default_details.border = Some(BorderSymbols {
top_right,
top_left,
bottom_right,
bottom_left,
horizontal,
vertical,
});
self
}

Check warning on line 251 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L233-L251

Added lines #L233 - L251 were not covered by tests

/// Menu builder with new value for cursor offset value
#[must_use]
pub fn with_cursor_offset(mut self, cursor_offset: i16) -> Self {
self.default_details.cursor_offset = cursor_offset;
self
}

Check warning on line 258 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L255-L258

Added lines #L255 - L258 were not covered by tests

/// Menu builder with marker
#[must_use]
pub fn with_marker(mut self, marker: String) -> Self {
self.marker = marker;
self
}

Check warning on line 265 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L262-L265

Added lines #L262 - L265 were not covered by tests

/// Menu builder with new only buffer difference
#[must_use]
pub fn with_only_buffer_difference(mut self, only_buffer_difference: bool) -> Self {
self.only_buffer_difference = only_buffer_difference;
self
}

Check warning on line 272 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L269-L272

Added lines #L269 - L272 were not covered by tests

/// Menu builder with new description mode
#[must_use]
pub fn with_description_mode(mut self, description_mode: DescriptionMode) -> Self {
self.default_details.description_mode = description_mode;
self
}

Check warning on line 279 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L276-L279

Added lines #L276 - L279 were not covered by tests

/// Menu builder with new min description width
#[must_use]
pub fn with_min_description_width(mut self, min_description_width: u16) -> Self {
self.default_details.min_description_width = min_description_width;
self
}

Check warning on line 286 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L283-L286

Added lines #L283 - L286 were not covered by tests

/// Menu builder with new max description width
#[must_use]
pub fn with_max_description_width(mut self, max_description_width: u16) -> Self {
self.default_details.max_description_width = max_description_width;
self
}

Check warning on line 293 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L290-L293

Added lines #L290 - L293 were not covered by tests

/// Menu builder with new max description height
#[must_use]
pub fn with_max_description_height(mut self, max_description_height: u16) -> Self {
self.default_details.max_description_height = max_description_height;
self
}

Check warning on line 300 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L297-L300

Added lines #L297 - L300 were not covered by tests

/// Menu builder with new description offset
#[must_use]
pub fn with_description_offset(mut self, description_offset: u16) -> Self {
self.default_details.description_offset = description_offset;
self
}

Check warning on line 307 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L304-L307

Added lines #L304 - L307 were not covered by tests
}

// Menu functionality
impl IdeMenu {
fn move_next(&mut self) {
if self.selected < (self.values.len() as u16).saturating_sub(1) {
self.selected += 1;
} else {
self.selected = 0;
}
}

Check warning on line 318 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L312-L318

Added lines #L312 - L318 were not covered by tests

fn move_previous(&mut self) {
if self.selected > 0 {
self.selected -= 1;
} else {
self.selected = self.values.len().saturating_sub(1) as u16;
}
}

Check warning on line 326 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L320-L326

Added lines #L320 - L326 were not covered by tests

fn index(&self) -> usize {
self.selected as usize
Expand All @@ -334,343 +334,343 @@
}

/// Calculates how many rows the Menu will try to use (if available)
fn get_rows(&self) -> u16 {
let mut values = self.get_values().len() as u16;

if values == 0 {

Check warning on line 340 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L337-L340

Added lines #L337 - L340 were not covered by tests
// When the values are empty the no_records_msg is shown, taking 1 line
return 1;
}

if self.default_details.border.is_some() {
// top and bottom border take 1 line each
values += 2;
}

Check warning on line 348 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L342-L348

Added lines #L342 - L348 were not covered by tests

let description_height = self
.get_value()
.and_then(|value| value.description)
.map(|description| {
self.description_dims(
description,
self.working_details.description_width,
self.default_details.max_description_height,
0,
)
.1
})
.unwrap_or(0)
.min(self.default_details.max_description_height);

values.max(description_height)
}

Check warning on line 366 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L350-L366

Added lines #L350 - L366 were not covered by tests

/// Returns working details width
fn get_width(&self) -> u16 {
self.working_details.menu_width
}

Check warning on line 371 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L369-L371

Added lines #L369 - L371 were not covered by tests

fn reset_position(&mut self) {
self.selected = 0;
}

fn no_records_msg(&self, use_ansi_coloring: bool) -> String {
let msg = "NO RECORDS FOUND";
if use_ansi_coloring {
format!(
"{}{}{}",
self.color.selected_text_style.prefix(),
msg,
RESET
)

Check warning on line 385 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L377-L385

Added lines #L377 - L385 were not covered by tests
} else {
msg.to_string()

Check warning on line 387 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L387

Added line #L387 was not covered by tests
}
}

Check warning on line 389 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L389

Added line #L389 was not covered by tests

fn create_description(
&self,
description: String,
use_ansi_coloring: bool,
available_width: u16,
available_height: u16,
min_width: u16,
) -> Vec<String> {
if description.is_empty() || available_width == 0 || available_height == 0 {
return Vec::new();
}

Check warning on line 401 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L391-L401

Added lines #L391 - L401 were not covered by tests

let border_width = if self.default_details.border.is_some() {
2

Check warning on line 404 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L403-L404

Added lines #L403 - L404 were not covered by tests
} else {
0

Check warning on line 406 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L406

Added line #L406 was not covered by tests
};

let content_width = available_width.saturating_sub(border_width);
let content_height = available_height.saturating_sub(border_width);

let mut description_lines = split_string(&description, content_width as usize);

// panic!("{:?}", description_lines);

if description_lines.len() > content_height as usize {
description_lines.truncate(content_height as usize);
truncate_string_list(&mut description_lines, "...");
}

Check warning on line 419 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L409-L419

Added lines #L409 - L419 were not covered by tests

let content_width = description_lines
.iter()
.map(|s| s.width())
.max()
.unwrap_or_default()
.max(min_width.saturating_sub(border_width) as usize);

Check warning on line 426 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L421-L426

Added lines #L421 - L426 were not covered by tests

// let needs_padding = description_lines.len() > 1

if let Some(border) = &self.default_details.border {
let horizontal_border = border.horizontal.to_string().repeat(content_width);

Check warning on line 431 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L430-L431

Added lines #L430 - L431 were not covered by tests

for line in &mut description_lines {
let padding = " ".repeat(content_width.saturating_sub(line.width()));

if use_ansi_coloring {
*line = format!(
"{}{}{}{}{}{}",
border.vertical,
self.color.description_style.prefix(),
line,
padding,
RESET,
border.vertical
);
} else {
*line = format!("{}{}{}{}", border.vertical, line, padding, border.vertical);
}

Check warning on line 448 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L433-L448

Added lines #L433 - L448 were not covered by tests
}

description_lines.insert(
0,
format!(
"{}{}{}",
border.top_left, horizontal_border, border.top_right
),
);
description_lines.push(format!(
"{}{}{}",
border.bottom_left, horizontal_border, border.bottom_right
));

Check warning on line 461 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L451-L461

Added lines #L451 - L461 were not covered by tests
} else {
for line in &mut description_lines {
let padding = " ".repeat(content_width.saturating_sub(line.width()));

if use_ansi_coloring {
*line = format!(
"{}{}{}{}",
self.color.description_style.prefix(),
line,
padding,
RESET
);
} else {
*line = format!("{}{}", line, padding);
}

Check warning on line 476 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L463-L476

Added lines #L463 - L476 were not covered by tests
}
}

description_lines
}

Check warning on line 481 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L480-L481

Added lines #L480 - L481 were not covered by tests

/// Returns width and height of the description, including the border
fn description_dims(
&self,
description: String,
max_width: u16,
max_height: u16,
min_width: u16,
) -> (u16, u16) {
// we will calculate the uncapped height, the real height
// will be capped by the available lines

let lines = self.create_description(description, false, max_width, max_height, min_width);
let height = lines.len() as u16;
let string = lines.first().cloned().unwrap_or_default();
let width = string.width() as u16;
(width, height)
}

Check warning on line 499 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L484-L499

Added lines #L484 - L499 were not covered by tests

fn create_value_string(
&self,
suggestion: &Suggestion,
index: usize,
use_ansi_coloring: bool,
padding: usize,
) -> String {
let border_width = if self.default_details.border.is_some() {
2

Check warning on line 509 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L501-L509

Added lines #L501 - L509 were not covered by tests
} else {
0

Check warning on line 511 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L511

Added line #L511 was not covered by tests
};

let vertical_border = self
.default_details
.border
.as_ref()
.map(|border| border.vertical)
.unwrap_or_default();

let padding_right = (self.working_details.completion_width as usize)
.saturating_sub(suggestion.value.chars().count() + border_width + padding);

let max_string_width =
(self.working_details.completion_width as usize).saturating_sub(border_width + padding);

Check warning on line 525 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L514-L525

Added lines #L514 - L525 were not covered by tests

let string = if suggestion.value.chars().count() > max_string_width {
let mut chars = suggestion
.value
.chars()
.take(max_string_width.saturating_sub(3))
.collect::<String>();
chars.push_str("...");
chars

Check warning on line 534 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L527-L534

Added lines #L527 - L534 were not covered by tests
} else {
suggestion.value.clone()

Check warning on line 536 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L536

Added line #L536 was not covered by tests
};

if use_ansi_coloring {
if index == self.index() {
format!(
"{}{}{}{}{}{}{}",
vertical_border,
self.color.selected_text_style.prefix(),
" ".repeat(padding),
string,
" ".repeat(padding_right),
RESET,
vertical_border,
)

Check warning on line 550 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L539-L550

Added lines #L539 - L550 were not covered by tests
} else {
format!(
"{}{}{}{}{}{}{}",
vertical_border,
self.color.text_style.prefix(),
" ".repeat(padding),
string,
" ".repeat(padding_right),
RESET,
vertical_border,
)

Check warning on line 561 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L552-L561

Added lines #L552 - L561 were not covered by tests
}
} else {
let marker = if index == self.index() { ">" } else { "" };

Check warning on line 564 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L564

Added line #L564 was not covered by tests

format!(
"{}{}{}{}{}{}",
vertical_border,
" ".repeat(padding),
marker,
string,
" ".repeat(padding_right),
vertical_border,
)

Check warning on line 574 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L566-L574

Added lines #L566 - L574 were not covered by tests
}
}

Check warning on line 576 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L576

Added line #L576 was not covered by tests
}

impl Menu for IdeMenu {
/// Menu name
fn name(&self) -> &str {
self.name.as_str()
}

Check warning on line 583 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L581-L583

Added lines #L581 - L583 were not covered by tests

/// Menu indicator
fn indicator(&self) -> &str {
self.marker.as_str()
}

Check warning on line 588 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L586-L588

Added lines #L586 - L588 were not covered by tests

/// Deactivates context menu
fn is_active(&self) -> bool {
self.active
}

Check warning on line 593 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L591-L593

Added lines #L591 - L593 were not covered by tests

/// The ide menu can to quick complete if there is only one element
fn can_quick_complete(&self) -> bool {
true
}

Check warning on line 598 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L596-L598

Added lines #L596 - L598 were not covered by tests

fn can_partially_complete(
&mut self,
values_updated: bool,
editor: &mut Editor,
completer: &mut dyn Completer,
) -> bool {
// If the values were already updated (e.g. quick completions are true)
// there is no need to update the values from the menu
if !values_updated {
self.update_values(editor, completer);
}

Check warning on line 610 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L600-L610

Added lines #L600 - L610 were not covered by tests

let values = self.get_values();
if let (Some(Suggestion { value, span, .. }), Some(index)) = find_common_string(values) {
let index = index.min(value.len());
let matching = &value[0..index];

// make sure that the partial completion does not overwrite user entered input
let extends_input = matching.starts_with(&editor.get_buffer()[span.start..span.end]);

if !matching.is_empty() && extends_input {
let mut line_buffer = editor.line_buffer().clone();
line_buffer.replace_range(span.start..span.end, matching);

Check warning on line 622 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L612-L622

Added lines #L612 - L622 were not covered by tests

let offset = if matching.len() < (span.end - span.start) {
line_buffer
.insertion_point()
.saturating_sub((span.end - span.start) - matching.len())

Check warning on line 627 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L624-L627

Added lines #L624 - L627 were not covered by tests
} else {
line_buffer.insertion_point() + matching.len() - (span.end - span.start)

Check warning on line 629 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L629

Added line #L629 was not covered by tests
};

line_buffer.set_insertion_point(offset);
editor.set_line_buffer(line_buffer, UndoBehavior::CreateUndoPoint);

// The values need to be updated because the spans need to be
// recalculated for accurate replacement in the string
self.update_values(editor, completer);

true

Check warning on line 639 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L632-L639

Added lines #L632 - L639 were not covered by tests
} else {
false

Check warning on line 641 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L641

Added line #L641 was not covered by tests
}
} else {
false

Check warning on line 644 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L644

Added line #L644 was not covered by tests
}
}

Check warning on line 646 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L646

Added line #L646 was not covered by tests

/// Selects what type of event happened with the menu
fn menu_event(&mut self, event: MenuEvent) {
match &event {
MenuEvent::Activate(_) => self.active = true,
MenuEvent::Deactivate => {
self.active = false;
self.input = None;
}
_ => {}

Check warning on line 656 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L649-L656

Added lines #L649 - L656 were not covered by tests
}

self.event = Some(event);
}

Check warning on line 660 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L659-L660

Added lines #L659 - L660 were not covered by tests

/// Update menu values
fn update_values(&mut self, editor: &mut Editor, completer: &mut dyn Completer) {
self.values = if self.only_buffer_difference {
if let Some(old_string) = &self.input {
let (start, input) = string_difference(editor.get_buffer(), old_string);
if !input.is_empty() {
completer.complete(input, start + input.len())

Check warning on line 668 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L665-L668

Added lines #L665 - L668 were not covered by tests
} else {
completer.complete("", editor.insertion_point())

Check warning on line 670 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L670

Added line #L670 was not covered by tests
}
} else {
completer.complete("", editor.insertion_point())

Check warning on line 673 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L673

Added line #L673 was not covered by tests
}
} else {
// If there is a new line character in the line buffer, the completer
Expand All @@ -678,7 +678,7 @@
// editing a multiline buffer.
// Also, by replacing the new line character with a space, the insert
// position is maintain in the line buffer.
let trimmed_buffer = editor.get_buffer().replace('\n', " ");
let trimmed_buffer = editor.get_buffer().replace("\r\n", " ").replace('\n', " ");
completer.complete(
&trimmed_buffer[..editor.insertion_point()],
editor.insertion_point(),
Expand All @@ -690,157 +690,157 @@

/// The working details for the menu changes based on the size of the lines
/// collected from the completer
fn update_working_details(
&mut self,
editor: &mut Editor,
completer: &mut dyn Completer,
painter: &Painter,
) {
if let Some(event) = self.event.take() {

Check warning on line 699 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L693-L699

Added lines #L693 - L699 were not covered by tests
// The working value for the menu are updated first before executing any of the
match event {
MenuEvent::Activate(updated) => {
self.active = true;
self.reset_position();

Check warning on line 704 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L701-L704

Added lines #L701 - L704 were not covered by tests

self.input = if self.only_buffer_difference {
Some(editor.get_buffer().to_string())

Check warning on line 707 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L706-L707

Added lines #L706 - L707 were not covered by tests
} else {
None

Check warning on line 709 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L709

Added line #L709 was not covered by tests
};

if !updated {
self.update_values(editor, completer);
}

Check warning on line 714 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L712-L714

Added lines #L712 - L714 were not covered by tests
}
MenuEvent::Deactivate => self.active = false,
MenuEvent::Edit(updated) => {
self.reset_position();

if !updated {
self.update_values(editor, completer);
}

Check warning on line 722 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L716-L722

Added lines #L716 - L722 were not covered by tests
}
MenuEvent::NextElement | MenuEvent::MoveDown => self.move_next(),
MenuEvent::PreviousElement | MenuEvent::MoveUp => self.move_previous(),

Check warning on line 725 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L724-L725

Added lines #L724 - L725 were not covered by tests
MenuEvent::MoveLeft
| MenuEvent::MoveRight
| MenuEvent::PreviousPage
| MenuEvent::NextPage => {}

Check warning on line 729 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L729

Added line #L729 was not covered by tests
}

self.longest_suggestion = self.get_values().iter().fold(0, |prev, suggestion| {
if prev >= suggestion.value.len() {
prev

Check warning on line 734 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L732-L734

Added lines #L732 - L734 were not covered by tests
} else {
suggestion.value.len()

Check warning on line 736 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L736

Added line #L736 was not covered by tests
}
});

let terminal_width = painter.screen_width();
let cursor_pos = self.working_details.cursor_col;

Check warning on line 741 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L738-L741

Added lines #L738 - L741 were not covered by tests

let border_width = if self.default_details.border.is_some() {
2

Check warning on line 744 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L743-L744

Added lines #L743 - L744 were not covered by tests
} else {
0

Check warning on line 746 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L746

Added line #L746 was not covered by tests
};

let description = self
.get_value()
.map(|v| {
if let Some(v) = v.description {
if v.is_empty() {
return None;

Check warning on line 754 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L749-L754

Added lines #L749 - L754 were not covered by tests
} else {
return Some(v);

Check warning on line 756 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L756

Added line #L756 was not covered by tests
}
}
None
})
.unwrap_or_default();

Check warning on line 761 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L758-L761

Added lines #L758 - L761 were not covered by tests

let mut min_description_width = if description.is_some() {
self.default_details.min_description_width

Check warning on line 764 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L763-L764

Added lines #L763 - L764 were not covered by tests
} else {
0

Check warning on line 766 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L766

Added line #L766 was not covered by tests
};

let completion_width = ((self.longest_suggestion.min(u16::MAX as usize) as u16)
+ 2 * self.default_details.padding
+ border_width)
.min(self.default_details.max_completion_width)
.max(self.default_details.min_completion_width)
.min(terminal_width.saturating_sub(min_description_width))
.max(3 + border_width); // Big enough to show "..."

let available_description_width = terminal_width
.saturating_sub(completion_width)
.min(self.default_details.max_description_width)
.max(self.default_details.min_description_width)
.min(terminal_width.saturating_sub(completion_width));

min_description_width = min_description_width.min(available_description_width);

Check warning on line 783 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L769-L783

Added lines #L769 - L783 were not covered by tests

let description_width = if let Some(description) = description {
self.description_dims(
description,
available_description_width,
u16::MAX,
min_description_width,
)
.0

Check warning on line 792 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L785-L792

Added lines #L785 - L792 were not covered by tests
} else {
0

Check warning on line 794 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L794

Added line #L794 was not covered by tests
};

let max_offset = terminal_width.saturating_sub(completion_width + description_width);

let description_offset = self.default_details.description_offset.min(max_offset);

self.working_details.completion_width = completion_width;
self.working_details.description_width = description_width;
self.working_details.description_offset = description_offset;
self.working_details.menu_width =
completion_width + description_offset + description_width;

let cursor_offset = self.default_details.cursor_offset;

self.working_details.description_is_right = match self.default_details.description_mode

Check warning on line 809 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L797-L809

Added lines #L797 - L809 were not covered by tests
{
DescriptionMode::Left => false,
DescriptionMode::Right => true,

Check warning on line 812 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L811-L812

Added lines #L811 - L812 were not covered by tests
DescriptionMode::PreferRight => {
// if there is enough space to the right of the cursor, the description is shown on the right
// otherwise it is shown on the left
let potential_right_distance = (terminal_width as i16)
.saturating_sub(
cursor_pos as i16
+ cursor_offset
+ description_offset as i16
+ completion_width as i16,
)
.max(0) as u16;

potential_right_distance >= description_width

Check warning on line 825 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L816-L825

Added lines #L816 - L825 were not covered by tests
}
};

let space_left = (if self.working_details.description_is_right {
cursor_pos as i16 + cursor_offset

Check warning on line 830 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L829-L830

Added lines #L829 - L830 were not covered by tests
} else {
(cursor_pos as i16 + cursor_offset)
.saturating_sub(description_width as i16 + description_offset as i16)

Check warning on line 833 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L832-L833

Added lines #L832 - L833 were not covered by tests
}
.max(0) as u16)
.min(terminal_width.saturating_sub(self.get_width()));

let space_right = terminal_width.saturating_sub(space_left + self.get_width());

self.working_details.space_left = space_left;
self.working_details.space_right = space_right;
}
}

Check warning on line 843 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L835-L843

Added lines #L835 - L843 were not covered by tests

/// The buffer gets replaced in the Span location
fn replace_in_buffer(&self, editor: &mut Editor) {
Expand All @@ -854,7 +854,7 @@
let start = span.start.min(editor.line_buffer().len());
let end = span.end.min(editor.line_buffer().len());
if append_whitespace {
value.push(' ');

Check warning on line 857 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L857

Added line #L857 was not covered by tests
}
let mut line_buffer = editor.line_buffer().clone();
line_buffer.replace_range(start..end, &value);
Expand All @@ -864,186 +864,186 @@
offset = offset.saturating_sub(end.saturating_sub(start));
line_buffer.set_insertion_point(offset);
editor.set_line_buffer(line_buffer, UndoBehavior::CreateUndoPoint);
}

Check warning on line 867 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L867

Added line #L867 was not covered by tests
}

/// Minimum rows that should be displayed by the menu
fn min_rows(&self) -> u16 {
self.get_rows()
}

Check warning on line 873 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L871-L873

Added lines #L871 - L873 were not covered by tests

fn get_values(&self) -> &[Suggestion] {
&self.values
}

Check warning on line 877 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L875-L877

Added lines #L875 - L877 were not covered by tests

fn menu_required_lines(&self, _terminal_columns: u16) -> u16 {
self.get_rows()
}

Check warning on line 881 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L879-L881

Added lines #L879 - L881 were not covered by tests

fn menu_string(&self, available_lines: u16, use_ansi_coloring: bool) -> String {
if self.get_values().is_empty() {
self.no_records_msg(use_ansi_coloring)

Check warning on line 885 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L883-L885

Added lines #L883 - L885 were not covered by tests
} else {
let border_width = if self.default_details.border.is_some() {
2

Check warning on line 888 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L887-L888

Added lines #L887 - L888 were not covered by tests
} else {
0

Check warning on line 890 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L890

Added line #L890 was not covered by tests
};

let available_lines = available_lines.min(self.default_details.max_completion_height);

Check warning on line 893 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L893

Added line #L893 was not covered by tests
// The skip values represent the number of lines that should be skipped
// while printing the menu
let skip_values = if self.selected >= available_lines.saturating_sub(border_width) {
let skip_lines = self
.selected
.saturating_sub(available_lines.saturating_sub(border_width))
+ 1;
skip_lines as usize

Check warning on line 901 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L896-L901

Added lines #L896 - L901 were not covered by tests
} else {
0

Check warning on line 903 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L903

Added line #L903 was not covered by tests
};

let available_values = available_lines.saturating_sub(border_width) as usize;

let max_padding = self.working_details.completion_width.saturating_sub(
self.longest_suggestion.min(u16::MAX as usize) as u16 + border_width,
) / 2;

let corrected_padding = self.default_details.padding.min(max_padding) as usize;

let mut strings = self
.get_values()
.iter()
.skip(skip_values)
.take(available_values)
.enumerate()
.map(|(index, suggestion)| {
// Correcting the enumerate index based on the number of skipped values

let index = index + skip_values;
self.create_value_string(
suggestion,
index,
use_ansi_coloring,
corrected_padding,
)
})
.collect::<Vec<String>>();

Check warning on line 931 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L906-L931

Added lines #L906 - L931 were not covered by tests

// Add top and bottom border
if let Some(border) = &self.default_details.border {
let inner_width = self.working_details.completion_width.saturating_sub(2) as usize;

strings.insert(
0,
format!(
"{}{}{}",
border.top_left,
border.horizontal.to_string().repeat(inner_width),
border.top_right,
),
);

strings.push(format!(
"{}{}{}",
border.bottom_left,
border.horizontal.to_string().repeat(inner_width),
border.bottom_right,
));
}

Check warning on line 953 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L934-L953

Added lines #L934 - L953 were not covered by tests

let decsription_height =
available_lines.min(self.default_details.max_description_height);
let description_lines = self
.get_value()
.and_then(|value| value.clone().description)
.map(|description| {
self.create_description(
description,
use_ansi_coloring,
self.working_details.description_width,
decsription_height,
self.working_details.description_width, // the width has already been calculated
)
})
.unwrap_or_default();

let distance_left = &" ".repeat(self.working_details.space_left as usize);

// Horizontally join the description lines with the suggestion lines
if self.working_details.description_is_right {
for (idx, pair) in strings
.clone()
.iter()
.zip_longest(description_lines.iter())
.enumerate()

Check warning on line 979 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L955-L979

Added lines #L955 - L979 were not covered by tests
{
match pair {
Both(_suggestion_line, description_line) => {
strings[idx] = format!(
"{}{}{}{}",
distance_left,
strings[idx],
" ".repeat(self.working_details.description_offset as usize),
description_line,
)

Check warning on line 989 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L981-L989

Added lines #L981 - L989 were not covered by tests
}
Left(suggestion_line) => {
strings[idx] = format!("{}{}", distance_left, suggestion_line);
}
Right(description_line) => strings.push(format!(
"{}{}",
" ".repeat(
(self.working_details.completion_width
+ self.working_details.description_offset)
as usize
) + distance_left,
description_line,
)),

Check warning on line 1002 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L991-L1002

Added lines #L991 - L1002 were not covered by tests
}
}
} else {
for (idx, pair) in strings
.clone()
.iter()
.zip_longest(description_lines.iter())
.enumerate()

Check warning on line 1010 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L1006-L1010

Added lines #L1006 - L1010 were not covered by tests
{
match pair {
Both(suggestion_line, description_line) => {
strings[idx] = format!(
"{}{}{}{}",
distance_left,
description_line,
" ".repeat(self.working_details.description_offset as usize),
suggestion_line,
)

Check warning on line 1020 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L1012-L1020

Added lines #L1012 - L1020 were not covered by tests
}
Left(suggestion_line) => {
strings[idx] = format!(
"{}{}",
" ".repeat(
(self.working_details.description_width
+ self.working_details.description_offset)
as usize
) + distance_left,
suggestion_line,
);
}
Right(description_line) => {
strings.push(format!("{}{}", distance_left, description_line,))

Check warning on line 1034 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L1022-L1034

Added lines #L1022 - L1034 were not covered by tests
}
}
}
}

strings.join("\r\n")

Check warning on line 1040 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L1040

Added line #L1040 was not covered by tests
}
}

Check warning on line 1042 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L1042

Added line #L1042 was not covered by tests

fn set_cursor_pos(&mut self, pos: (u16, u16)) {
self.working_details.cursor_col = pos.0;
}

Check warning on line 1046 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L1044-L1046

Added lines #L1044 - L1046 were not covered by tests
}

/// Split the input into strings that are at most `max_length` (in columns, not in chars) long
Expand Down Expand Up @@ -1459,7 +1459,7 @@
// After replacing the editor, make sure insertion_point is at the right spot
assert!(
editor.is_cursor_at_buffer_end(),
"cursor should be at the end after completion"

Check warning on line 1462 in src/menu/ide_menu.rs

View check run for this annotation

Codecov / codecov/patch

src/menu/ide_menu.rs#L1462

Added line #L1462 was not covered by tests
);
}
}
Loading