Notxor tiene un blog

Defenestrando la vida


Trabajo con ventanas y buffers

Hemos tenido ya dos entregas anteriores de este «minicurso» o tutorial de cómo empezar a utilizar Emacs. De momento hemos visto cómo podemos abrir, modificar y guardar ficheros. También cómo movernos por una ventana con el cursor.

Plegado del texto en el modo org

Para continuar con el tutorial o cursillo que estamos haciendo sobre Emacs, enfocado a los no programadores y gentes venidas de otros entornos de trabajo, vamos a necesitar el fichero org que guardamos el otro día. Tenemos que abrirlo, si no te acuerdas del comando, no te preocupes: utiliza el ratón y el menú File -> Open File.... Si prefieres ir acostumbrándote a los comandos: C-x C-f (find-file), recuerda que puedes utilizar <TAB> para completar el path y el nombre.

¡Sorpresa! El buffer sólo contiene:

* Esto es un título de primer nivel...

¡¿Cómo?! ¡Si lo tecleé entero!... No te apures. en esa línea pulsa <TAB> y mira lo que aparece:

* Esto es un título de primer nivel

Esto es un párrafo normal. A partir de ahora puedes escribir
libremente en el editor. La separación entre párrafos es una línea en
blanco. Por eso, estas líneas son un párrafo.

Esto es el segundo párrafo. Como se puede ver está separado por una
línea en blanco del párrafo anterior. Si pulsamos =M-q= en un párrafo,
nos lo justifica y divide en líneas.

** Esto es un título de segundo nivel...
** Formato del texto...
** Bloques...
** Tablas...

¡Ey! ¡Aparecen las cabeceras de segundo nivel! Vuelve a pulsar <TAB>. ¡Ahora aparece todo el texto! Como nos indica el área de eco, estamos cambiando entre FOLDED, CHILDREN y SUBTREE. Ya veremos cómo se puede hacer que se muestre todo el texto al cargar el fichero cuando veamos más cosas del modo org y sus infinitas características. El tema es que veas que aunque tengas un fichero de texto de cientos de líneas, puedes trabajar con cada apartado ocultando el resto. Si te has fijado, cuando una cabecera está plegada muestra al final ...1.

Una anotación sobre la ayuda

A parte del manual de Emacs que viene con el editor, hay otras formas de acceder a la ayuda. Por ejemplo, pulsa C-h m (describe-mode) que mostrará en un buffer de ayuda las combinaciones de teclas y acciones que tiene un buffer activadas según los modos que tenga cargados. Aparecerán primero las teclas que correspondan al modo mayor activo.

También podemos hacer la búsqueda al revés. Nos viene a la memoria una combinación de teclas pero no estamos seguros de que es el que necesitamos, ¿cómo nos aseguramos? Si pulsamos C-h k nos pedirá que introduzcamos una combinación de teclas, al hacerlo nos mostrará un buffer de ayuda explicándonos qué comando lanza esa combinación y la ayuda que tenga asociada. Si sólo queremos que nos diga el comando, podemos utilizar C-h c.

Hay muchas más combinaciones para acceder a distintos aspectos de la ayuda, pero creo que te he contado las básicas y te las voy a resumir de nuevo:

C-h i
Ayuda al estilo info de Unix (info).
C-h r
Acceder al manual de Emacs (info-emacs-manual).
C-h m
Muestra documentación de los modos activos (describe-mode).
C-h k
Muestra documentación sobre el comando (describe-key).
C-h c
Muestra el nombre del comando asociado (describe-key-briefly).

Copiar, cortar y pegar

Como en otras cosas que hemos visto hasta ahora, Emacs no sigue las convenciones en las acciones de cortar y pegar. ¿Por qué? Pues porque cuando se estandarizaron para otros programas las combinaciones de teclas C-c, C-x y C-v, Emacs ya llevaba muchos años utilizando su complejo sistema de comandos y combinaciones de teclas. Las acciones son las mismas, pero las teclas distintas.

Cortar
C-w (kill-region).
Copiar
M-w (kill-ring-save).
Pegar
C-y (yank).

