Lier un mot de suppression en arrière à Ctrl + w

23

J'essaie de passer d'une utilisation prolongée de Tcsh à une exploration récente de Bash.

J'ai réussi à porter sur toutes mes fonctionnalités préférées, à l'exception de Ctrl + w qui traite les espaces et les barres obliques comme des limites de mot, très probablement un mot de suppression en arrière. Dans Bash, readline supprime jusqu'au premier espace, supprimant toutes les barres obliques entre les deux.

J'ai essayé de nombreuses combinaisons de \ Cw: backward-kill-word dans .inputrc et .bashrc en utilisant bind mais je n'arrive pas à le faire fonctionner comme je le souhaite.

Assez drôle, grâce à Putty de Windows au travail, je peux utiliser Alt + Backspace, qui, selon le manuel, est la liaison par défaut, pour produire le comportement exact que je veux. Mais dans Terminal.app sur mes Mac à la maison, cela ne fonctionne pas. Il en va de même pour tout serveur FreeBSD ou Linux auquel je suis connecté depuis Terminal.app.

Je me tourne donc vers le superutilisateur pour obtenir de l'aide.

Stefan M
la source

Réponses:

40

readlinene se lie pas Ctrl- Wcar il est géré par le pilote de terminal par défaut:

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

Pour désactiver cela, vous devez exécuter (in ~/.bashrc):

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

.inputrcn'aidera pas ici car il est lu quand Ctrl- West toujours affecté à werase.

Notez également que les \C-wclés de format doivent être mises entre guillemets, comme ci-dessus.


Différents terminaux peuvent gérer Alt- Backspacedifféremment.

  • Terminal PuTTY et GNOME (avec les paramètres par défaut) send 1b 7f( ESC DEL)
  • Xterm avec metaSendsEscape: trueenvoie 1b 08( ESC BS).
  • Xterm sans metaSendsEscape envois 88( HTS, ou BSavec le bit le plus élevé).

Xterm dispose de quelques paramètres pour contrôler le comportement des Alttouches (appelés Metadans Xterm et X11 en général). Avec metaSendsEscape, la tenue maintiendra Altle préfixe de la touche avec un ESC(hex 1b). Sans le paramètre (mode par défaut), Altdéfinira le bit le plus élevé du caractère saisi, ce qui donnera des caractères spéciaux. (Par exemple, Alt- Ndonne respectivement ESC net î.)

Pour autant que je me souvienne, Terminal.app a également un paramètre similaire pour contrôler le comportement de Meta / Alt / quelle que soit-Mac-utilisation.

grawity
la source
Ce n'est pas seulement la meilleure réponse mais extrêmement informative, merci!
Stefan M
1
@shurane: L'action d' effacement "word erase", comme l'effacement normal (Backspace), est implémentée par le système d'exploitation lui-même, dans le pilote "tty device" - notez qu'ils sont disponibles même dans des programmes qui lisent aveuglément stdin, par exemple cat. Sur tous les Unix, sttyest utilisé pour contrôler divers paramètres tty, y compris ces touches spéciales. (Voici à quoi ressemblait la 7e édition d'UNIXstty .)
grawity
1
@shurane: Pendant ce temps, readline est une bibliothèque d'espace utilisateur écrite à l'origine pour le shell bash (bien que maintenant utilisée par de nombreux programmes). Il est possible que les autres actions aient été implémentées en ligne de lecture pour éviter de gonfler le pilote tty (qui avait déjà une quantité considérable de drapeaux et de bascules, comme vu dans sttyle manuel de). En outre, bash était à l'origine destiné au système d'exploitation GNU et n'a été porté que plus tard sur d'autres Unix; il est beaucoup plus facile de maintenir les fonctions d'édition dans une seule bibliothèque que dans plusieurs noyaux très différents.
grawity
3
@shurane: Techniquement, cependant, toutes ces actions, y compris l'effacement des mots, sont implémentées par readline - lorsqu'elle est active, elle désactive complètement la gestion de Backspace et Ctrl + W par le pilote du terminal. readline respecte simplement la sttyconfiguration pour plus de simplicité, mais elle peut être remplacée par les propres paramètres de readline (comme décrit dans la réponse de Matt Day).
grawity
4
Ceci est une excellente réponse pour l'information, vote positif. Cependant, il convient de noter que cela désactive Ctrl-w pour tous les programmes à moins qu'ils n'utilisent readline, ce qui n'est probablement pas ce que quiconque veut ..., alors essayez la réponse de @fjarlq.
0fnt
19

grawity a écrit que cela ne peut pas être contrôlé dans le .inputrcfichier, mais c'est incorrect.

Si vous set bind-tty-special-chars offdans votre .inputrc, vous pouvez alors personnaliser le comportement des caractères spéciaux du terminal.

Par exemple:

set bind-tty-special-chars off
Control-u: kill-whole-line
Control-w: backward-kill-word
fjarlq
la source
2
Et cela a l'avantage de fonctionner pour tous les programmes qui utilisent readline, par exemple python.
wchargin
3

Pour mémoire, la réponse telle qu'elle s'applique à iTerm2 est de définir Alt- Backspace(ou Opt ⌥- sur Mac) pour envoyer des codes hexadécimaux 0xb1et 0x7fafin d'effectuer l' backward-kill-wordaction qui traite les caractères non alphanumériques comme des délimiteurs.

Pour faire la distinction, voici le comportement que je décris, dans lequel appuyer sur Opt ⌥- une fois change cela:

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

pour ça:

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

Et les pressions suivantes de 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/

Voici à quoi ressemble le paramètre dans iTerm2: entrez la description de l'image ici

Donc, spécifique à Putty et Terminal, la réponse de grawity est excellente. Mais après avoir passé un temps embarrassant à chercher comment appliquer le paramètre dans iTerm2, ce message de superutilisateur semble apparaître le plus souvent, il semblait donc responsable de fournir les informations pertinentes car il s'applique à iTerm2 en tant que réponse jointe à cette question.

TCAllen07
la source
Il m'a fallu beaucoup de temps pour comprendre cela, et cette solution fonctionne effectivement sur OS X (avec iTerm2) lors de la connexion à un shell bash distant. Merci!
Martijn