Python实现Tab自动补全和历史命令管理的方法

yizhihongxing

演示代码可以在这里找到:https://github.com/neal1991/articles/blob/master/python-tab-auto-completion/autocompletion.py,接下来的讲解将以这份代码为例子。

什么是Tab自动补全和历史命令管理

在命令行中,我们经常需要输入很长的命令,会出现拼写错误、错误的命令、或者常见的命令不够智能的情况。Tab自动补全和历史命令管理正是这些问题的解决方案。

Tab自动补全: 在输入命令时可以利用Tab键,来自动补全命令。当输入的文字只有一个可能性,或者系统能够解决同名问题的时候,就能够自动匹配。如果有多个匹配,则可以通过多敲几个字母来缩小范围。

历史命令管理: 在输入命令时,我们经常需要输入之前输入过的某个命令。此时,如果可以通过上下箭头选择之前的命令,那么就可以省去不少的重复输入。

Python实现Tab自动补全和历史命令管理的方法

实现Tab自动补全和历史命令管理的方法便是通过输入的字符来快速查询匹配的命令传递给控制台。

通过读取控制台输入,来实现Tab自动补全

在Python中通过使用readline库,我们可以监控控制台的输入流。我们可以找到当前输入流中的最后一个字符,然后将标记位移到最后一个字符后,以使进行自动补全,如下所示:

line_buffer = readline.get_line_buffer()
line_buffer += " "

if re.search(r"^\s*ls\s*$", line_buffer):
    line_buffer = "ls --color=auto"

line_buffer = re.sub("\\\s", " ", line_buffer)
start_index = readline.get_begidx()
end_index = readline.get_endidx()

word_part = line_buffer[start_index:end_index]
match_list = [item for item in self._match_list if item.startswith(word_part)]

在上面的代码中,我们首先使用readline.get_line_buffer() 读取当前控制台输入的内容,在行尾加上一个空格,然后把正则表达式作用在当前输入字符的内容上。如果匹配到的是ls命令,我们加上--color=auto 参数,即着色显示文件目录。如果你习惯使用ls显示目录,这段代码加上这个判断非常方便。在处理好输入字符后,我们读取了当前输入字符的起始位置和结束位置,以确定我们需要自动补全的字符。在此之后,我们就可以对历史命令进行查找,如上代码所示,以便找到所有匹配的命令,这些命令也是我们需要展示在控制台供用户选择的命令。

readline.parse_and_bind("tab: complete")
readline.set_completer_delims(" \t\n()\"\'")
readline.set_completer(self.match)

在这段代码中,我们首先为Tab键绑定了自动完成操作。接下来我们为自动完成操作设置了分隔符,如下所示:

readline.set_completer_delims(" \t\n()\"\'")

在上面的代码中,我们设置了Tab、空格、换行、括号以及引号都是输入的分隔符。

接下来,我们将一个函数作为自动完成函数传递给readline.set_completer方法。在这个函数中,我们根据当前输入的东西和历史匹配的命令过滤出要展示在控制台上供用户选择的命令。由于使用Tab自动完成的目的是找到历史命令。因此我们方法的内容需要看下面的历史命令管理部分。

通过读取控制台输入来实现历史命令管理

在Python中,我们的历史命令管理主要通过readline模块实现。

为了使用历史命令管理,我们可以使用readline库中的readline方法获取当前行的内容,以便在用户按上下箭头时,将当前行中的内容载入下一个或上一个命令。接下来,我们可以读取历史命令列表,从而遍历在用户在控制台中输入过的历史记录。最常见的历史管理方法有两种:

第一种方法是使用readline模块中的readline.get_history_length() 方法来获取历史记录列表的长度,之后调用readline.get_history_item(index) 方法来读取我们需要的记录,并返回一个字符串。字符串最后附有一个代表每个选项的索引,如下所示:

index = readline.get_current_history_length() - 1
state = readline.get_history_item(index + 1)
print('%s - %s' % (index, state))

在上面的代码中,我们读取历史记录列表的长度以及读取了历史记录列表中的第一个匹配项。注意到,我们的索引从0开始,但readline.get_current_history_length() 返回的数据却是从1开始计算的,所以我们需要使用index + 1 来读取正确的偏移量。

第二种方法是使用readline模块中的readline.get_history_item(-n) 方法来获取历史记录列表中的最后n项,值为负数。当值为-1时,我们取到的是最后一项。这是因为负数表示取本身以及向前的项数,而不是从前向后的项数。

