Python + readline + autocomplete (tab): why are dashes and question marks considered word delimiters?

Hi, coders and brave GNU-readline users,
A few months ago I started using the Python readline module (2.7.1) for an application like the shell I wrote. The application has nothing to do with files and file systems - it is a specially designed solution for proprietary management software.

Yesterday, I discovered that a particular text caused unexpected completion behavior and did not find a way to solve this problem in the documentation. I desperately ask you to help here. I will start with an example and follow a piece of code that reproduces unwanted behavior.

Providing values ​​for autocomplete:

aaa0   aaa1   aaa2   bbb_0  bbb_1  bbb_2
ccc-0  ccc-1  ccc-2  ddd?0  ddd?1  ddd?2

... then the unexpected behavior looks like this (each action is followed by the final result, and the pipe sign is the cursor):

  • Enter 'b'.
    Input> b|
  • Press TAB (which in my configuration is associated with the auto complete action).
    Input> bbb_|
  • Press TAB again. Your text will remain the same, but you will receive the following hint:
    bbb_0 bbb_1 bbb_2
    Input> bbb_|
  • Enter "0" and press "TAB". Pay attention to the space between the character "0" and the cursor (below is a snippet of code below). So far, so good, and if you try to be the same with "a", the result will be similar, only without underlining (aaa0, aaa1, aaa2).
    bbb_0 bbb_1 bbb_2
    Input> bbb_0 |


  • Start and type 'c'.
    Input> c
  • Press TAB.
    Input> ccc-
  • Press TAB again. This is the first half of my problem. All values ​​are displayed, not just the values ​​starting with "ccc -".
    aaa0 aaa1 aaa2 bbb_0 bbb_1 bbb_2 ccc-0 ccc-1 ccc-2 ddd?0 ddd?1 ddd?2
    Input> ccc-|

  • "0" "TAB".
    aaa0 aaa1 aaa2 bbb_0 bbb_1 bbb_2 ccc-0 ccc-1 ccc-2 ddd?0 ddd?1 ddd?2
    Input> ccc-0|

    , , "0" ( , , ). , TAB , TAB .

, 7, . Readline "" "-" ( "?", "ddd?", - , : space, tab, '='). , , , ? , 7 ( ) TAB.

8, "Input> ccc-0|", TAB , , , : "ccc" "0" . , , , "0" , , , "0" , .

, , . , = = , "-" . , , , . .

- , , :

import readline
values = ['aaa0',  'aaa1',  'aaa2',  'bbb_0', 'bbb_1', 'bbb_2',
          'ccc-0', 'ccc-1', 'ccc-2', 'ddd?0', 'ddd?1', 'ddd?2']
def complete(text, state):
    matches = [v for v in values if v.startswith(text)]
    if len(matches) == 1 and matches[0] == text:
        # Add space if the current text is the same as the only match
        return "{} ".format(matches[0]) if state == 0 else None
    if state >= len(matches):
        return None
    return matches[state]
readline.set_completer(complete)
for line in ("tab: complete", "set show-all-if-unmodified on"):
    readline.parse_and_bind(line)
raw_input("Input> ")

, - ! . :)

, Amnon G

+5
1

dir(readline), get_completer_delims() set_completer_delims() , . readline :

set_completer_delims(...)
    set_completer_delims(string) -> None
    set the readline word delimiters for tab-completion

, , . Python 2.6.7; - , , .

+5

All Articles