diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 64194221f..c464bd877 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -44,6 +44,7 @@ Interactive improvements - Command-specific tab completions may now offer results whose first character is a period. For example, it is now possible to tab-complete ``git add`` for files with leading periods. The default file completions hide these files, unless the token itself has a leading period (:issue:`3707`). - The :kbd:`Control-R` history search now uses glob syntax (:issue:`10131`). - :kbd:`Alt-E` now passes the cursor position to the external editor also if the editor aliases a supported editor (via ``complete --wraps``). +- Option completion now uses fuzzy subsequence filtering as well. This means that ``--fb`` may be completed to ``--foobar`` if there is no better match. New or improved bindings ^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/complete.rs b/src/complete.rs index d9a750a50..03ab564e9 100644 --- a/src/complete.rs +++ b/src/complete.rs @@ -1435,21 +1435,18 @@ impl<'ctx> Completer<'ctx> { if whole_opt.len() < s.len() { continue; } - let r#match = string_prefixes_string(s, &whole_opt); - if !r#match { - let match_no_case = string_prefixes_string_case_insensitive(s, &whole_opt); - if !match_no_case { - continue; - } - } + let anchor_start = !self.flags.fuzzy_match; + let Some(r#match) = string_fuzzy_match_string(s, &whole_opt, anchor_start) else { + continue; + }; let mut offset = 0; let mut flags = CompleteFlags::empty(); - if r#match { - offset = s.len(); - } else { + if r#match.requires_full_replacement() { flags = CompleteFlags::REPLACES_TOKEN; + } else { + offset = s.len(); } // does this switch have any known arguments diff --git a/tests/checks/complete.fish b/tests/checks/complete.fish index 65f23d852..931c2cc22 100644 --- a/tests/checks/complete.fish +++ b/tests/checks/complete.fish @@ -593,3 +593,11 @@ complete -C'complete_unescaped_tokens "foo" bar\\ baz (qux) ' # CHECK: foo # CHECK: bar baz # CHECK: (qux) + +## Fuzzy completion of options +complete complete_long_option -f -l some-long-option +complete -C'complete_long_option --slo' +# CHECK: --some-long-option +complete complete_long_option -f -o an-old-option +complete -C'complete_long_option -ao' +# CHECK: -an-old-option