Cuaderno de GNUtas

Automatizar en Emacs la apertura de dos archivos en doble ventana

Traducir la Odisea en Org Mode es un proceso que sigue resultando «fecundo en ardides». Veamos aquí uno más. En ocasiones necesito abrir un canto determinado en una doble ventana de Emacs, junto al canto original en griego. Esto se puede conseguir, claro, encadenando una serie de atajos de teclas (creo que lo más cerca que estaré en mi vida de tocar el piano es usando GNU Emacs), pero siempre podemos hacerlo más sencillo y rápido.

Por ejemplo, combinando por un lado el código que explicamos en esta otra GNUta, donde queríamos aislar un sub-árbol determinado de un documento Org; y por otro lado, el eficacísimo sistema de marcadores que nos proporciona Emacs. Recordemos que para Emacs cualquier cosa en un archivo de texto (incluyendo un directorio), y cualquier parte de un archivo de texto puede anclarse a un marcador determinado. ¿Cómo creamos un marcador? Basta con llevar el cursor a la línea que deseamos marcar, y pulsamos la secuencia C-x r m. Cuando se nos pregunta en el minibúfer por el nombre que queremos darle al marcador, lo escribimos y damos al RET. Y, para visitar el marcador: C-x r b, escribimos el nombre de nuestro marcador y después RET. Esta última acción está asociada a la función bookmark-jump, que nos vendrá de perlas para lo que sigue.

Y seguimos, para ilustrar mi caso concreto. Cada canto traducido es un árbol (con encabezado de primer nivel) de un único documento de Org, con la estructura:

* Canto I
* Canto II
* Canto III
[etc]

Y cada encabezado tiene su respectivo marcador: canto1, canto2, etc. Por otra parte, los cantos originales en griego son documentos independientes de texto plano, también con sus marcadores: canto1gr, canto2gr, etc. Para poder abrir cada canto traducido en una doble ventana junto a su original griego (a la izquierda mi traducción, a la derecha el original, para entendernos), he creado un pequeño paquete de código Elisp que contiene una serie de funciones interactivas, para poder llamar luego desde dentro de Emacs. El paquete ha de estar guardado en un directorio accesible a Emacs, y también ha de cargarse en nuestro archivo de inicio. Por ejemplo, en mi /.emacs tengo este par de líneas:

;; Para hacer accesible a Emacs esta ruta

(add-to-list 'load-path "~/.emacs.d/lisp/")

;; para abrir los cantos de la Odisea

(load "odisea-cantos.el")

Cada función de mi archivo de código tiene la misma estructura, una para cada canto. Dejo aquí cómo empieza (con las funciones para abrir los dos primeros cantos, y paso a explicarlo un poco más abajo:

(require 'bookmark)

;; Canto 1

(defun canto-i ()
  (interactive)
  (bookmark-maybe-load-default-file)
  (bookmark-jump "canto1")
  (org-tree-to-indirect-buffer)
  (other-window 1)
  (delete-other-windows)
  (linum-mode)
  (bookmark-jump-other-window "canto1gr")
  (linum-mode))

;; Canto 2

(defun canto-ii ()
  (interactive)
  (bookmark-maybe-load-default-file)
  (bookmark-jump "canto2")
  (org-tree-to-indirect-buffer)
  (other-window 1)
  (delete-other-windows)
  (linum-mode)
  (bookmark-jump-other-window "canto2gr")
  (linum-mode))

Se ve que lo que viene a hacer cada función es bastante simple. (bookmark-jump "canto x") visita mi documento de Org con la traducción y sitúa el cursor en el encabezado del canto correspondiente. Lo que sigue, es para aislar en único búfer y una única ventana el sub-árbol de dicho canto (tal y como se explicó aquí). Y (bookmark-jump-other-window "cantoxgr"), como sugiere su nombre, nos abre una ventana a la derecha con el correspondiente canto en griego, que, como dije, es un archivo independiente. Ah, pero eso sí: para que esto suceda cada vez que reiniciemos Emacs, tenemos que decirle a Emacs que cargue antes el archivo de marcadores. Para ello hemos de requerir bookmark al principio de nuestro código. E incluir al principio del cuerpo de cada función (bookmark-maybe-load-default-file).

Y ya está. Tan sencillo como eso. Sólo nos queda guardar como un tesoro nuestro archivo de marcadores. Y, como una imagen vale más que mil palabras, aquí un pequeño vídeo de muestra:

Automatizar en Emacs la apertura de dos archivos en doble ventana from Juan Manuel Macías Chaín on Vimeo.

Actualización de 13/12/19

La Odisea ha ido creciendo y creciendo, así que finalmente simplifiqué todo con una función general que pregunte en el minibúfer por el número de canto adonde queremos saltar:

(defun doble-canto-odisea-es-gr ()
  "permite saltar a una doble ventana con el número de canto
indicado a la izquierda y el original a la derecha"
  (interactive)
  (let
      ((num-canto (read-from-minibuffer "canto: ")))
    (bookmark-maybe-load-default-file)
    (bookmark-jump (concat "canto" (format "%s" num-canto)))
    (org-tree-to-indirect-buffer)
    (other-window 1)
    (delete-other-windows)
    (goto-char (point-min))
    (re-search-forward "#\\+begin_verse\\|#\\+BEGIN_VERSE")
    (org-narrow-to-element)
    (display-line-numbers-mode)
    (bookmark-jump-other-window (concat "canto" (format "%s" num-canto) "gr"))
    (goto-char (point-min))
    (re-search-forward "#\\+begin_verse\\|#\\+BEGIN_VERSE")
    (org-narrow-to-element)
    (display-line-numbers-mode)
    (display-line-numbers-mode)))

Publicado: 02/11/2018

Última actualización: 18/05/20


Índice general

Acerca de...

Esta obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial 4.0 Internacional.

© Juan Manuel Macías
Creado con esmero en
GNU Emacs