comment obtenir des tampons (pas seulement des fichiers) pour honorer la liste des modes automatiques?

13

Q: comment puis-je obtenir de nouveaux tampons pour honorer le mappage auto-mode-alist?

Lors de la recherche d'un fichier , Emacs compare l'extension du fichier à auto-mode-alistpour déterminer le mode principal à utiliser pour le tampon du fichier. Existe-t-il un moyen d'utiliser les informations dans auto-mode-alistpour déterminer le mode d'un tampon auquel aucun fichier n'est (encore) associé?

C'est-à-dire: si j'ouvre un nouveau tampon dont le nom a quelque chose qui ressemble à une extension de fichier, puis-je le faire s'ouvrir automatiquement dans le mode attendu? Par exemple, si je devais ouvrir un nouveau tampon a-new-buffer.elqui n'est pas encore associé à un fichier, je veux qu'il s'ouvre emacs-lisp-modeplutôt que dans le mode par défaut.

Dan
la source
2
Juste curieux: quel est le cas d'utilisation? IOW, pourquoi / quand / dans quel contexte voulez-vous faire cela? En règle générale, si vous souhaitez associer un tampon à un fichier et ainsi récupérer son mode auto-mode-alist, vous faites en sorte que le tampon " visite " le fichier (et cela s'occupe de tout).
Tiré
5
Des exemples de cas d'utilisation typiques pour moi sont: a) un orgtampon temporaire pour tester les nouvelles fonctions que j'écris pour utilisation org-mode; b) un Rtampon temporaire pour effectuer des manipulations statistiques rapides et jetables; c) un tampon de texte temporaire pour composer un e-mail. Dans tous les cas, je ne pas veux créer un fichier à la visite, je veux juste un tampon jetable qui ouvre néanmoins dans le mode approprié.
Dan
2
Commandes visite de fichiers tels que C-x C-fne pas « créer un fichier à la visite ». C'est un malentendu fondamental. Ils font simplement exactement ce que vous cherchez. Ce n'est que si et lorsque vous essayez d' enregistrer le tampon qu'un fichier est créé. Si vous n'essayez pas d'enregistrer le tampon, aucun fichier n'est créé. Ce que vous voulez, d'après ce que je comprends jusqu'à présent, est de "visiter un fichier" (ce qui signifie vraiment ouvrir un tampon dans le mode approprié).
Drew
8
Comme Dan, je crée tout le temps des tampons temporaires que je ne veux pas associer à un chemin de fichier réel. Visiter un chemin de fichier faux fonctionnerait mais il y a au moins une petite friction dans le choix d'un répertoire (ou l'acceptation du répertoire actuel). Il pourrait y avoir d'autres effets secondaires selon le reste de votre configuration: Comportement d'enregistrement automatique? Groupes Ibuffer ou projets de projectiles déterminés par la trajectoire? Des invites de confirmation d'idéo? Étant donné que les tampons doivent de toute façon avoir un nom, l'utilisation du nom pour définir automatiquement le mode d'un tampon temporaire est logique pour moi.
glucas
@Drew, oui, cela a du sens et serait la réponse la plus simple à cette question - pourriez-vous l'afficher comme réponse, s'il vous plaît? Il mérite une mise à niveau.
Dan

Réponses:

8

Commandes de visite de fichiers telles que C-x C-f ne pas créer de fichier à visiter. Ils font ce que vous cherchez.

Ce n'est que si et lorsque vous essayez d' enregistrer le tampon qu'un fichier est créé .

Si vous n'essayez pas d'enregistrer le tampon, aucun fichier n'est créé. Ce que vous voulez, d'après ce que je comprends jusqu'à présent, est de " visiter un fichier " (ce qui signifie vraiment ouvrir un tampon dans le mode approprié).

