From 0adebdfbc45233fbe7357d7d933af7a03cb925e5 Mon Sep 17 00:00:00 2001 From: Mahmoud Al-Qudsi Date: Thu, 27 Jun 2024 20:43:14 -0500 Subject: [PATCH] Fix completely broken __fish_describe_command integration Command completion descriptions were not being generated from `apropos`. Well, they were being generated but that was not being correctly used by fish core. Not sure when this was broken, but there's a possibility it was during the rust port. In addition to simply not working, it seems the old code tried to avoid allocations but String::split_at_mut() allocates a new string (since one allocation from the global allocator can't be split into two allocations to be freed separately). Use `String::as_mut_utfstr()` before splitting the &wstr instead of splitting the &str to actually do this alloc-free. --- src/complete.rs | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/complete.rs b/src/complete.rs index 64ad59077..94f441887 100644 --- a/src/complete.rs +++ b/src/complete.rs @@ -1006,26 +1006,24 @@ impl<'ctx> Completer<'ctx> { continue; } - // Make the key. This is the stuff after the command. + // Make the set components. This is the stuff after the command. // For example: - // elstr = lsmod + // elstr = lsmod\ta description // cmd = ls // key = mod + // val = A description // Note an empty key is common and natural, if 'cmd' were already valid. - let (key, val) = elstr.split_at_mut(cmd.len()); - let val = &mut val[1..]; - assert!( - !val.is_empty(), - "tab index should not have been at the end." - ); + let parts = elstr.as_mut_utfstr().split_at_mut(tab_idx); + let key = &parts.0[cmd.len()..tab_idx]; + let (_, val) = parts.1.split_at_mut(1); // And once again I make sure the first character is uppercased because I like it that // way, and I get to decide these things. - let mut upper_chars = val.as_char_slice()[0].to_uppercase(); + let mut upper_chars = val.chars().next().unwrap().to_uppercase(); if let (Some(c), None) = (upper_chars.next(), upper_chars.next()) { val.as_char_slice_mut()[0] = c; } - lookup.insert(&*key, &*val); + lookup.insert(key, &*val); } // Then do a lookup on every completion and if a match is found, change to the new