Как стать автором
Обновить

Terminode или Новичок пишет «терминал» (часть 2)

Уровень сложностиСредний
Время на прочтение4 мин
Количество просмотров1.6K

В прошлой своей статье я рассказывал о том, как начинал создавать свой якобы «терминал». Её заметило две с лишним тысячи человек, что для меня уже было каким‑то неплохим числом. Некоторые писали мне различные советы, кто‑то давал критику по статье. И вот, спустя небольшое время работы я снова пишу статью о своем «терминале» под именем Terminode. Вот она вторая часть «новичка пишущего терминал».

Что же это такое?

Terminode — CLI App, позволяющее немного облечить работу с терминалом.

Судя по прошлой статье я понял, что я пишу CLI App. На тот момент мой проект не выделялся ничем не мог похвастаться каким‑то прям функциями. Сейчас я добавил некоторые интересные фичи, используя новую библиотеку — prompt_toolkit

Prompt Toolkit — радость любого питониста

prompt_toolkit — библиотека, позволяющая создавать мощные приложения в терминале.

Pyvim - Vim в терминале на Python
Pyvim - Vim в терминале на Python

Данная библиотека позволяет создавать из простых 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()

Здесь начнём по порядку разбирать, за что отвечают различные настройки

  1. cmd_completer— Автодополнение (ну почти). Когда приложение видит что‑то похожее на команду, которая есть в списке кастомных команд, то она предлагает быстро дописать эту/эти команды.

  2. completer — Использует список слов, которые нужно сверять с промптом.

  3. mouse_support — Позволяет скроллить список предлагаемых команд в терминале с помощью колесика мыши. Честно, багованная фича.

  4. auto_suggest — Автодополнение из истории введенных Вами команд. Помогает быстрее вспоминать Ваши бывшие промпты!

Заключение этой работы

В заключении второй части (она вышла конечно короче) могу сказать, что моё приложение становится всё более удобным для работы с терминалом. На текущий момент уже можнонеплохо скоротать время, используя Terminode. Также я напоминаю, что есть система модулей — моды для Terminode, которые может создать кто‑угодно!

Я надеюсь вам было интересно читать мою статью. После некоторых следующих наработок я напишу третью часть DevBlog‑а о Terminode. За прогрессом работы можно следить в репозитории проекта. Также можно всегда сделать форк или пулл реквест и помочь проекту.

Всем спасибо за прочтение моей статьи!

GitHub Repo | TG-Channel

Теги:
Хабы:
+4
Комментарии5

Публикации

Работа

Data Scientist
45 вакансий

Ближайшие события