copiare il contenuto del buffer corrente in un buffer temporaneo e operare su quello


8

Ho bisogno di copiare il contenuto del buffer corrente in un buffer temporaneo, impostare quel buffer su una particolare modalità principale per sfruttare i suoi vantaggi e ottenere le informazioni di cui ho bisogno nella logica principale.

Questa follia è completa? E se no, qual è la struttura per questo?

Risposte:


10

Se si desidera copiare alcune informazioni in un altro buffer, e da quel momento in poi consentire ai buffer di evolversi in modo indipendente, è possibile farlo .

Ma se si desidera che l'altro buffer rifletta il contenuto originale in tempo reale, Emacs fornisce buffer indiretti . Un buffer indiretto è un altro buffer che ha lo stesso contenuto dell'originale (le modifiche in un buffer si riflettono nell'altro buffer), ma impostazioni diverse: una modalità principale diversa, diverse modalità secondarie, variabili locali diverse, un punto diverso, segni diversi , un restringimento diverso, ecc.

In questo modo è possibile ottenere una vista di una parte di un buffer in una diversa modalità principale, tenendo traccia delle modifiche nel buffer originale e riflettendo le modifiche nel buffer originale. Per prima cosa crea un buffer indiretto con M-x clone-indirect buffer; c'è anche quello a clone-indirect-buffer-other-windowcui è associato C-x 4 c( C-x 4prefisso finestra e cper clone ). Nel buffer clonato, restringere l'area desiderata: selezionare la parte interessante ed eseguire C-x n n( narrow-to-region). Modificare la modalità principale come desiderato.

Puoi automatizzarlo con un comando come questo per un uso interattivo:

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

Per la programmazione utilizzare:

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

8

Qualcosa come questo:

(let ((old-buffer (current-buffer)))
  (with-temp-buffer
    (insert-buffer-substring old-buffer)
    (my-favourite-major-mode 1)
    (extract-needed-information)))

2
Stava scrivendo quasi esattamente quello. Basta avvolgerlo in uno sfidante se devi essere in grado di chiamarlo arbitrariamente
Jonathan Leech-Pepin,

Sembra abbastanza buono. Aspetterò un po ', nel caso in cui esista qualcosa di meglio da contrassegnare come accettato, ma penso che sia così :)
Trevoke,

In realtà stavo suggerendo M-x copy-to-buffer, quindi ho rosso la risposta @legoscia, che è probabilmente quello che vuoi. se il processo di estrazione e la modalità principale sono uguali, una funzione sarà migliore
Nsukami _

2

Mi è piaciuto quello che ha scritto @Gilles. Ho modificato ciò che @Gilles ha scritto per chiedere all'utente quale modalità vorrebbero usare. Puoi modificare ciò che ho scritto per fornire le modalità che preferisci o addirittura modificare la chiamata per completare la lettura in modo che ti consenta di fornire una modalità non fornita nell'elenco predefinito.

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

1

Per un caso d'uso simile, avevo scritto una funzione elisp modi/switch-to-scratch-and-backche consente di passare rapidamente da un buffer FILE a un buffer * scratch * con la stessa modalità principale del buffer FILE. La funzione di collegamento ipertestuale sopra riportata ti porterà a una domanda emacs SE esistente.

Ecco come è possibile utilizzare quella funzione:

  • Creare una funzione wrapper per copiare il buffer esistente, creare un buffer * scratch * con la stessa modalità principale e incollare il contenuto copiato.

Ecco una funzione wrapper di esempio

(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))
  • Ora puoi associarlo copy-current-buffer-to-scratcha una chiave se lo desideri ed eseguirlo ti darà un buffer * scratch * con i contenuti del tuo buffer di lavoro.
  • Una volta che sei soddisfatto delle modifiche nel buffer di memoria virtuale, dovrai copiare manualmente la sezione richiesta nel buffer originale.

Questo è solo un altro modo di fare quello che vuoi; potresti comunque voler usare buffer indiretti di cui parla la soluzione di @Gilles. Questo approccio è utile se è necessario apportare modifiche pesanti in un buffer temporaneo senza rischiare di salvare accidentalmente nel buffer originale fino a quando non si è raggiunta una soluzione stabile.

Un caso d'uso di esempio è provare le funzioni elisp sperimentali prima di salvarle su emacs init.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.