Mengikat mundur-bunuh-kata ke Ctrl + w

23

Saya mencoba untuk beralih dari penggunaan Tcsh dalam waktu lama ke eksplorasi Bash baru-baru ini.

Saya telah berhasil mem-porting semua fitur favorit saya, kecuali untuk Ctrl + w yang memperlakukan spasi dan garis miring sebagai batas kata, kemungkinan besar mundur-membunuh-kata. Namun dalam Bash readline menghapus semua jalan ke ruang pertama, menghapus semua garis miring di antara.

Saya sudah mencoba berbagai kombinasi \ Cw: backward-kill-word di kedua .inputrc dan .bashrc menggunakan bind tapi saya tidak bisa membuatnya bekerja seperti yang saya inginkan.

Cukup lucu, melalui Putty dari Windows di tempat kerja saya dapat menggunakan Alt + Backspace, yang juga manual mengatakan adalah ikatan default, untuk menghasilkan perilaku yang tepat yang saya inginkan. Tetapi di Terminal.app di Mac saya di rumah ini tidak berfungsi. Hal yang sama berlaku untuk server FreeBSD atau Linux yang kebetulan saya masuk dari Terminal.app.

Jadi saya beralih ke superuser untuk meminta bantuan.

Stefan M
sumber

Jawaban:

40

readlinetidak mengikat Ctrl- Wkarena ditangani oleh driver terminal secara default:

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

Untuk menonaktifkan ini, Anda harus menjalankan (dalam ~/.bashrc):

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

.inputrctidak akan membantu di sini karena sudah dibaca ketika Ctrl- Wmasih ditugaskan untuk werase.

Juga perhatikan bahwa \C-wformat keyseqs harus dilampirkan dalam tanda kutip ganda, seperti di atas.


Terminal yang berbeda dapat menangani Alt- secara Backspaceberbeda.

  • Putty dan Terminal GNOME (dengan pengaturan default) kirim 1b 7f( ESC DEL)
  • Xterm dengan metaSendsEscape: truemengirim 1b 08( ESC BS).
  • Xterm tanpa metaSendsEscape mengirim 88( HTS, atau BSdengan set bit tertinggi).

Xterm memiliki beberapa pengaturan untuk mengontrol perilaku Altkunci (disebut MetaXterm dan X11 secara umum). Dengan metaSendsEscape, holding Altakan mengawali penekanan tombol dengan ESC(hex 1b). Tanpa pengaturan (mode default), Altakan mengatur bit tertinggi dari karakter input, menghasilkan karakter khusus. (Misalnya, Alt- Nmenghasilkan ESC ndan îmasing - masing.)

Sejauh yang saya ingat, Terminal.app juga memiliki pengaturan serupa untuk mengontrol perilaku Meta / Alt / apa pun-Mac-gunakan.

grawity
sumber
Ini bukan hanya jawaban terbaik tetapi sangat informatif, terima kasih!
Stefan M
1
@shurane: Tindakan werase "word erase", seperti penghapusan normal (Backspace), diimplementasikan oleh OS itu sendiri, di driver "tty device" - perhatikan bahwa mereka tersedia bahkan dalam program yang hanya membaca secara membabi buta dari stdin, misalnya cat. Pada semua Unix, sttydigunakan untuk mengontrol berbagai parameter tty termasuk kunci-kunci khusus ini. (Begini tampang UNIX 7th Editionstty .)
grawity
1
@shurane: Sementara itu, readline adalah library userspace yang awalnya ditulis untuk bash shell (meskipun sekarang digunakan oleh banyak program). Mungkin saja tindakan lain diterapkan dalam readline untuk menghindari kembungnya driver tty (yang sudah memiliki cukup banyak flag dan matikan, seperti terlihat dalam sttymanual). Juga, bash pada awalnya ditujukan untuk OS GNU dan hanya kemudian diangkut ke Unix lain; jauh lebih mudah untuk mempertahankan fitur pengeditan di satu perpustakaan daripada di beberapa kernel yang sangat berbeda.
grawity
3
@shurane: Namun, secara teknis, semua tindakan ini, termasuk penghapusan kata, diimplementasikan oleh readline - saat aktif, ia sepenuhnya menonaktifkan penanganan Backspace dan Ctrl + W oleh driver terminal. readline hanya menghargai sttykonfigurasi untuk kesederhanaan, tetapi dapat ditimpa oleh pengaturan readline sendiri (seperti yang dijelaskan dalam jawaban Matt Day).
grawity
4
Ini adalah jawaban yang bagus untuk informasi, jelas. Namun, perlu dicatat bahwa ini menonaktifkan Ctrl-w untuk semua program kecuali mereka menggunakan readline, yang mungkin bukan yang diinginkan siapa pun ..., jadi coba jawaban @fjarlq.
0fnt
19

grawity menulis bahwa ini tidak dapat dikontrol dalam .inputrcfile, tetapi itu tidak benar.

Jika Anda berada set bind-tty-special-chars offdi Anda .inputrc, Anda kemudian dapat menyesuaikan perilaku chars terminal khusus.

Sebagai contoh:

set bind-tty-special-chars off
Control-u: kill-whole-line
Control-w: backward-kill-word
fjarlq
sumber
2
Dan ini bermanfaat untuk bekerja pada semua program yang menggunakan readline — mis python. , .
wchargin
3

Sebagai catatan, jawaban yang berlaku untuk iTerm2 adalah untuk mengatur Alt- Backspace(atau Opt ⌥- pada Mac) untuk mengirim Kode Hex 0xb1dan 0x7funtuk melakukan backward-kill-wordtindakan yang memperlakukan karakter non-alfanumerik sebagai pembatas.

Sebagai pembeda, inilah perilaku yang saya jelaskan, di mana menekan Opt ⌥- satu kali mengubah ini:

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

untuk ini:

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

Dan menekan berikutnya 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/

Seperti apa pengaturannya di iTerm2: masukkan deskripsi gambar di sini

Jadi, khusus untuk Putty dan Terminal, jawaban grawity luar biasa. Tetapi setelah menghabiskan waktu yang memalukan untuk mencari cara menerapkan pengaturan di iTerm2, posting pengguna super ini tampaknya paling sering muncul, jadi sepertinya bertanggung jawab untuk memberikan info yang relevan sebagaimana berlaku untuk iTerm2 sebagai Jawaban yang terlampir pada Pertanyaan ini.

TCAllen07
sumber
Butuh waktu lama bagi saya untuk mengetahui hal ini, dan solusi ini benar-benar bekerja pada OS X (dengan iTerm2) ketika masuk menggunakan bash shell jarak jauh. Terima kasih!
Martijn