Ctrl-Backspace i Ctrl-Delete w bash

14

Instalacja Debiana 8.3

stty werase '^H'

lub w Arch Linux 2/2016

stty werase '^?'

in .bashrc(na przykład) tworzy Ctrl- Backspaceusuń ostatnie słowo w terminalu. Nie jest to jednak to samo zachowanie, co we współczesnych aplikacjach GUI (np. Firefox): Usuwa ostatnie słowo oddzielone białymi spacjami, a nie ostatnie słowo oddzielone białymi spacjami lub podobnymi znakami . : , ; " ' & / ( ).

Czy jest możliwe, aby Ctrl- Backspacezachowywać się w terminalu podobnie jak nowoczesne aplikacje GUI? Czy jest też jakikolwiek sposób Ctrl- Deleteusunąć słowo bezpośrednio przed kursorem?

wilko-rewo-koty
źródło
1
Twoja powłoka może obsługiwać te akcje, które mogą być powiązane z danym kluczem.
Thomas Dickey,
@ThomasDickey: Używam bash. W porządku, jeśli działa tylko w trybie bash.
wolf-revo-cats

Odpowiedzi:

27

W grze są dwa edytory linii: podstawowy edytor linii dostarczany przez jądro (edytor linii tty w trybie kanonicznym) oraz edytor linii bash (implementowany przez bibliotekę readline). Oba mają komendę usuwania do poprzedniego słowa, która domyślnie jest powiązana z Ctrl+ W. Klucz można skonfigurować dla edytora linii tty w trybie kanonicznym stty werase; bash imituje powiązanie klucza, które znajduje w ustawieniu tty, chyba że zostanie zastąpione w jego własnej konfiguracji.

weraseNie można skonfigurować działanie w edytorze linii tty. Zawsze usuwa (ASCII) słowa rozdzielone białymi znakami. Rzadko wchodzi się w interakcję z edytorem linii tty - to jest to, co dostajesz, np. Gdy piszesz catbez argumentów. Jeśli chcesz mieć fantazyjne powiązania klawiszy, możesz uruchomić polecenie pod narzędziem takim jak rlwrap, który używa readline.

Bash udostępnia dwa polecenia do usunięcia poprzedniego słowa : unix-word-rubout( Ctrl+ wlub zgodnie z ustawieniem stty werase) i backward-kill-word( M-DEL, tj. Esc Backspace), Który traktuje słowo jako ciąg znaków alfanumerycznych w bieżącym języku i_ . Jeśli chcesz Ctrl+, Backspaceaby usunąć poprzednią sekwencję znaków alfanumerycznych, nie ustawiaj stty werase, a zamiast tego wstaw następujący wiersz w .inputrc:

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

Zauważ, że zakłada to, że twój terminal wysyła znak Ctrl + H dla Ctrl+ Backspace. Niestety jest to jeden z tych kluczy bez standardowego wiązania ( Backspaceaw szczególności z powodów historycznych jest bałaganem ).

Istnieje również polecenie symetryczne, kill-wordktóre jest domyślnie powiązane z M-d( Alt+ D). Aby powiązać go z Ctrl+ Delete, najpierw musisz dowiedzieć się, jaką sekwencję ucieczki wysyła twój terminal, a następnie dodaj odpowiednią linię w swoim .inputrc. Wpisz Ctrl+, Va następnie Ctrl+ Delete; spowoduje to wstawienie czegoś takiego, jak ^[[3;5~gdzie inicjał ^[jest wizualną reprezentacją znaku ucieczki. Zatem wiązanie jest

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

Jeśli nie jesteś zadowolony z żadnej z definicji słowa, możesz podać własne w bash: zobacz mylące zachowanie skrótów klawiszowych w stylu emacs w bash

Gilles „SO- przestań być zły”
źródło
2
doskonałe wyjaśnienie! Ctrl+DelDziała dobrze. Nie mogę jednak zabrać się Ctrl+Backspacedo pracy. Bo Ctrl+v, Ctrl+Backspacemój terminal mówi ^?. Co mam włożyć .inputrc? Dziękuję
Ciprian Tomoiagă,
3
@CiprianTomoiaga "\C-?": backward-kill-wordlub dowolna inna funkcja readline. Ale możesz zdefiniować powiązanie dla Ctrl + Backspace, które różni się od wiązania dla Backspace, jeśli wysyłają różne znaki. Jeśli twój terminal wysyła ^?zarówno Backspace, jak i Ctrl + Backspace, aplikacja działająca w terminalu nie ma możliwości ich rozróżnienia. Niektóre terminale można skonfigurować (np. Xterm, urxvt), inne (np. Emulatory terminali oparte na VTE) nie mogą.
Gilles 'SO - przestań być zły'
4
należy zauważyć, że zdefiniowanie ~/.inputrcwyłącza wartość domyślną /etc/inputrc. aby to naprawić, musisz dołączyć ten plik: $include /etc/inputrc( stąd )
Ciprian Tomoiagă
+1 dla Esc + Backspace
Celal Ergün
6

Próbować

alt+backspace

W podstawowym systemie operacyjnym działa tak, jak chcesz (tak jak ctrl+ backspace)

Ahmed Elkoussy
źródło
1

Zachowanie znaku WERASE w trybie terminalowym przetwarzania gotowego jest zakodowane na stałe , przynajmniej w Linuksie:

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

Więc słowa to litery, cyfry i podkreślniki. Tak właśnie będzie przez cały czas w terminalu w systemie Linux, gdy aplikacja, która wykonuje własne przetwarzanie w trybie gotowanym, nie jest uruchomiona.

Wersja readline (używana przez bash i inne) wydaje się nieco inna niż wersja jądra, ale wydaje się też, że jest zakodowana na stałe :

Słowa składają się z liter i cyfr.

Ale to nie pasuje do tego, co bashfaktycznie dla mnie robi: foo+bar^Wusuwa wszystko, nie tylko bar. Więcej informacji na ten temat tutaj .

Celada
źródło
1. Użytkownik vi prawdopodobnie szuka backward-kill-word(domyślnego wiązania M-DEL) zamiast unix-word-rubout.
Gilles „SO- przestań być zły”