Excluir a última palavra (Ctrl-W): Fazer o shell bash se comportar como a linha de comando do vim

6

Entre os muitos atalhos de teclado úteis disponíveis no bash shell, existe Ctrl - W para apagar a palavra à esquerda do cursor. Vamos supor que minha linha de comando se pareça com o seguinte:

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

Agora eu esperaria poder pressionar Ctrl - W e terminar com o seguinte:

cp some-file /foo/bar/baz/

Na linha de comando do Vim, ele funciona da seguinte maneira: somente caracteres alfanuméricos são tratados como "palavra", enquanto caracteres especiais (como / ) servem como delimitadores que marcam o início de uma nova "palavra".

Mas infelizmente não funciona assim em todos os shells que usei até agora. Somente espaços delimitarão uma "palavra", então pressionar o atalho com a linha de comando mostrada acima me dará:

cp some-file

Existe uma maneira de fazer o Bash se comportar como o Vim? Alguma configuração que eu posso colocar no meu .bashrc ?

    
por lethal-guitar 23.01.2014 / 11:51

3 respostas

11

Isso não tem nada a ver com o Vim, todos os editores se comportam dessa maneira (incluindo o emacs), eles tratam caracteres não-word como delimitadores. De qualquer forma, o comportamento do qual você está falando é controlado por readline e seu manual lista alguns comandos aos quais você pode atribuir atalhos. Estou colando alguns relevantes aqui, mas recomendo que você leia man readline para mais informações:

   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.

Então, o que você quer é backward-kill-word , que usa caracteres não alfanuméricos como limites de palavras. Por padrão, ele é atribuído a Alt + Backspace , mas você pode alterá-lo usando o% global/etc/inputrc se quiser que eles se apliquem a todos os usuários ou (melhor) seu próprio local $HOME/.inputrc .

Tanto quanto eu posso dizer, Ctrl + W parece ser reservado e você não pode usar esse, mas você pode escolher outro atalho, Ctrl + J por exemplo. Crie um arquivo $HOME/.inputrc se ele não existir e adicione esta linha a ele:

Control-J: backward-kill-word 

Isso deve ser suficiente para a maioria dos emuladores de terminal modernos. No entanto, alguns terminais mais antigos usam códigos diferentes. Se você estiver usando xterm , por exemplo, a linha acima deve ser escrita como:

C-J: backward-kill-word 
    
por 23.01.2014 / 16:19
5

Você pode habilitar a linha de leitura (e assim o bash), chamada "modo vi", colocando as seguintes linhas em ~/.inputrc e iniciando um novo shell:

set editing-mode vi
set keymap vi-command

Mas você notará que <C-w> funciona da mesma forma que no modo Emacs padrão: as palavras são delimitadas por espaço. Você pode fazer dT/ ou comandos semelhantes, no entanto. Ainda é uma emulação, não o verdadeiro negócio. Os mapeamentos disponíveis estão listados no manual da readline:

$ man readline
/VI

Veja também esta página no wiki do Vim .

Mas eu não acho que o modo vi de readline é tão útil, se você frequentemente se vê precisando de editar seriamente sua linha de comando ... por que não usar o Vim para real ?

<C-x><C-e>
    
por 23.01.2014 / 12:19
1

Existem duas opções que eu conheço, embora nenhuma delas faça diretamente o que você pergunta.

  1. define bash para usar o modo vi, onde o prompt se comporta como uma linha no vi. O comando é set -o vi . Ref: Ajuda BASH - Um Tutorial de Bash
  2. Adicione os mapas de chave vi ao seu prompt de shell atual. Ref: StackOverflow: O que o vi key map vi do?
por 23.01.2014 / 12:21