Hello, There is a small bug in the default completion system due to a disagreement between a few functions in what is considered a command delimiter. I have tested this on the current devel HEAD in the git repo (d00a2d6).
Define a default completion: _completion_loader() { complete -W "COMPLETE ME" "$1" && return 124 } complete -F _completion_loader -D Try to trigger completion for ">" (^I is literal tab): $ > ^I^I $ complete -p complete -F _completion_loader -D complete -W 'COMPLETE ME' > Check to make sure things are working: $ ls ^I^I COMPLETE ME $ complete -p complete -F _completion_loader -D complete -W 'COMPLETE ME' > complete -W 'COMPLETE ME' ls Works just fine for "ls". Now, set a COMPSPEC for the empty string, "": $ complete -W "EMPTY STRING" "" And try to complete ">" again: $ > ^I^I EMPTY STRING $ complete -p complete -W 'EMPTY STRING' complete -F _completion_loader -D complete -W 'COMPLETE ME' > complete -W 'COMPLETE ME' ls It works this time, but only because it is loading the COMPSPEC for the empty string, instead of for ">". The reason for this is that gen_progcomp_completions() first searches the prog_completes table with the results from find_cmd_name() [1], which given a command line "> ", returns "" (the empty string). Failing this, it will call the default completion function _completion_loader(), and pass it a word list composed from the results of command_line_to_word_list(), which when given the _same_ command line "> ", returns the list [">", ""]. Our default completion function then faithfully inserts a COMPSPEC into prog_completes for the key ">" and returns 124 to restart the completion loop. However, since the prog_completes table is never looked up with the key ">", it is never actually found. Of course, once a COMPSPEC for the empty string is inserted into the table (which can also be done by trying to complete an empty command line), completing ">" works as if one was completing the empty string, which will most likely be assigned the same dynamic completion, thus having the unfortunate appearance of suddenly working as intended. I have not attached a patch to this bug report, because I know the subtle differences of rl_basic_word_break_characters, COMMAND_SEPARATORS, and the value embedded in find_cmd_name(), are important, and that any changes, for better or worse, are scrupulously recorded for ALL TIME. I have implemented a couple of solutions, but who am _I_ to say what is a command delimiter? So while a proper fix is complicated, there is a simple workaround that can be implemented in userland: simply define the completion for the empty string ("") for the keys that slip between the cracks of the different command delimiter lists (i.e. "<", ">", ">>"): complete -o default "" Cheers, Sung Pae [1]: Not directly, but by provenance. These are the stack traces for the functions progcomp_search() and progcomp_insert(): (HASH SEARCH) (HASH INSERTION) 0 progcomp_search + 39 0 progcomp_insert + 101 1 gen_progcomp_completions + 40 1 complete_builtin + 943 2 programmable_completions + 115 2 execute_builtin + 500 3 attempt_shell_completion + 1201 3 execute_command_internal + 8420 4 gen_completion_matches + 58 4 execute_command + 138 5 rl_complete_internal + 294 5 execute_command_internal + 16943 6 _rl_dispatch_subseq + 623 6 execute_command_internal + 14939 7 readline_internal_char + 267 7 execute_function + 1339 8 readline + 101 8 execute_shell_function + 135 9 yy_readline_get + 185 9 gen_compspec_completions + 1107 10 shell_getc + 490 10 gen_progcomp_completions + 149 11 read_token + 525 11 programmable_completions + 261 12 yyparse + 1189 12 attempt_shell_completion + 1201 13 parse_command + 184 13 gen_completion_matches + 58 14 read_command + 200 14 rl_complete_internal + 294 15 reader_loop + 355 15 _rl_dispatch_subseq + 623 16 main + 6292 16 readline_internal_char + 267 17 start + 52 17 readline + 101 18 0x0 + 2 18 yy_readline_get + 185 19 shell_getc + 490 20 read_token + 525 21 yyparse + 1189 22 parse_command + 184 23 read_command + 200 24 reader_loop + 355 25 main + 6292 26 start + 52 27 0x0 + 2