Platzieren Sie in dired-Puffern den Punkt in der wichtigsten Datei dieses Verzeichnisses

14

In 90% der Fälle, in denen ich ein Verzeichnis in Emacs besuche, gehe ich zuerst auf eine bestimmte Datei und öffne sie. Oft ist die Datei, die ich öffnen muss, sehr vorhersehbar. Zum Beispiel:

  • Wenn sich .texDateien in diesem Verzeichnis befinden, gehe ich normalerweise direkt zu master.tex.
  • Bei der Wurzel von Android-Projekten ist es häufig AndroidManifest.xml.
  • In einem Verzeichnis, in dem ich ein Emacs-Paket entwickle, ist es fast immer die Hauptquelldatei des Pakets. .elDies ist normalerweise, aber nicht immer, die einzige Datei in diesem Verzeichnis.

Gibt es eine Möglichkeit, wie ich diesen Dateien automatisch einen Punkt zuweisen kann, wenn ich diese Verzeichnisse öffne?

Dies würde eine Menge Komfort bieten (da ich sie durch einfaches Drücken öffnen könnte RET), würde aber dennoch die Flexibilität bieten , andere Dateien zu besuchen.

Malabarba
quelle

Antworten:

16

Schreiben Sie eine benutzerdefinierte Funktion für dired-initial-position-hook. In dieser Funktion können Sie verschiedene dired-Funktionen verwenden, um nach Dateien zu suchen und schließlich aufzurufen dired-goto-file, um den Punkt auf die "beste" Datei zu verschieben:

(defun my-dired-goto-important-file ()
  "Go to an important file in the current dired buffer."
  (unless (bound-and-true-p save-place)
    (let ((candidates '("master.tex" "AndroidManifest.xml"))
          candidate)
      (while (and candidates
                  (not (dired-goto-file (expand-file-name (pop candidates)))))
        nil))))

(add-hook 'dired-initial-position-hook #'my-dired-goto-important-file)

Im Folgenden werde ich bestimmte Aspekte dieser Funktion erläutern und mögliche Erweiterungen hervorheben.

Zu Dateien springen

dired-goto-filenilGibt zurück, wenn die Datei im aktuellen Zielpuffer nicht vorhanden ist, sodass ein Aufruf ohne vorherige Überprüfung sicher ist. Benötigt dired-goto-filejedoch einen absoluten Dateinamen (Fehler bei relativen Namen), daher expand-file-name.

Dateien suchen

Dired bietet keine direkte API für die Suche nach Dateien. Im Allgemeinen können Sie über alle Dateien iterieren, genau wie Sie über alle Zeilen in einem Puffer iterieren würden:

(let (files)
  (goto-char (point-min))
  (while (not (eobp))
    (let ((filename (dired-get-filename nil 'no-error)))
      (when filename
        (push filename files)))
    (forward-line 1))
  ;; Now `files' is a list of files, which you can search for patterns
  ;; …
  )

Es ist jedoch bequemer, die Markierungsfunktionen zu verwenden. Achten Sie einfach darauf, dass Sie „ungewöhnliche“ Markierungszeichen verwenden, um vorhandene interaktive Markierungen nicht zu verlieren:

(unwind-protect
    (when (dired-mark-files-regexp (rx ".tex" string-end) ?t)
      (dired-goto-file (expand-file-name "master.tex")))
  (dired-unmark-all-files ?t))

Platzierungsmodus speichern

Sie müssen auch im Hinblick auf den Save Place-Modus vorsichtig sein, falls Sie ihn aktiviert haben. In gerichteten Puffern merkt sich der Ort speichern-Modus nicht wie in anderen Modi den Punktwert, sondern der letzte Dateinamenpunkt war aktiviert. Es stellt diesen Dateinamen wieder her, so wie wir es tun: Es schließt sich an dired-initial-position-hookund ruft auf dired-goto-file(tatsächlich habe ich dort den Code gestohlen :)).

Wenn unser Haken vor dem Ort des Speicherns kommt, überschreibt der Ort des Speicherns bedingungslos unsere Position. Wenn es jedoch vor unserem Hook kommt (wie es der Fall ist, wenn "Ort speichern" aktiviert ist, nachdem Sie diesen Hook eingerichtet haben), würde unsere Funktion "Ort speichern" überschreiben, was nicht wünschenswert ist. Wie in jedem Puffer setzt Save Place die lokale Variable save-placeauf einen Wert ungleich Null, sodass wir dies einfach überprüfen und nur so vorgehen können. Save Place hat keinen Dateinamen wiederhergestellt.

Wenn Sie Save Place lieber "lose" haben möchten, entfernen Sie das Häkchen für save-placeund stellen Sie sicher, dass unser Hook nach Save Place ausgeführt wird, indem Sie zuerst den Save Place-Modus aktivieren und dann add-hookeinen Wert ungleich Null für das APPENDArgument aufrufen .

Mondhorn
quelle
Gute Antwort. Vielleicht möchten Sie definieren bound-and-true-p. :-)
Malabarba
@Malabarba bound-and-true-pist ein eingebautes Makro von bindings.el.
Lunaryorn
Lieber Gott, ich weiß nicht, was mich schlimmer macht, die Tatsache, dass ich das nicht wusste oder die Tatsache, dass ich es nicht einmal überprüft habe.
Malabarba
@ Malabarba Egal, ich habe (im wahrsten Sinne des Wortes) ein Jahr gebraucht, um die Existenz dieser Funktion zu entdecken.
Lunaryorn
Ja, das ist eine wunderbare Funktion, von der ich bis jetzt auch noch nie gehört hatte!
Sanityinc