mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-06-03 15:01:16 -03:00
complete: tab-complete anywhere-position abbrs in non-command position
Make abbreviations with `--position anywhere` appear in the completion menu when tabbing in argument position (e.g. `cat foo.log pg<TAB>` shows pgr, pgrv, pjq, etc.), not just in command position. Lift "do_file" into an enum, so we don't have to check "is_redirection" twice, and can express more accurately the reason for not completing abbreviations after redirection. Co-authored-by: Johannes Altmanninger <aclopte@gmail.com> Closes #12764
This commit is contained in:
committed by
Johannes Altmanninger
parent
c10e782838
commit
4b2aba31ee
@@ -12,6 +12,7 @@ Interactive improvements
|
||||
- ``fish_hg_prompt``, ``fish_git_prompt`` and ``fish_fossil_prompt`` now strip control characters from VCS state read off disk, matching ``prompt_pwd``.
|
||||
- The sample informative and minimalist prompts now use ``prompt_pwd`` instead of printing ``$PWD`` directly.
|
||||
- ``bind`` shows the file where bindings were defined (:issue:`12504`).
|
||||
- Abbreviations with ``--position=anywhere`` can now be completed in argument position, not just in command position (:issue:`12630`).
|
||||
|
||||
For distributors and developers
|
||||
-------------------------------
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::{
|
||||
abbrs::with_abbrs,
|
||||
abbrs::{Position, with_abbrs},
|
||||
ast::unescape_keyword,
|
||||
autoload::{Autoload, AutoloadResult},
|
||||
builtins::shared::{builtin_exists, builtin_get_desc, builtin_get_names},
|
||||
@@ -689,7 +689,7 @@ fn perform_for_commandline_impl(&mut self, cmdline: WString) {
|
||||
return;
|
||||
}
|
||||
self.complete_cmd(WString::new());
|
||||
self.complete_abbr(L!(""));
|
||||
self.complete_abbr(L!(""), true);
|
||||
return;
|
||||
};
|
||||
|
||||
@@ -744,7 +744,7 @@ fn perform_for_commandline_impl(&mut self, cmdline: WString) {
|
||||
return;
|
||||
}
|
||||
// Complete command filename.
|
||||
self.complete_abbr(current_token);
|
||||
self.complete_abbr(current_token, true);
|
||||
self.complete_cmd(current_token.to_owned());
|
||||
return;
|
||||
}
|
||||
@@ -784,10 +784,17 @@ fn perform_for_commandline_impl(&mut self, cmdline: WString) {
|
||||
}
|
||||
}
|
||||
|
||||
let mut do_file = false;
|
||||
#[derive(Eq, PartialEq)]
|
||||
enum DoFile {
|
||||
No,
|
||||
Yes,
|
||||
Only,
|
||||
}
|
||||
|
||||
let mut do_file = DoFile::No;
|
||||
let mut handle_as_special_cd = false;
|
||||
if in_redirection {
|
||||
do_file = true;
|
||||
do_file = DoFile::Only;
|
||||
} else {
|
||||
// Try completing as an argument.
|
||||
let mut arg_data = CustomArgData::new(&mut var_assignments);
|
||||
@@ -817,11 +824,15 @@ fn perform_for_commandline_impl(&mut self, cmdline: WString) {
|
||||
command_range,
|
||||
&mut arg_data,
|
||||
);
|
||||
do_file = arg_data.do_file;
|
||||
do_file = if arg_data.do_file {
|
||||
DoFile::Yes
|
||||
} else {
|
||||
DoFile::No
|
||||
};
|
||||
|
||||
// If we're autosuggesting, and the token is empty, don't do file suggestions.
|
||||
if is_autosuggest && arg_data.current_argument.is_empty() {
|
||||
do_file = false;
|
||||
do_file = DoFile::No;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -833,10 +844,14 @@ fn perform_for_commandline_impl(&mut self, cmdline: WString) {
|
||||
// Maybe apply variable assignments.
|
||||
let block = self.apply_var_assignments(&var_assignments);
|
||||
if !self.ctx.check_cancel() {
|
||||
if do_file != DoFile::Only {
|
||||
self.complete_abbr(current_argument, false);
|
||||
}
|
||||
|
||||
// This function wants the unescaped string.
|
||||
self.complete_param_expand(
|
||||
current_argument,
|
||||
do_file,
|
||||
do_file != DoFile::No,
|
||||
handle_as_special_cd,
|
||||
cur_tok.is_unterminated_brace,
|
||||
);
|
||||
@@ -1144,15 +1159,18 @@ fn complete_cmd(&mut self, str_cmd: WString) {
|
||||
}
|
||||
}
|
||||
|
||||
/// Attempt to complete an abbreviation for the given string.
|
||||
fn complete_abbr(&mut self, cmd: &wstr) {
|
||||
/// Attempt to complete a non-regex abbreviation for the given string.
|
||||
fn complete_abbr(&mut self, cmd: &wstr, is_command_position: bool) {
|
||||
// Copy the list of names and descriptions so as not to hold the lock across the call to
|
||||
// complete_strings.
|
||||
let mut possible_comp = Vec::new();
|
||||
let mut descs = HashMap::new();
|
||||
with_abbrs(|set| {
|
||||
for abbr in set.list() {
|
||||
if !abbr.is_regex() {
|
||||
if abbr.is_regex() {
|
||||
continue;
|
||||
}
|
||||
if abbr.position == Position::Anywhere || is_command_position {
|
||||
possible_comp.push(Completion::from_completion(abbr.key.clone()));
|
||||
descs.insert(abbr.key.clone(), abbr.replacement.clone());
|
||||
}
|
||||
|
||||
@@ -645,6 +645,22 @@ abbr cat cat
|
||||
complete -C ca | string match -r '^cat(?:\t.*)?$'
|
||||
# CHECK: cat{{\t}}Abbreviation: cat
|
||||
|
||||
# anywhere-position abbrs complete in non-command position
|
||||
abbr --position anywhere __test_pgr '| grep -i'
|
||||
complete -C'echo __test_pgr' | string match -r '^__test_pgr.*'
|
||||
# CHECK: __test_pgr{{\t}}Abbreviation: | grep -i
|
||||
|
||||
# anywhere-position abbrs still complete in command position (regression guard)
|
||||
complete -C__test_pgr | string match -r '^__test_pgr.*'
|
||||
# CHECK: __test_pgr{{\t}}Abbreviation: | grep -i
|
||||
|
||||
# command-position-only abbrs do NOT complete in non-command position
|
||||
abbr --position command __test_cmd_only 'git status'
|
||||
complete -C'echo __test_cmd' | string match -rq '^__test_cmd'
|
||||
echo $status
|
||||
# CHECK: 1
|
||||
abbr --erase __test_pgr __test_cmd_only
|
||||
|
||||
complete complete-list -xa '(__fish_complete_list , "seq 2")'
|
||||
complete -C "complete-list 1,"
|
||||
# CHECK: 1,1
|
||||
|
||||
Reference in New Issue
Block a user