Usuń ostatnie słowo (Ctrl-W): Spraw, aby powłoka bash zachowywała się jak linia poleceń vima

6

Wśród wielu przydatnych skrótów klawiaturowych dostępnych w powłoce bash Ctrl - W aby usunąć słowo po lewej stronie kursora. Załóżmy, że moja linia poleceń wygląda następująco:

cp some-file /foo/bar/baz/copy

Teraz oczekuję, że będę mógł nacisnąć Ctrl - W i skończyć z następującymi:

cp some-file /foo/bar/baz/

W wierszu poleceń Vima rzeczywiście działa w ten sposób: Tylko znaki alfanumeryczne są traktowane jako „słowo”, podczas gdy znaki specjalne (np. / ) służą jako ograniczniki oznaczające początek nowego „słowa”.

Ale niestety nie działa tak we wszystkich pociskach, z których korzystałem do tej pory. Tylko spacje ograniczają „słowo”, więc naciśnięcie skrótu za pomocą wiersza polecenia pokazanego powyżej da mi:

cp some-file

Czy istnieje sposób, aby Bash zachowywał się jak Vim? Pewna konfiguracja, którą mogę umieścić w moim .bashrc?

lethal-guitar
źródło
1
Widzieć to pytanie i zwróć uwagę na ta odpowiedź . Z jakiegoś powodu nie jest popierany, ale robi dokładnie to, co chcesz.
taketwo

Odpowiedzi:

11

Nie ma to nic wspólnego z Vimem, wszystkie edytory zachowują się w ten sposób (w tym emacs), traktują znaki inne niż słowa jako ograniczniki. W każdym razie zachowanie, o którym mówisz, jest kontrolowane przez readline a jego instrukcja zawiera kilka poleceń, do których można przypisać skróty. Wklejam tutaj kilka odpowiednich, ale polecam przeczytanie man readline po więcej informacji:

   backward-word (M-b)
          Move  back  to  the  start  of the current or previous word.  Words 
          are composed of alphanumeric characters (letters and digits).

   kill-line (C-k)
          Kill the text from point to the end of the line.
   kill-word (M-d)
          Kill from point the end of  the  current  word,  or  if  between
          words,  to  the  end  of the next word.  Word boundaries are the
          same as those used by forward-word.
   backward-kill-word (M-Rubout)
          Kill the word behind point.  Word boundaries  are  the  same  as
          those used by backward-word.
   unix-word-rubout (C-w)
          Kill  the  word behind point, using white space as a word bound‐
          ary.  The killed text is saved on the kill-ring.
   unix-filename-rubout
          Kill the word behind point, using  white  space  and  the  slash
          character  as  the word boundaries.  The killed text is saved on
          the kill-ring.

Tak więc chcesz backward-kill-word, który używa znaków niealfanumerycznych jako granic słów. Domyślnie jest przypisany do Alt + Backspace ale możesz to zmienić, używając globalnego /etc/inputrc jeśli chcesz, aby dotyczyły wszystkich użytkowników lub (lepiej) twojego lokalnego $HOME/.inputrc.

O ile wiem, Ctrl + W wydaje się być zarezerwowany i nie możesz go użyć, ale możesz wybrać inny skrót, Ctrl + jot na przykład. Stwórz $HOME/.inputrc plik, jeśli nie istnieje i dodaj do niego ten wiersz:

Control-J: backward-kill-word 

To powinno wystarczyć dla większości nowoczesnych emulatorów terminali. Jednak niektóre starsze terminale używają różnych kodów. Jeśli używasz xtermna przykład powyższy wiersz powinien być napisany jako:

C-J: backward-kill-word 
terdon
źródło
Bardzo dokładne wyjaśnienie, dzięki! W końcu zdecydowałem się zastosować to podejście.
lethal-guitar
5
\C-w nie jest zastrzeżone. Po prostu biegnij bind 'set bind-tty-special-chars off' wyłączyć bind-tty-special-chars ustawienie, które powoduje, że readline ponownie odczytuje i wiąże znaki specjalne terminala (w tym przypadku werase znak) za każdym razem, gdy ma zostać wprowadzona nowa linia.
JdeBP
@JdeBP ah, OK, dzięki. Właśnie zobaczyłem, że zostało to wyraźnie wymienione w man i że nie mogę nadpisać ustawienia w moim .inputrc.
terdon
Pamiętaj, że: słowo-zabij-wstecz nie działa jak w vim ... foo / bar zostanie usunięty w 3 ctrl + w, tj. Foo / bar - & gt; foo / - & gt; foo - & gt; usunięte, gdzie w powłoce, foo / bar - & gt; foo / - & gt; usunięte
azorius
5

Możesz włączyć tak zwany „tryb vi” readline (a więc i basha), wstawiając następujące wiersze ~/.inputrc i rozpoczęcie nowej powłoki:

set editing-mode vi
set keymap vi-command

Ale zauważysz to <C-w> działa tak samo jak w domyślnym trybie Emacs: słowa są rozdzielane spacjami. Możesz to zrobić dT/ lub podobne polecenia. To wciąż naśladowanie, a nie prawdziwy interes. Dostępne mapowania są wymienione w podręczniku readline:

$ man readline
/VI

Zobacz też ta strona na wiki Vima .

Ale nie sądzę, aby tryb vi readline był tak użyteczny, jeśli często musisz poważnie edytować linię poleceń… czemu nie użyć Vima na serio ?

<C-x><C-e>
romainl
źródło
Wow, ten ostatni skrót do wywołania mojego edytora jest świetny! Chociaż jeśli mój wiersz poleceń osiągnie taki poziom złożoności, wolę trzymać go w skrypcie powłoki. Wciąż dobrze wiedzieć!
lethal-guitar