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 的绑定无法访问它。
幸运的是,这并不意味着您无法使用它 - 您可以使用 cdll
或 ctypes
进行更改。因为它是一个全局变量而不是函数,所以我将使用 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
可移植性不在本答案的范围内。
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 的绑定无法访问它。
幸运的是,这并不意味着您无法使用它 - 您可以使用 cdll
或 ctypes
进行更改。因为它是一个全局变量而不是函数,所以我将使用 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
可移植性不在本答案的范围内。