for index in range(max(self._history_list, None, item for item in 0, length):
    line_buffer += self._history_list[index]

在这段代码中,我们首先定义了一个使用for循环从0到历史记录列表长度的循环,以便读取历史记录列表的所有项,并将其保存在当前命令的单元中。

总结

自动补全能够快速让用户在控制台中找到他们想要的命令,因此是命令行工具开发中不可缺少的一部分。通过使用readline库,Python实现了自动匹配并显示历史命令,并为使用者提供了极大的方便。此外,上述的代码实现,也可以应用到其他的开发领域中,如网站开发、Python编程、以及命令从新编写等上。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python实现Tab自动补全和历史命令管理的方法 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • Python的缺点和劣势分析

    Python的缺点和劣势分析 Python是一种非常流行且使用广泛的编程语言,但在其方便和易用性之外,也有一些缺点和劣势。在本文中,我们将探究Python的缺点和劣势分析。 1. 较慢的执行速度 Python是一种解释型语言,因此其执行速度通常较慢。与其他编译型语言(如C++或Java)相比,Python通常需要更多的运行时间来执行相同的操作。这主要是由于P…

    python 2023年5月30日
    00
  • 如何检查NumPy数组中是否存在指定的值

    要检查NumPy数组中是否存在指定的值,可以使用np.isin()函数。该函数返回一个布尔数组,数组中的每个元素都是原数组中对应元素是否与指定值相等的结果。 下面是使用np.isin()函数的方法: 导入NumPy库,创建一个NumPy数组。 import numpy as np arr = np.array([1, 2, 3, 4, 5]) 使用np.is…

    python-answer 2023年3月25日
    00
  • 解决pycharm启动后总是不停的updating indices…indexing的问题

    这个问题是由于Pycharm在启动时需要对Python包进行扫描索引,如果包数量较多,则需要一些时间来进行索引。但是有些情况下,这个过程可能会出现意外中断,导致Pycharm无法完成索引任务。 以下是解决这个问题的步骤: 1. 检查是否有防火墙或者代理软件导致的网络问题 在索引Python包时,Pycharm需要连接到网站来获取Python包的信息。因此,如…

    python 2023年6月3日
    00
  • Python抓取Discuz!用户名脚本代码

    以下是Python抓取Discuz!用户名脚本代码的完整攻略: 步骤1:安装requests库 在使用Python抓取Discuz!用户名之前,需要安装requests库。以下是一个示例: pip install requests 在这个例子中,我们使用pip命令安装了requests库。 步骤2:发送HTTP请求 在完成安装requests库后,我们就可以…

    python 2023年5月14日
    00
  • BeautifulSoup获取指定class样式的div的实现

    在BeautifulSoup中,可以使用CSS选择器语法获取指定class样式的div。本文将详细讲解如何使用BeautifulSoup获取指定class样式的div,包括两个示例。 示例一:获取单个class样式的div 以下是一个示例代码,演示如何使用BeautifulSoup获取单个class样式的div: from bs4 import Beauti…

    python 2023年5月15日
    00
  • 使用 Python 检查互联网连接

    【问题标题】:Checking internet connection with Python使用 Python 检查互联网连接 【发布时间】:2023-04-03 15:06:01 【问题描述】: 我正在开发一个使用互联网的应用程序,因此我需要检查应用程序加载时是否有互联网连接,因此我使用此功能: def is_connected(): try: prin…

    Python开发 2023年4月8日
    00
  • 带有 Google App Engine Python 2.7 的 Django 1.2 中的自定义标签

    【问题标题】:Custom Tags in Django 1.2 with Google App Engine Python 2.7带有 Google App Engine Python 2.7 的 Django 1.2 中的自定义标签 【发布时间】:2023-04-05 12:11:02 【问题描述】: 使用 Webapp 在 Google App Eng…

    Python开发 2023年4月5日
    00
  • Python爬虫获取基金列表

    下面我将为您详细讲解如何用Python爬虫获取基金列表的完整攻略。 前置知识 在进行Python爬虫获取基金列表前,需要了解以下知识: Python编程基础 网络爬虫基础知识 HTTP协议 BeautifulSoup库 requests库 爬虫流程 使用Python爬虫获取基金列表的流程如下: 分析目标网站的HTML结构 发送HTTP请求获取目标网页的HTM…

    python 2023年6月3日
    00
合作推广
合作推广
分享本页
返回顶部