Você notará que, quando você executa cat
um prompt de shell em um terminal, cat
deve escrever para stdout o que lê de stdin, e pressionar a, você vê um a
eco de volta pelo driver do terminal, mas cat
não escreve isso a
(você vê apenas um a
, aquele ecoado pelo driver do terminal).
No entanto, se você digitar a Backspace b Enter, não verá a cat
saída a\010b\015
, mas b\012
( b
e nova linha).
Isso ocorre porque o driver do terminal (estamos falando de software no kernel, não no emulador de terminal xterm
) implementa um editor de linhas muito básico quando no modo canônico . O driver do terminal pode ser configurado usando ioctl()
chamadas do sistema, como ao usar o stty
comando Por exemplo, para sair do modo canônico, você pode fazer stty -icanon
. Se você fizer:
stty -icanon; cat
Em seguida, você verá o echo
(com o qual você poderia ter desativado stty -echo
) e a cat
saída ao mesmo tempo.
Esse editor é um editor de linha. Ou seja, cabe ao usuário editar uma linha de texto até que seja enviada ao aplicativo que lê o dispositivo terminal ao pressionar Enter.
Os recursos de edição desse editor são muito limitados. Na maioria das implementações, existem apenas 4 chaves de edição (na verdade caracteres) também configuráveis com stty
:
- apagar (
^H
ou ^?
geralmente): apaga o caractere anterior
- kill (
^U
geralmente): vazio (kill) a linha inserida até o momento
- werase (
^W
): apaga a palavra anterior
- lnext (
^V
): insira o próximo caractere literalmente (cancele o significado especial de todos os itens acima)
Antigamente, pensava-se que esse editor de linha de driver de terminal seria estendido com recursos mais sofisticados. É por isso que nenhum dos shells anteriores possui recursos de edição de linha de comando (você obteria os mesmos recursos de edição de linha no prompt do shell do que quando executava cat
como fizemos acima).
No entanto, isso realmente nunca aconteceu, talvez parte do motivo seja a bagunça com terminais diferentes que não enviam os mesmos caracteres em algumas teclas pressionadas, o que tornou evidente que isso não deve ser implementado no espaço do kernel.
Assim, alguns shells começaram a abandonar o modo canônico do driver do terminal e a implementar seu próprio editor de linha. Na época, emacs
e vi
eram os editores visuais de texto mais populares com ligação de teclas e modo de operação completamente diferentes. Em vi
, você tem um modo para inserir texto e outro para editar. Em emacs
, você está sempre entrando no modo de texto , mas a edição é feita pressionando as combinações de teclas (como ^b
mover o caractere para trás).
Não havia nenhum ponto para as conchas no momento apresentarem suas próprias chaves diferentes. Isso causaria frustração para as pessoas terem que aprender outra. No entanto, escolher um ( emacs
ou vi
) estilo sobre o outro teria sido uma maneira de alienar os usuários do outro editor.
De acordo com https://www.usenix.org/legacy/publications/library/proceedings/vhll/full_papers/korn.ksh.a :
Os populares recursos de edição em linha (modo vi e emacs) do ksh foram criados por desenvolvedores de software nos Laboratórios Bell; o modo de edição de linha vi, de Pat Sullivan, e o modo de edição de linha emacs, de Mike Veach. Cada um deles modificou independentemente o shell Bourne para adicionar esses recursos, e ambos estavam em organizações que queriam usar o ksh apenas se o ksh tivesse seu respectivo editor embutido. Originalmente, a idéia de adicionar edição de linha de comando ao ksh foi rejeitada na esperança de que a edição de linha passasse para o driver do terminal. No entanto, quando ficou claro que não era provável que isso acontecesse em breve, os dois modos de edição de linha foram integrados ao ksh e tornaram-se opcionais para que pudessem ser desativados em sistemas que forneciam edição como parte da interface do terminal.
Então, em vez disso, eles implementaram ambos e uma interface para os usuários escolherem entre os dois. ksh
foi provavelmente o primeiro no início dos anos 80 (reutilizando código que foi escrito separadamente para adicionar um modo vi e um modo emacs ao shell Bourne, como visto acima), seguido por tcsh
( tcsh
inicialmente só tinha emacs
ligação de teclas, o vi
modo foi adicionado posteriormente) e mais tarde bash
e zsh
no início dos anos 90.
Você alterna entre os dois modos em bash
, zsh
ou ksh
com set -o vi
ou set -o emacs
, e com bindkey -e
ou bindkey -v
em tcsh
ou zsh
.
O POSIX na verdade especifica o vi
modo e não o emacs
modo sh
(a história mostraemacs
sh
que Richard Stallman se opôs ao POSIX especificar o modo para ).
O modo padrão para bash
, as variantes de domínio público de ksh
(pdksh, mksh, oksh) tcsh
e zsh
é o modo emacs (embora com zsh
, seja vi
se você $EDITOR
for vi
), enquanto na AT&T ksh
é o modo burro , a menos que $EDITOR
ou $VISUAL
mencione vi
ou emacs
.
ksh
posteriormente, também adicionou um gmacs
modo para acomodar os usuários de Gosling emacs
que lidavam de maneira Ctrl+Tdiferente.
Agora a manipulação de ^W
em emacs
ou em tcsh
modo de emacs, provavelmente antecede a werase
personagem no editor de linha terminal, por isso não podemos culpá-los por isso e minha declaração sobre "partida ..." pode ser visto como enganosa. É só que eu acho que é irritante quando as coisas gostam emacs
, tcsh
ou info
se comportam de maneira diferente de tudo o resto quando você digita Ctrl-W. Você pode imaginar que eu achei muito mais irritante quando alguns aplicativos começaram a fechar a janela quando você digitou Ctrl-W.