mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-05-22 20:31:15 -03:00
fish_indent: fix accidentally quadratic perf regression due to chars().last()
Iterator::last() consumes the entire iterator, even for DoubleEndedIterator, see https://github.com/rust-lang/rust/pull/28125#issuecomment-145070161 Because of this, "at_line_start()" took 90% of fish_indent share/completions/git.fish making it take 1000ms instead of 30 ms. Fix that.
This commit is contained in:
@@ -545,7 +545,7 @@ enum Mode {
|
||||
// In general, this is ANY_STRING. But as a hack, if the last appended char
|
||||
// is ANY_STRING, delete the last char and store ANY_STRING_RECURSIVE to
|
||||
// reflect the fact that ** is the recursive wildcard.
|
||||
if result.chars().last() == Some(ANY_STRING) {
|
||||
if result.chars().next_back() == Some(ANY_STRING) {
|
||||
assert!(!result.is_empty());
|
||||
result.truncate(result.len() - 1);
|
||||
to_append_or_none = Some(ANY_STRING_RECURSIVE);
|
||||
|
||||
@@ -319,7 +319,7 @@ fn gap_text_flags_before_node(&self, node: &dyn Node) -> GapFlags {
|
||||
|
||||
// \return whether we are at the start of a new line.
|
||||
fn at_line_start(&self) -> bool {
|
||||
self.output.chars().last().is_none_or(|c| c == '\n')
|
||||
self.output.chars().next_back().is_none_or(|c| c == '\n')
|
||||
}
|
||||
|
||||
// \return whether we have a space before the output.
|
||||
|
||||
@@ -782,7 +782,7 @@ pub fn is_potential_path(
|
||||
return false;
|
||||
}
|
||||
let mut abs_path = path_apply_working_directory(&clean_potential_path_fragment, wd);
|
||||
let must_be_full_dir = abs_path.chars().last() == Some('/');
|
||||
let must_be_full_dir = abs_path.chars().next_back() == Some('/');
|
||||
if flags.contains(PathFlags::PATH_FOR_CD) {
|
||||
abs_path = normalize_path(&abs_path, /*allow_leading_double_slashes=*/ true);
|
||||
}
|
||||
|
||||
@@ -340,7 +340,7 @@ pub fn path_get_cdpath(dir: &wstr, wd: &wstr, vars: &dyn Environment) -> Option<
|
||||
if dir.is_empty() {
|
||||
return None;
|
||||
}
|
||||
assert!(wd.chars().last() == Some('/'));
|
||||
assert!(wd.chars().next_back() == Some('/'));
|
||||
let paths = path_apply_cdpath(dir, wd, vars);
|
||||
|
||||
for a_dir in paths {
|
||||
|
||||
@@ -3798,7 +3798,7 @@ fn get_autosuggestion_performer(
|
||||
// Here we do something a little funny. If the line ends with a space, and the cursor is not
|
||||
// at the end, don't use completion autosuggestions. It ends up being pretty weird seeing
|
||||
// stuff get spammed on the right while you go back to edit a line
|
||||
let last_char = search_string.chars().last().unwrap();
|
||||
let last_char = search_string.chars().next_back().unwrap();
|
||||
let cursor_at_end = cursor_pos == search_string.len();
|
||||
if !cursor_at_end && last_char.is_whitespace() {
|
||||
return nothing;
|
||||
@@ -4693,7 +4693,7 @@ fn add_to_history(&mut self) {
|
||||
|
||||
// Historical behavior is to trim trailing spaces, unless escape (#7661).
|
||||
let mut text = self.command_line.text().to_owned();
|
||||
while text.chars().last() == Some(' ')
|
||||
while text.chars().next_back() == Some(' ')
|
||||
&& count_preceding_backslashes(&text, text.len() - 1) % 2 == 0
|
||||
{
|
||||
text.pop();
|
||||
|
||||
@@ -632,7 +632,7 @@ pub fn expand(&mut self, base_dir: &wstr, wc: &wstr, effective_prefix: &wstr) {
|
||||
// ANY_STRING_RECURSIVE character is present in both the head and the tail.
|
||||
let head_any = wc_segment.slice_to(asr_idx + 1);
|
||||
let any_tail = wc.slice_from(asr_idx);
|
||||
assert!(head_any.chars().last().unwrap() == ANY_STRING_RECURSIVE);
|
||||
assert!(head_any.chars().next_back().unwrap() == ANY_STRING_RECURSIVE);
|
||||
assert!(any_tail.chars().next().unwrap() == ANY_STRING_RECURSIVE);
|
||||
|
||||
dir.rewind();
|
||||
|
||||
Reference in New Issue
Block a user