copier le contenu du tampon actuel dans un tampon temporaire et opérer sur celui-ci

8

Je dois copier le contenu du tampon actuel dans un tampon temporaire, régler ce tampon sur un mode majeur particulier pour profiter de ses avantages et récupérer les informations dont j'ai besoin dans la logique principale.

Est-ce une folie complète? Et sinon, quelle est la structure pour cela?

Trevoke
la source

Réponses:

10

Si vous souhaitez copier des informations dans un autre tampon, puis laisser les tampons évoluer indépendamment, vous pouvez le faire .

Mais si vous voulez que l'autre tampon reflète le contenu original en temps réel, alors Emacs fournit cela avec des tampons indirects . Un tampon indirect est un autre tampon qui a le même contenu que l'original (les modifications dans un tampon sont reflétées dans l'autre tampon), mais des paramètres différents: un mode majeur différent, différents modes mineurs, différentes variables locales, un point différent, des marques différentes , un rétrécissement différent, etc.

Vous pouvez donc obtenir une vue d'une partie d'un tampon dans un autre mode principal, tout en gardant une trace des modifications dans le tampon d'origine et en reflétant les modifications dans le tampon d'origine. Créez d'abord un tampon indirect avec M-x clone-indirect buffer; il y a aussi clone-indirect-buffer-other-windowqui est lié à C-x 4 c( C-x 4préfixe de la fenêtre et cpour le clone ). Dans le tampon cloné, restreignez à la région souhaitée: sélectionnez la partie intéressante et exécutez C-x n n( narrow-to-region). Modifiez le mode principal comme vous le souhaitez.

Vous pouvez automatiser cela avec une commande comme celle-ci pour une utilisation interactive:

(defun edit-region-in-foo-mode (beg end)
  (interactive "@r")
  (let ((new-buffer (clone-indirect-buffer nil t)))
    (narrow-to-region beg end)
    (foo-mode)))

Pour la programmation, utilisez:

(defmacro with-indirect-buffer-in-foo-mode (beg end &rest body)
  `(with-current-buffer (clone-indirect-buffer nil nil)
     (narrow-to-region beg end)
     (foo-mode)
     (unwind-protect
         ,body
       (kill-buffer (current-buffer)))))
Gilles 'SO- arrête d'être méchant'
la source
8

Quelque chose comme ça:

(let ((old-buffer (current-buffer)))
  (with-temp-buffer
    (insert-buffer-substring old-buffer)
    (my-favourite-major-mode 1)
    (extract-needed-information)))
legoscia
la source
2
J'écrivais presque exactement ça. Enveloppez-le dans un defun si vous avez besoin de pouvoir l'appeler arbitrairement
Jonathan Leech-Pepin
Ça a l'air plutôt bien. Je vais attendre un peu, juste au cas où il y aurait quelque chose de mieux à marquer comme accepté, mais je pense que c'est ça :)
Trevoke
Je M-x copy-to-bufferproposais en fait , puis j'ai rouge la réponse @legoscia, qui est probablement ce que vous voulez. si le processus d'extraction et le mode principal sont les mêmes, une fonction sera meilleure
Nsukami _
2

J'ai aimé ce que @Gilles a écrit. J'ai modifié ce que @Gilles a écrit pour demander à l'utilisateur quel mode il aimerait utiliser. Vous pouvez modifier ce que j'ai écrit pour fournir les modes que vous préférez ou même modifier l'appel pour terminer la lecture afin qu'il vous permette de fournir un mode non fourni dans la liste par défaut.

(defun edit-region-in-mode (beg end)
  "Create an indirect buffer cloned from the current buffer and
  narrowed to the highlighted region. The cloned indirect buffer
  will have org-mode active. Changes to the indirect buffer will
  be updated in real time in the originating buffer. This is
  useful, for instance, when you are in a non-org-mode mode and
  want to edit table data or in a non-emacs-lisp mode and want to
  write some elisp utilizing code formatting and highlighting."
  (interactive "@r")
  (let ((new-buffer (clone-indirect-buffer nil t)))
    (narrow-to-region beg end)
    (funcall
     (intern
      (completing-read
       "Choose the mode you want to use when editing the highlighted region: "
       '(org-mode emacs-lisp-mode lisp-mode haskell-mode julia-mode
          python-mode mathematica-mode matlab-mode c++-mode))))))
Joe
la source
1

Pour un cas d'utilisation similaire, j'avais écrit une fonction elisp modi/switch-to-scratch-and-backqui vous permet de basculer rapidement entre un tampon FILE et un tampon * scratch * ayant le même mode principal que le tampon FILE. La fonction hyperliée ci-dessus vous mènera à une question emacs SE existante.

Voici comment vous pouvez utiliser cette fonction:

  • Créez une fonction wrapper pour copier votre tampon existant, créez un tampon * scratch * avec le même mode principal et collez le contenu copié.

Voici un exemple de fonction wrapper

(defun copy-current-buffer-to-scratch ()
 "Copied the current buffer, open scratch, paste it there."
  (interactive)
  (kill-ring-save (point-min) (point-max))
  (modi/switch-to-scratch-and-back)
  (yank))
  • Vous pouvez maintenant le lier copy-current-buffer-to-scratchà une clé si vous le souhaitez et son exécution vous donnera un tampon * scratch * avec le contenu de votre tampon de travail.
  • Une fois que vous êtes satisfait des modifications dans le tampon de travail, vous devrez copier manuellement la section requise dans le tampon d'origine.

C'est juste une autre façon de faire ce que vous voulez; vous voudrez peut-être utiliser des tampons indirects dont parle la solution de @Gilles. Cette approche est utile si vous devez effectuer des modifications importantes dans un tampon temporaire sans risquer des sauvegardes accidentelles dans le tampon d'origine jusqu'à ce que vous ayez atteint une solution stable.

Un exemple d'utilisation consiste à essayer des fonctions expérimentales elisp avant de les enregistrer dans votre init emacs.

Kaushal Modi
la source