Você não pode realmente alterar a C-[ligação nos mapas no nível do usuário, como faria com global-set-key
. No entanto, você pode alterá-lo como um evento de teclado antes de atingir esses mapas de teclas. Você pode dizer, por exemplo:
(define-key input-decode-map
(kbd "C-[")
[control-bracketleft])
e depois use [control-bracketleft]
nos seus mapas de teclas. Muito simples, não é?
Corte do Diretor
Infelizmente, não é tão simples, e essa solução requer alguns ajustes, que parecerão muito dolorosos. Voce foi avisado. Mas vamos ver primeiro por que os mapas no nível do usuário não podem responder à pergunta. A seguir, refiro-me ao manual do Emacs Lisp para o emacs 26.1 quando digo "ver algo" sem mais precisão.
C-[é interpretado muito cedo como o caractere de controle ASCII ESC
(consulte 21.7.1 - Eventos do teclado ). Esse código está espalhado em todos os outros lugares como prefixo para seqüências mais longas. Há uma razão para isso: ESC
é realmente o meta prefixo (consulte meta-prefix-char
), e todas as ligações que lêem
M-algo serão traduzidas para uma sequência que começa com ESC
. Assim, alterar o mapa global não será suficiente: você precisa primeiro mudar e meta-prefix-char
, em seguida, remapear ESC
para o seu novo meta-prefix-char
em cada mapa usado M-antes de poder mapear com segurança C-[.
OK, é claro: vamos usar input-decode-map
. Existem alguns mapas semelhantes que podemos ficar tentados a usar (consulte as seções 21.8.3 e 22.14), mas vamos nos ater a este. E bem ... isso funciona! Você terminou, não está?
Na verdade, não, a história não termina aqui. Isso funciona ... desde que você esteja usando um sistema de janelas. Se, devido à má sorte, você estiver preso no console do linux em um estado de emergência, você perceberá o quão dramática a situação se tornou: teclas de seta Homee M-, é claro , ligações, são tudo lixo. Por quê? Porque quando o terminal diz ESC
(o que faz quando você digita C-[), realmente significa ESC
e inicia uma sequência do mesmo tipo usada para transmitir caracteres não ASCII.
Observando o desastre, considere prudente proteger a input-decode-map
modificação acima de forma que ela seja ativada apenas no caso de um sistema de janelas estar controlando o teclado:
(let ((frame (framep (selected-frame))))
(or (eq t frame)
(eq 'pc frame)
(define-key input-decode-map
(kbd "C-[")
[control-bracketleft])
)))
Os terminais então funcionam como costumavam.
Agora, podemos lidar com C-[terminais? Na verdade, sim, podemos, no console linux e nos outros emuladores de terminal com os quais posso brincar. Mas isso torna a história bastante longa, à medida que novos personagens entram em cena. Pois não há mais emacs por si só: o terminal tem agora o papel central.
Vamos dar uma olhada no que o console linux tem a dizer. Digite C-vantes de alguma tecla para ouvir claramente. C-[é ESC
; assim é Esc. A seta para cima soa como ESC [ A
, enquanto M-aé
ESC A
. Hmm ... Parece que essa meta-circunvolução no emacs não é? De qualquer forma.
A menos que nós estamos prontos para jogar alguns truques com base no tempo decorrido entre os eventos de caracteres (que por sinal não vai distinguir
Esca partir C-[), parece que não tenho escolha a não ser dizer a consola o que realmente não significam ESC
quando digitamos C-[. Além disso, parece que em breve esse C-[não é o único problema com os códigos dos terminais de estoque: os modificadores geralmente apagam as informações transmitidas. Precisamos personalizar o terminal pela mesma razão que personalizamos o emacs: seria muito mais prático se o fizermos.
Neste ponto, você deve se aprofundar nos olhos da documentação do seu terminal: páginas de manual loadkeys(1)
do console linux, xterm
xterm(1)
na seção Custom Key Bindings e o que eu não sei sobre outros terminais. Em KDE konsole
, você pode definir traduções personalizadas em Configurações / Editar perfil atual ... e
depois em Teclado . Aqui está um trecho de ~/.local/share/konsole/Test.keytab
depois de jogar com este último diálogo:
key [+Ctrl+AnyModifier : "\EO*["
Assim que tiver o envio de terminal ESC O 5 [
para
C-[(como na configuração acima), você pode voltar para emacs. Pois é claro, você ainda não terminou.
Para instruir o emacs qual dialeto usa um determinado terminal, você pode ajustar input-decode-map
. Sim, é por sorte o que modificamos no início desta história, e é
term/xterm.el
exatamente o que toca quando o xterm está envolvido. Um bom local para o ajuste é tty-setup-hook
(consulte a seção 40.1.3):
(add-hook 'tty-setup-hook
(lambda ()
(let ((term (getenv "TERM")))
(cond
(;; xterm-function-map not in doc, but in term/xterm.el
(boundp 'xterm-function-map)
(map-my-term-codes xterm-function-map))
((equal term "linux")
(map-my-term-codes input-decode-map))
)
)))
Esteja ciente de que este gancho só funciona se você estiver em um terminal. Portanto, você não pode inserir aqui o código para a inicialização do sistema de janelas. Aqui está a função de tradução por si só:
(defun map-my-term-codes (map)
(define-key map (kbd "M-O 5 [")
[control-bracketleft])
)
E então você pode descansar um pouco: é o fim da jornada. Claro, se você não se importa com terminais, é rápido, pois você pulará toda a parte dolorosa. Mas você admitirá que também é bastante incompleto.
Duas notas finais:
Eu escolho ESC O 5 [
codificar C-[. Este é apenas um exemplo: não vou fingir que é uma boa escolha. Apenas a 5
parte, o que significa C-, parece obedecer a algum tipo de convenção estabelecida
configurar o console linux deixa um gosto ruim: não parece possível fazer a ligação sem usar um símbolo existente intermediário , e aqueles que eu precisaria
não existem . Eu uso símbolos no intervalo F21- F246como na maioria dos exemplos da Internet, mas não é muito satisfatório. Não há problema em algumas ligações não relacionadas, mas não servirá um esquema sistemático.
Editar
- Concluí isso com o Esccaso - que tem personalidade própria - em outro post: Como remover ligações à chave de prefixo ESC
Aqui está um fragmento de uma configuração para alimentar loadkeys
. Coloquei isso em /root/custom.kmap e carrego quando preciso (o que é raro). Minha configuração atual também mapeia setas e diferentes combinações de modificador, mas é bastante longo, a escolha de símbolos e seqüências é questionável, e não tenho certeza de que os códigos de teclas do meu teclado correspondam aos seus. Então, vamos mantê-lo no seu devido nível: isso não passa de uma ilustração.
keymaps 0-127
# http://tldp.org/HOWTO/Keyboard-and-Console-HOWTO-15.html
# web+man:keymaps
# web+man:loadkeys
# escape
keycode 1 = F100
alt keycode 1 = Escape # keep the Escape behavior somewhere
# keycode 26 = bracketleft
control keycode 26 = F115 # Control_bracketleft does not exist
string F100 = "\033OO" # map this to [escape] in map-my-term-codes
string F115 = "\033O5["
A solução a seguir é um pouco confusa, mas parece funcionar:
Vamos
~/.xbindkeysrc
conter o seguinte:Agora
xbindkeys
será traduzido C-[para C-<f13>e C-]para C-<f14>, para que possam ser vinculados livremente no emacs. Você provavelmente desejará vincular-seabort-recursive-edit
a algo diferente de C-], por exemplo C-S-g,.A desvantagem é que agora C-[está quebrado em todos os aplicativos, exceto no Emacs, que podem ser corrigidos adicionando alguma lógica para testar se a combinação de teclas está sendo enviada ao emacs ...
fonte
C-]
.C-]
ligação parou de funcionar depois que eu iniciei o Xbindkeys, então eu recuperei essa também.