在 emacs 中交换花括号和方括号

在 emacs 中交换花括号和方括号

目前,emacs我必须输入SHIFT-[SHIFT-]才能分别获得{}。输入[和分别]产生[]。我想在 emacs 中交换此行为,即我想要:

  • [并且]会产生{}
  • SHIFT-[并且SHIFT-]会产生[]

这个想法的灵感来自于https://tex.stackexchange.com/a/1985/412

奖励:我希望此行为仅适用于某些主要模式。

答案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 ([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)

它并不完美;请注意有关 linum-mode 的注意事项,以及这种奇怪的错误行为可能暗示此模式对使用 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 编辑,仅当选定的窗口不是迷你缓冲区时才应用翻译;参见评论。

答案2

让我们来看看...

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 "[")))
             ...))

我觉得这不是最好的解决方案。如果你使用类似自动配对或者帕里迪特有了这些支撑风格,奇怪的事情就会发生™©。

相关内容