Автоматичне повторне відступ коду elisp при додаванні або видаленні коду перед відступним блоком


18

Скажіть, у мене є код elisp, як:

(+ 2 3▮(+ 3
          4))

Чи є спосіб автоматичного повторного відступу сексора після курсору, коли я додаю або видаляю символи?

Тож після натискання SPC 4 SPCя автоматично отримаю:

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

Я можу зробити це керівництво з допомогою виклику mark-sexpслід indent-region. Чи є кращі способи зробити це?


Я не думаю, що існують зручні типові вкладки, але ви можете їх легко створити самостійно.
shosti

Я знаю, але мені конкретно цікаво, чи є кращі способи зробити це. Наприклад , як electric-indent-modeце набагато краще , ніж відображення <return>доnewline-and-indent
Мацей Goszczycki

Відповіді:


14

Замість mark-sexp+ indent-regionви можете натиснути C-M-q. Це зателефонує indent-pp-sexp. Не автоматично, але трохи краще, ніж викликати дві команди.

Або якщо ви користуєтесь paredit-mode, натисніть M-q. Це буде нагадувати все визначення функції, в якому ви перебуваєте.


1
(add-hook 'post-self-insert-hook 'indent-pp-sexp)працює напрочуд добре.
Maciej Goszczycki

Виглядає чудово. Це може бути дорогим у деяких режимах, але все-таки приємний підхід.
Дмитро

Для користувачів Smartparens ви можете нагадати поточне відключення за допомогою M-x sp-indent-defun. Я це пов'язую C-M-q.
Радон Росборо

15

Режим агресивного відступу

Оскільки деякі люди просили його, я перетворив цю відповідь на пакет .

Якщо у вас налаштована Melpa, ви можете встановити її

M-x package-install RET aggressive-indent

Дивіться у Readme всі варіанти, але найпростіший спосіб увімкнути це:

(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 впевнений, я можу це спробувати. У якому основному режимі є повідомлення з відступами? І в чому проблема з напівколонами?
Малабарба

Усі режими, які я пробував на Emacs-магістралі, створювали відступні повідомлення, включаючи elisp. Оскільки крапки з комою закінчуються рядком на багатьох мовах, поки ви не введете крапку з комою, наступний рядок скаче приблизно так, ніби він був частиною поточного рядка.
holocronweaver

@holocronweaver Промовчав повідомлення. Дякуємо, що вказали на це.
Малабарба

Дякуємо за виправлення! Одне з варіантів проблеми з крапкою з комою полягає в відступі лише мовами c-mode, коли вводиться крапка з комою.
holocronweaver

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)

Хоча я б переймався можливими проблемами з роботою.


1

Ви можете спробувати режим el-fly-indent , який є більш aggressive-indent-modeсприятливим, ніж при роботі з Elisp.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.