Привязка обратного слова уничтожения к Ctrl + w


23

Я пытаюсь перейти от длительного использования Tcsh к недавнему исследованию Bash.

Мне удалось перенести все мои любимые функции, кроме Ctrl + w, который рассматривает пробелы и слэши как границы слов, скорее всего, backward-kill-word. В Bash, однако, readline удаляет весь путь до первого пробела, удаляя все косые черты между ними.

Я пробовал много разных комбинаций \ Cw: backward-kill-word в .inputrc и .bashrc, используя bind, но не могу заставить его работать так, как я хочу.

Как ни странно, через Putty из Windows на работе я могу использовать Alt + Backspace, который также в руководстве называется привязкой по умолчанию, чтобы получить точное поведение, которое я хочу. Но в Terminal.app на моих компьютерах Mac это не работает. То же самое относится и к любому серверу FreeBSD или Linux, в который я входил из Terminal.app.

Поэтому я обращаюсь к суперпользователю за помощью.

Ответы:


40

readlineне привязывается Ctrl- Wпоскольку он обрабатывается драйвером терминала по умолчанию:

$ stty -a
(...) werase = ^W; (...)

Чтобы отключить это, вы должны запустить (в ~/.bashrc):

stty werase undef
bind '"\C-w": backward-kill-word'

.inputrcздесь не поможет, поскольку он читается, когда Ctrl- Wвсе еще назначен werase.

Также обратите внимание, что \C-wформат keyseqs должен быть заключен в двойные кавычки, как указано выше.


Разные терминалы могут обрабатывать Alt- по- Backspaceразному.

  • PuTTY и GNOME Terminal (с настройками по умолчанию) send 1b 7f( ESC DEL)
  • Xterm с metaSendsEscape: trueпосылает 1b 08( ESC BS).
  • Xterm без metaSendsEscape посылает 88( HTSили BSсо старшим битом).

Xterm имеет несколько настроек для управления поведением Altклавиш (которые называются Metaв Xterm и X11 в целом). С metaSendsEscape, холдинг Altбудет префикс нажатие клавиши с ESC(шестнадцатеричной 1b). Без настройки (режим по умолчанию), Altбудет установлен старший бит входного символа, в результате чего специальные символы. (Например, Alt- Nприводит к ESC nи îсоответственно.)

Насколько я помню, Terminal.app также имеет похожую настройку для управления поведением Meta / Alt / what-Macs-use.


Это не только лучший ответ, но и чрезвычайно информативный, спасибо!
Стефан М

1
@shurane: Действие werase « удаление слова», как и обычное стирание (Backspace), осуществляется самой ОС в драйвере «tty device» - обратите внимание, что они доступны даже в программах, которые просто слепо читают из stdin, например cat, На всех Unixes sttyиспользуется для управления различными параметрами tty, включая эти специальные ключи. (Вот как выглядело UNIX 7th Editionstty .)
grawity

1
@shurane: Между тем, readline - это библиотека пользовательского пространства, изначально написанная для оболочки bash (хотя сейчас используется многими программами). Возможно, что другие действия были реализованы в readline, чтобы избежать вздутия драйвера tty (у которого уже было значительное количество флагов и переключателей, как видно в sttyруководстве пользователя). Кроме того, bash изначально предназначался для ОС GNU и только позже был портирован на другие Unixes; гораздо проще поддерживать функции редактирования в одной библиотеке, чем в нескольких очень разных ядрах.
Гравитация

3
@shurane: Технически, однако, все эти действия, включая стирание слов, выполняются readline - когда он активен, он полностью отключает обработку Backspace и Ctrl + W драйвером терминала. readline просто учитывает sttyконфигурацию для простоты, но она может быть переопределена собственными настройками readline (как описано в ответе Мэтта Дея).
Гравитация

4
Это отличный ответ для информации, upvote. Однако следует отметить, что это отключает Ctrl-w для всех программ, если они не используют readline, что, вероятно, не то, что кто-то хочет ..., поэтому попробуйте ответ @fjarlq.
0

19

Гравити написал, что это не может контролироваться в .inputrcфайле, но это неверно.

Если вы set bind-tty-special-chars offв вашем .inputrc, вы можете настроить поведение специальных терминальных символов.

Например:

set bind-tty-special-chars off
"\C-u": kill-whole-line
"\C-w": backward-kill-word

2
И это имеет преимущество работы для всех программ, которые используют readline, например python.
wchargin

3

Для записи, ответ , как он относится к iTerm2 является установка Alt- Backspace(или Opt ⌥- на Mac) , чтобы отправить Hex коды 0xb1и 0x7fдля того , чтобы выполнить backward-kill-wordдействие , которое лечит не алфавитно-цифровые символы в качестве разделителей.

Для различия вот поведение, которое я описываю, при котором нажатие Opt ⌥- один раз меняет это:

echo "/example/filepath/with_non-alpha.characters@blah:meh

к этому:

echo "/example/filepath/with_non-alpha.characters@blah:

И последующие нажатия Opt ⌥- :

echo "/example/filepath/with_non-alpha.characters@

echo "/example/filepath/with_non-alpha.

echo "/example/filepath/with_non-

echo "/example/filepath/with_

echo "/example/filepath/

Вот как выглядит настройка в iTerm2: введите описание изображения здесь

Так что, специфично для Putty и Terminal, ответ grawity великолепен. Но потратив немало времени на поиски того, как применить настройку в iTerm2, этот пост суперпользователя, кажется, появляется чаще всего, поэтому он, кажется, ответственен за предоставление соответствующей информации, поскольку она относится к iTerm2 в качестве Ответа, прилагаемого к этому Вопросу.


Мне потребовалось много времени, чтобы понять это, и это решение действительно работает на OS X (с iTerm2) при входе в систему на удаленной оболочке bash. Спасибо!
Мартин
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.