Gibt es ein Auto-Align-Paket oder einen Auto-Align-Modus für Emacs?


15

Es gibt Zeiten, in denen ich Dateien bearbeite (z. B. Puppet-Manifeste), in denen ich den Pufferinhalt spontan ausrichten möchte. Ich weiß zum Beispiel, dass ich Code wie diesen verwenden align-regexpoder alignausrichten kann, solange ich ihn ausgewählt habe:

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

Aber was ich wirklich will , ist , damit dies geschieht hat im Fluge - ohne eine Region oder den gesamten Puffer auswählen zu müssen. Gibt es ein Paket oder einen Modus, die dies tun, oder müsste dies in den Modus eingebaut werden, der mich interessiert?

Bearbeiten: Ich habe nach Puppet und CFEngine gefragt, da ich das in diesen Tagen meistens codiere und ausgerichteten Text sehr bevorzuge. Ich war jedoch auch neugierig (und habe dies nicht gut ausgedrückt) zu wissen, ob die Direktausrichtung eine in Emacs-Modi übliche Funktion ist (hauptsächlich in Modi für Programmiersprachen) oder ob sich die meisten Leute beim Speichern oder bei manchen ausrichten anderer Punkt.


Es gibt einen Erweiterungsbereich , der nützlich ist, um sukzessive größere Bereiche auszuwählen.
Bastibe

1
Können Sie mehr über das beschreiben, was Sie normalerweise ausrichten würden? Ist es nur Gleichheitszeichen und im Marionettenmodus? Sie können den Code in dieser Emacs SE-Antwort für die automatische Einrückung durch @Malabarba ändern, um das zu erhalten, was Sie möchten. Ersetzen Sie einfach indent-regionmit align-to-equalsund definieren Sie diese Funktion als (defun align-to-equals (begin end) (interactive "r") (align-regexp begin end "\\(\\s-*\\)=" 1 1 nil)); und emacs-lisp-mode-hookmit puppet-mode-hook.
Kaushal Modi

Antworten:


5

Wenn Sie eine Region für die automatische Ausrichtung markieren möchten, ist es wahrscheinlich nicht allzu schwierig, mit etwas wie Folgendem umzugehen:

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

Wenn es jedoch vollautomatisch sein soll, müssen Sie einen Weg finden, um zu charakterisieren, welche Regionen Sie automatisch ausrichten möchten (und mit welchem ​​regulären Ausdruck), was schwieriger ist. Ich vermute, Sie könnten einige reguläre Ausdrücke bereitstellen und dann den Puffer nach aufeinanderfolgenden Zeilen durchsuchen, die mit einem dieser regulären Ausdrücke übereinstimmen.


Ich habe noch nie Overlays verwendet, aber das Elisp-Handbuch scheint zu sagen, dass sie das Erscheinungsbild verändern sollen - habe ich das richtig verstanden? Wenn ja, bedeutet dies, dass diese Antwort nur das Aussehen des Puffers und nicht den tatsächlichen Inhalt der Datei nach dem Speichern ändert? (Letzteres habe ich gesucht, aber ein
anderes

2
@SaintAardvarktheCarpeted Overlays werden häufig verwendet, um das Erscheinungsbild zu ändern, aber ihre Anwendbarkeit geht darüber hinaus. In dieser Antwort (IIUC) werden die Überlagerungen verwendet, um Bereiche zu markieren, die ausgerichtet werden sollen (damit der Puffer wirklich geändert wird, nicht nur das Erscheinungsbild). Mit der Funktion my-auto-alignwerden diese Überlagerungen definiert (markieren Sie die Bereiche, die ausgerichtet werden sollen). Der Grund, warum Stefan (glaube ich) all diese Probleme durchmacht, ist, dass (anders als beim Einrücken), wenn Sie nur versuchen, den gesamten Puffer auszurichten, unerwünschte Ergebnisse erzielt werden, sodass Sie die Teile nacheinander ausrichten müssen.
Malabarba

3

Marionettenmodus bietet puppet-align-block. Sie können veranlassen, dass diese Funktion automatisch aufgerufen wird, z. B. indem Sie sie post-command-hooklokal hinzufügen (ungetestet):

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

Beachten Sie jedoch, dass es einen guten Grund gibt, dies nicht zu tun. Es ist nicht besonders clever und überschreibt jede manuelle Ausrichtung, die Sie irgendwo vornehmen, was besonders schlimm ist, wenn die automatische Ausrichtung für etwas gewundenen Puppet-Code nicht funktioniert.

Daher empfehle ich, als Betreuer des Puppet-Modus, dagegen zu sprechen, und wir werden Ihnen nicht helfen oder Fehlerberichte akzeptieren, wenn Sie diesen Code verwenden.

Außerdem kann es bei großen Ressourcenblöcken langsam sein, sodass Sie wahrscheinlich einen Leerlaufzeitgeber anstelle von post-command-hookdirekt verwenden möchten .

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.