【问题标题】:python user input autocompletion tab [duplicate]python用户输入自动完成选项卡[重复]
【发布时间】:2021-07-09 12:33:14
【问题描述】:

我想为我的项目制作一个 CLI 应用程序,像这样 示例:

Enter: se<TAB>
set search
Enter: set <TAB>
username password

当用户按下选项卡时,以下文本出现在包含选项的列表中,如果文本完整(例如设置),那么如果用户在设置后按下选项卡以下选项将出现用户名和密码。谢谢:)
(我认为如果 text.startswith("set") 可行)

【问题讨论】:

  • 这应该重新打开,因为欺骗目标是关于如何在 Python 中完成选项卡,但是关于如何 递归 选项卡完成,这要复杂得多,因为你可以在我在答案中链接的示例中看到。

标签: python


【解决方案1】:

我认为他们在Pymotw 有一个完美的例子 - 唯一不好的是它不适用于 Python 3 - 它是为 Python 2 编写的。下面是 Python 3 版本:

import readline
import logging

LOG_FILENAME = '/tmp/completer.log'
logging.basicConfig(filename=LOG_FILENAME,
                    level=logging.DEBUG,
                    )

class BufferAwareCompleter(object):
    def __init__(self, options):
        self.options = options
        self.current_candidates = []

    def complete(self, text, state):
        response = None
        if state == 0:
            # This is the first time for this text, so build a match list.
            
            origline = readline.get_line_buffer()
            begin = readline.get_begidx()
            end = readline.get_endidx()
            being_completed = origline[begin:end]
            words = origline.split()

            logging.debug('origline = %s', repr(origline))
            logging.debug('begin = %s', begin)
            logging.debug('end = %s', end)
            logging.debug('being_completed = %s', being_completed)
            logging.debug('words = %s', words)
            
            if not words:
                self.current_candidates = sorted(self.options.keys())
            else:
                try:
                    if begin == 0:
                        # first word
                        candidates = self.options.keys()
                    else:
                        # later word
                        first = words[0]
                        candidates = self.options[first]
                    
                    if being_completed:
                        # match options with portion of input
                        # being completed
                        self.current_candidates = [w for w in candidates if w.startswith(being_completed)]
                    else:
                        # matching empty string so use all candidates
                        self.current_candidates = candidates

                    logging.debug('candidates = %s', self.current_candidates)
                    
                except (KeyError, IndexError) as err:
                    logging.error('completion error: %s', err)
                    self.current_candidates = []
        
        try:
            response = self.current_candidates[state]
        except IndexError:
            response = None
        logging.debug('complete(%s, %s) => %s', repr(text), state, response)
        return response
            

def input_loop():
    line = ''
    while line.strip() != 'stop':
        line = input('Prompt ("stop" to quit): ')
        print('Dispatch %s' % line)

# Register our completer function
readline.set_completer(BufferAwareCompleter(
    {'list':['files', 'directories'],
     'print':['byname', 'bysize'],
     'stop':[],
    }).complete)

# Use the tab key for completion
readline.parse_and_bind('tab: complete')

# Prompt the user for text
input_loop()

【讨论】:

  • @sysinfo 请不要发布 Thank youThanks 之类的 cmets - 相反,只需为答案投票,如果可能,请接受它。
猜你喜欢
  • 2023-03-29
  • 1970-01-01
  • 2014-01-25
  • 2023-01-23
  • 2017-04-19
  • 2020-05-01
  • 1970-01-01
  • 2021-12-15
  • 1970-01-01
相关资源
最近更新 更多