From 373bb5644159232c6bee29b53be8b112bd0dd785 Mon Sep 17 00:00:00 2001 From: Johannes Altmanninger Date: Sun, 12 Jan 2025 09:50:10 +0100 Subject: [PATCH] Treat '!' as super-command (it's not reserved!) Other sigil-aliases ('[' and '_') are reserved words that cannot be redefined as function. Only '!' is not. Whereas several users define "function !!", I found only one public occurrence of "function !": https://github.com/xnuk/--/blob/5c7f87ed0788b2f83426ed52893cb582f4fb202c/fish/functions/!.fish Note that "function !" only works if invoked as "!", "! -h" or "! --help" or "foo | !". In most other cases we parse it as negation. We should probably make it a reserved word to reduce confusion. If we do that, we should also add it to __fish_print_help, to make "! -h" work. For now let's rearrange the code so we can recognize "!" as super-command. This fixes completion-based autosuggestions on "! ". --- src/parser_keywords.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/parser_keywords.rs b/src/parser_keywords.rs index ffc59353f..3cb110b2f 100644 --- a/src/parser_keywords.rs +++ b/src/parser_keywords.rs @@ -4,6 +4,7 @@ use crate::wchar::prelude::*; struct ReservedWord { text: &'static wstr, + is_reserved: bool, is_super_command: bool, } @@ -11,12 +12,21 @@ macro_rules! rw { ( ( $text:literal ) ) => { ReservedWord { text: L!($text), + is_reserved: true, is_super_command: false, } }; ( ( $text:literal, [subcommand] ) ) => { ReservedWord { text: L!($text), + is_reserved: true, + is_super_command: true, + } + }; + ( ( $text:literal, [subcommand], not reserved ) ) => { + ReservedWord { + text: L!($text), + is_reserved: false, is_super_command: true, } }; @@ -29,6 +39,7 @@ macro_rules! reserved_words { // Don't forget to add any new reserved keywords to the documentation const RESERVED_WORDS: &[ReservedWord] = reserved_words!( + ("!", [subcommand], not reserved), ("["), ("_"), ("and", [subcommand]), @@ -74,5 +85,5 @@ pub fn parser_keywords_is_subcommand(cmd: &impl AsRef) -> bool { /// functions that change the block or command scope, like 'for', 'end' or 'command' or 'exec'. /// These functions may not be overloaded, so their names are reserved. pub fn parser_keywords_is_reserved(word: &wstr) -> bool { - reserved_word(word).is_some() + reserved_word(word).is_some_and(|reserved_word| reserved_word.is_reserved) }