Python + GNU/readline 绑定:保持我的排序顺序

Python + GNU/readline bindings: keep my sort order

GNU/readline 似乎无论我做什么都会对我的数据进行排序。我的代码代码看起来就像文档中的代码:

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')

如果我的标签是 ['jarre', 'abba', 'beatles'],我会一直收到 ['abba', 'beatles', 'jarre']。我怎样才能强制保留我的订单?

有专门的选项:rl_sort_completion_matches。它按字典顺序对选项进行排序,并删除重复项 - 因此如果您覆盖它,您需要自己处理重复项。

但是,Python 的绑定无法访问它。

幸运的是,这并不意味着您无法使用它 - 您可以使用 cdllctypes 进行更改。因为它是一个全局变量而不是函数,所以我将使用 in_dll 方法:

import ctypes
rl = ctypes.cdll.LoadLibrary('libreadline.so')
sort = ctypes.c_ulong.in_dll(rl, 'rl_sort_completion_matches')
sort.value = 0

在此之后,应该以正确的顺序检索匹配项。

不幸的是,这不是一种非常便携的方法 - 例如,在 Windows 中,您应该使用 .dll 后缀而不是 Linux 的 .so。但是,关注 ctypes 可移植性不在本答案的范围内。