Ctrl-Backspace и Ctrl-Delete в bash


14

Установка Debian 8.3

stty werase '^H'

или на Arch Linux 2/2016

stty werase '^?'

в .bashrc(например) делает Ctrl- Backspaceудалить последнее слово в терминале. Тем не менее , это не то же самое поведение , как в современных приложениях с графическим интерфейсом (например , Firefox): он удаляет последний пробельные -разделенное слово, и не последнее слово , разделенных пробелами или символами , как . : , ; " ' & / ( ).

Можно ли заставить Ctrl- Backspaceвести себя в терминале аналогично современным приложениям с графическим интерфейсом? Кроме того, есть ли способ сделать Ctrl- Deleteудалить слово непосредственно перед курсором?


1
Ваша оболочка может поддерживать те действия, которые могут быть связаны с данным ключом.
Томас Дики

@ThomasDickey: я использую bash. Хорошо, если это работает только в bash.
волк-рево-кошки

Ответы:


27

Здесь работают два линейных редактора: редактор основных строк, предоставляемый ядром (редактор строки tty в каноническом режиме), и редактор строк bash (реализован через библиотеку readline). У обоих из них есть команда erase-to-previous-word, которая по умолчанию связана с Ctrl+ W. Ключ может быть настроен для канонического режима tty line editor через stty werase; bash имитирует привязку ключа, которую находит в настройке tty, если она не переопределена в его собственной конфигурации.

weraseДействие в редакторе TTY линии не может быть настроено. Он всегда стирает (ASCII) слова, разделенные пробелами. Редко взаимодействовать с редактором строки tty - это то, что вы получаете, например, когда вы печатаете catбез аргументов. Если вам нужны необычные привязки клавиш, вы можете запустить команду под инструментом вроде rlwrap, который использует readline.

Bash предоставляет две команды для удаления предыдущего слова : unix-word-rubout( Ctrl+ wили как задано stty werase), и backward-kill-word( M-DEL, т.е. Esc Backspace), который обрабатывает слово как последовательность буквенно-цифровых символов в текущей локали и_ . Если вы хотите Ctrl+ Backspaceстереть предыдущую последовательность буквенно-цифровых символов, не устанавливайте stty werase, а вместо этого вставьте следующую строку в ваш .inputrc:

"\C-h": backward-kill-word

Обратите внимание, что это предполагает, что ваш терминал отправляет символ Ctrl + H для Ctrl+ Backspace. К сожалению, это один из тех ключей без стандартной привязки (и, Backspaceв частности, беспорядок по историческим причинам).

Также есть симметричная команда, kill-wordкоторая по умолчанию связана с M-d( Alt+ D). Чтобы связать его с Ctrl+ Delete, вам сначала нужно выяснить, какую escape-последовательность отправляет ваш терминал, а затем добавить соответствующую строку в ваш .inputrc. Тип Ctrl+ Vзатем Ctrl+ Delete; это вставит что-то вроде того, ^[[3;5~где инициал ^[является визуальным представлением escape-символа. Тогда привязка

"\e[3;5~": kill-word

Если вас не устраивает ни одно из определений слова, вы можете предоставить свое собственное в bash: см. Запутанное поведение сочетаний клавиш в стиле emacs в bash


2
отличное объяснение! Ctrl+DelРаботал хорошо. Однако я не могу добраться Ctrl+Backspaceдо работы. За Ctrl+v, Ctrl+Backspaceмой терминал говорит ^?. Что я должен положить в .inputrc? Спасибо
Ciprian Tomoiagă

3
@CiprianTomoiaga "\C-?": backward-kill-wordили любую другую функцию readline, которую вы хотите. Но вы можете определить привязку для Ctrl + Backspace, которая отличается от привязки для Backspace, если они отправляют разные символы. Если ваш терминал отправляет ^?как Backspace, так и Ctrl + Backspace, то приложение, запущенное в терминале, не может их различить. Некоторые терминалы могут быть настроены (например, xterm, urxvt), другие (например, эмуляторы терминалов на основе VTE) не могут.
Жиль "ТАК - перестань быть злым"

4
важно отметить, что определение ~/.inputrcотключает значение по умолчанию /etc/inputrc. чтобы исправить это, вы должны включить этот файл: $include /etc/inputrc( отсюда )
Ciprian Tomoiagă

+1 для Esc + Backspace
Celal Ergün


1

Поведение символа WERASE при обработке терминала в готовом режиме жестко задано , по крайней мере, в Linux:

           if (kill_type == WERASE) {
                   /* Equivalent to BSD's ALTWERASE. */
                   if (isalnum(c) || c == '_')
                           seen_alnums++;
                   else if (seen_alnums)
                           break;
           }

Так что слова - это буквы, цифры и подчеркивание. Так будет всегда в терминале в Linux, когда приложение, которое выполняет свою собственную обработку в готовом режиме, не работает.

Версия readline (используемая bash и другими), кажется, немного отличается от версии ядра, но также кажется жестко закодированной :

Слова состоят из букв и цифр.

Но это не похоже на то, что на bashсамом деле делает для меня: foo+bar^Wстирает все, а не только bar. Больше информации об этом здесь .


1. Пользователь vi, вероятно, просто ищет backward-kill-word(связывание по умолчанию M-DEL) вместо unix-word-rubout.
Жиль "ТАК - перестань быть злым"
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.