Troque as chaves e as chaves quadradas no emacs

2

Atualmente, em emacs , tenho que digitar SHIFT-[ e SHIFT-] para obter { e } , respectivamente. Digitar [ e ] rende [ e ] , respectivamente. Eu quero trocar esse comportamento no emacs, ou seja, eu quero ter:

  • [ e ] produzirão { e }
  • SHIFT-[ e SHIFT-] produzirão [ e ]

Esta ideia é inspirada no link

BÔNUS: Eu quero que esse comportamento seja aplicado apenas para determinados modos principais.

    
por Dror 21.08.2013 / 07:13

2 respostas

1

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.

    
por 21.08.2013 / 16:45
1

Vamos ver ...

M-x describe-key [
\    [ runs the command self-insert-command ...
M-x describe-key
\    { runs the command self-insert-command ...

Parece que podemos apenas trocá-los ingenuamente adicionando

(global-set-key (kbd "{") (lambda () (interactive) (insert "[")))

para .emacs . Para modos específicos, adicione coisas assim ao mode-hook apropriado em vez de defini-las globalmente. Então,

(add-hook 'some-mode-hook
          (lambda ()
             (define-key some-mode-map (kbd "{") (lambda () (interactive) (insert "[")))
             ...))

Tenho a sensação de que esta não é a melhor solução. Se você usa coisas como autopairs ou paredit com esses estilos de chaves, coisas estranhas acontecerão © ©.

    
por 21.08.2013 / 16:20