Tự động thụt lại mã elisp khi thêm hoặc xóa mã trước một khối thụt lề


18

Nói rằng tôi có một mã elisp như:

(+ 2 3▮(+ 3
          4))

Có cách nào để tự động thụt lại giới tính sau con trỏ, khi tôi thêm hoặc xóa biểu tượng không?

Vì vậy, sau khi nhấn SPC 4 SPC, tôi sẽ tự động nhận được:

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

Tôi có thể làm hướng dẫn này bằng cách gọi mark-sexptheo sau indent-region. Có cách nào tốt hơn để làm điều này?


Tôi không nghĩ rằng có bất kỳ keybindings mặc định thuận tiện nào, nhưng bạn có thể dễ dàng tự tạo một số.
shosti

Tôi biết nhưng tôi đặc biệt tự hỏi là có cách nào tốt hơn để làm điều này. Ví dụ: làm thế nào electric-indent-modetốt hơn nhiều so với ánh xạ <return>tớinewline-and-indent
Maciej Goszczycki

Câu trả lời:


14

Thay vì mark-sexp+ indent-region, bạn có thể nhấn C-M-q. Cái này sẽ gọi indent-pp-sexp. Không tự động, nhưng tốt hơn một chút so với việc phải gọi hai lệnh.

Hoặc nếu bạn đang sử dụng paredit-mode, nhấn M-q. Điều đó sẽ giới thiệu lại toàn bộ định nghĩa chức năng bạn đang ở.


1
(add-hook 'post-self-insert-hook 'indent-pp-sexp)hoạt động tốt đáng ngạc nhiên.
Maciej Goszczycki

Có vẻ tốt. Điều đó có thể tốn kém trong một số chế độ, tuy nhiên đó là một cách tiếp cận tốt.
Dmitry

Đối với người dùng Smartparens, bạn có thể giới thiệu lại defun hiện tại M-x sp-indent-defun. Tôi ràng buộc điều này với C-M-q.
Radon Rosborough

15

Chế độ thụt lề xâm lược

Vì một số người hỏi nó, tôi đã biến câu trả lời này thành một gói .

Nếu bạn đã cấu hình Melpa, bạn có thể cài đặt nó với

M-x package-install RET aggressive-indent

Xem Readme cho tất cả các tùy chọn, nhưng cách đơn giản nhất để bật nó là:

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

Câu trả lời cũ

Dưới đây không chỉ tự động thụt vào bộ đệm elisp. Nó có lợi thế là cũng hoạt động khi bạn xóa hoặc kéo đồ (thay vì chỉ gõ). Thật dễ dàng để thêm vào các chế độ khác.

Hàm này sẽ thụt vào bất cứ biểu thức s nào mà điểm hiện tại bên trong. Bạn có thể liên kết nó với một khóa nếu bạn muốn, nhưng xem bên dưới trước.

(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))))))

Móc này sẽ làm cho nó để chức năng này sẽ được chạy sau khi bạn gõ bất cứ thứ gì, nhưng chỉ trong bộ đệm elisp. Điều này sẽ giữ mọi thứ luôn thụt vào.

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

Thử nó! Nó hoạt động rất tốt.

Ngoài ra, theo gợi ý của @ holocronweaver trong các bình luận, bạn có thể sử dụng một cái gì đó như sau cho các ngôn ngữ giống như c:

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

Sẽ là tuyệt vời nếu tin nhắn tự động thụt lề im lặng này và các ngôn ngữ được xử lý tốt hơn kết thúc dòng bằng dấu chấm phẩy.
holocronweaver

@holocronweaver chắc chắn, tôi có thể thử nó. Chế độ chính nào có tin nhắn thụt lề? Và vấn đề với dấu hai chấm là gì?
Malabarba

Tất cả các chế độ tôi đã thử trên thân Emacs tạo ra các thông điệp thụt lề, bao gồm cả elisp. Vì dấu chấm phẩy kết thúc một dòng bằng nhiều ngôn ngữ, cho đến khi bạn gõ dấu chấm phẩy, dòng sau sẽ nhảy như thể nó là một phần của dòng hiện tại.
holocronweaver

@holocronweaver Im lặng các tin nhắn. Cảm ơn đã chỉ ra điều đó.
Malabarba

Cảm ơn đã sửa chữa! Một giải pháp cho vấn đề dấu chấm phẩy là chỉ thụt lề trong các ngôn ngữ chế độ c khi một dấu chấm phẩy được gõ.
holocronweaver

3

Tôi không biết về một giải pháp đã có từ trước, nhưng bạn có thể sử dụng post-self-insert-hookđể tự thực hiện điều này:

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

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

Tôi sẽ lo lắng về các vấn đề hiệu suất tiềm năng mặc dù.


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.