Помните, как вы пытались записать демонстрацию CLI-инструмента? Делимся материалом о том, как записывать гифки с консоли кодом, чтобы тестировать сборки ПО и показывать ваши консольные инструменты.
Этот пример сгенерирован с помощью VHS (посмотреть исходный код).
Для начала установим VHS и создадим файл .tape
:
vhs new demo.tape
Откроем файл .tape
в вашем любимом $EDITOR
:
vim demo.tape
Файлы .tape
состоят из серий команд. Команды — это инструкции, с помощью которых работает виртуальная консоль VHS. Полный перечень возможных команд доступен здесь.
# Куда записать гифку?
Output demo.gif
# Установим размер консоли 1200x600 и шрифт 46 px.
Set FontSize 46
Set Width 1200
Set Height 600
# Введём команду в консоль.
Type "echo 'Welcome to VHS!'"
# Выдержим паузу для пущей драмы…
Sleep 500 ms
# Запустим команду нажатием Enter.
Enter
# Немного полюбуемся тем, что получилось.
Sleep 5 s
Сохраним файл по готовности и скормим его VHS:
vhs < demo.tape
Готово! Смотрим новый файл demo.gif
(или как вы назвали его командой Output
) в директории:
В директории examples/
есть и другие примеры.
Для работы VHS требуется установкаttyd
иffmpeg
в вашу директориюPATH
.
Воспользуемся менеджером пакетов:
# macOS или Linux
brew install charmbracelet/tap/vhs ffmpeg
brew install ttyd --HEAD
# Arch Linux (btw)
yay -S vhs ttyd ffmpeg
# Nix
nix-env -iA nixpkgs.vhs nixpkgs.ttyd nixpkgs.ffmpeg
# Debian/Ubuntu
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://repo.charm.sh/apt/gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/charm.gpg
echo "deb [signed-by=/etc/apt/keyrings/charm.gpg] https://repo.charm.sh/apt/ * *" | sudo tee /etc/apt/sources.list.d/charm.list
# ttyd ставим отсюда: https://github.com/tsl0922/ttyd/releases
sudo apt update && sudo apt install vhs ffmpeg
# Fedora/RHEL
echo '[charm]
name=Charm
baseurl=https://repo.charm.sh/yum/
enabled=1
gpgcheck=1
gpgkey=https://repo.charm.sh/yum/gpg.key' | sudo tee /etc/yum.repos.d/charm.repo
# ttyd ttyd ставим отсюда: https://github.com/tsl0922/ttyd/releases
sudo yum install vhs ffmpeg
Или запустим VHS напрямую из Docker'а вместе с зависимостями:
docker run ghcr.io/charmbracelet/vhs <cassette>.tape
Или скачаем:
Или установим командой go
:
go install github.com/charmbracelet/vhs@latest
У VHS есть встроенный SSH-сервер! Когда вы запускаете VHS как отдельное приложение, доступ к нему можно получить, как к приложению, установленному локально. VHS будут доступны команды и программы на хосте, ставить их на свою машину нужды нет.
Запускаем сервер командой:
vhs serve
Получаем доступ к VHS с любой машины через ssh
:
ssh vhs.example.com < demo.tape > demo.gif
Посмотреть всю документацию по VHS в командной строке поможет команда
vhs manual
.
Вот несколько основных типов команд VHS:
Output <путь>
: задать местоположение и формат вывода файла; Set <настройки> Value
: задать параметры записи;Type "<символы>"
: имитация набора текста;Left
Right
Up
Down
: клавиши со стрелками;Backspace
Enter
Tab
Space
: специальные клавиши;Ctrl+<char>
: клавиша с зажатым ctrl;Sleep <время>
: выждать указанное время;Hide
: скрыть выводимые команды;Show
: не скрывать выводимые команды.
Команда Output
позволяет задать местоположение и формат вывода файла для визуализации. В файл .tape
можно записать более одного местоположения для вывода файлов.
Output out.gif
Output out.mp4
Output out.webm
Output frames/ # директория с кадрами, представленными последовательностью PNG
Команда Set
позволяет менять общие настройки консоли: параметры шрифта, настройки окна и директорию для вывода GIF-файлов.
Настройки задаются выше уровня файла .tape
. Любые настройки (кроме скорости набора — TypingSpeed
) применяются после игнорирования всех команд, кроме указания настроек (Set) и вывода (Output).
Размер шрифта задаём командой Set FontSize <число>
:
Set FontSize 10
Set FontSize 20
Set FontSize 40
Семейство шрифтов задаём командой Set FontFamily "<шрифт>"
:
Set FontFamily "Monoflow"
Ширину консоли задаём командой Set Width
:
Set Width 300
Высоту консоли — командой Set Height
:
Set Height 1000
Межзнаковый интервал (разреженный/уплотнённый) задаём командой Set LetterSpacing
:
Set LetterSpacing 20
Высоту строк задаём командой Set LineHeight
:
Set LineHeight 1.8
Set TypingSpeed 500 ms # 500 ms
Set TypingSpeed 1 s # 1 s
Этот параметр задаёт скорость набора в секундах после нажатия клавиши. Например, при значении 0.1
пауза между набором символов будет 0.1 s
(100 ms
).
Настройку можно изменить командой с синтаксисом вида @<время>
.
Set TypingSpeed 0.1
Type "100ms delay per character"
Type@500ms "500ms delay per character"
Оформление консоли задаём командой Set Theme
. Оформление текста (foreground) и фона (background) задаётся строковой переменной формата JSON, которая ограничена 16 базовыми цветами.
Set Theme { "name": "Whimsy", "black": "#535178", "red": "#ef6487", "green": "#5eca89", "yellow": "#fdd877", "blue": "#65aef7", "purple": "#aa7ff0", "cyan": "#43c1be", "white": "#ffffff", "brightBlack": "#535178", "brightRed": "#ef6487", "brightGreen": "#5eca89", "brightYellow": "#fdd877", "brightBlue": "#65aef7", "brightPurple": "#aa7ff0", "brightCyan": "#43c1be", "brightWhite": "#ffffff", "background": "#29283b", "foreground": "#b3b0d6", "selectionBackground": "#3d3c58", "cursorColor": "#b3b0d6" }
Длину пробела консоли (в пикселях) задаём командой Set Padding
:
Set Padding 0
Частоту захвата кадров VHS — командой Set Framerate
:
Set Framerate 60
Скорость воспроизведения выходного файла задаём командой Set Framerate
:
Set PlaybackSpeed 0.5 # Замедлим вывод в 2 раза
Set PlaybackSpeed 1.0 # Вернём нормальную скорость(заданную по умолчанию)
Set PlaybackSpeed 2.0 # Ускорим вывод в 2 раза
Команда Type
позволяет имитировать нажатия клавиш. Type
можно использовать для скриптов с вводом текста в консоль. Это удобно как для ввода команд, так и для взаимодействия с подсказками и текстовым пользовательским интерфейсом в консоли. Команда принимает строковый аргумент из символов, которые нужно набрать.
Стандартная скорость ввода задаётся командой Set TypingSpeed
, но аргумент @time
имеет приоритет над этой командой.
# Напечатаем что-нибудь
Type "Whatever you want"
# Напечатаем что-нибудь очень медленно!
Type@500ms "Slow down there, partner."
Команды для клавиш принимают необязательный атрибут @time
и имеют необязательный счётчик повторений count
для повторения нажатия клавиши через каждый интервал вида <время>
:
Key[@<time>] [count]
Нажатие клавиши backspace задаём командой Backspace
:
Backspace 18
Вы можете получить доступ к модификатору ctrl и отправлять последовательности ctrl по командое Ctrl
:
Ctrl+R
Нажатие клавиши enter задаём командой Enter
:
Enter 2
Нажатие одной из клавиш со стрелками задаём командой Up
, Down
, Left
или Right
:
Up 2
Down 2
Left
Right
Left
Right
Type "B"
Type "A"
Нажатие клавиши tab задаём командой Tab
:
Tab@500ms 2
Нажатие пробела — командой Space
:
Space 10
Команда Sleep
позволяет продолжить захват кадров без взаимодействия с консолью. Это полезно, когда нужно дождаться завершения какого-то процесса и включить это ожидание в запись. Например, это может быть загрузка или изменение значения счётчика. Аргумент команды — число секунд ожидания.
Sleep 0.5 # 500 милисекунд
Sleep 2 # 2 секунды
Sleep 100 ms # 100 милисекунд
Sleep 1 s # 1 секунда
Команда Hide
позволяет исключить из выходного файла любые команды:
Hide
Эта команда полезна при любой отладке и очистке, которая может потребоваться при записи гифки, например при сборке последней версии бинарного файла и удалении бинарника после записи демо:
Output example.gif
# Настройка
Hide
Type "go build -o example . && clear"
Enter
Show
# Запись...
Type 'Running ./example'
...
Enter
# Очистка кода
Hide
Type 'rm example'
Команда Show
позволяет указать, что следующие за ней команды нужно снова включить в выходной файл. Так как по умолчанию все команды являются «видимыми», эта команда может потребоваться только после использования Hide
:
Hide
Type "You won't see this being typed."
Show
Type "You will see this being typed."
VHS можно соединить с вашим конвейером непрерывной интеграции (CI), чтобы ваши гифки обновлялись вместе с официальным VHS GitHub Action:
charmbracelet/vhs-action
VHS может использоваться и для тестирования интеграции. Используйте выходной формат .txt
ли .ascii
для генерации golden-файлов. Храните эти файлы в репозитории git, чтобы не было различий между отдельными запусками файла .tape
:
Output golden.ascii
При работе с файлами .tape
в редакторах с поддержкой Tree-sitter доступна «грамматика» Tree-sitter:
charmbracelet/tree-sitter-vhs
Она отлично работает в Neovim, Emacs и многом другом!
на главную сниппетов