entry finder function. */
int rl_filename_quoting_desired = 1;
+/* Non-zero means we should apply filename-type quoting to all completions
+ 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_full_quoting_desired = 0;
+
+#define QUOTING_DESIRED() \
+ (rl_full_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.
return TAB;
}
+/********************************************/
+/* */
+/* Completion signal handling and cleanup */
+/* */
+/********************************************/
+
+/* State to clean up and free if completion is interrupted by a signal. */
+typedef struct {
+ char **matches;
+ char *saved_line;
+} complete_sigcleanarg_t;
+
+static void
+_rl_complete_sigcleanup (int sig, void *ptr)
+{
+ complete_sigcleanarg_t *arg;
+
+ if (sig == SIGINT) /* XXX - for now */
+ {
+ arg = ptr;
+ _rl_free_match_list (arg->matches);
+ FREE (arg->saved_line);
+ _rl_complete_display_matches_interrupt = 1;
+ }
+}
+
/************************************/
/* */
/* Completion utility functions */
rl_completion_quote_character = 0;
}
-static void
-_rl_complete_sigcleanup (int sig, void *ptr)
-{
- if (sig == SIGINT) /* XXX - for now */
- {
- _rl_free_match_list ((char **)ptr);
- _rl_complete_display_matches_interrupt = 1;
- }
-}
-
/* Set default values for readline word completion. These are the variables
that application completion functions can change or inspect. */
static void
/* Only the completion entry function can change these. */
rl_filename_completion_desired = 0;
rl_filename_quoting_desired = 1;
+ rl_full_quoting_desired = 0;
rl_completion_type = what_to_do;
rl_completion_suppress_append = rl_completion_suppress_quote = 0;
rl_completion_append_character = ' ';
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;
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 ||
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);
{
char **matches;
rl_compentry_func_t *our_func;
- int start, end, delimiter, found_quote, i, nontrivial_lcd;
+ int start, end, delimiter, found_quote, i, nontrivial_lcd, do_display;
char *text, *saved_line_buffer;
char quote_char;
int tlen, mlen, saved_last_completion_failed;
+ complete_sigcleanarg_t cleanarg; /* state to clean up on signal */
RL_SETSTATE(RL_STATE_COMPLETING);
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);
if (matches && matches[0] && *matches[0])
last_completion_failed = 0;
+ do_display = 0;
+
switch (what_to_do)
{
case TAB:
{
if (what_to_do == '!')
{
- display_matches (matches);
+ do_display = 1;
break;
}
else if (what_to_do == '@')
{
if (nontrivial_lcd == 0)
- display_matches (matches);
+ do_display = 1;
break;
}
else if (rl_editing_mode != vi_mode)
break;
}
- if (rl_completion_display_matches_hook == 0)
- {
- _rl_sigcleanup = _rl_complete_sigcleanup;
- _rl_sigcleanarg = matches;
- _rl_complete_display_matches_interrupt = 0;
- }
- display_matches (matches);
- if (_rl_complete_display_matches_interrupt)
- {
- matches = 0; /* already freed by rl_complete_sigcleanup */
- _rl_complete_display_matches_interrupt = 0;
- if (rl_signal_event_hook)
- (*rl_signal_event_hook) (); /* XXX */
- }
- _rl_sigcleanup = 0;
- _rl_sigcleanarg = 0;
+ do_display = 1;
break;
default:
return 1;
}
+ /* If we need to display the match list, set up to clean it up on receipt of
+ a signal and do it here. If the application has registered a function to
+ display the matches, let it do the work. */
+ if (do_display)
+ {
+ if (rl_completion_display_matches_hook == 0)
+ {
+ _rl_sigcleanup = _rl_complete_sigcleanup;
+ cleanarg.matches = matches;
+ cleanarg.saved_line = saved_line_buffer;
+ _rl_sigcleanarg = &cleanarg;
+ _rl_complete_display_matches_interrupt = 0;
+ }
+
+ display_matches (matches);
+
+ if (_rl_complete_display_matches_interrupt)
+ {
+ matches = 0; /* Both already freed by _rl_complete_sigcleanup */
+ saved_line_buffer = 0;
+ _rl_complete_display_matches_interrupt = 0;
+ if (rl_signal_event_hook)
+ (*rl_signal_event_hook) ();
+ }
+ _rl_sigcleanup = 0;
+ _rl_sigcleanarg = 0;
+ }
+
_rl_free_match_list (matches);
/* Check to see if the line has changed through all of this manipulation. */
if (rl_completion_query_items > 0 && match_list_size >= rl_completion_query_items)
{
rl_ding ();
- FREE (matches);
+ _rl_free_match_list (matches);
matches = (char **)0;
full_completion = 1;
return (0);