В прошлой своей статье я рассказывал о том, как начинал создавать свой якобы «терминал». Её заметило две с лишним тысячи человек, что для меня уже было каким‑то неплохим числом. Некоторые писали мне различные советы, кто‑то давал критику по статье. И вот, спустя небольшое время работы я снова пишу статью о своем «терминале» под именем Terminode. Вот она вторая часть «новичка пишущего терминал».
Что же это такое?
Terminode — CLI App, позволяющее немного облечить работу с терминалом.
Судя по прошлой статье я понял, что я пишу CLI App. На тот момент мой проект не выделялся ничем не мог похвастаться каким‑то прям функциями. Сейчас я добавил некоторые интересные фичи, используя новую библиотеку — prompt_toolkit
Prompt Toolkit — радость любого питониста
prompt_toolkit — библиотека, позволяющая создавать мощные приложения в терминале.

Данная библиотека позволяет создавать из простых CLI Apps, мощные текстовые редакторы, эмуляторы терминала.В ней есть автодополнение кода, подсветка синтаксиса, история введенных команд, Vim‑режим и многое другое. Эта библиотека позволила мне внести новые фичи в своей проект без особых усилий, а также немного «выделить» его среди других.
Автодополнение в Terminode
В моем приложении есть набор некоторых команд. Иногда вводить их надоедает, хочется вводить всё по нажатию одной кнопки. Поэтому сначала я улучшил свою переменную промптов
from prompt_toolkit import PromptSession
class Terminode:
def __init__(self):
self.username = config.username
self.session = PromptSession()
def run(self):
while True:
try:
now = datetime.now()
time_format = '%H:%M:%S'
cur_dir = os.getcwd()
cmd_prompt = f"{now:{time_format}} | {self.username} | {cur_dir} | "
user_input = self.session.prompt(cmd_prompt).strip()
PromptSession()
требуется для создания сессии ввода промптов. Эта сессия может сохранять введенные команды в файл истории. Также здесь я переместил cmd_prompt
внутрь цикла, чтобы убрать функцию обновления промпта (это помогло немного ускорить приложение)
Далее я добавил к сессии промптов уже добавление каждой введенной команды в файл истории
from sys_controller import get_script_root
from prompt_toolkit.history import FileHistory
self.session = PromptSession(history=FileHistory(
f"{get_script_root()}/history.terminode"))
Файл можно назвать как угодно, главное, чтобы он мог быть читаемым для библиотеки. Здесь также можно наблюдать секретную функцию get_script_root()
. В прошлый раз я допустил огромную ошибку, не посмотрев куда сохраняются логи моего приложения. Файлы Terminode сохранялись в той директории, которая была активна на этот момент в приложении. Из-за этого не работали многие функции приложения. Мною было принято решение добавить две функции, которые ищут путь до корневой папки Terminode и файлов в ней.
def get_script_root():
if getattr(sys, 'frozen', False):
return Path(sys.executable).parent
else:
return Path(__file__).parent.resolve()
def find_file_in_root(filename):
root_dir = get_script_root()
file_path = root_dir / filename
if file_path.exists():
return file_path
else:
raise FileNotFoundError(f"File {filename} not found in {root_dir}")
get_script_root()
отдает корневую папку приложения. find_file_in_root()
принимает название файла и отдает абсолютный путь до файла в корневой папке приложения. Эти две функции помогли мне заставить файлы создаваться только в корневой папке самого Terminode.
Автодополнение и подсказки из истории
После всех наработок пришло время добавлять автодополнение и подсказки.
На самом деле добавить их было очень просто, ведь всё это является настройкой в промптах библиотеки.
from prompt_toolkit.completion import WordCompleter
from prompt_toolkit.auto_suggest import AutoSuggestFromHistory
now = datetime.now()
time_format = '%H:%M:%S'
cur_dir = os.getcwd()
cmd_prompt = f"{now:{time_format}} | {self.username} | {cur_dir} | "
cmd_completer = WordCompleter(self.commands)
user_input = self.session.prompt(
cmd_prompt, completer=cmd_completer,
mouse_support=True, auto_suggest=AutoSuggestFromHistory()).strip()
Здесь начнём по порядку разбирать, за что отвечают различные настройки
cmd_completer
— Автодополнение (ну почти). Когда приложение видит что‑то похожее на команду, которая есть в списке кастомных команд, то она предлагает быстро дописать эту/эти команды.completer
— Использует список слов, которые нужно сверять с промптом.mouse_support
— Позволяет скроллить список предлагаемых команд в терминале с помощью колесика мыши. Честно, багованная фича.auto_suggest
— Автодополнение из истории введенных Вами команд. Помогает быстрее вспоминать Ваши бывшие промпты!
Заключение этой работы
В заключении второй части (она вышла конечно короче) могу сказать, что моё приложение становится всё более удобным для работы с терминалом. На текущий момент уже можнонеплохо скоротать время, используя Terminode. Также я напоминаю, что есть система модулей — моды для Terminode, которые может создать кто‑угодно!
Я надеюсь вам было интересно читать мою статью. После некоторых следующих наработок я напишу третью часть DevBlog‑а о Terminode. За прогрессом работы можно следить в репозитории проекта. Также можно всегда сделать форк или пулл реквест и помочь проекту.
Всем спасибо за прочтение моей статьи!