Наверное все из нас открывали эмулятор терминала в Linux. Вроде, ничего необычного нет и он отлично вписывается в систему. Но погодите, а что у нас делает Ctrl+C? Ну конечно он копирует останавливает текст текущую в программу буфер-обмена! Стоп, что? Во всей системе он копирует текст, а в терминале вдруг он останавливает программу, а для копирования используется Ctrl+Shift+C. Это как минимум нестандартно, поэтому давайте разберёмся почему так и исправим это.
Почему?
Ну для начала давайте поймём что такое Ctrl:
Ctrl — клавиша на клавиатуре компьютера, обычно используемая как клавиша-модификатор. Изначально появилась на телетайпах и видеотерминалах для ввода управляющих символов (отсюда и название) — на многих терминалах эта клавиша просто сбрасывала в «0» бит № 6 в коде передаваемой клавиши, что позволяло вводить символы из области 00-1F, недоступные при вводе напрямую.
Самое интересное, что такое поведение было в UNIX, а затем перешло и в современный Linux. Да, если мы откроем ASCII-таблицу через $ man ascii
(или онлайн), то можем заметить, что если взять любой управляющий символ и прибавить к нему 40 в шестнадцатеричной системе счисление, то мы получим символ (который будет находится ровно во второй колонке напротив) который надо нажать с Ctrl чтобы получить управляющий символ. Да, именно поэтому, к примеру, Ctrl+L передаёт именно символ FORM FEED, который служит для очистки терминала. (подробнее про символы можно узнать в Википедии)
Но время шло, появился GUI и Apple Computer Company решила в своём компьютере «Lisa» использовать нижний ряд раскладки QWERTY с Command-модификатором уже привычным нам образом, а именно: Z для отмены, X для вырезания, C для копирования, V для вставки. Это решение оказалось очень удачным, поэтому именно его растащили в другие ОС и именно оно дожило до наших дней.
Думаем как исправлять конфликт
Окей, а можно сделать что-бы Ctrl работал везде одинаково? Ну можно, конечно, настроить чтобы клавиши X, C, V вместо того, чтобы слать управляющие символы, работали бы с буфер-обмена. А символ EOT, который останавливает выполнение программы и шлётся по умолчанию на Ctrl+C, выполняло бы другое сочетание, но это не наш метод. Сочетания превращаются в кашу, например, теперь нельзя включить выделение блоками в Vim на Ctrl+V, а Ctrl+C который по другому используется в Nano который у нас другой клавише. (Да, вы вряд-ли будете использовать vim и nano одновременно, но это первое что мне пришло в голову, и тут могут быть любые другое программы). Поэтому, давайте посмотрим как исправляют это другие:
Windows. Когда-то это была моя основная ОС, но в терминал она всегда умела плохо. Изначально даже копировать и вставлять можно было только через контекстное меню, браво сейчас это исправили. В общем смотреть тут не на что.
MacOS. А тут уже интереснее! Терминал тут самый самый обычный, даже обычный zsh (а раньше был не менее обычный bash). Ctrl, соответственно, тут работает также как и обычном терминале Linux. Но если мы захотим что-то скопировать, для этого придётся использовать не Ctrl, а Cmd. И так по всей системе, никакого конфликта или различий в сочетаниях в разных приложениях нет! Выглядит очень хорошо!
Исправляем конфликт
Ну, в точности скопировать вариант с MacOS у нас не выйдет, как минимум потому что, у нас нет клавиши Command, но даже если использовать подобный Super, то ничего исправить не получиться, потому что все программы ожидают именно Ctrl. Но! Мы всегда используем один и тот же эмулятор терминала, к примеру я использую Kitty.
Поскольку Super в Linux не использует почти ни одна программа, ему самое место для управления системой (я использую его для i3wm). Как раз слово Super будет значит что мы управляем чем-то сверх (окнами в целом, а не программой). Поэтому для терминала лучше всего подходит другой модификатор, а именно у нас остался только Alt.
Что ж, в Kitty нет простой перестановки модификаторов (да и в других терминалах я её не видел), поэтому вспоминаем что Ctrl лишь меняет вводимые символы, поэтому мы делаем чтобы сочетания с Alt их автоматически меняли подобным образом.
Конфиг
Меняем действия с терминалом с Ctrl+Shift на Ctrl:
kitty_mod ctrl
Делаем чтобы Alt слал управляющие символы:
map alt+at send_text all \x00
map alt+a send_text all \x01
map alt+b send_text all \x02
map alt+c send_text all \x03
map alt+d send_text all \x04
map alt+e send_text all \x05
map alt+f send_text all \x06
map alt+g send_text all \x07
map alt+h send_text all \x08
map alt+i send_text all \x09
map alt+j send_text all \x0a
map alt+k send_text all \x0b
map alt+l send_text all \x0c
map alt+m send_text all \x0d
map alt+n send_text all \x0e
map alt+o send_text all \x0f
map alt+p send_text all \x10
map alt+q send_text all \x11
map alt+r send_text all \x12
map alt+s send_text all \x13
map alt+t send_text all \x14
map alt+u send_text all \x15
map alt+v send_text all \x16
map alt+w send_text all \x17
map alt+x send_text all \x18
map alt+y send_text all \x19
map alt+z send_text all \x1a
map alt+bracketleft send_text all \x1b
map alt+backslash send_text all \x1c
map alt+bracketright send_text all \x1
map alt+asciicircum send_text all \x1e
map alt+underscope send_text all \x1f
Ага, а теперь тащим попкорн смотреть как я (дурак со своими дикими кофигами) буду в терминале пытаться нажимать Alt!
Да, по началу это может показаться проблемой. Сначала я думал сделать не занятые сочетания для Alt, но тогда я бы не смог нажимать Alt+C и тому подобные сочетания. Потом я думал сделать обычные сочетания с Alt на Shift+Alt, но этот вариант не заработал, но на самом то деле это всё и не нужно! Что такое Alt? Если Ctrl у нас просто смещает символы, то Alt просто посылает ESC, а затем уже нажатую букву!
Об подобном даже говорится в туториале Emacs
Для управления Emacs обычно используются сочетания клавиш (key -- сочетание клавиш клавиатуры и/или кнопок мыши), включающие в себя клавишу CONTROL (иногда отмечаемая как CTRL или CTL) или клавишу META (иногда помеченную как ALT или EDIT). Вместо того, чтобы каждый раз писать META или CONTROL, мы будем использовать следующие сокращения:
C- — следует удерживать клавишу CONTROL, пока набирается символ <chr> . Так, C-f должно означать: одновременно нажать клавиши CONTROL и f.
M- — следует удерживать клавишу META, пока набирается символ <chr> . Если нет клавиши META, ALT или EDIT, то нажмите, <ESC> отпустите ее, а потом наберите символ <chr>.
Поэтому, если мне в терминале понадобится нажать Alt, то я смогу нажать ESC, а потом нужную клавишу (ESC у меня на Caps Lock, поэтому это будет очень легко). Единственное "но": так как программы замечают большую задержку, они часто считают это отдельными нажатиями, поэтому клавиши надо нажимать мгновенно. Но если ESC не нажимать, а также зажимать как Alt, то всё будет работать прекрасно!
Кстати, сам ESC шлёт управляющий символ, который можно послать с помощью Ctrl+[. Поэтому, в теории, можно пользоваться терминалом имея из несимвольных клавиш только Ctrl и Shift!
Итого
Я рассказал откуда пошли сочетания с Ctrl. Я рассказал, как я сделал себе терминал в котором, не убирая возможность нажимать другие сочетания, я могу использовать Ctrl+n/t/w/x/c/v абсолютно как в браузере, не задумываясь. Могу даже сделать клавиатуру на Arduino в которой Ctrl+C будут вынесенны на отдельную клавишу. В общем, одинаковые сочетания клавиш — это круто.
Не спорю, если кому-то данный вариант не понравится, например, если вы терминальщик 127 уровня и Ctrl+C у вас уже не ассоциируется с копированием или вы просто не используйте X11/Wayland (используете Linux только на сервере). Или, если вы считаете что это как-то портит стандартный Linux. ¯\_(ツ)_/¯