<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:dw="https://www.dreamwidth.org">
  <id>tag:dreamwidth.org,2011-12-22:1181104</id>
  <title>Блокнотик Centaur’а</title>
  <subtitle>Yuri Khan</subtitle>
  <author>
    <name>Yuri Khan</name>
  </author>
  <link rel="alternate" type="text/html" href="https://yurikhan.dreamwidth.org/"/>
  <link rel="self" type="text/xml" href="https://yurikhan.dreamwidth.org/data/atom"/>
  <updated>2016-01-20T18:06:37Z</updated>
  <dw:journal username="yurikhan" type="personal"/>
  <entry>
    <id>tag:dreamwidth.org,2011-12-22:1181104:63673</id>
    <link rel="alternate" type="text/html" href="https://yurikhan.dreamwidth.org/63673.html"/>
    <link rel="self" type="text/xml" href="https://yurikhan.dreamwidth.org/data/atom/?itemid=63673"/>
    <title>Раздумья о файловых менеджерах</title>
    <published>2016-01-20T18:06:37Z</published>
    <updated>2016-01-20T18:06:37Z</updated>
    <category term="mc"/>
    <category term="usability"/>
    <category term="soft"/>
    <category term="tmux"/>
    <category term="far manager"/>
    <dw:security>public</dw:security>
    <dw:reply-count>8</dw:reply-count>
    <content type="html">&lt;p&gt;Когда-то в прошлой жизни я сидел на Windows. Там был FAR. FAR был инструментом для всего.&lt;/p&gt;

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

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

&lt;a name="cutid1"&gt;&lt;/a&gt;&lt;p&gt;Функция запуска команд шелла первична. Первое, что должно быть в файловом менеджере — это командная строка и буфер с результатами выполнения команд. Панели вторичны и нужны для удобного выбора файловых аргументов к этим командам и для естественного порядка ввода команд (сначала — что и куда (или с чем), потом уже — что делать). Панели можно прятать (&lt;kbd&gt;Ctrl+O&lt;/kbd&gt;). Командную строку прятать нельзя.&lt;/p&gt;

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

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

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

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

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

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

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

&lt;p&gt;А что если мы… принесём в проект &lt;em&gt;весь&lt;/em&gt; &lt;code&gt;tmux&lt;/code&gt; как чёрный ящик?&lt;/p&gt;

&lt;p&gt;Пруф-оф-концепт:&lt;/p&gt;

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

&lt;p&gt;Теперь можно остановиться и посмотреть, что же мы получили.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Зная истинное имя сокета сессии, мы можем повелевать всеми её окнами и панелями.&lt;/li&gt;
&lt;li&gt;Например, мы можем слать в шелл нажатия клавиш и текстовые строки: при гулянии по каталогам выполняем &lt;code&gt;tmux -L $имя_сокета send-keys -t %1 C-u ' cd /usr/share' Enter C-l C-y&lt;/code&gt; (&lt;kbd&gt;C-u&lt;/kbd&gt; для сохранения командной строки и &lt;kbd&gt;C-y&lt;/kbd&gt; для восстановления — bash- и user-specific, но можно сделать настраиваемым).&lt;/li&gt;
&lt;li&gt;Также у нас есть многоэкранный и многопанельный движок. Мы можем легко по &lt;kbd&gt;F3&lt;/kbd&gt; открывать внешний вьюер в новом экране, по &lt;kbd&gt;F4&lt;/kbd&gt; — внешний редактор в новом экране. А это значит, что реализовывать-то надо только собственно панели, ну и, может быть, какие-нибудь внутренние команды для удобной работы с файлами.&lt;/li&gt;
&lt;li&gt;По &lt;kbd&gt;Ctrl+O&lt;/kbd&gt; просто зумим или раззумливаем панель с шеллом.&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=yurikhan&amp;ditemid=63673" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
</feed>
