在缩进的块之前添加或删除代码时,自动重新缩进省略号


18

假设我有一个elisp代码,例如:

(+ 2 3▮(+ 3
          4))

添加或删除符号时,有没有一种方法可以在光标后自动重新缩进sexp?

因此,按之后SPC 4 SPC,我将自动获得:

(+ 2 3 4 ▮(+ 3
             4))

我可以先打,mark-sexp然后再打indent-region。有更好的方法吗?


我认为没有任何方便的默认键绑定,但是您可以轻松地自己创建一些。
shosti 2014年

我知道,但是我特别想知道是否还有更好的方法可以做到这一点。例如,electric-indent-mode与映射<return>newline-and-indent
Maciej Goszczycki 2014年

Answers:


14

可以按mark-sexp+ 代替+ 。这会打电话给。不是自动的,但是比必须调用两个命令要好一些。indent-regionC-M-qindent-pp-sexp

或者,如果您正在使用paredit-mode,请按M-q。这将使您所在的整个函数定义缩进。


1
(add-hook 'post-self-insert-hook 'indent-pp-sexp)效果很好。
Maciej Goszczycki 2014年

看起来不错。在某些模式下,这可能会付出高昂的代价,但这仍然是一种不错的方法。
德米特里(Dmitry)

对于Smartparens用户,您可以使用来重新缩进当前定义M-x sp-indent-defun。我将此绑定到C-M-q
Radon Rosborough

15

积极缩进模式

由于有人提出了要求,所以我把这个答案 变成了一个包装

如果配置了Melpa,则可以使用

M-x package-install RET aggressive-indent

有关所有选项,请参见自述文件,但打开它的最简单方法是:

(add-hook 'emacs-lisp-mode-hook #'aggressive-indent-mode)

旧答案

以下仅在elisp缓冲区上执行自动缩进。它具有在擦除或拖拽内容(而不只是键入内容)时也可以工作的优点。也很容易添加到其他模式。

该函数将缩进该点当前位于其中的任何s表达式。您可以根据需要将其绑定到密钥,但请先参见下文。

(require 'cl-lib)

(defun endless/indent-defun ()
  "Indent current defun.
Do nothing if mark is active (to avoid deactivating it), or if
buffer is not modified (to avoid creating accidental
modifications)."
  (interactive)
  (ignore-errors
    (unless (or (region-active-p)
                buffer-read-only
                (null (buffer-modified-p)))
      (let ((l (save-excursion (beginning-of-defun 1) (point)))
            (r (save-excursion (end-of-defun 1) (point))))
        (cl-letf (((symbol-function 'message) #'ignore))
          (indent-region l r))))))

该挂钩将使您可以在键入任何内容后运行此函数,但只能在elisp缓冲区中运行。这应该使所有内容始终缩进。

(add-hook
 'emacs-lisp-mode-hook
 (lambda ()
   (add-hook 'post-command-hook
             #'endless/indent-defun nil 'local)))

尝试一下!它工作得非常好。

另外,按照@holocronweaver在评论中的建议,您可以对类似c的语言使用类似以下的内容:

(define-key c++-mode-map ";"
  (lambda () (interactive)
    (insert ";")
    (endless/indent-defun)))

如果这种方法可以使自动缩进消息静音并且可以更好地处理以分号结尾的语言,那将是很好的选择。
holocronweaver

@holocronweaver当然,我可以尝试。哪个主要模式有缩进消息?而半冒号有什么问题?
Malabarba

我在Emacs干线上尝试的所有模式都会产生缩进消息,包括elisp。由于分号以多种语言结束一行,因此在您键入分号之前,以下行会像跳到当前行一样跳跃。
holocronweaver

@holocronweaver使消息静音。感谢您指出。
马拉巴巴2014年

感谢您的修复!分号问题的一种解决方案是在键入分号时仅缩进c模式语言。
holocronweaver 2014年

3

我不知道已有的解决方案,但是您可以post-self-insert-hook自己完成此任务:

(defun my-indent-next-sexp ()
  (interactive)
  (mark-sexp)
  (indent-region))

(add-hook 'post-self-insert-hook 'my-indent-next-sexp)

我会担心潜在的性能问题。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.