Emacs를위한 자동 정렬 패키지 또는 모드가 있습니까?


15

버퍼 내용을 즉석에서 정렬하려는 파일 (예 : 꼭두각시 매니페스트)을 편집 할 때가 있습니다. 예를 들어, 내가 선택한 한 다음과 같은 코드를 사용 align-regexp하거나 align정렬 할 수 있다는 것을 알고 있습니다 .

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

그러나 내가 정말로 원하는 것은 영역이나 전체 버퍼를 선택할 필요없이 즉시 발생 시키는 것입니다. 이 작업을 수행 할 패키지 또는 모드가 있습니까, 아니면 제가 관심있는 모드에 내장되어야하는 것입니까?

편집 : Puppet과 CFEngine에 대해 질문했습니다 . 요즘 대부분 코딩하는 것이기 때문에 정렬 된 텍스트를 선호합니다. 그러나 직접 정렬이 Emacs 모드 (주로 프로그래밍 언어의 모드)에서 공통적 인 기능인지 또는 대부분의 사람들이 저장하거나 일부를 정렬 할 때 정렬되는지 궁금합니다. 다른 점.


확장 - 지역 연속적으로 더 큰 범위를 선택하는 데 유용합니다.
bastibe

1
일반적으로 정렬하는 것에 대해 더 자세히 설명 할 수 있습니까? 그냥 등호와 꼭두각시 모드입니까? @Malabarba의 자동 들여 쓰기 를 위해이 Emacs SE 응답 의 코드를 수정하여 원하는 것을 얻을 수 있습니다. 이 기능으로 대체 indent-region하고 간단히 다음 align-to-equals과 같이 정의하십시오 (defun align-to-equals (begin end) (interactive "r") (align-regexp begin end "\\(\\s-*\\)=" 1 1 nil)). 와 emacs-lisp-mode-hook함께 puppet-mode-hook.
Kaushal Modi

답변:


5

자동 정렬 영역을 표시하려면 다음과 같은 작업을 수행하기가 어렵지 않을 것입니다.

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

그러나 완전 자동화를 원한다면 자동 정렬하려는 영역과 정규 표현식을 사용하여 더 어려운 영역을 특성화하는 방법을 찾아야합니다. 정규 표현식을 제공 한 다음 정규 표현식 중 하나와 일치하는 연속 줄을 버퍼에서 스캔 할 수 있다고 생각합니다.


나는 전에 오버레이를 사용하지 않았지만 Elisp 매뉴얼은 외관을 변경하기위한 것이라고 말한 것 같습니다. 그렇다면이 대답은 파일이 저장되면 파일의 실제 내용이 아니라 버퍼의 모양 만 변경한다는 의미입니까? (내가 찾던 후자이지만 외형을 바꾸는 것은 흥미로운 옵션이 될 것이다.)
Saint Aardvark가 카펫을

2
@SaintAardvarktheCarpeted Overlays는 일반적으로 모양을 변경하는 데 사용되지만 적용 범위는 그 이상입니다. 이 답변 (IIUC)에서 오버레이는 정렬 될 영역을 표시하는 데 사용됩니다 (따라서 버퍼는 모양뿐만 아니라 실제로 변경됩니다). 이 기능 my-auto-align은 이러한 오버레이를 정의하는 데 사용됩니다 (정렬하려는 영역을 표시). Stefan 이이 모든 문제를 겪고있는 이유는 전체 버퍼를 정렬하려고하면 원하지 않는 결과를 얻을 수 있으므로 한 번에 조각을 정렬해야하기 때문입니다 (들여 쓰기와 달리).
Malabarba

3

꼭두각시 모드가 제공합니다 puppet-align-block. 예를 들어 post-command-hook로컬 에 추가 (예정 되지 않은) 하여이 함수가 자동으로 호출되도록 정렬 할 수 있습니다 .

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

그러나 이것을하지 않는 좋은 이유가 있습니다. 그것은 영리하지 않으며, 어디에서든 수동 정렬을 덮어 쓸 것입니다. 자동 정렬이 더 복잡한 Puppet 코드에서 작동하지 않으면 특히 나빠질 수 있습니다.

따라서 Puppet Mode 유지 관리자라고 말하면이 코드에 반대하는 것이 좋습니다.이 코드를 사용하는 경우 버그 보고서를 받거나 수락하지 않습니다.

또한 큰 리소스 블록의 경우 속도가 느릴 수 있으므로 post-command-hook직접 대신 유휴 타이머를 사용하는 것이 좋습니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.