В прошлой своей статье я рассказывал о том, как начинал создавать свой якобы «терминал». Её заметило две с лишним тысячи человек, что для меня уже было каким‑то неплохим числом. Некоторые писали мне различные советы, кто‑то давал критику по статье. И вот, спустя небольшое время работы я снова пишу статью о своем «терминале» под именем 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. За прогрессом работы можно следить в репозитории проекта. Также можно всегда сделать форк или пулл реквест и помочь проекту.
Всем спасибо за прочтение моей статьи!
