copiar el contenido del búfer actual en un búfer temporal y operar en ese

8

Necesito copiar el contenido del búfer actual en un búfer temporal, configurar ese búfer en un modo principal particular para aprovechar sus beneficios y llevar la información que necesito a la lógica principal.

¿Es esta locura completa? Y si no, ¿cuál es la estructura para esto?

Trevoke
fuente

Respuestas:

10

Si desea copiar alguna información en otro búfer y, a partir de ese momento, dejar que los búferes evolucionen de forma independiente, puede hacerlo .

Pero si desea que el otro búfer refleje el contenido original en tiempo real, Emacs proporciona esto con búferes indirectos . Un búfer indirecto es otro búfer que tiene el mismo contenido que el original (las modificaciones en un búfer se reflejan en el otro búfer), pero diferentes configuraciones: un modo principal diferente, modos menores diferentes, variables locales diferentes, un punto diferente, marcas diferentes , un estrechamiento diferente, etc.

Por lo tanto, puede obtener una vista de una parte de un búfer en un modo principal diferente, mientras realiza un seguimiento de las modificaciones en el búfer original y refleja las modificaciones en el búfer original. Primero haga un buffer indirecto con M-x clone-indirect buffer; también hay clone-indirect-buffer-other-windowque está vinculado a C-x 4 c( C-x 4prefijo de ventana y cpara clonar ). En el búfer clonado, acérquese a la región que desea: seleccione la parte interesante y ejecute C-x n n( narrow-to-region). Cambie el modo principal como lo desee.

Puede automatizar eso con un comando como este para uso interactivo:

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

Para uso de programación:

(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- deja de ser malvado'
fuente
8

Algo como esto:

(let ((old-buffer (current-buffer)))
  (with-temp-buffer
    (insert-buffer-substring old-buffer)
    (my-favourite-major-mode 1)
    (extract-needed-information)))
legoscia
fuente
2
Estaba escribiendo casi exactamente eso. Simplemente envuélvelo en un defun si necesitas poder llamarlo arbitrariamente
Jonathan Leech-Pepin
Eso se ve bastante bien. Voy a esperar un poco, en caso de que exista algo mejor para marcar como aceptado, pero creo que esto es todo :)
Trevoke
En realidad estaba sugiriendo M-x copy-to-buffer, luego redimí la respuesta de @legoscia, que es probablemente lo que quieres. Si el proceso de extracción y el modo principal son los mismos, una función será mejor
Nsukami _
2

Me gustó lo que escribió @Gilles. Modifiqué lo que @Gilles escribió para preguntarle al usuario qué modo le gustaría usar. Puede editar lo que escribí para proporcionar los modos que prefiera o incluso alterar la llamada para completar la lectura, de modo que le permita proporcionar un modo no proporcionado en la lista predeterminada.

(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
fuente
1

Para un caso de uso similar, escribí una función elisp modi/switch-to-scratch-and-backque le permite cambiar rápidamente entre un buffer FILE y un * scratch * buffer que tiene el mismo modo mayor que el buffer FILE. La función hipervinculada anterior lo llevará a una pregunta existente de emacs SE.

Así es como puede usar esa función:

  • Cree una función de contenedor para copiar su búfer existente, cree un búfer * scratch * con el mismo modo mayor y pegue el contenido copiado.

Aquí hay un ejemplo de función de contenedor

(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))
  • Ahora puede vincular esto copy-current-buffer-to-scratcha una clave si lo desea y ejecutarlo le dará un búfer * scratch * con el contenido de su búfer de trabajo.
  • Una vez que esté satisfecho con las ediciones en el búfer de memoria virtual, deberá copiar manualmente la sección requerida de nuevo al búfer original.

Esta es solo otra forma de hacer lo que quieres; Sin embargo, es posible que desee utilizar buffers indirectos de los que habla la solución de @Gilles. Este enfoque es útil si necesita hacer algunas ediciones pesadas en un búfer temporal sin correr el riesgo de guardar accidentalmente en el búfer original hasta que haya alcanzado una solución estable.

Un caso de uso de ejemplo es probar funciones experimentales de elisp antes de guardarlas en su emacs init.

Kaushal Modi
fuente