Completion state is not fully restored after invoking `compgen' within a competition function.
Normally, if a compspec does not specifically include one of the options that triggers filename completion, the generated completions are not treated as filenames: $ complete -W '/tmp /var' cmd $ cmd /[TAB] /tmp /var However, if a completion function is invoked, and that function happens to call `compgen' with one of the options that triggers filename completion, the generated completions _are_ treated as filenames (i.e. get quoted, have `/' appended to directories, etc.) $ fun() { compgen -f >/dev/null; } $ complete -W '/tmp /var' -F fun cmd $ cmd /[TAB] tmp/ var/ ---- diff --git a/builtins/complete.def b/builtins/complete.def index 0d9b9293..37eb20ba 100644 --- a/builtins/complete.def +++ b/builtins/complete.def @@ -650,7 +650,7 @@ compgen_builtin (WORD_LIST *list) STRINGLIST *sl; char *word, **matches; char *old_line; - int old_ind; + int old_ind, old_completion, old_quoting, old_suppress; if (list == 0) return (EXECUTION_SUCCESS); @@ -692,6 +692,10 @@ compgen_builtin (WORD_LIST *list) rval = EXECUTION_FAILURE; + old_completion = rl_filename_completion_desired; + old_quoting = rl_filename_quoting_desired; + old_suppress = rl_completion_suppress_append; + /* probably don't have to save these, just being safe */ old_line = pcomp_line; old_ind = pcomp_ind; @@ -720,6 +724,10 @@ compgen_builtin (WORD_LIST *list) strvec_dispose (matches); } + rl_filename_completion_desired = old_completion; + rl_filename_quoting_desired = old_quoting; + rl_completion_suppress_append = old_suppress; + if (sl) { if (sl->list && sl->list_len)