Dans les tampons dirigés, placez le point sur le fichier le plus important de ce répertoire

14

90% du temps que je visite un répertoire dans Emacs, la première chose que je fais est de déplacer le point vers un fichier spécifique et de l'ouvrir. Souvent, le fichier que je dois ouvrir est très prévisible. Par exemple:

  • S'il y a des .texfichiers dans ce répertoire, je vais généralement directement vers master.tex.
  • À l'origine des projets Android, c'est commun AndroidManifest.xml.
  • Dans un répertoire où je développe un paquet emacs, c'est presque toujours le fichier source principal du paquet. C'est généralement, mais pas toujours, le seul .elfichier de ce répertoire.

Existe-t-il un moyen de diriger automatiquement le point sur ces fichiers lorsque j'ouvre ces répertoires?

Cela offrirait beaucoup de commodité (car je pourrais les ouvrir en appuyant simplement sur RET), mais donnerait toujours la flexibilité de visiter d'autres fichiers.

Malabarba
la source

Réponses:

16

Écrivez une fonction personnalisée pour dired-initial-position-hook. Dans cette fonction, vous pouvez utiliser diverses fonctions dirigées pour rechercher des fichiers, et éventuellement appeler dired-goto-filepour déplacer le point vers le «meilleur» fichier:

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

Dans ce qui suit, je vais expliquer les aspects spécifiques de cette fonction et souligner les extensions potentielles.

Saut vers des fichiers

dired-goto-filerenvoie nilsi le fichier n'existe pas dans le tampon dired actuel, il est donc sûr d'appeler sans vérification préalable. Cependant, dired-goto-filenécessite un nom de fichier absolu (il erreur sur les noms relatifs), par conséquent expand-file-name.

Recherche de fichiers

Dired ne fournit pas d'API simple pour rechercher des fichiers. En règle générale, vous pouvez parcourir tous les fichiers comme vous le feriez sur toutes les lignes d'un tampon:

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

Cependant, il est plus pratique d'utiliser les fonctions de marquage. Veillez simplement à utiliser un marqueur «inhabituel» pour ne pas perdre les marques interactives existantes:

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

Enregistrer le mode Place

Vous devez également faire attention au mode Save Place, au cas où vous l'auriez activé. Dans les tampons fatigués, le mode Save Place ne se souvient pas de la valeur du point comme dans les autres modes, mais plutôt le dernier point de nom de fichier était activé. Il restaure ce nom de fichier comme nous le faisons: il se connecte dired-initial-position-hooket appelle dired-goto-file(en fait, c'est là que j'ai volé ce code :)).

Si notre crochet vient avant la sauvegarde de la place, le mode sauvegarde de la place écrasera sans condition notre position. Cependant, si elle vient avant notre hook (comme c'est le cas lorsque Save Place est activé après avoir configuré ce hook), notre fonction écraserait réellement Save Place, ce qui n'est pas souhaitable. Cependant, comme dans tout tampon, Save Place définit la variable locale save-placesur une valeur non nulle, de sorte que nous pouvons simplement vérifier cela et ne l'activer que Save Place n'a pas restauré de nom de fichier.

Si vous préférez que Save Place soit "lâche", supprimez la coche save-placeet assurez-vous que notre hook est exécuté après Save Place, en activant d' abord le mode Save Place , puis en appelant add-hookavec une valeur non nulle pour son APPENDargument.

lunaryorn
la source
Très bonne réponse. Vous voudrez peut-être définir bound-and-true-p. :-)
Malabarba
@Malabarba bound-and-true-pest une macro intégrée de bindings.el.
lunaryorn
Cher dieu, je ne sais pas ce qui me fait me sentir pire, le fait que je ne le savais pas ou le fait que je n'ai même pas vérifié.
Malabarba
@Malabarba Peu importe, il m'a fallu un an (littéralement) pour découvrir l'existence de cette fonction.
lunaryorn du
Oui, c'est une fonction merveilleuse dont je n'avais jamais entendu parler jusqu'à présent!
sanityinc