bug-bash
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]