Mémoriser les modes pour les fichiers sans extensions

10

J'ai commencé à éditer beaucoup de fichiers qui n'ont pas d'extensions, mais qui sont toujours dans un format de mode majeur.

Je suis le seul utilisateur d'Emacs au sein de l'équipe, et je ne veux pas dire clairement que mon éditeur a besoin de choses spéciales . Je voudrais éviter de changer la base de code.

  • Je ne peux pas changer le nom de fichier
  • Je ne peux pas utiliser de commentaires Emacs spéciaux

Je voudrais qu'Emacs se souvienne du mode dans M-x conf-modelequel j'ai mis le fichier manuellement en dernier (avec, disons ) et active automatiquement ce mode lorsque je le revois.

J'utilise savehist-modepour gérer la persistance.

Puis-je faire cela sans douleur?

PythonNut
la source
1
Si c'est le fichier que vous pouvez modifier, vous pouvez généralement ajouter une première ligne avec un commentaire:, # -*- mode: conf -*-et cela conseillerait Emacs à utiliser conf-mode. S'il y en a peu et que vous pouvez les faire correspondre via une expression régulière, vous pouvez ajouter l'expression régulière à automode-alist.
wvxvw
2
@wvxvw l'une de mes limitations est que " je ne peux pas utiliser de commentaires Emacs spéciaux ".
PythonNut
2
Aïe, désolé, je ne comprends pas comment j'ai raté ça. C'est aussi auto-mode-alistmon mauvais.
wvxvw
De toute évidence, la bonne réponse ici est d'amener le reste de votre équipe à utiliser Emacs. Toute autre réponse n'est qu'une solution de contournement.
Malabarba

Réponses:

13

Il existe plusieurs façons d'identifier le mode principal d'un fichier qui ne dépend pas d'une extension, voir Choix des modes de fichier dans le manuel.

Selon les types de fichiers que vous traitez, vous pouvez peut-être utiliser le magic-mode-alist. Notez également que cela auto-mode-alistne se limite pas aux extensions correspondantes: vous pouvez faire correspondre n'importe quelle partie du nom ou du chemin du fichier.

Si les fichiers que vous traitez ne sont pas suffisamment cohérents pour ces mécanismes, une option consiste à ajouter des auto-mode-alistentrées qui correspondent au nom de fichier entier, ou correspondre au chemin racine de certains projets et appeler une fonction personnalisée pour faire correspondre les noms aux modes.

Si tous les fichiers d'un répertoire donné sont du même type, vous pouvez également utiliser une variable de répertoire local pour définir le mode. Les variables de répertoire peuvent être définies dans votre fichier init plutôt que dans un fichier .dir-locals - voir Variables de répertoire pour plus de détails.

Mettre à jour

Voici une tentative rapide de gérer votre propre liste de noms de fichiers absolus et de modes principaux.

(defvar my-custom-mode-alist '())
(defvar my-custom-mode-alist-file (expand-file-name "custom-file-assoc" user-emacs-directory))

;; command to save the file->mode association of the current buffer
(defun save-file-mode-association ()
  (interactive)
  (when buffer-file-name
    (add-to-list 'my-custom-mode-alist (cons buffer-file-name major-mode))
    (write-custom-mode-alist my-custom-mode-alist-file)))

(defun write-custom-mode-alist (file)
  (with-current-buffer (get-buffer-create " *Custom File Assocations*")
    (goto-char (point-min))
    (delete-region (point-min) (point-max))
    (pp my-custom-mode-alist (current-buffer))
    (condition-case nil
        (write-region (point-min) (point-max) file)
      (file-error (message "Can't write %s" file)))
    (kill-buffer (current-buffer))
    (message "Wrote custom file associations to file %s" file)))

(defun load-custom-mode-alist (file)
  (when (file-exists-p file)
    (with-current-buffer
        (let ((enable-local-variables nil))
          (find-file-noselect file))
      (goto-char (point-min))
      (setq my-custom-mode-alist (read (current-buffer)))
      (setq auto-mode-alist (append auto-mode-alist my-custom-mode-alist))
      (kill-buffer (current-buffer)))))

;; Load any custom file associations and add them to auto-mode-alist
(load-custom-mode-alist my-custom-mode-alist-file)
glucas
la source
Malheureusement, les fichiers sont formatés de manière assez lâche et ils ont des noms de fichiers très génériques. Merci d'avoir souligné les détails de auto-mode-alist, cependant. Je garderai probablement magic-mode-alistdans le fond de mon esprit quelque chose à l'avenir.
PythonNut
4

Ce qui suit, basé sur les conseils de Glucas, semble fonctionner parfaitement.

(defvar file-name-mode-alist '())
;; other stuff here, of course
(setq savehist-additional-variables '(file-name-mode-alist))
(savehist-mode +1)
(setq auto-mode-alist (append auto-mode-alist file-name-mode-alist))

(add-hook 'after-change-major-mode-hook
  (lambda ()
    (when (and
            buffer-file-name
            (not
              (file-name-extension
                buffer-file-name)))
       (setq file-name-mode-alist
        (cons
          (cons buffer-file-name major-mode)
          file-name-mode-alist))
      (setq auto-mode-alist
        (append auto-mode-alist
          (list (cons buffer-file-name major-mode)))))))
PythonNut
la source
1
Agréable. Une solution plus élégante que celle que j'ai piratée ensemble. :-)
glucas