Почему я не могу выделить текст в эмуляторе терминала Linux с помощью клавиш Shift+ стрелка?

Это стандартные сочетания клавиш для редактирования текста, которые я постоянно использую при редактировании текста, буквально, в любом приложении linux, кроме эмуляторов терминала:

  • стрелки влево + вправо для перемещения влево + вправо
  • Ctrl+ стрелка для перемещения всего слова
  • начало / конец, чтобы перейти к началу / концу строки
  • ctrl+c/ctrl+v для копирования / вставки [некоторые терминалы могут использовать shift-ctrl-C/shift-ctrl-V; это хорошая замена]
  • Shift+ стрелка, чтобы выделить текст
  • Shift+ Ctrl+ стрелка, чтобы выделить все слово

Я никогда не находил комбинацию эмулятора оболочки плюс терминала, которая позволяла бы последние два элемента в этом списке, и это сводило меня с ума. Очевидно, что эмуляторы терминала поддерживают выделение (мышь может это сделать), и они поддерживают использование клавиш ctrl и shift в качестве модификаторов (их можно использовать для перемещения курсора на целое слово и для прописных букв соответственно; [edit:] их даже можно использовать вместе для копирования / вставки с помощью shift-ctrl-C и shift-ctrl-V), так в чем же проблема, препятствующая этой функциональности? У меня есть несколько вопросов:

  • Это проблема с моим эмулятором терминала или с моей оболочкой (bash, хотя я готов измениться)?
  • Почему эмуляторы / оболочки терминалов не соответствуют этому универсальному стандарту?
  • Если есть реальная причина, является ли она древней и устаревшей, или она все еще актуальна для значительного числа пользователей Linux для настольных ПК?
  • Есть ли какое-нибудь решение?
  • Есть какая-то неясная программа, которую я могу использовать, которая поддерживает это?
  • Можно ли изменить источник, скажем, gnome-Terminal для поддержки этого?

Я знаю, что текст можно копировать / вставлять с помощью мыши, это не то, о чем я спрашиваю. Я спрашиваю, почему я не могу сделать это с помощью клавиатуры в эмуляторе терминала.

9 ответов

Я думаю, было бы очень полезно, если бы я взял этот кусок за раз. Общая проблема: для кого предназначено нажатие клавиши? Терминал или программа, работающая внутри терминала?

Например, "экран", который является своего рода терминалом, использует Ctrl + A в качестве префикса для своих команд, чтобы отличать их от вещей, идущих в саму запущенную программу. (И предоставляет способ отправить Ctrl + A.)

gnome-terminal имеет несколько ключей, которые он захватывает для выполнения различных задач, включая некоторые из тех, о которых вы спрашиваете.

Также имейте в виду, что "подсветка" терминала отделена от позиции курсора терминала. Некоторые терминалы вообще не имеют возможности подсветки.

Теперь, принимая эту комбинацию клавиш одновременно:

стрелки влево + вправо для перемещения влево + вправо ctrl+ стрелка для перемещения всего слова домой / конец для перемещения в начало / конец строки

Двигайся влево и вправо? Bash может быть настроен для этого, и обычно это по умолчанию. Как правило, они перемещают позицию курсора.

Ctrl + C / Ctrl + V для копирования / вставки

Первый: имеет ли смысл копировать / вставлять? Если вы находитесь в VT, у вас действительно нет буфера обмена, особенно если X не работает.

Некоторые терминалы могут копировать текст в выводе, а некоторые также "вставляют", имитируя ввод текста в буфер обмена. Ctrl + Shift + V, например, вставить в gnome-terminal, который может помочь. (И Ctrl + Shift + C является копией.) Как уже говорилось ранее, большая проблема с Ctrl + C и Ctrl + V состоит в том, что они перекрываются с общими командами терминала / программы. (Ctrl + C - прерывание отправки (SIGINT), а Ctrl + V - дословно.)

Некоторые терминалы также поддерживают два режима копирования данных: более обычный режим "просто копировать" и так называемый "выбор блока" или "копирование блока". (Удерживайте Ctrl, а затем перетащите, находясь в gnome-terminal например.)

Дополнительно, xsel -b может быть использован для передачи содержимого буфера обмена вокруг. Зависит от точного положения xsel или версия пасты терминала более полезна. Увидеть man xsel,

Shift + стрелка для выделения текста Shift + Ctrl + стрелка для выделения всего слова

Подсветка вашего терминала (если у него есть такая возможность) отделена от позиции курсора. Опять же, отсутствие доступных комбинаций клавиш, вероятно, является фактором. Имейте в виду, что выделение имеет две позиции: либо начало и конец, либо верхний левый и нижний правый углы. Как вы управляете обоими?

Наконец, обратите внимание, что во многих графических терминалах двойной щелчок по слову выделяет его. (И в X, скопируйте в основной выбор.)

screen Например, имеет ключи для переключения в режим перемещения по буферу (предыдущий вывод) и копирования / вставки.