A dessiné
la source
4
Et si vous avez un doigt hyperactif qui enregistre constamment le fichier actuel toutes les 3 secondes, peu importe ce que vous voulez?
Malabarba
1
@Malabarba: En fait, j'ai ce doigt! ;-) Peut-être que la plupart d'entre nous font de vieux pets - une habitude a repris quand les choses se sont brisées tout le temps. Mais de toute façon, je fais exactement ce que j'ai suggéré: éditer dans un tampon de fichier visité jetable. Si ma mémoire musculaire hyperactive gêne et essaie de sauvegarder, qu'il en soit ainsi: soit je frappe npour ne pas sauvegarder, soit (souvent) je sauvegarde simplement le tampon. Et plus tard, je lance le fichier créé ... ou pas.)
Drew
1
@Malabarba C'est exactement pour éviter l'encombrement des fichiers temporaires, que j'ai commencé à utiliser des tampons de travail spécifiques au mode principal. Si le scratch mérite un fichier, vous pouvez toujours l'enregistrer comme un plus tard.
Kaushal Modi
1
@kaushalmodi: Rien contre vos tampons spécifiques au mode, mais un " encombrement de fichiers temporaires " est aussi facile à nettoyer qu'un encombrement de tampons . ;-) Et le doigt hyperactif dans un tampon de travail spécifique au mode présente le même problème, probablement - le même que dans *scratch*: vous êtes invité à enregistrer lorsque ce doigt frappe automatiquement C-x C-s.
Drew
9

Si vous utilisez la solution de Juri Linkov depuis des années.

Je crée des tampons temporaires avec quelque chose comme C-x b test.org C-j. Le major-modeest déterminé par l'extension de fichier via auto-mode-alist.

;; http://thread.gmane.org/gmane.emacs.devel/115520/focus=115794
(setq-default major-mode
              (lambda () (if buffer-file-name
                          (fundamental-mode)
                            (let ((buffer-file-name (buffer-name)))
                          (set-auto-mode)))))

Pour tester l'effet, vous pouvez essayer (prog1 (and (switch-to-buffer "my-new.org") major-mode) (kill-buffer "my-new.org")) => org-mode. Dans un nettoyage, emacs -qle test reviendrait fundamental-mode.

rasmus
la source
1
C'est très intelligent! C'est aussi plus propre que l' adviceoption que j'utilisais. Je ne suis pas sûr de savoir à quoi (prog1...)sert la pièce, mais la (setq-default major-mode ...)pièce est plutôt sympa.
Dan
1
N'hésitez pas à consulter le site Emacs de Juri . Le prog1-test montre simplement que vous obtenez ce que vous attendez major-modelorsque vous passez à un tampon. Évaluez la setq-defaultpièce et exécutez le test. Il reviendra org-mode Sans le setq-defaultil reviendrait fundamental-mode.
rasmus
C'est beaucoup plus élégant que mon crochet-liste-mise à jour-crochet. Merci!
glucas
cela devrait être la réponse acceptée, car elle répond en fait à la question plutôt que de nous dire pourquoi nous avons tort de la poser :)
Shlomi
6

J'ai trouvé une manière basée sur des conseils en utilisant des idées qui provenaient des commentaires de @ Drew et de la réponse de @ glucas que j'enregistrerai ici au cas où elles seraient utiles à n'importe qui.

La version courte: utilisez des afterconseils pour demander si le tampon a un nom de fichier associé, définissez-en un temporairement si ce n'est pas le cas, puis laissez le reste de la set-auto-modemachine s'occuper des détails. Après un peu de test (pas extensif), cela semble très bien fonctionner.

Pour ido-switch-bufferet vanille switch-to-buffer, les deux conseils seraient:

(defadvice ido-switch-buffer (after set-mode activate)
  (unless buffer-file-name
    (let ((buffer-file-name (buffer-name)))
      (set-auto-mode t))))

(defadvice switch-to-buffer (after set-mode activate)
  (unless buffer-file-name
    (let ((buffer-file-name (buffer-name)))
      (set-auto-mode t))))

Je trouve cette option utile en plus du find-filepoint soulevé par @Drew parce que mes doigts peuvent devancer mon cerveau: la mémoire musculaire m'amènera souvent dans un territoire de basculement vers le tampon avant qu'elle ne me vienne à l'esprit qui find-fileferait ce dont j'ai besoin. Maintenant, les deux options sont disponibles.

MISE À JOUR: petit bug potentiellement irritant dans le code ci-dessus: il réexécutera le hook de mode sur le tampon à chaque fois que vous y basculerez. Ce qui suit lui donne un nom de fichier réel hors du /tmprépertoire et évite ce problème:

