GNU/readline seems to sort my data no matter what I do. My code code looks just like in the documentation:
tags = [tag.lower() for tag in tags]
def completer(text, state):
text = text.lower()
options = [tag for tag in tags if tag.startswith(text)]
try:
return options[state]
except IndexError:
return None
readline.set_completer(completer)
readline.parse_and_bind('tab: menu-complete')
If my tags are ['jarre', 'abba', 'beatles']
, I keep getting ['abba', 'beatles', 'jarre']
. How can I force my order to be kept?
There is dedicated option for this: rl_sort_completion_matches. It sorts the options lexicographically, and removes duplicates - so if you override it, you'll need to take care of duplicates yourself.
However, it's not accessible from the Python's bindings.
Fortunately it doesn't mean you can't get it to work - you can change it using cdll
or ctypes
. Since it's a global variable rather than a function, I'll use in_dll
method:
import ctypes
rl = ctypes.cdll.LoadLibrary('libreadline.so')
sort = ctypes.c_ulong.in_dll(rl, 'rl_sort_completion_matches')
sort.value = 0
After this, the matches should be retrieved in correct order.
This isn't a very portable method, unfortunately - for example, in Windows you should use .dll
suffix rather than Linux's .so
. However, focusing on ctypes
portability is outside the scope of this answer.