Вопрос или проблема
В последних версиях терминалов (gnome-terminal, mate-terminal, konsole, xfce4-terminal, xterm и т.д.) программы, похоже, распознают, откуда поступает текст: из буфера обмена или с клавиатуры. В частности:
- Если я вставляю что-то в bash, вставленный текст будет выделен, и новая строка не приведет к выполнению команды.
- Если я вставляю что-то в vim, текст будет вставлен в позицию курсора, даже если режим вставки неактивен.
Как называется эта функция? Как я могу имитировать это поведение в своей программе? Могу ли я временно отключить эту функцию в этих программах?
Согласно связанной ссылке, терминал автоматически выполняет мою команду после вставки текста.
Как говорит Стефан Шазелас, эта функция называется “ограниченная вставка”.
Согласно связанной странице, вы можете использовать следующий код, чтобы включить эту функцию:
printf '\33[?2004h'
А когда все будет сделано, выполните следующее, чтобы вернуться в состояние без этой функции:
printf '\33[?2004l'
Вставленные данные будут заключены в кавычки с использованием ^[[200~
…^[[201~
, где ^[
— это управляющий символ \e
.
Поскольку последние версии терминалов также автоматически фильтруют вставляемые данные и изменяют ESC (\33
, также известный как \e
, также известный как ^[
) на U+241B ␛
, что, я не знаю, есть ли способ отключить, вставленные данные не будут содержать ^[[201~
, поэтому их не нужно декодировать.
Ответ или решение
Как различить вставку и ввод текста в терминалах
С недавних пор в современных терминалах, таких как gnome-terminal, mate-terminal, konsole и других, появилась возможность определять, был ли текст введен с клавиатуры или вставлен с помощью буфера обмена. Эта функция, известная как "умная вставка" (или "bracketed paste"), значительно упрощает работу с текстом в таких средах, как bash и vim.
Что такое "умная вставка"?
"Умная вставка" — это механизм, который позволяет терминалам и программам, работающим внутри них, отличать данные, вставленные из буфера обмена, от обычного ввода с клавиатуры. Примеры поведения, наблюдаемого при использовании этой функции:
- Bash: Когда вы вставляете текст в терминал, он выделяется, а новые строки не приводят к немедленному выполнению команды.
- Vim: При вставке текста, курсор может оставаться в режиме обычного ввода без перехода в режим вставки, и текст будет добавлен в нужной позиции.
Как воспроизвести это поведение в своей программе?
Для реализации "умной вставки" в вашей программе необходимо использовать специальные управляющие последовательности ANSI. Чтобы включить эту функцию, отправьте следующую последовательность в терминал:
printf '\33[?2004h'
Когда вы закончите работу с вставками, вы можете отключить эту функцию:
printf '\33[?2004l'
При вставке текста терминал оборачивает данные в специальные символы: ^[[200~
в начале и ^[[201~
в конце.
Как обрабатывать вставленный текст
При получении данных вашей программой необходимо учитывать обрамляющие символы. Если ваше приложение получает данные между этими последовательностями, оно должно обрабатывать их как вставленный текст. Так как новые версии терминалов также могут автоматически обрабатывать специальные символы, данные не будут содержать ^[[201~
, что упрощает процесс обработки.
Важно отметить, что при использовании умной вставки текст автоматически очищается от специальных символов, таких как ESC (код \33
или \e
), заменяя их на символы, не вызывающие проблем. Поэтому после получения строк необходимо удалить только обрамляющие символы.
Можно ли временно отключить эту функцию?
Да, в некоторых терминалах можно временно отключить "умную вставку" для определённых случаев, например, если вы хотите избежать нежелательных эффектов при вставке больших объемов текста или при выполнении сложных команд. Для этого достаточно ввести управляющую последовательность printf '\33[?2004l'
, как упоминалось ранее. Это отключит функцию до тех пор, пока вы не решите снова её включить.
Заключение
Функция "умной вставки" значительно улучшает взаимодействие пользователя с терминалами и текстовыми редакторами. Правильное использование управляющих последовательностей позволяет точно различать вставленный и вводимый текст, что будет полезно в разработке и использовании консольных приложений. Понимание и внедрение этой функции в ваши программы может улучшить пользовательский опыт и повысить эффективность выполнения задач.