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:
- Pulsa la combinación
C-s
, fíjate que el área de prompt muestra la cadenaI-search:
. - Pulsa una
s
, fíjate que el cursor salta a la siguiente «s» del buffer y muestra todas las eses marcadas. - Pulsa una
o
, fíjate de nuevo, que salta a la siguiente ocurrencia de «so» y marca todas las coincidencias. - 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:
- Ve al principio del buffer
primer-texto.org
pulsando la combinaciónM-<
. - Pulsa la tecla
M-%
y aparecerá en el área de prompt el mensaje: Query replace. - Escribe la cadena «sol» (como verás ahora el cursor se mantiene situado en el mismo sitio.
- Al pulsar
<RET>
preguntará Query replace sol with. - Teclea «luna» y verás que al pulsar
<RET>
ha saltado a la primera aparición de la cadena «sol» - 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:
- 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,
- 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 todas las ventanas menos la actual:
- 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>
yC-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 f
3, 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
.
Footnotes:
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.
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.
Si utilizamos C-x 4 r
abriremos el fichero pero en modo de
sólo lectura.
Comentarios