Я думаю, что если вы используете адекватно xsel и основной выбор, вы обнаружите, что операции с буфером обмена являются достаточно редкими и достаточно сложными, чтобы их можно было использовать с помощью мыши.

Как упомянул Танатос, следует различать эмулятор терминала (работающий на X Windows или Wayland) и программы, работающие в терминале (назовем это "оболочкой", хотя это может и не быть); эти две вещи изолированы друг от друга (см. технические детали).

Первые элементы в вашем списке (клавиши со стрелками, Home/End и т. Д.) Обрабатываются непосредственно программой внутри терминала, поэтому положение курсора контролируется программой внутри терминала.

Скопировать и вставить ярлыки (Ctrl+Shift+C и Ctrl+Shift+V), с другой стороны, обрабатываются эмулятором терминала, который понимает мышь (так что вы можете выделять текст с помощью мыши), он знает, что на экране (чтобы он мог копировать), и может отправлять нажатия клавиш в программу внутри (чтобы он мог вставлять).

Чтобы поддерживать Shift+Left и Shift+Right, эмулятор терминала или оболочка должны были обрабатывать нажатие клавиш. В любом случае у нас есть проблема:

  1. Оболочка не может легко обрабатывать эти клавиши, потому что в конечном итоге вам захочется скопировать выделенный текст в буфер обмена, а буфер обмена - это концепция X Windows, к которой оболочка не обязательно имеет доступ (но смотрите xclip). И, насколько мне известно, если оболочка поддерживает выделение текста, Linux не определяет какой-либо механизм для уведомления эмулятора терминала о том, что выбрано.
  2. Между тем, эмулятор терминала не отвечает за местоположение курсора. Даже если эмулятор терминала может изменить местоположение курсора, он, вероятно, не знает, где начинается и заканчивается текущая строка текста. Например, терминал может содержать текст ~ $ ls -l и эмулятор терминала не знает, что только ls -l часть принадлежит пользователю.

Нетрудно представить себе эмулятор терминала, который поддерживает выделение с помощью Shift+Arrows, но я думаю, что ему придется скрыть курсор оболочки и ввести свой собственный "поддельный курсор", который временно существует, чтобы помочь вам выбрать что-то, а затем вы можете нажать Ctrl+C / Ctrl+Shift+C / Ctrl+Ins для копирования (или Esc для отмены) и показать реальный курсор еще раз. Конечно, в нем не было бы всех возможностей обычного выбора - в частности, вырезать и удалять не было бы.

Это привязки клавиатуры CUA, которые вы описываете, стандарт от IBM в середине 80-х:

https://en.wikipedia.org/wiki/IBM_Common_User_Access

Обычно они реализуются во всех средах рабочего стола, созданных с тех пор. DOS, Windows, Motif и даже инструменты Netware - все сошлись на этом стандарте. Единственным исключением является Mac, который использует довольно похожий, но другой набор (Cmd вместо Ctrl) для того же периода времени.

Терминалы Unix (и более поздние эмуляторы) намного предшествовали этому стандарту и в большинстве случаев игнорировали его. Кроме того, если бы они реализовали эти привязки клавиш, это могло бы помешать программам TUI, которые уже используют их для других функций. Так что, хотя технически это возможно, но тоже проблематично.

Программы:

В micro текстовый редактор - лучшее, что я видел для эмуляции текстового редактора GUI, похожего на DOS  edit но с более современными функциями а-ля Sublime Text. ne является более старым в репозиториях Debian, и даже nanoможно настроить с помощью разумных сочетаний клавиш. А вот голого терминала / оболочки нет.

С участием libvteможет быть легко создать элементарный виртуальный терминал, который самостоятельно обрабатывает эти сочетания клавиш. Однако много работы за крошечный выигрыш.

Полученные ответы являются хорошим объяснением того, почему это сложно сделать. Вот что вы можете сделать в gnome-terminal, чтобы настроить ctrl-c и ctrl-v для копирования и вставки, одновременно привязывая другие ключи в дисциплине терминала с помощью stty отправлять SIGINT и вставьте дословно символ. Это не полное решение, потому что некоторые программы отключают терминальную дисциплину, и вы не сможете отправить им "^C" и "^V". Больше информации здесь.

В вашем скрипте запуска оболочки (например, ~/.bashrc, ~/.zshrc, ~/.rcrc), делать

stty intr '^Q' 2>/dev/null  # To send SIGINT I will use ctrl-q
stty lnext '^A' 2>/dev/null # To insert a character verbatim I will use ctrl-a

Затем в gnome-terminal Edit > Preferences > Shortcuts вы можете связать Copy и Paste с ctrl-c и ctrl-v. Обратите внимание, что терминал получит ключевые события до того, как что-либо будет отправлено на терминальное устройство, поэтому с этого момента вы не сможете отправлять '^C' и '^V' любому процессу, запущенному на терминале.

Я только что сделал это, и я посмотрю, как это происходит, и какие проблемы это вызывает. Я сделал stty's условно, чтобы применить их только тогда, когда я использую X.