Tendría que hablar un poco de cómo funciona el borrado en Emacs para explicar todas las posibilidades, y sobre todo del kill ring. Sin embargo es muy complicado y son muchas las opciones no sólo las tres anteriores que son las habituales en otros editores. Más adelante, es posible que veamos cómo se pueden marcar zonas, mandarlas al anillo de borrado y recuperarlas. De momento, nos vamos a quedar con que al marcar el texto y borrarlo, lo manda a una zona de memoria especial que se llama Kill Ring, ─o anillo de borrado si quieres una traducción aproximada al significado─. Podrías pensar en el como una especie de portapapeles porque se parecen conceptualmente. Ya te adelanto que no es sólo eso, pero te sirve el símil para entenderlo de primeras. Si alargamos mucho estas entradas de introducción, prometo que hablaré con más detalle del kill ring.

Buscar y reemplazar

Una de las funciones más importantes de cualquier editor es la de buscar y sustituir texto de una manera eficiente y sencilla para el usuario. Otros editores más gráficos despliegan un diálogo modal con un campo de edición donde escribir lo que buscamos y por qué debemos reemplazarlo. Emacs para eso tiene el minibuffer. Los comandos más utilizados, podríamos decir: los más básicos, son C-s (isearch-forward) y C-r (isearch-backward). Al invocarlos nos pedirá que introduzcamos una cadena en el minibuffer y veremos cómo el cursor va saltando a la siguiente ─o la anterior, según el comando─ cadena en el buffer que se corresponda con lo buscado. Como el movimiento se aprende andando, vamos a verlo buscando algo, como por ejemplo:

  1. Pulsa la combinación C-s, fíjate que el área de prompt muestra la cadena I-search:.
  2. Pulsa una s, fíjate que el cursor salta a la siguiente «s» del buffer y muestra todas las eses marcadas.
  3. Pulsa una o, fíjate de nuevo, que salta a la siguiente ocurrencia de «so» y marca todas las coincidencias.
  4. Pulsa una l. De nuevo el cursor salta a la primera aparición de la palabra «sol» y marca las otras ocurrencias.

Pulsa C-g para anular la búsqueda... el cursor vuelve donde estaba ¿Por qué? ¿Qué ha pasado? Este es uno de los casos en que la posición del punto no sigue al cursor. Tenlo en cuenta si lo que haces es buscar una cadena en particular para moverte hasta allí, tienes que forzar que se desplace el punto una vez encuentres el sitio, simplemente moviendo el cursor con C-b o C-f o con las teclas de cursor, en el área de eco nos dirá Mark saved where search started.

Podemos reanudar la última búsqueda. Ahora si pulsamos C-s C-s, vemos que reaparece «sol» en el espacio y salta a la siguiente aparición de la cadena. Por supuesto, los mismos pasos son correctos para una búsqueda hacia atrás, pero con la combinación C-r. Además, si ahora pulsamos C-r C-r, Emacs asumirá que la cadena guardada para la última búsqueda: «sol», es la adecuada para buscar hacia atrás. Si un término no se encuentra el mensaje del prompt será Failing I-Search: y nos dará opción a modificar la cadena de búsqueda que estamos utilizando.

Además de esa búsqueda simple, podemos utilizar también otra búsqueda más compleja y completa mediante expresiones regulares pulsando C-M-s y C-M-r. Si no sabes qué son las expresiones regulares no te preocupes, seguramente no las necesitarás para el trabajo que puedas hacer con Emacs, pues son cosas más útiles para programadores. Si sí sabes qué son y te interesa el tema, busca en la ayuda (C-h r) el apartado sobre regexp search y recuerda que puedes alternar entre una búsqueda regexp y no-regexp pulsando la combinación M-s ó M-s r (isearch-toggle-regexp).

Sin embargo, aunque la búsqueda es importante, es más potente la sustitución. Igual que con la acción de buscar, la acción de sustituir también cuenta con su versión compleja mediante regexp, que no voy a contar aquí, porque la mayoría de los usuarios apenas las utilizamos.

