Общие сведения о работе терминала
Эту заметку пишу как ответ на коммент в тему Хочу работу с мышкой как в терминале ConEmu Но пишу быстро и по верхам, так что в общий раздел, а не в раздел статьи. Возможно окажется полезным, чтоб ссылаться сюда в случае похожих вопросов у новичков.
Всё это у меня немного путается. Терминалы, консоли, командные строки. Признаюсь, я в терминологии немного чайник.
Ща всё разъясним.
Базово есть такая архитектура:
Приложение-терминал <--> TTY <--> программа, которая хочет общаться через терминал
TTY это компонент ядра. Кроме того, что служит связующим звеном, он также реализует некоторые базовые фичи, которые делают терминал немного «умнее». Дело в том, что исторически терминалы (те самые — физические, аппаратные терминалы) для Unix были концептуально «тупые». То есть умели только выводить текст по командам программы, а также пересылать ей, какие клавиши пользователь нажал. Для некоторых других ОС терминалы были «умные», с продвинутыми средствами работы с данными на стороне терминала. Но в Unix они не применялись. Unix вообще концептуально была про простоту. А ля делай только самое необходимое и не больше.
Так вот TTY реализует некоторые базовые примитивы и алгоритмы для случаев, когда программа не умеет или не предназначена сама работать с терминалом.
Про работу TTY я писал подробную статью, вот тут можно прочитать: https://wandrien.github.io/articles/tty/
Далее.
Если программа хочет сама продвинуто работать с терминалом, она настраивает TTY, чтобы оно ей не мешало, то есть отключает его логику обработки данных частично или полностью. И таким образом работает с терминалом прозрачно, без особого вмешательства TTY.
Кроме того, что программа настроила TTY, ей нужно еще управлять самим терминалом.
Терминал управляется через некоторый протокол. Этих протоколов и их вариаций за историю была чертова уйма. Обычно конкретное приложение-терминал поддерживает некоторый базовый набор + какие-нибудь специфичные для себя фишки. Кто-то меньше, кто-то больше. Например, если внимательно почитать, сколько команд и режимов работы имеет xterm, там можно потеряться. Ну короче зоопарк как с браузерами или как с поддержкой разных фич в видеокартах.
Для реализации концепции командной строки программы обычно не велосипедят всю логику работы с терминалом с нуля, а берут готовые решения. Часто это библиотека readline. Например, она используется в bash.
В мире BSD-софта вместо readline обычно используется libedit. Ну и еще куча альтернатив есть, как обычно.
Итак, если мы работаем с командным интерпретатором bash, он использует библиотеку readline, реализующую фичи строки ввода, и readline отображает текст в терминале и реагирует на наши команды правки текста.
Если мы работаем с Midnight Commander, то там вместо readline применяется продвинутый тулкит, который реализует окошки, кнопки, поля ввода и так далее.
В zsh, если память не изменяет, используется не readline, а свой отдельный велосипед. (Лень факт-чекать.)
Вот так всё это устроено.
То есть в таких случаях логика работы с вводом пользователя находится в некотором компоненте в составе клиентской программы. А сам терминал тут не особо играет роль.
Теперь к вопросу про мышь, который был в исходном треде.
Если программа не включила в терминале режим передачи событий мыши, то мы видим вот эту простую логику, встроенную в любой терминал, когда можно мышкой выделить текст и скопировать. Если же программа сказала, что хочет сама обрабатывать события мыши, то терминал свою логику выделения текста отключает.
Таким образом получается, что не достаточно сделать так, чтобы мышь работала только в командной строке. Нужно, чтобы приложение еще и «обычную» логику выделения текста как-то у себя поддерживало.
Но! Тут есть обходной путь. Если, например, мы запустим mc и попытаемся выделить текст с нажатой Shift, то увидим, что мышь обрабатывается терминалом, а не mc. Удержание Shift принудительно возвращает обработку мыши в терминал.
Вот вроде и всё, что я хотел вам на эту тему сообщить сегодня. =)