一个好的REPL(Read-Eval-Print Loop),交互式命令行程序,需要具备以下几个特点:
- 最基本的命令行与回显
- 回显带有分页效果,类似 more
- 带有历史命令推荐
- 关键词自动补全
- 语法高亮
示例
我们以模拟Sql的REPL来将这些特性一点点来累加起来
基本命令行与回显
from prompt_toolkit import prompt
while 1:
user_input = prompt('>')
print(user_input)
添加分页效果
使用的是click.echo_via_pager
from prompt_toolkit import prompt
import click
while 1:
user_input = prompt('>')
click.echo_via_pager(user_input)
历史命令推荐
使用的是 prompt_toolkit.history
模块中的 FileHistory
会创建一个历史记录的文件,然后通过prompt_toolkit.auto_suggest.AutoSugguestFromHistory
进行推荐。
from prompt_toolkit import prompt
from prompt_toolkit.history import FileHistory
from prompt_toolkit.auto_suggest import AutoSuggestFromHistory
import click
while 1:
user_input = prompt('>',
history=FileHistory('history.txt'),
auto_suggest=AutoSuggestFromHistory(),
)
click.echo_via_pager(user_input)
关键词补全
关键词补全有两种方法:
- 用
prompt_toolkit.completion.WordCompleter
直接定义单词 - 用
prompt_toolkit.completion
中的Completer
和Completion
配合fuzzyfinder
进行模糊查询,这种方法自定义程度更高
WordCompleter
from prompt_toolkit import prompt
from prompt_toolkit.history import FileHistory
from prompt_toolkit.auto_suggest import AutoSuggestFromHistory
import click
from prompt_toolkit.completion import WordCompleter
SQLCompleter = WordCompleter(
['select', 'from', 'insert', 'update', 'delete', 'drop'], ignore_case=True)
while 1:
user_input = prompt('>',
history=FileHistory('history.txt'),
auto_suggest=AutoSuggestFromHistory(),
completer=SQLCompleter,
)
click.echo_via_pager(user_input)
fuzzyfinder
from prompt_toolkit import prompt
from prompt_toolkit.history import FileHistory
from prompt_toolkit.auto_suggest import AutoSuggestFromHistory
import click
from prompt_toolkit.completion import Completer, Completion
from fuzzyfinder.main import fuzzyfinder
SQLKeywords = ['select', 'from', 'insert', 'update', 'delete', 'drop']
class SQLCompleter(Completer):
def get_completions(self, document, complete_event):
word_before_cursor = document.get_word_before_cursor(WORD=True)
matches = fuzzyfinder(word_before_cursor, SQLKeywords)
for m in matches:
yield Completion(m, start_position=-len(word_before_cursor))
while 1:
user_input = prompt('>',
history=FileHistory('history.txt'),
auto_suggest=AutoSuggestFromHistory(),
completer=SQLCompleter(),
)
click.echo_via_pager(user_input)
语法高亮
高亮可以使用Pygments.lexers
模块
from prompt_toolkit import prompt
from prompt_toolkit.history import FileHistory
from prompt_toolkit.auto_suggest import AutoSuggestFromHistory
import click
from prompt_toolkit.completion import Completer, Completion
from fuzzyfinder.main import fuzzyfinder
from pygments.lexers.sql import SqlLexer
from prompt_toolkit.lexers import PygmentsLexer
SQLKeywords = ['select', 'from', 'insert', 'update', 'delete', 'drop']
class SQLCompleter(Completer):
def get_completions(self, document, complete_event):
word_before_cursor = document.get_word_before_cursor(WORD=True)
matches = fuzzyfinder(word_before_cursor, SQLKeywords)
for m in matches:
yield Completion(m, start_position=-len(word_before_cursor))
while 1:
user_input = prompt('SQL>',
history=FileHistory('history.txt'),
auto_suggest=AutoSuggestFromHistory(),
completer=SQLCompleter(),
lexer=PygmentsLexer(SqlLexer)
)
click.echo_via_pager(user_input)
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 365433079@qq.com