[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Default completion bug
From: |
Sung Pae |
Subject: |
Default completion bug |
Date: |
Wed, 11 Jan 2012 02:31:42 -0600 |
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