Có gói tự động căn chỉnh hoặc chế độ cho Emacs không?


15

Đôi khi tôi đang chỉnh sửa các tệp (ví dụ như biểu hiện rối) khi tôi muốn căn chỉnh nội dung bộ đệm một cách nhanh chóng. Ví dụ: tôi biết rằng tôi có thể sử dụng align-regexphoặc aligncăn chỉnh mã như thế này, miễn là tôi đã chọn nó:

# M-x align-regexp "=>" will line everything up nicely 
file { "/etc/foo":
  ensure => present,
  mode => "0666",
  source => "puppet:///modules/example/foo",
}

Nhưng những gì tôi thực sự muốn là có điều này xảy ra nhanh chóng - mà không phải chọn một khu vực hoặc toàn bộ bộ đệm. Có một gói hoặc chế độ sẽ làm điều này, hoặc đây có phải là thứ sẽ được tích hợp vào chế độ mà tôi quan tâm không?

Chỉnh sửa: Tôi đã hỏi về Puppet và CFEngine, vì đó là những gì tôi viết mã trong hầu hết những ngày này và tôi có một sở thích mạnh mẽ cho văn bản được căn chỉnh. Tuy nhiên, tôi cũng tò mò (và không thể hiện rõ điều này) để biết liệu căn chỉnh nhanh có phải là một tính năng phổ biến trong chế độ Emacs (chủ yếu ở chế độ cho ngôn ngữ lập trình) hoặc nếu hầu hết mọi người căn chỉnh khi lưu hoặc ở một số điểm khác.


vùng mở rộng , rất hữu ích để chọn phạm vi lớn hơn liên tiếp.
bastibe

1
Bạn có thể mô tả thêm về những gì bạn thường căn chỉnh? Có phải nó chỉ là dấu hiệu bằng nhau và trong chế độ bù nhìn? Bạn có thể sửa đổi mã trong câu trả lời Emacs SE này để tự động thụt lề bởi @Malabarba để có được những gì bạn muốn. Đơn giản chỉ cần thay thế indent-regionbằng align-to-equalsvà định nghĩa chức năng này là (defun align-to-equals (begin end) (interactive "r") (align-regexp begin end "\\(\\s-*\\)=" 1 1 nil)); và emacs-lisp-mode-hookvới puppet-mode-hook.
Kaushal Modi

Câu trả lời:


5

Nếu bạn muốn đánh dấu một khu vực để tự động căn chỉnh, thì có lẽ không quá khó để thực hiện với một cái gì đó như:

(require 'cl-lib)

(defvar my--auto-align-overlays nil)
(make-variable-buffer-local 'my--auto-align-overlays)

(defun my-auto-align (beg end regexp)
  (interactive "r\nsRegexp: ")
  (let ((ol (make-overlay beg end)))
    (overlay-put ol 'evaporate t)
    (overlay-put ol 'my--auto-align-regexp regexp)
    (overlay-put ol 'modification-hooks '(my--auto-align-function))
    (push ol my--auto-align-overlays)
    (add-hook 'post-command-hook 'my--auto-align-pch nil t)))

(defun my--auto-align-function (ol &rest _args)
  (cl-pushnew ol my--auto-align-overlays)
  (add-hook 'post-command-hook 'my--auto-align-pch nil t))

(defun my--auto-align-pch ()
  (dolist (ol my--auto-align-overlays)
    (align-regexp (overlay-start ol) (overlay-end ol)
                  (concat "\\(\\s-*\\)" (overlay-get ol 'my--auto-align-regexp))
                  1 align-default-spacing))
  (setq my--auto-align-overlays nil)
  (remove-hook 'post-command-hook 'my--auto-align-pch))

Nhưng nếu bạn muốn nó hoàn toàn tự động, bạn cần tìm cách mô tả vùng nào bạn muốn tự động căn chỉnh (và với regrec nào), điều này khó hơn. Tôi đoán bạn có thể cung cấp một số biểu thức chính, và sau đó quét bộ đệm cho các dòng liên tiếp khớp với một trong các biểu thức chính đó.


Trước đây tôi chưa sử dụng lớp phủ, nhưng hướng dẫn Elisp dường như nói rằng chúng để thay đổi ngoại hình - tôi đã hiểu điều đó đúng chưa? Nếu vậy, điều đó có nghĩa là câu trả lời này chỉ thay đổi bộ đệm trông như thế nào, chứ không phải là nội dung thực sự của tệp khi nó được lưu? (Đó là cái sau mà tôi đang tìm kiếm, nhưng thay đổi ngoại hình sẽ là một lựa chọn thú vị.)
Saint Aardvark the Carpched

2
@SaintAardvarktheCarpatted Overlays thường được sử dụng để thay đổi ngoại hình, nhưng khả năng ứng dụng của chúng vượt xa điều đó. Trong câu trả lời này (IIUC), các lớp phủ được sử dụng để đánh dấu các khu vực được căn chỉnh (vì vậy bộ đệm thực sự thay đổi, không chỉ là hình thức bên ngoài). Hàm my-auto-alignđược sử dụng để xác định các lớp phủ này (đánh dấu các khu vực bạn muốn được căn chỉnh). Lý do (tôi nghĩ) Stefan đang trải qua tất cả những rắc rối này là (không giống như thụt đầu dòng) nếu bạn chỉ cố gắng căn chỉnh toàn bộ bộ đệm, bạn sẽ nhận được kết quả không mong muốn, vì vậy bạn cần căn chỉnh từng miếng một.
Malabarba

3

Chế độ bù nhìn cung cấp puppet-align-block. Bạn có thể sắp xếp để chức năng này được gọi tự động, ví dụ: bằng cách thêm nó vào post-command-hookcục bộ (chưa được kiểm tra):

(defun puppet-auto-align ()
  (unless (puppet-in-string-or-comment-p)
    (puppet-align-block)))

(define-minor-mode puppet-auto-align-mode
  :init-value nil
  :keymap nil
  :lighter "PAl"
  :group 'puppet-lint
  (if puppet-auto-align-mode
      (add-hook 'post-command-hook #'puppet-auto-align nil 'local)
    (remove-hook 'post-command-hook #'puppet-auto-align 'local)))

(add-hook 'puppet-mode-hook #'puppet-auto-align-mode)

Lưu ý rằng, đó là một lý do tốt để không làm điều này. Nó không đặc biệt thông minh và sẽ ghi đè lên bất kỳ căn chỉnh thủ công nào bạn có thể làm ở bất cứ đâu, điều này sẽ phá vỡ đặc biệt tồi tệ, nếu căn chỉnh tự động không hoạt động đối với một số mã rối phức tạp hơn.

Do đó, nói chuyện với tư cách là người duy trì chế độ rối, tôi khuyên bạn nên chống lại nó và chúng tôi sẽ không giúp bạn hoặc chấp nhận các báo cáo lỗi, nếu bạn đang sử dụng mã này.

Ngoài ra, đối với các khối tài nguyên lớn, nó có thể chậm, vì vậy bạn có thể muốn sử dụng bộ đếm thời gian nhàn rỗi thay vì post-command-hooktrực tiếp.

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.