(ELisp)使用大括号返回自动嵌套下一行

时间:2014-05-24 02:24:56

标签: emacs formatting elisp key-bindings auto-indent

我对Lisp和Emacs都是全新的。在Emacs中,例如,当用Java编码时,我希望能够键入“{”然后点击“ENTER”并让下一行准备好嵌套在大括号中的任何内容。例如,如果我有以下行:

public void method()

然后我键入“{”然后点击返回我应该得到这个:

public void method() {
    // indentation applied, no additional tabbing necessary
}

我已经能够成对插入,例如,键入“{”会在我的光标位于括号之间给出“{}”。我通过将这些行添加到emacs init文件来完成此操作:

;; insert by pairs (parens, quotes, brackets, braces)
(defun insert-pair (leftChar rightChar)
  (if (region-active-p)
      (let (
        (p1 (region-beginning))
        (p2 (region-end))
        )
    (goto-char p2)
    (insert rightChar)
    (goto-char p1)
    (insert leftChar)
    (goto-char (+ p2 2))
    )
(progn
  (insert leftChar rightChar)
  (backward-char 1) ) )
  )
(defun insert-pair-brace () (interactive) (insert-pair "{" "}") )
(global-set-key (kbd "{") 'insert-pair-brace)

为了获得上面描述的自动嵌套,我添加了以下几行:

;; automatically nest next line
(defun auto-nest ()
  (insert "\n\n")
  (backward-char 1)
  (insert "\t")
)
(defun auto-nest-brace () (interactive) (auto-nest) )
(global-set-key (kbd "{ RET") 'auto-nest-brace)

然而,当我启动Emacs时,我收到此消息:

error: Key sequence { RET starts with non-prefix key {

我做错了什么,我该怎么做才能解决这个问题?我不想使用不同的组合键来执行此操作。有很多文本编辑器,其中这种自动嵌套是标准的,它应该很容易在ELisp中编码。

3 个答案:

答案 0 :(得分:1)

您尝试自己将此功能添加到Emacs真是太棒了,但是没有必要在这里重新发明轮子。 Emacs已经有了一个用于自动缩进的命令;它被称为newline-and-indent。它默认绑定到 C-j ,但您可以将其重新绑定到 RET

  1. 全局:

    (global-set-key (kbd "RET") 'newline-and-indent)
    
  2. 仅适用于特定模式:

    (require 'cc-mode)
    (define-key java-mode-map (kbd "RET") 'newline-and-indent)
    

    java-mode-mapcc-mode.el中定义,默认情况下不可用,这就是为什么在修改require之前必须cc-mode java-mode-map的原因


  3. 请注意newline-and-indent 根据主要模式缩进。也就是说,如果你是在java-mode中并在某个随机位置按 RET ,这对于Java语法没有意义,它不会在新的开头插入额外的空格线。

    阅读所有有关newline-and-indent

    的信息

    C-h f newline-and-indent RET

答案 1 :(得分:1)

我的emacs配置中有类似的东西,我已经使用了一段时间。它会调用'newline-and-indent两次,然后在正确缩进之前将点向上移动一行。以下是我的配置文件中执行此操作的代码片段:

;; auto indent on opening brace
(require 'cc-mode)
(defun av/auto-indent-method ()
  "Automatically indent a method by adding two newlines.
Puts point in the middle line as well as indent it by correct amount."
  (interactive)
  (newline-and-indent)
  (newline-and-indent)
  (forward-line -1)
  (c-indent-line-or-region))

(defun av/auto-indent-method-maybe ()
  "Check if point is at a closing brace then auto indent."
  (interactive)
  (let ((char-at-point (char-after (point))))
    (if (char-equal ?} char-at-point)
        (av/auto-indent-method)
      (newline-and-indent))))

(define-key java-mode-map (kbd "RET") 'av/auto-indent-method-maybe)

如你所见,非常简单明了。希望它对你有用。我没有在除java之外的任何其他模式中使用它。

答案 2 :(得分:0)

您需要自动对(或备选方案)和自动缩进的组合。查看前者的电子邮件:http://www.emacswiki.org/emacs/AutoPairs

关于后者: http://www.emacswiki.org/emacs/AutoIndentation