Emacs用の自動整列パッケージまたはモードはありますか?


15

バッファの内容をその場で調整したいファイル(たとえば、Puppetマニフェスト)を編集している場合があります。たとえば、私はそれを選択している限り、このようなコードを使用し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モード(主にプログラミング言語のモード)で一般的な機能であるかどうか、またはほとんどの人が保存時または特定の場所でアライメントする場合、他のポイント。


expand-regionがあります。これは、連続して大きなスコープを選択するのに役立ちます。
バスティーブ

1
普段何を調整するかについて詳しく説明してください。それはちょうど等号であり、人形モードですか?このEmacs SEの回答で @Malabarbaによる自動インデントのコードを変更して、必要なものを取得できます。この関数を次のように置き換えindent-regionalign-to-equals定義するだけ(defun align-to-equals (begin end) (interactive "r") (align-regexp begin end "\\(\\s-*\\)=" 1 1 nil))です。とemacs-lisp-mode-hookpuppet-mode-hook
カウシャルモディ

回答:


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のマニュアルには、外観を変更するためのものであると書かれているようです。もしそうなら、それはこの回答が保存された後のファイルの実際の内容ではなく、バッファの外観を変更するだけであることを意味しますか?(私が探していたのは後者ですが、外観を変更することは興味深いオプションです。)
セントアードバークザカーペット14年

2
@SaintAardvarktheCarpetedオーバーレイは、外観を変更するために一般的に使用されますが、その適用範囲はそれを超えています。この回答(IIUC)では、オーバーレイを使用して、位置合わせする領域をマークしています(したがって、外観だけでなく、バ​​ッファーが実際に変更されます)。この関数my-auto-alignは、これらのオーバーレイを定義するために使用されます(位置合わせする領域をマークします)。ステファンがこの問題をすべて経験している理由は(インデントとは異なり)バッファー全体を揃えようとすると、望ましくない結果が得られるため、一度にピースを揃える必要があるためです。
マラバルバ

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.