【问题标题】:Autocomplete with readline in python3在python3中使用readline自动完成
【发布时间】:2014-01-04 17:06:22
【问题描述】:

我正在尝试使用这个巧妙的技巧here 来处理 csv 文件。不过,我似乎无法在 python3 中获得自动完成功能。我不知道从哪里开始 readline。文档有点密集。我的猜测是,如果没有来自 Python 2 的 raw_input(),我会遗漏一些东西。

我在下面粘贴了我的尝试。当我在 shell 中并点击选项卡时,我只会得到大选项卡并且没有自动完成操作。我的意图是下面的输入语句在字符串 ['10/10/2013', '10/13/2013', '10/14/2013', '10/15/2013'] 上自动完成。

我错过了什么?

import readline

class MyCompleter(object):  # Custom completer

    def __init__(self, options):
        self.options = sorted(options)

    def complete(self, text, state):
        if state == 0:  # on first trigger, build possible matches
            if text:  # cache matches (entries that start with entered text)
                self.matches = [s for s in self.options
                                    if s and s.startswith(text)]
            else:  # no text entered, all matches possible
                self.matches = self.options[:]

        # return match indexed by state
        try:
            return self.matches[state]
        except IndexError:
            return None


dates = [
    '10/10/2013 13:03:51',
    '10/10/2013 13:54:32',
    '10/10/2013 18:48:48',
    '10/10/2013 19:13:00',
    '10/13/2013 12:58:17',
    '10/13/2013 13:38:15',
    '10/13/2013 16:48:58',
    '10/13/2013 17:23:59',
    '10/13/2013 20:09:56',
    '10/13/2013 21:54:14',
    '10/13/2013 21:57:43',
    '10/13/2013 22:47:40',
    '10/14/2013 13:32:53',
    '10/14/2013 21:14:51',
    '10/15/2013 10:18:23'
    ]

dates = [x.split(' ')[0] for x in dates]

completer = MyCompleter(list(set(dates)))
readline.set_completer(completer.complete)
readline.parse_and_bind('tab: complete')
date = input('Enter a date in m/d/yy format\n\t')

更新:下面的答案很好,但在 OS X 上对我来说仍然是坏的。我什至不知道从哪里开始解决这个问题。我在 Ubuntu 上获得了自动完成功能,但它并没有以某种方式绑定到我的 OS X 系统上的tab

【问题讨论】:

  • 您的示例代码对我来说适用于 Python 3.3 虽然不是很好。我认为你的Completer() 有一些缺陷:)
  • 哎呀,听起来你比我走得更远。我在 OS X,Python 3.3...
  • 这里也一样! :) 我正在尝试修复您显示匹配选项的问题。但我可能不得不把这个留给别人。我已经成功地做到了。见:bitbucket.org/prologic/mio-lang/src/tip/mio/state.py
  • 感谢下面的回答。我的 OS X 环境肯定有问题。
  • brew install python3了吗? :)

标签: python python-3.x autocomplete readline


【解决方案1】:

更正版本:

from __future__ import print_function

import sys
import readline
from os import environ


class MyCompleter(object):  # Custom completer

    def __init__(self, options):
        self.options = sorted(options)

    def complete(self, text, state):
        if state == 0:  # on first trigger, build possible matches
            if not text:
                self.matches = self.options[:]
            else:
                self.matches = [s for s in self.options
                                if s and s.startswith(text)]

        # return match indexed by state
        try:
            return self.matches[state]
        except IndexError:
            return None

    def display_matches(self, substitution, matches, longest_match_length):
        line_buffer = readline.get_line_buffer()
        columns = environ.get("COLUMNS", 80)

        print()

        tpl = "{:<" + str(int(max(map(len, matches)) * 1.2)) + "}"

        buffer = ""
        for match in matches:
            match = tpl.format(match[len(substitution):])
            if len(buffer + match) > columns:
                print(buffer)
                buffer = ""
            buffer += match

        if buffer:
            print(buffer)

        print("> ", end="")
        print(line_buffer, end="")
        sys.stdout.flush()


dates = [
    '10/10/2013 13:03:51',
    '10/10/2013 13:54:32',
    '10/10/2013 18:48:48',
    '10/10/2013 19:13:00',
    '10/13/2013 12:58:17',
    '10/13/2013 13:38:15',
    '10/13/2013 16:48:58',
    '10/13/2013 17:23:59',
    '10/13/2013 20:09:56',
    '10/13/2013 21:54:14',
    '10/13/2013 21:57:43',
    '10/13/2013 22:47:40',
    '10/14/2013 13:32:53',
    '10/14/2013 21:14:51',
    '10/15/2013 10:18:23'
    ]

dates = [x.split(' ')[0] for x in dates]

completer = MyCompleter(list(set(dates)))
readline.set_completer_delims(' \t\n;')
readline.set_completer(completer.complete)
readline.parse_and_bind('tab: complete')
readline.set_completion_display_matches_hook(completer.display_matches)
print('Enter a date in m/d/yy format\n\t')
date = input("> ")

注意事项:

  • 添加了自定义display_matches()可能对你没用
  • 添加了readline.set_completer_delims() 调用,因为我们希望将/ 视为单词的一部分。

在 Mac OS X 上的 Python-3.3 上测试

【讨论】:

  • 好吧,我的系统肯定有问题。这在 Ubuntu 上对我有用,但我只是在 OS X 上获得实际标签。感谢您的清理。
猜你喜欢
  • 2016-01-07
  • 2014-01-08
  • 1970-01-01
  • 2017-08-23
  • 2012-11-25
  • 2011-05-04
  • 1970-01-01
  • 2014-05-31
  • 2014-05-23
相关资源
最近更新 更多