Si buscamos modos de reemplazar una cadena en un texto en la ayuda, seguramente tropecemos con el comando replace-string. Está muy bien, porque eso reemplaza una cadena por otra... pero sólo una vez. Eso es suficiente en muchas ocasiones, sin embargo, es habitual que esa sustitución deba repetirse por todo el texto, para lo cual es más útil el comando M-% (query-replace). Realiza los siguientes pasos:

  1. Ve al principio del buffer primer-texto.org pulsando la combinación M-<.
  2. Pulsa la tecla M-% y aparecerá en el área de prompt el mensaje: Query replace.
  3. Escribe la cadena «sol» (como verás ahora el cursor se mantiene situado en el mismo sitio.
  4. Al pulsar <RET> preguntará Query replace sol with.
  5. Teclea «luna» y verás que al pulsar <RET> ha saltado a la primera aparición de la cadena «sol»
  6. Pulsa y y verás cómo se sustituye «sol» por «luna» y saltará a la siguiente ocurrencia.

Así podremos saltar de una ocurrencia a otra pulsando y cuando queremos sustituir y n cuando no. Si queremos sustituir todas las apariciones sin que pregunte más, pulsaremos !. Si lo que queremos es que deje de buscar pulsaremos q o si lo que queremos es que haga esta última sustitución y salga, utilizaremos el .

Existen más teclas, como la posibilidad de arrepentirte de todas las sustituciones con U o de la última con u, pero son menos frecuentes y es mejor que las consultes en la ayuda.

También hay que recordar que:

  1. las sustituciones pueden modificar la posición del punto, no como la mera búsqueda, que como hemos visto antes sólo movía el cursor,
  2. y no hay sustituciones hacia atrás, por lo que si quieres realizar un query-replace te aconsejo que antes vayas al principio del buffer.

¿Qué tal si practicas un poco la sustitución? Estamos toqueteando un fichero de pruebas, siéntete libre de torturarlo hasta hacerlo incomprensible.

Obsesos de la posición del cursor y el control manual

Recuerdo una conversación con un amigo. Me vio trabajando en mi ordenador, con Emacs escribiendo un texto sin preocuparme de otra cosa que del contenido. Le llamó la atención esta manera de trabajar tan antigua, habiendo editores que te permiten ver el texto como si lo estuvieras imprimiendo en una hoja en blanco virtual. También recuerdo que traía su parte de un trabajo común, escrita en un maravilloso archivo y cuando lo abrimos en mi ordenador, su estructura resultó del todo incomprensible: páginas a medio llenar, un montón de líneas en blanco, ausencia de títulos de apartados, saltos de línea en mitad de una. En fin, un caos de texto. Le intenté contar que lo importante de un texto es su estructura, no cómo se imprimirá. Le expliqué que lo de poner los títulos y marcarlos como tales es importante, sobre todo cuando sabes que ese texto lo vas a llevar a otro ordenador, que no tendrá los mismos tipos de letra o incluso la misma versión del programa que utilice para la edición.

El caso es que aquel día pandoc, con la inestimable ayuda de iconv convirtieron el contenido que traía a texto plano al que luego nos llevó un poco de tiempo en dotar de estructura. Recuerdo que mientras lo hacíamos (bueno, lo iba haciendo yo, mientras él se sentaba a mi lado nervioso porque no entendía nada), dijo que cómo sabía yo que estaba llegando al final de una línea para saltar a la siguiente si no hay una regla arriba que lo indique.

Mi amigo, parece ser, que metía los saltos de línea también donde él quería, porque era lo que había aprendido cuando estudió mecanografía, además, algunas veces incluso dividía alguna palabra escribiendo un guión y un salto de línea... (Un infierno). El caso es que cuando activé el ruler-mode parece que se tranquilizó un poco al ver que había una regla superior donde se marcaba la posición del cursor con el carácter |. Además, había dos caracteres # y que marcaban la columna de comentarios (comment-column) y el salto de línea (fill-column). El que yo tuviera activado el auto-fill-mode y el texto saltara a la siguiente línea de forma automática y yo no me preocupara de cómo, le chirriaba un poco.

Preguntó también cómo sabía yo cuándo venía un salto de página, que le faltaba una regla vertical. Ahí no pude ayudarle tanto, no hay una manera de mostrar una regla en algún margen, como mucho los números de línea con linum-mode. En mi caso, cuando estoy escribiendo texto me molestan los números de línea, prefiero activar column-number-mode, que cambia en la línea de estado el mensaje de L00 por un formato (Linea, columna) y así está controlado el cursor de un vistazo. Y dejo para los modos de programación el que muestre a la izquierda el número de línea.

Navegar entre ventanas

En general, no sólo tenemos que modificar un fichero, al contrario, en muchas ocasiones tenemos que trabajar con varios ficheros y para eso tenemos que navegar entre ventanas, buffers y ficheros.

Ya he hablado sobre buffers, cómo abrirlos y cómo cambiar de un buffer a otro. Recuerdo la combinación C-x b para cambiar de buffer. Hay más formas de cambiar lo que estemos editando en pantalla, por ejemplo con C-x <LEFT> o con C-x <RIGHT>. Pero esto ya lo vimos, ─aunque no viene mal recordarlo─.

Muchas veces necesitamos cambiar de buffer pero no queremos dejar de ver el que tenemos ahora en ventana. La opción sería abrir otra ventana y cambiar a ella mostrando el buffer. Para ello podemos utilizar la combinación C-x 4 b. Si sustituimos el 4 por un 5 lo que hacemos es abrir un nuevo frame2.

Voy a hacer un repaso de cómo abrir, cerrar buffers, ventanas y frames, no es necesario que te aprendas todas las teclas de memoria, lo harás con el uso, pero así reunidas se pueden consultar de un vistazo:

  • Abrir una ventana al lado de la actual: C-x 3.
  • Abrir una ventana debajo de la actual: C-x 2.
  • Abrir un buffer en otra ventana: C-x 4 b.
  • Abrir un buffer en otro frame: C-x 5 b.
  • Obtener una lista de buffers y cambiarlo con <RET>: C-x C-b.
  • Cerrar ventanas sin cerrar el buffer:
    • Cerrar todas las ventanas menos la actual: C-x 1.
    • Cerrar la ventana actual: C-x 0.
  • Cerrar el frame actual sin cerrar la sesión: C-x 5 0.
  • Cerrar todos los frames menos el actual: C-x 5 1.
  • Navegar entre buffers sin movernos de la ventana: C-x <LEFT> y C-x <RIGHT>.
  • Cerrar un buffer: C-x k, por defecto cierra el actual.

Como hemos visto con C-x 4 b podemos abrir un buffer en una nueva ventana, pero también podemos abrir (visitar) un fichero en otra ventana con C-x 4 f3, o un directorio con C-x 4 d.

Otras acciones con los buffers

No voy a enrollarme mucho para no alargar inútilmente esta entrega:

  • Renombrar el buffer actual: M-x rename-buffer.
  • Renombrar el buffer actual añadiendo un número: M-x rename-uniquely.
  • Alternar entre modo de sólo lectura y edición de un buffer: C-x C-q (read-only-mode).
  • Añadir el contenido del buffer actual por encima del cursor/punto, a otro buffer: M-x append-to-buffer.
  • Añadir el contenido de otro buffer en la posición del cursor/punto: M-x insert-buffer.

Conclusiones

Es muy recomendable que comiences a jugar con los ficheros, buffers, ventanas y marcos; que copies, cortes y pegues texto; que te familiarices con la ayuda. Que juguetees con estas cosas sin miedo.

Si ves otros tutoriales, o artículos o cursos, verás que comienzan recomendando que instales tales o cuales paquetes, o que configures tal o cual funcionalidad de una determinada manera, y yo aún no he hecho lo mismo. Mi intención es seguir así de momento hasta que agotemos las funcionalidades que vienen de fábrica con Emacs. Prefiero dedicar más tiempo a que te acostumbres al entorno y a la ayuda. Porque el entorno, las ventanas, buffers, frames y ficheros los vas a utilizar en todas las sesiones y la ayuda es lo que te puede servir para salir de dudas en aspectos que no se tocan en los tutoriales, artículos o cursos; o simplemente en esas raras ocasiones que necesitas una determinada funcionalidad tan infrecuente que de una vez a otra, no te acuerdas del comando, o la tecla.

No te preocupes por aprenderte las combinaciones de teclas, al final te aprenderás las que utilices de una manera frecuente. Como resumen me gustaría que te quedaras con una impresión general, ─que no siempre es cierta, pero que puede ayudarte a reconocer comandos a simple vista─. Normalmente, los comandos relacionados con el funcionamiento relacionado con el editor, comienzan por C-x, mientras que las funciones o comandos que se relacionan un modo, comienzan por C-c.

Nota al pie de página:

1

También se puede cambiar, pero una vez te acostumbras no necesitas nada más visual que los tres puntos para saber que esa cabecera está plegada.

2

Algo muy útil cuando tienes varios monitores y quieres utilizarlos todos. Recordando, que seguimos en la misma sesión, es decir, tenemos todos los buffers abiertos a nuestra disposición en todos los frames y en cualquiera de ellos podemos cerrar la sesión.

3

Si utilizamos C-x 4 r abriremos el fichero pero en modo de sólo lectura.


Comentarios

Debido a algunos ataques mailintencionados a través de la herramienta de comentarios, he decidido no proporcionar dicha opción en el Blog. Si alguien quiere comentar algo, me puede encontrar en Mastodon y en Diaspora con el nick de Notxor.

También se ha abierto un grupo en Telegram, para usuarios de esa red.

Disculpen las molestias.