Fix a bug in attempt_shell_completion() since 4.3-beta that allows the programmable completion code to override a prior decision made by attempt_shell_completion() that command completion is >not< to be used.
A test case (the simplest of two possible) follows. Please Reply-To-All. Thanks. Marc. -- In an empty directory, do ... touch aaaaaaaaaaaaaaaaaaaaaaaaaaaaa Then (where [tab] means the TAB key) ... echo >& [tab] # correctly gives the above touch'ed filename echo >& a[tab][tab] # gives a list of commands that start with "a" echo >& aa[tab][tab] # gives a list of commands that start with "aa" .. and so on, until the aa... string is long enough to not match any command, at which point the touch'ed filename is correctly displayed. -- --- bash-5.1/bashline.c +++ devel-5.1/bashline.c @@ -1560,7 +1560,7 @@ attempt_shell_completion (text, start, end) in_command_position++; if (check_redir (ti) == 1) - in_command_position = 0; + in_command_position = -1; /* No override */ } else { @@ -1569,7 +1569,7 @@ attempt_shell_completion (text, start, end) assignments. */ } - if (in_command_position && invalid_completion (text, ti)) + if (in_command_position > 0 && invalid_completion (text, ti)) { rl_attempted_completion_over = 1; return ((char **)NULL); @@ -1577,9 +1577,9 @@ attempt_shell_completion (text, start, end) /* Check that we haven't incorrectly flagged a closed command substitution as indicating we're in a command position. */ - if (in_command_position && ti >= 0 && rl_line_buffer[ti] == '`' && + if (in_command_position > 0 && ti >= 0 && rl_line_buffer[ti] == '`' && *text != '`' && unclosed_pair (rl_line_buffer, end, "`") == 0) - in_command_position = 0; + in_command_position = -1; /* No override */ /* Special handling for command substitution. If *TEXT is a backquote, it can be the start or end of an old-style command substitution, or @@ -1587,8 +1587,9 @@ attempt_shell_completion (text, start, end) succeed. Don't bother if readline found a single quote and we are completing on the substring. */ if (*text == '`' && rl_completion_quote_character != '\'' && - (in_command_position || (unclosed_pair (rl_line_buffer, start, "`") && - unclosed_pair (rl_line_buffer, end, "`")))) + (in_command_position > 0 || + (unclosed_pair (rl_line_buffer, start, "`") && + unclosed_pair (rl_line_buffer, end, "`")))) matches = rl_completion_matches (text, command_subst_completion_function); #if defined (PROGRAMMABLE_COMPLETION) @@ -1596,7 +1597,8 @@ attempt_shell_completion (text, start, end) have_progcomps = prog_completion_enabled && (progcomp_size () > 0); iw_compspec = progcomp_search (INITIALWORD); if (matches == 0 && - (in_command_position == 0 || text[0] == '\0' || (in_command_position && iw_compspec)) && + (in_command_position == 0 || text[0] == '\0' || + (in_command_position > 0 && iw_compspec)) && current_prompt_string == ps1_prompt) { int s, e, s1, e1, os, foundcs; @@ -1718,7 +1720,7 @@ attempt_shell_completion (text, start, end) if (matches == 0) { dflags = 0; - if (in_command_position) + if (in_command_position > 0) dflags |= DEFCOMP_CMDPOS; matches = bash_default_completion (text, start, end, qc, dflags); }