Como algumas pessoas pediram, eu transformei essa resposta
em um pacote .
Se você tiver o Melpa configurado, poderá instalá-lo com
M-x package-install RET aggressive-indent
Consulte o Leia-me para obter todas as opções, mas a maneira mais simples de ativá-lo é:
(add-hook 'emacs-lisp-mode-hook #'aggressive-indent-mode)
A resposta antiga
A seguir, a indentação automática apenas nos buffers elisp. Tem a vantagem de também funcionar quando você apaga ou arranca coisas (em vez de apenas digitar). Também é fácil adicionar a outros modos.
Esta função irá indentar qualquer expressão s que o ponto esteja atualmente dentro. Você pode vinculá-lo a uma chave, se desejar, mas veja abaixo primeiro.
(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))))))
Esse gancho fará com que essa função seja executada após você digitar qualquer coisa, mas apenas nos buffers elisp. Isso deve manter tudo sempre recuado.
(add-hook
'emacs-lisp-mode-hook
(lambda ()
(add-hook 'post-command-hook
#'endless/indent-defun nil 'local)))
Tente! Funciona notavelmente bem.
Além disso, seguindo a sugestão de @ holocronweaver nos comentários, você pode usar algo como o seguinte para idiomas semelhantes a c:
(define-key c++-mode-map ";"
(lambda () (interactive)
(insert ";")
(endless/indent-defun)))