yurikhan: (Default)
[personal profile] yurikhan

Когда-то в прошлой жизни я сидел на Windows. Там был FAR. FAR был инструментом для всего.

Потом я пересел на X11/GNU/Linux. Там FAR’а нет. Есть отдельно Midnight Commander, у которого убогий редактор, и отдельно Emacs, у которого убогий файловый менеджер. Об Emacs’е я здесь и сейчас говорить не буду. Буду говорить о классе программ, позиционирующихся как файловые менеджеры. Говорить буду резко и в основном для себя и про себя. Всем остальным читателям к каждому высказыванию неявно добавлять «IMHO».

Итак, что такое файловый менеджер? Многие считают, что файловый менеджер — это две синие панельки, между которыми можно копировать файлы. Ну и изредка запускать команды шелла. А вот и ни фига.

Функция запуска команд шелла первична. Первое, что должно быть в файловом менеджере — это командная строка и буфер с результатами выполнения команд. Панели вторичны и нужны для удобного выбора файловых аргументов к этим командам и для естественного порядка ввода команд (сначала — что и куда (или с чем), потом уже — что делать). Панели можно прятать (Ctrl+O). Командную строку прятать нельзя.

Как это решается в mc? У терминала есть два буфера. Один — бесконечная лента с прокруткой. Другой — размером с окно, экран для приложений. Панели отображаются в этом самом альтернативном буфере. Ctrl+O переключает между этими двумя буферами. За панелями работает настоящий живой шелл (в подпроцессе, связанном с псевдотерминалом, создаваемым Midnight Commander’ом, чтобы последний мог посылать в него команды помимо пользователя). Под панелями отображается имитация. Если пользователь набирает в неё команду и жмёт Enter, mc прячет панели и посылает введённую команду в шелл. Если пользователь гуляет по каталогам, mc посылает в шелл команду cd куда/теперь/перейти.

Чем плоха имитация комадной строки, и почему в FAR’е это было незаметно?

В Windows у нас есть один командный процессор, cmd.exe, с довольно скудными средствами редактирования командной строки, историей и рудиментарным tab completion’ом. В GNU/Linux у нас есть десять тысяч шеллов, и каждый со своими особенностями. И tab completion у них очень развитый.

Соответственно, пользователь, пересевший с голого cmd на FAR, не испытывает никаких неудобств. Ну может, разве что, придётся переучиться историю листать не стрелками вверх/вниз, а Ctrl+E/Ctrl+X. Пересесть с bash’а на mc невозможно, потому что сразу теряешь почти весь completion. В командной строке под панелями работает только дополнение имён файлов. В шелле за панелями работает всё. Содержимое командной строки mc никак не связано с командной строкой шелла, пока не нажмёшь Enter. Поэтому, когда ты написал git checkout и хочешь вспомнить, как называется нужный тебе бранч, у тебя есть выбор: либо спрятать панели, выполнить за ними git branch, запомнить нужное имя, вернуть панели, ввести имя ветки; либо выругаться, стереть всё, спрятать панели, набрать git checkout и воспользоваться completion’ом.

А что нужно, чтобы иметь полноценный completion в панелях?

Долго думать не нужно, чтобы понять, что имитация командной строки не катит. В ней, в принципе, можно было бы с большими трудозатратами эмулировать, скажем, bash completion. Даже с его API расширения. Но если у пользователя основной шелл — zsh, то он будет страдать. Нет, нам нужен под панелями настоящий шелл. Причём, в идеале, тот же самый, который и за панелями. Чтобы при включении/отключении панелей у нас сохранялось содержимое командной строки.

Ни один файловый менеджер под GNU/Linux, если верить некоторым участникам linux.org.ru, так не делает. Потому что сложно. Это ж надо на лету менять размер псевдотерминала и при включённых панелях рулить отображением. Поди ещё и всю функциональность эмулятора терминала придётся самому поддерживать. Да ну нафиг, тут придётся половину tmux’а в проект принести.

А что если мы… принесём в проект весь tmux как чёрный ящик?

Пруф-оф-концепт:

  • На старте запускаем tmux с отдельным (от пользовательского) конфигом, на отдельном управляюшем сокете, с новой сессией.
  • Делим первое и пока единственное окно на две части (они будут называться %0 и %1). Нижнюю (%1) стягиваем до минимума и пускаем в ней шелл.
  • В %0 пускаем панели.
  • Панель с шеллом держим почти всегда активной (чтоб в ней был курсор). В нашем конфиге tmux’а биндим клавиши, которые будут обрабатываться панелями, чтоб они перехватывались и отправлялись в панели.

Теперь можно остановиться и посмотреть, что же мы получили.

  • Зная истинное имя сокета сессии, мы можем повелевать всеми её окнами и панелями.
  • Например, мы можем слать в шелл нажатия клавиш и текстовые строки: при гулянии по каталогам выполняем tmux -L $имя_сокета send-keys -t %1 C-u ' cd /usr/share' Enter C-l C-y (C-u для сохранения командной строки и C-y для восстановления — bash- и user-specific, но можно сделать настраиваемым).
  • Также у нас есть многоэкранный и многопанельный движок. Мы можем легко по F3 открывать внешний вьюер в новом экране, по F4 — внешний редактор в новом экране. А это значит, что реализовывать-то надо только собственно панели, ну и, может быть, какие-нибудь внутренние команды для удобной работы с файлами.
  • По Ctrl+O просто зумим или раззумливаем панель с шеллом.

Profile

yurikhan: (Default)
Yuri Khan

August 2018

S M T W T F S
   1234
567891011
12131415161718
19202122232425
26 2728293031 

Links

Most Popular Tags

Page Summary

Style Credit

Expand Cut Tags

No cut tags
Page generated 2025-06-27 04:22
Powered by Dreamwidth Studios