Se você quisesse esse comportamento em todo o Emacs, seria trivial alcançá-lo usando key-translation-map
, um mapa de teclas fornecido especificamente para essa finalidade. Querer usá-lo apenas em certos modos principais complica um pouco as coisas. A melhor maneira que encontrei até agora para fazer isso é definir um modo secundário que realiza a tradução de acordo com um determinado mapa de teclado e, em seguida, adicionar um gancho para ativar esse modo secundário junto com cada modo principal ao qual você deseja aplicar .
Aqui está a definição do modo secundário. Solte isso em um arquivo swap-braces.el
em algum lugar no caminho de carregamento.
;;; swap-braces.el - a minor mode to swap square and curly braces
;;; Installation:
;; Drop it in your load path and (require 'swap-braces).
;; Possibly also (add-hook 'foo-mode-hook 'swap-braces-mode).
;;; Commentary:
;; The swap function explicitly instructs Linum to schedule an update,
;; if Linum mode is enabled; otherwise, Linum does not automatically
;; update while Swap-Braces mode is enabled.
;; This seems like it should not be necessary, and I'm uncertain whether
;; it has greater implications regarding interaction between this mode
;; and others.
;; (That is, it makes me worry that something about how I've implemented
;; this makes it screw up other modes using post-command-hook. Caveat user!)
;;; Author
;; Aaron Miller ([email protected])
(setq swap-braces-map (make-sparse-keymap))
(define-key swap-braces-map (kbd "{") "[")
(define-key swap-braces-map (kbd "}") "]")
(define-key swap-braces-map (kbd "[") "{")
(define-key swap-braces-map (kbd "]") "}")
(define-minor-mode swap-braces-mode
"When active, swap square braces and curly braces, so that e.g. pressing [
elicits '{', and S-[ elicits '['.
The keymap 'swap-braces-map' defines this mode's behavior. It is strongly
recommended that you do not define keys in this map which are not self-
inserting characters; the resulting behavior is indeterminate, but almost
certainly not what you intended."
:init-value nil
:lighter " [{"
(if swap-braces-mode
(add-hook 'post-command-hook
'swap-braces-mode-swap)
(remove-hook 'post-command-hook
'swap-braces-mode-swap)))
(defun swap-braces-mode-swap ()
;; this worries me
(if (and (boundp 'linum-mode)
(not (eq nil linum-mode)))
(linum-schedule))
(when (and (eq (char-before) last-command-event)
(not (window-minibuffer-p (selected-window))))
(let* ((translation (lookup-key swap-braces-map (string (char-before)))))
(if (stringp translation)
(progn
(backward-delete-char 1)
(insert translation))))))
(provide 'swap-braces)
Não é perfeito; observe as ressalvas relacionadas ao modo linum, e o que esse mau comportamento pode implicar nos efeitos desse modo em outros que usam post-command-hook. Eu uso vários desses modos, e não vi nenhum problema (além do linum não atualizar) durante o teste, mas sua milhagem pode variar, então esteja ciente. (Estranhamente, usar o hook pós-self-insert em vez disso não fez diferença aqui; estabeleci o hook pós-comando porque o hook pós-self-insert é aparentemente novo no Emacs 24 e não oferece nenhuma diferença de comportamento vale a pena abandonar a compatibilidade com versões anteriores.)
Em seguida, em algum lugar no seu código de inicialização, (require 'swap-braces)
; a partir de agora, você pode ativar o comportamento de troca com M-x swap-braces-mode
.
Finalmente, para ativar o modo menor junto com um modo principal, adicione-o ao gancho de carregamento do modo principal. Se o modo principal que você está usando for chamado de 'foo-mode', adicione o seguinte ao seu código de inicialização:
(add-hook 'foo-mode-hook 'swap-braces-mode)
Ajuste a gosto; no seu caso, provavelmente será chamado de latex-mode-hook
, mas verifique a documentação do modo para ter certeza.
Editado em 2013-10-09 para aplicar a tradução somente quando a janela selecionada não for o minibuffer; veja comentários.