mirror of
https://github.com/fish-shell/fish-shell
synced 2024-11-10 15:14:44 +00: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:
parent
57d7c46d22
commit
8d2fa4ae95
6 changed files with 7 additions and 7 deletions
|
@ -545,7 +545,7 @@ fn unescape_string_internal(input: &wstr, flags: UnescapeFlags) -> Option<WStrin
|
|||
// 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 @@ impl<'source, 'ast> PrettyPrinterState<'source, 'ast> {
|
|||
|
||||
// \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 @@ impl ReaderData {
|
|||
|
||||
// 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 @@ mod expander {
|
|||
// 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();
|
||||
|
|
Loading…
Reference in a new issue