(defadvice ido-switch-buffer (after set-mode activate)
  (unless buffer-file-name
    (setq buffer-file-name (concat "/tmp/" (buffer-name)))
    (set-auto-mode t)))
Dan
la source
Ça a l'air bien, et nettoie la cruauté que ma réponse avait accumulée en quelques itérations. :-) Je vais juste répéter ici que si vous ne voulez pas définir un chemin de fichier réel pour une raison quelconque, vous pouvez utiliser une variable locale de tampon pour éviter de définir le mode plusieurs fois.
glucas
5

La set-auto-modefonction définit le mode en fonction du fichier associé à un tampon. Voici une fonction qui définit temporairement à buffer-file-namepartir du nom du tampon afin de définir le mode:

(defun my/set-buffer-mode (buffer &optional again)
  "Set the mode for BUFFER from the name.  
When called repeatedly for the same buffer only set the mode the first
time, unless the optional argument AGAIN is specified.
Does nothing if the buffer is associated with a file."

  (with-current-buffer buffer
    (when again (kill-local-variable 'my/buffer-mode-set))
    (unless (or buffer-file-name 
            (local-variable-p 'my/buffer-mode-set))
      (let ((buffer-file-name (buffer-name)))
        (set-auto-mode t)
        (setq-local my/buffer-mode-set t)))))

Vous pouvez l'exécuter lorsqu'un tampon est renommé à l'aide des conseils:

(defadvice rename-buffer (after my/rename-update-mode activate)
  (my/set-buffer-mode (current-buffer) 'again))

Je ne suis pas sûr du meilleur endroit pour connecter ceci pour affecter de nouveaux tampons. Ici, j'utilise le buffer-list-update-hook, mais qui est appelé dans plus de cas que nécessaire.

(add-hook 'buffer-list-update-hook
      '(lambda ()
         (my/set-buffer-mode (car (buffer-list)))))
glucas
la source
La réponse ci-dessus a été révisée pour traiter certains problèmes. En particulier, j'ai recommencé à utiliser le buffer-list-update-hookcar le change-major-mode-hookn'était pas appelé avec le tampon actuel attendu. Pour mémoire, il est probablement plus judicieux de conseiller votre fonction de commutateur-tampon comme le fait @Dan dans sa réponse.
glucas
3

Vous pouvez utiliser des tampons * scratch * dans le but de créer des tampons temporaires qui ont le même mode principal que le fichier sur lequel vous travaillez.

Voici une réponse emacs SE qui pourrait résoudre votre problème:

Comment basculer rapidement entre un fichier et un tampon * scratch * ayant le même mode majeur?

La question et la réponse référencées ont toutes deux été publiées par moi. La réponse dans la fonction fait ce qui suit:

  • Si vous travaillez en mode majeur X dans un fichier, l'appel de cette fonction crée un nouveau tampon de travail appelé *scratch-X-mode*s'il n'en existe pas déjà, et bascule vers ce nouveau tampon créé.
  • S'il *scratch-X-mode*existe déjà, il passe simplement à ce tampon.
  • Le fait d'appeler à nouveau cette fonction dans ce tampon de travail vous ramènera au tampon de fichier sur lequel vous travailliez à l'origine.
Kaushal Modi
la source
0

Il y a de bonnes réponses ici, mais je voulais ajouter une chose. Emacs a une tonne de fonctionnalités et il y a souvent plusieurs façons de faire quelque chose. Vous pouvez ajouter des balises en haut de n'importe quel fichier qui indiquent à emacs de quel type il s'agit, quelle que soit l'extension. Par exemple, en ajoutant ceci:

# -*-Python-*-

En haut d'un fichier, emacs saura qu'il s'agit d'un fichier Python même sans l' .pyextension. Notez que le #début de la ligne est un commentaire de style Python. Pour différents types de fichiers, vous pouvez utiliser différents commentaires. Par exemple, pour spécifier un fichier Lisp que vous utilisez ;pour démarrer une ligne de commentaire et définir le mode dans emacs comme ceci:

; -*- mode: Lisp;-*-

Voir Spécification des variables de fichier et choix des modes de fichier .

jcoffland
la source
Oui, mais la question ici concerne spécifiquement la création d'un nouveau tampon temporaire (par exemple avec switch-buffer) et le réglage automatique du mode sur autre chose que fundamental-mode.
glucas