From 8049e9f920fde4f84422fd651ba4a4beeafb7f10 Mon Sep 17 00:00:00 2001 From: Grisha Levit Date: Fri, 14 Apr 2023 16:10:22 -0400 Subject: [PATCH] allow quoting completions w/o filename treatment lib/readline/complete.c - rl_all_quoting_desired: new variable to tell readline to quote matches even if not doing filename completion - QUOTING_DESIRED: new macro for checking if quoting is enabled - change checks of filename comoletion && filename quoting to use QUOTING_DESIRED. - set_completion_defaults: set rl_all_quoting_desired to 0 lib/readline/readline.h - rl_all_quoting_desired: extern declaration lib/readline/doc/rltech.texi - document rl_all_quoting_desired pcomplete.h - COPT_ALLQUOTE: new value for compspec option, corresponds to rl_all_quoting_desired pcomplete.c - pcomp_set_readline_variables: handle COPT_ALLQUOTE builtins/complete.def - compopts: add allquote option for COPT_ALLQUOTE lib/readline/doc/rluser.texi - document allquote compopt --- builtins/complete.def | 1 + lib/readline/complete.c | 26 +++++++++++++------------- lib/readline/doc/rltech.texi | 7 +++++++ lib/readline/doc/rluser.texi | 3 +++ lib/readline/readline.h | 6 ++++++ pcomplete.c | 2 ++ pcomplete.h | 3 ++- 7 files changed, 34 insertions(+), 14 deletions(-) diff --git a/builtins/complete.def b/builtins/complete.def index 881c4711..89ce0726 100644 --- a/builtins/complete.def +++ b/builtins/complete.def @@ -141,6 +141,7 @@ static const struct _compopt { const char * const optname; unsigned long optflag; } compopts[] = { + { "allquote", COPT_ALLQUOTE }, { "bashdefault", COPT_BASHDEFAULT }, { "default", COPT_DEFAULT }, { "dirnames", COPT_DIRNAMES }, diff --git a/lib/readline/complete.c b/lib/readline/complete.c index bf7cc856..3cf050fc 100644 --- a/lib/readline/complete.c +++ b/lib/readline/complete.c @@ -336,6 +336,14 @@ int rl_filename_completion_desired = 0; entry finder function. */ int rl_filename_quoting_desired = 1; +/* Non-zero means that we should apply filename quoting to the matches + even if we are not otherwise treating the matches as filenames. This + is ALWAYS zero on entry, and can only be changed within a completion + entry finder function. */ +int rl_all_quoting_desired = 0; + +#define QUOTING_DESIRED (rl_all_quoting_desired || (rl_filename_completion_desired && rl_filename_quoting_desired)) + /* This function, if defined, is called by the completer when real filename completion is done, after all the matching names have been generated. It is passed a (char**) known as matches in the code below. @@ -510,7 +518,7 @@ static void set_completion_defaults (int what_to_do) { /* Only the completion entry function can change these. */ - rl_filename_completion_desired = 0; + rl_filename_completion_desired = rl_all_quoting_desired = 0; rl_filename_quoting_desired = 1; rl_completion_type = what_to_do; rl_completion_suppress_append = rl_completion_suppress_quote = 0; @@ -1408,10 +1416,7 @@ compute_lcd_of_matches (char **match_list, int matches, const char *text) check against the list of matches FI */ dtext = (char *)NULL; - if (rl_filename_completion_desired && - rl_filename_dequoting_function && - rl_completion_found_quote && - rl_filename_quoting_desired) + if (QUOTING_DESIRED && rl_completion_found_quote && rl_filename_dequoting_function) { dtext = (*rl_filename_dequoting_function) ((char *)text, rl_completion_quote_character); text = dtext; @@ -1766,10 +1771,7 @@ make_quoted_replacement (char *match, int mtype, char *qc) matches don't require a quoted substring. */ replacement = match; - should_quote = match && rl_completer_quote_characters && - rl_filename_completion_desired && - rl_filename_quoting_desired; - + should_quote = match && rl_completer_quote_characters && QUOTING_DESIRED; if (should_quote) should_quote = should_quote && (!qc || !*qc || (rl_completer_quote_characters && strchr (rl_completer_quote_characters, *qc))); @@ -1980,8 +1982,7 @@ compare_match (char *text, const char *match) char *temp; int r; - if (rl_filename_completion_desired && rl_filename_quoting_desired && - rl_completion_found_quote && rl_filename_dequoting_function) + if (QUOTING_DESIRED && rl_completion_found_quote && rl_filename_dequoting_function) { temp = (*rl_filename_dequoting_function) (text, rl_completion_quote_character); r = strcmp (temp, match); @@ -2043,8 +2044,7 @@ rl_complete_internal (int what_to_do) strcmp directly. */ /* nontrivial_lcd is set if the common prefix adds something to the word being completed. */ - if (rl_filename_completion_desired && rl_filename_quoting_desired && - rl_completion_found_quote && rl_filename_dequoting_function) + if (QUOTING_DESIRED && rl_completion_found_quote && rl_filename_dequoting_function) { char *t; t = (*rl_filename_dequoting_function) (text, rl_completion_quote_character); diff --git a/lib/readline/doc/rltech.texi b/lib/readline/doc/rltech.texi index db38a311..df76f6f9 100644 --- a/lib/readline/doc/rltech.texi +++ b/lib/readline/doc/rltech.texi @@ -2300,6 +2300,13 @@ The quoting is effected via a call to the function pointed to by @code{rl_filename_quoting_function}. @end deftypevar +@deftypevar int rl_all_quoting_desired +Non-zero means that we should apply filename quoting to the matches +even if we are not otherwise treating the matches as filenames. This +is @emph{always} zero on entry, and can only be changed within a completion +entry finder function. +@end deftypevar + @deftypevar int rl_attempted_completion_over If an application-specific completion function assigned to @code{rl_attempted_completion_function} sets this variable to a non-zero diff --git a/lib/readline/doc/rluser.texi b/lib/readline/doc/rluser.texi index bb1a24f5..a9a702d5 100644 --- a/lib/readline/doc/rluser.texi +++ b/lib/readline/doc/rluser.texi @@ -2177,6 +2177,9 @@ beyond the simple generation of completions. @table @code +@item allquote +Tell readline to quote the completed words even if they are not filenames. + @item bashdefault Perform the rest of the default Bash completions if the compspec generates no matches. diff --git a/lib/readline/readline.h b/lib/readline/readline.h index 48f1210a..4a0c3d1d 100644 --- a/lib/readline/readline.h +++ b/lib/readline/readline.h @@ -790,6 +790,12 @@ extern int rl_filename_completion_desired; entry finder function. */ extern int rl_filename_quoting_desired; +/* Non-zero means that we should apply filename quoting to the matches + even if we are not otherwise treating the matches as filenames. This + is ALWAYS zero on entry, and can only be changed within a completion + entry finder function. */ +extern int rl_all_quoting_desired; + /* Set to a function to quote a filename in an application-specific fashion. Called with the text to quote, the type of match found (single or multiple) and a pointer to the quoting character to be used, which the function can diff --git a/pcomplete.c b/pcomplete.c index 553623d5..1d99c317 100644 --- a/pcomplete.c +++ b/pcomplete.c @@ -1486,6 +1486,8 @@ pcomp_set_readline_variables (int flags, int nval) rl_filename_quoting_desired = 1 - nval; if (flags & COPT_NOSORT) rl_sort_completion_matches = 1 - nval; + if (flags & COPT_ALLQUOTE) + rl_all_quoting_desired = nval; } /* Set or unset FLAGS in the options word of the current compspec. diff --git a/pcomplete.h b/pcomplete.h index f0821b19..076c2eb7 100644 --- a/pcomplete.h +++ b/pcomplete.h @@ -76,8 +76,9 @@ typedef struct compspec { #define COPT_BASHDEFAULT (1<<6) #define COPT_PLUSDIRS (1<<7) #define COPT_NOSORT (1<<8) +#define COPT_ALLQUOTE (1<<9) -#define COPT_LASTUSER COPT_NOSORT +#define COPT_LASTUSER COPT_ALLQUOTE #define PCOMP_RETRYFAIL (COPT_LASTUSER << 1) #define PCOMP_NOTFOUND (COPT_LASTUSER << 2) -- 2.40.0