Я не эксперт по эмуляторам терминала, но...

приложения, такие как bash (readline), работающие в эмуляторе терминала, ничего не знают о работающей системе X Window и X Window, в которой они находятся, они знают stdin и stdout на терминальном устройстве (ttyS/ttyUSB/tty/pts в linux).

Проблема не в том, чтобы показать какой-то выделенный текст, а в том, как сообщить приложению X Window (эмулятору терминала), что текст был выбран, через эти терминальные устройства.

Я предполагаю, что приложение X-терминала открывает одно из этих устройств на входе и выходе, а затем транслирует события клавиш X для правильного вывода (со стороны X) ввода (со стороны bash). Наоборот, поток вывода bash на терминал X в качестве входных данных, здесь терминал X обрабатывает этот ввод для перемещения курсора, заливает фон некоторым цветом, в соответствии с выводом приложения bash.

Насколько мне известно, управляющие коды могут использоваться для управления специальным поведением, таким как очистка, заливка фона, перемещение курсора, и, возможно, может быть добавлен некоторый пользовательский управляющий код, чтобы сообщить X-терминалу, что текст из строки, столбца в строку, столбца был выбран, просто пример, может быть, вместо этого можно просто вернуть выбранный текст (подробности реализации).

Я думаю, что не являясь стандартным определением, вам придется исправлять каждое приложение, которое вы хотите поддержать, чтобы знать о нажатии комбинации клавиш и выводить соответствующий escape-код, readline, если вы хотите его в bash, эмулятор терминала X на с другой стороны, чтобы правильно обработать управляющий код (и, наконец, отправить информацию в буфер обмена). Вероятно, реализация этого в качестве терминальной возможности избавит вас от исправления каждого отдельного приложения. Я надеюсь (и предполагаю), что драйверы терминальных устройств в ядре хотят знать как можно меньше о escape-кодах, поэтому, если вам повезет, патч не потребуется.

Терминал X выводит выходные данные, поэтому при использовании мыши легко узнать, какой текст / символы вы выбираете.

Графический текстовый виджет знает все о своем X окне, поэтому его так легко реализовать, выбирая и копируя.

РЕДАКТИРОВАТЬ

Здесь этот патч urxvt-9.16-image-display может стать хорошей отправной точкой для понимания того, что необходимо для поддержки новых escape-кодов. http://lists.schmorp.de/pipermail/rxvt-unicode/2013q1/001736.html

До Ubuntu 20 вы могли прокрутить до начала вывода, начать выделять мышью, а затем нажать любую клавишу, чтобы опустить выделение вниз.
Теперь нажатие клавиши отменяет выбор мышью, поэтому единственный способ скопировать часть многостраничного вывода (кроме сохранения в файл и отдельного открытия) — это перенести выделение в нижнюю часть экрана и подождать около минуты, пока оно не зафиксируется. прокрутите до конца вывода.

Я отвечу только на эту часть:«Если есть реальная причина, является ли она древней и устаревшей или все еще актуальна для значительного числа пользователей настольного Linux?»

Как видно из предыдущих ответов, существуют реальные причины, но они не имеют отношения к пользователям Linux на настольных компьютерах .

По иронии судьбы, в Windows вы можете использовать ConEmu в качестве окна консоли, поддерживающего все упомянутые вами ярлыки (также при использовании Bash в WSL и при удаленном подключении к серверу Linux), поэтому не должно быть невозможно добиться этого и в Linux. Итак, в заключение, эти причины действительно «древние и устаревшие».

(EDIT: это ключи терминала Windows cmd. Я не заметил, что вы используете Linux)

Если это поможет:

Весь текст может быть coppied с помощью Alt+ Space, E, S, Enter(занимает второе или меньше)
и, конечно, приличный редактор как VS код может быть использован, чтобы потянуть соответствующую часть (занимает несколько секунд).

Coppied текст может быть вставлен с помощью Alt+ Space, E, P.

И экран можно прокручивать после использования Alt+ Space, E, L.

Чтобы ответить на исходный вопрос:

Во-первых, я полностью согласен с тем, что эта функция должна существовать.

Что касается того, почему нынешние разработчики терминалов не используют его, Танатос упомянул в своем ответе. Но может существовать приложение-терминал, которое его использует и имеет обходной путь для приложений оболочки, которым нужны ключи.

Относительно того, почему старые терминальные дизайнеры создали такую традицию (если они используются клавиши для выбора текста, а затем оболочки приложения не будет использовать их), вероятно, потому, что когда аппратные терминалы были заменены видеотерминалами и первыми текстовыми редакторами были появились, Прошло еще около 15 лет, прежде чем появилась эта великолепная идея выделения текста в пользовательском интерфейсе !:)

Я просто помог собеседнику решить проблему, аналогичную этой, и обнаружил, что виновником является клип менеджера буфера обмена.

sudo apt-get удалить clipit

был в состоянии восстановить все и работать просто отлично для него. Надеюсь, что это может помочь кому-то еще там.

Другие вопросы по тегам