2

В настоящее время в emacs я должен набрать SHIFT-[ и SHIFT-] чтобы получить { и } соответственно. Ввод [ и ] приводит к [ и ] соответственно. Я хочу поменять это поведение в Emacs, а именно:

  • [ и ] даст { и }
  • SHIFT-[ и SHIFT-] приведет к [ и ]

Эта идея вдохновлена https://tex.stackexchange.com/a/1985/412

БОНУС: Я хочу, чтобы это поведение применялось только для определенных основных режимов.

2 ответа2

1

Посмотрим...

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

Похоже, мы можем просто поменять их местами, добавив

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

в .emacs . Для определенных режимов добавьте подобные вещи в соответствующий mode-hook вместо того, чтобы устанавливать их глобально. Так,

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

Я чувствую, что это на самом деле не лучшее решение. Если вы используете такие вещи, как автопары или парэдит с этими стилями фигурных скобок, Odd Things Will Happen ™ ©.

1

Если бы вы хотели такое поведение во всем Emacs, было бы тривиально добиться этого с помощью key-translation-map , карты ключей , предоставленной специально для этой цели. Желание использовать его только в определенных основных режимах несколько усложняет ситуацию. Наилучший способ, который я нашел до сих пор, - это определить второстепенный режим, который выполняет перевод в соответствии с заданной таблицей ключей, а затем добавить хук для активации этого второстепенного режима вместе с каждым основным режимом, к которому вы хотите его применить. ,

Вот определение второстепенного режима. Перетащите это в файл swap-braces.el где - нибудь в вашем пути загрузки.

;;; 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 (me@aaron-miller.me)

(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)

Это не идеально; обратите внимание на предостережения относительно режима linum и то, что это странное неправильное поведение может указывать на эффекты этого режима для других, которые используют post-command-hook. Я использую несколько таких режимов, и не видел никаких проблем (кроме linum, не обновляющихся) во время тестирования, но ваш пробег может отличаться, так что будьте внимательны. (Как ни странно, использование post-self-insert-hook вместо этого не имело никакого значения; я остановился на post-command-hook, потому что post-self-insert-hook, очевидно, является новым в Emacs 24 и не предлагает никакой разницы в поведении Стоит отказаться от обратной совместимости.)

Затем, где-то в вашем коде инициализации, (require 'swap-braces) ; отныне вы можете активировать режим обмена с помощью M-x swap-braces-mode .

Наконец, чтобы активировать второстепенный режим вместе с основным режимом, добавьте его в хук загрузки основного режима. Если основной режим, который вы используете, называется «foo-mode», то вы добавите следующее в код инициализации:

(add-hook 'foo-mode-hook 'swap-braces-mode)

Настроить по вкусу; в вашем случае, он, вероятно, будет называться latex-mode-hook , но проверьте документацию режима, чтобы убедиться в этом.

Отредактировано 2013-10-09 для применения перевода только тогда, когда выбранное окно не является минибуфером; см комментарии

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .