Un recorrido
Cada pantalla que tiene Textchum, en el orden en que las irías encontrando, en los dos entornos: la app de macOS a la izquierda y la de GTK a la derecha. Las capturas vienen de un proyecto ficticio pequeño — Harbor, un gestor de puertos que existe solo para que estas imágenes tengan algo honesto que mostrar — y cada una sigue tu ajuste de tema claro u oscuro.
Los dos entornos son el mismo editor sobre el mismo núcleo, así que las imágenes se diferencian sobre todo en lo que aporta la plataforma: el marco de la ventana, dónde se dibuja un panel y qué tipografía entrega el sistema.
La ventana
Un documento por ventana, pestañas por defecto, y un cajón navegador con dos mitades: arriba los búferes abiertos agrupados por proyecto, abajo el árbol de archivos de ese proyecto.
La barra de título lleva los datos del documento — codificación, tamaño, lenguaje y el número de problemas en cuanto el servidor de lenguaje opina. El árbol acompaña: cambiar de pestaña despliega la ruta del archivo actual y lo resalta, y un archivo guardado, creado o borrado en una carpeta que muestra — por el editor, una refactorización o una orden en una terminal — aparece o desaparece solo.
Al hacer clic derecho en el texto aparece el menú del editor: saltar a la definición, buscar referencias, renombrar el símbolo, el diagnóstico de la línea, el blame de la línea, formatear el documento y las propiedades del archivo, junto a cortar, copiar, pegar y las sugerencias de ortografía. Esos comandos actúan sobre el carácter en el que se hizo clic, no sobre el cursor, que el clic deja donde estaba. Lo que el documento no puede usar no está: sin servidor no hay buscar referencias, sin hallazgos no hay filas de diagnósticos.
Plegado
Fold (⌘[, Ctrl+[ en Linux) cierra el bloque que abre en la línea del cursor; Fold All (⌥⌘[, Ctrl+Alt+[) cierra todos los que no estén ya dentro de uno cerrado, y Unfold All (⌘], Ctrl+]) los abre de nuevo. Un bloque cerrado muestra su línea de apertura con puntos suspensivos detrás.
Los bloques salen del mismo árbol que usa el coloreado, y los pliegues son del documento: cerrar una función en una vista la cierra en todas las vistas de ese archivo.
Columnas
Una ventana es una fila de columnas. Una columna muestra un archivo a la vez y sostiene una o más vistas de él, apiladas.
New Column (⌘\, Ctrl+\ en Linux) pone una columna al lado de
esta, mostrando el mismo archivo hasta que se le dé otro; Close
Column (⇧⌘\, Ctrl+Shift+\) la quita. Second View (⌥⌘\,
Ctrl+Alt+\) apila otra vista del archivo de la columna bajo la
primera, y Close View (⇧⌥⌘\, Ctrl+Alt+Shift+\) la retira. Next
Pane (⌥⌘, Ctrl+Alt+) mueve el teclado entre ellas.
Cada vista se desplaza por su cuenta, que es de lo que se trata: leer el principio de un archivo mientras se edita el final. La columna es dueña del archivo que muestra, así que cambiar su pestaña lleva todas sus vistas al archivo nuevo.
Los dos lados son un solo documento. Hay una historia y un guardado, así que una edición en cualquiera de los dos es la misma edición y ninguna vista puede quedarse vieja. Ambos toolkits están hechos para esto —un búfer de texto que varias vistas comparten— y lo que no sale gratis es el coloreado, que en macOS vive en el layout y no en el texto; se pinta cada vista.
Servidores de lenguaje
Los diagnósticos llegan como marcas tintadas en el texto y un contador en la barra de título. Nada del editor espera al servidor: se conecta cuando puede, y lo dice cuando no.
El margen dice lo mismo: una línea con un hallazgo lleva su número en el color de la severidad — rojo, naranja, azul — con un disco al lado para un error o una advertencia y un anillo para información y sugerencias. El código en la documentación del servidor — una firma, una definición — se colorea como el editor colorea ese lenguaje, y el menú contextual del editor muestra las mismas teclas que el menú principal para cada comando.
Dejar el puntero sobre un símbolo muestra la documentación del servidor, con el Markdown que envía ya renderizado — bloques de código en monoespaciada, énfasis con estilo. ⌃⌘H la pide para el símbolo bajo el cursor, lo que funciona incluso con el hover del ratón apagado.
La misma documentación puede vivir en un panel en lugar de una burbuja. Ver ▸ Panel de información (⌥⌘I) acopla uno bajo el editor, como una segunda vista se apila en la columna; mientras está visible la burbuja no aparece, y el panel muestra la documentación del símbolo bajo el puntero, y la del símbolo en el cursor a medida que se mueve. Su segunda cara lista los diagnósticos del documento — línea, tipo, mensaje — y un clic lleva a la línea. El panel sigue al archivo con el foco entre pestañas y columnas.
Ir ▸ Historial de saltos… lista el recorrido que Volver seguiría, el más reciente primero, con el recorrido hacia adelante debajo cuando lo hay, en la misma lista que usa Buscar referencias; elegir un lugar lleva allí, como un salto más. Ambas listas muestran cada línea con los colores de su lenguaje.
Una carpeta se abre como proyecto: Archivo ▸ Abrir acepta un
directorio, y también chum ruta/a/carpeta. Una ruta que aún no existe
— chum notas/nuevo.go — abre un documento nuevo con ese nombre,
tratado como el lenguaje que su nombre indica, y Guardar lo escribe ahí
sin preguntar. Si hay una pestaña de ese
proyecto abierta en algún sitio, esa pestaña pasa al frente; si no, se
abre una ventana nueva con el proyecto en su árbol y sin archivo aún, y
sigue abierta cuando se cierra su última pestaña. La barra de estado
dice la rama de git del proyecto, leída al mostrar el archivo y de
nuevo cuando git reescribe HEAD — el editor vigila ese archivo en vez
de preguntar con un temporizador. Tras ella vienen las migas de
pan: las construcciones con nombre en las que está el cursor, la más
externa primero — el impl y la función, la clase y el método —,
leídas del árbol sintáctico, así que no necesitan servidor de
lenguaje. Cada una es un menú de lo que tiene al lado, con la que
nombra marcada; elegir una va allí, como un salto del que Go Back
vuelve. Un texto que ninguna gramática lee no tiene. Su extremo
derecho es el área de
notificaciones: lo último que el editor tuvo que decir — un servidor
de lenguaje que no encontró, y qué lo instalaría; una gramática que no
pudo cargar; un guardado que siguió adelante sin sus preprocesadores —
tanto como quepa, y entero como descripción emergente. Nada de eso
interrumpe: lo que antes era un diálogo que cerrar es una línea aquí.
Un clic lista las notificaciones de la sesión, la más reciente
primero con la hora de cada una, seleccionables, porque lo dicho suele
ser un comando que ejecutar. Todavía no: la lista no sobrevive a la
sesión, y nada la vacía. Ir ▸ Árboles de trabajo… lista
los árboles de trabajo del repositorio: elige uno para cambiar esta
ventana a él — sus archivos se cierran y los que el otro árbol también
tiene se vuelven a abrir allí, y los servidores de lenguaje arrancan en
la nueva raíz — o para abrirlo como proyecto propio. Con archivos
modificados en el árbol actual, o sin guardar en la ventana, solo se
ofrece abrir; un árbol ya abierto simplemente pasa al frente. Un
archivo que git entrega al editor — un mensaje de commit, la lista de
un rebase — empieza siempre arriba.
Buscar y reemplazar (⌥⌘F) acopla una barra sobre el texto con el
patrón, el reemplazo y tres interruptores: expresión regular,
distinguir mayúsculas, palabra completa. Las expresiones son las de
Vim — grupos \( \), \|, \+, \?, \{n,m}, \< \>, \v y
\V, \c — y el reemplazo admite \1…\9, & o \0 para la
coincidencia, \n, y \u \l \U \L \E para las mayúsculas. ⏎
en el patrón va a la siguiente coincidencia, ⇧⏎ a la anterior, ⏎ en el
reemplazo reemplaza la actual y sigue; Todo reemplaza todas como un
solo paso de deshacer. ⎋, en la barra o en el texto, guarda la barra y
sus marcas y deja el teclado en el texto.
Ir a la línea (⌘L, Ctrl+L en Linux) acepta un número, o el
src/main.rs:412:8 entero pegado desde un registro de compilación —
el nombre del archivo y el ruido sobrante se ignoran, la línea queda a
un tercio de la altura de la vista, y Atrás vuelve a donde se interrumpió la lectura.
Una barra de cambios baja por la izquierda del margen y dice qué líneas difieren del archivo tal como está en git: una franja verde para una línea nueva, azul para una que dice otra cosa, y una cuña roja en el límite donde se borraron líneas —las líneas borradas no ocupan alto, así que una franja no tendría nada que cubrir—. Sigue al búfer y no al archivo en disco, así que acierta antes de guardar, y se recalcula cuando la escritura se detiene. Un archivo sin versión confirmada, o fuera de un repositorio, no lleva marcas en vez de dar todas sus líneas por nuevas.
La barra compara con el último commit salvo que se le diga otra cosa.
En lo hondo de una rama esa respuesta se calla —todo lo confirmado en
la rama cuenta como sin cambios—, así que editor.git_marks: "branch"
compara con el commit del que nació la rama, y la barra muestra todo lo
que la rama toca. Cuando git no nombra una rama por defecto,
editor.merge_base_branches lista los nombres que probar, el más
probable primero; ambos ajustes se pueden anular por proyecto.
Ir → Cambiado en la rama (⌃⌘T, Ctrl+Alt+G en Linux) lista los
archivos de la rama —los del pull request, leídos solo de git— tras el
mismo filtro difuso que Abrir rápido.
Autoría de la línea (⌃⌘B, Ctrl+Alt+B en Linux) le pregunta a git quién tocó por última vez la línea bajo el cursor: el commit, el autor y cuándo la escribió, el asunto y el cuerpo del mensaje —donde suele estar el porqué— y el nombre que tenía el archivo entonces si se ha renombrado desde. El commit queda a un botón del portapapeles, que es para lo que sirve la respuesta. Una línea escrita desde el último commit lo dice, en vez de tomar prestado un autor ajeno.
Pregunta con el texto del búfer y no con el archivo en disco, así que una edición sin guardar por encima del cursor no puede desplazar la respuesta a la línea vecina.
En el espacio inicial de una línea, dos teclas hacen algo más de lo habitual. Retroceso borra hasta la parada de tabulación anterior en vez de espacio a espacio, y Tab alinea la línea con la primera línea no vacía de arriba —al pulsarla otra vez, ya alineada, baja un nivel más—. En el resto de la línea ambas teclas son ellas mismas: decide la posición y no un modo, que es lo que evita que sorprendan. Una línea con tabuladores se deja a su propio carácter, que ya es una pulsación por nivel.
Con texto seleccionado, escribir un delimitador de apertura —(, [,
{, ', ", `— envuelve la selección en el par en vez de
reemplazarla. Lo envuelto sigue seleccionado, así que pulsar otro lo
envuelve a su vez: [, ( y { sobre hello dan [({hello})].
Escribir cualquier otra cosa reemplaza la selección como siempre.
Sin nada seleccionado, Close brackets and quotes as they are typed
(Ajustes ▸ General, apagado por defecto) trae consigo la mitad de
cierre — ( da () con el cursor en medio — y el ) que se escribe
después pasa por encima del que ya está en vez de añadir un segundo;
Retroceso entre un par vacío se lleva los dos. Los corchetes se
emparejan en todas partes; las comillas siguen al lenguaje: ' es un
apóstrofo en prosa y un lifetime en Rust, así que ahí se deja en paz, y
el acento grave solo se empareja donde significa código. Ningún par se
abre dentro de una palabra, y ninguna comilla justo después de una. Un
lenguaje que la regla no conoce, o en el que se equivoca con una
comilla, trae su propia tabla en el archivo: editor.pairs en
la configuración.
La barra fina bajo el editor responde lo que mirar el texto no puede: dónde está el cursor, si el archivo indenta con tabuladores o espacios y de cuántos, como qué lenguaje se trata, y su codificación. La indentación y el lenguaje se pueden pulsar y abren Propiedades del Archivo, donde se hacen esas elecciones.
Con un cuerpo largo desplazado, la primera línea de cada construcción
envolvente queda fija en lo alto de la vista —la línea class y la
línea def mientras un método Python se desplaza— y pulsar una lleva
hasta ella. Las líneas fijadas cuestan filas, así que
editor.context_lines: false (o el interruptor en Ajustes) las apaga.
La línea del cursor lleva un tinte leve, para encontrar el cursor de un
vistazo en un archivo largo. El botón derecho sobre el texto —o
Archivo → Copiar ruta— ofrece la línea del cursor en las formas que
se pegan: Ruta y línea (ruta:línea, que un terminal abre
directo) y URL de la forja para la línea, la URL del archivo en la
forja con el fragmento de línea escrito como lo escribe esa forja.
Moverse por palabras (⌥→/⌥←, Ctrl+flechas en Linux, y sus formas de
seleccionar y borrar) se detiene en cada cambio de clase de carácter
—identificador, símbolo, blanco— y en cada salto de línea, así que una
tira como )} es una parada y el cursor nunca salta de línea. Una
comilla pertenece a la palabra que tiene al lado, así que "hello" es
una sola parada, y ., , y ; se pasan por encima como blancos
—separan cosas en vez de ser cosas—, así que a.b son dos paradas y
el punto se salta. Un
paréntesis o llave de cierre escrito al principio de su línea toma la
sangría de la línea que lo abrió.
El autocompletado aparece al escribir tras caracteres de identificador
y .; ↑/↓ eligen, ⏎ o ⇥ aceptan, ⎋ descarta. Un snippet llega con su
primer marcador seleccionado, así que escribir lo reemplaza; ⇥ pasa al
siguiente marcador y ⇧⇥ al anterior, y uno escrito dos veces se copia
mientras se teclea. El último ⇥ deja el cursor donde el snippet lo
pidió y devuelve las teclas.
⇧⌘O lista los símbolos del archivo, filtrables desde el teclado.
Vista ▸ Estado de servidores responde a «¿está vivo mi servidor?» — qué corre y dónde, y las transiciones recientes de la sesión, refrescado en vivo.
Encontrar cosas
⌘T abre archivos por nombre difuso dentro del proyecto. El ámbito se recorre una vez y se filtra en memoria, así que escribir es instantáneo; la línea de estado dice cuántos de cuántos archivos coinciden y qué hace cada tecla — ⏎ abre la fila seleccionada cuando las filas ya responden a la consulta, y busca mientras queda una pendiente; ⌘⏎ abre siempre — para que afinar una consulta nunca abra un archivo por accidente.
⇧⌘F busca en el contenido el texto tal como se escribe — o una
expresión regular, con el conmutador .* junto a la consulta — con filtros
apilados que refinan por texto de línea o por ruta. La línea de estado
siempre dice qué hizo la búsqueda.
⇧⌘P es la paleta de comandos: cada acción de menú, buscable de forma difusa, con su atajo al lado.
Ejecutar comandos
Run → Ejecutar un comando… (⌃⌥R, Mayús+F10 en Linux) ejecuta una
línea de comandos con el shell en el proyecto del archivo en primer
plano — cargo test, go build ./..., pytest -x — y muestra su
salida a medida que llega en un panel bajo el editor. La línea
ofrecida es la última ejecutada en ese proyecto; Ejecutar de nuevo
(⌘R, Ctrl+F5 en Linux) ejecuta otra vez la orden del panel, y
Detener (⌘F2, Ctrl+F2 en Linux) la detiene junto con lo que haya
lanzado. La salida conserva sus colores — a la herramienta que escribe
en un panel se le piden, como se le pedirían en una terminal — y una
línea de progreso que se redibuja en su sitio sigue siendo una línea.
Los sitios que la salida nombra — src/main.rs:12:5, el File
"app.py", line 3 de un traceback de Python, ui.ts(4,7) — aparecen
subrayados y se abren con un clic; Siguiente sitio de la salida
(F4) y Sitio anterior (⇧F4) los recorren como los hallazgos. Una
orden que lleva un rato sin decir nada mientras sigue en marcha puede
estar esperando una entrada: el panel lo dice, y una línea escrita en
su campo va a la entrada de la orden.
Lo que se puede ejecutar en el archivo está marcado en el margen con un
triángulo verde: en Rust, un #[test], un #[bench] y el main de un
binario o de un ejemplo; en Go, un TestX, un BenchmarkX y el main
de un paquete main; en Python, una función o método de prueba de
pytest y el if __name__ == "__main__": de un módulo. Un clic en la
marca ejecuta solo eso — cargo test -- tests::adds --exact, go test
-v -run '^TestAdds$' ., python3 -m pytest -v tests/test_app.py::test_adds
— en el panel, desde la carpeta del paquete. Run → Ejecutar en
el cursor (⌃⇧R, Ctrl+Mayús+F10 en Linux) ejecuta el más interior
alrededor del cursor. Donde la bombilla de un arreglo está en la misma
línea, se dibuja la bombilla y el clic ofrece el arreglo.
Cuando la salida informa de pruebas — el test x ... ok de cargo, go
test -v, pytest — el panel las lista a su lado por suite, cada una
marcada como aprobada, fallida, omitida o aún en marcha, con los
recuentos en su cabecera. Una prueba elegida en la lista muestra la
línea de la salida que informó de ella, tras la que viene su fallo;
Retorno o un doble clic ejecuta esa prueba sola, y el campo sobre la
lista la filtra por nombre mientras escribes. Repetir fallidas
en el panel, o Run → Repetir pruebas fallidas,
vuelve a ejecutar solo las que fallaron, desde la misma carpeta: la
orden es la que las ejecutó, con sus propios filtros sustituidos por
los nombres fallidos. Ejecutar de nuevo también ejecuta en la
carpeta donde empezó la ejecución, así que una prueba lanzada desde su
marca vuelve a ejecutarse en su paquete.
Todavía no: el panel no es una terminal. Un programa que dibuja la
pantalla entera — un editor, top, un REPL que edita su propia línea —
no cabe en él. Las marcas solo se encuentran para Rust, Go y Python, y
una prueba escrita según las convenciones de otro ejecutor no se marca.
Las pruebas solo se leen de la salida de cargo, go test y pytest; sin
-v, go test y pytest solo nombran lo que falló, así que solo eso se
lista. Una línea de órdenes con una tubería o && no se acota para
Repetir fallidas, y una prueba de la lista todavía no abre su código —
el sitio de su fallo en la salida sí.
Depuración
Un clic en la columna de marcas del margen, en una línea sin otra
marca, pone ahí un punto de interrupción — un disco rojo — y un segundo
clic lo quita; Run → Alternar punto de interrupción (⌘F8, Ctrl+F8
en Linux) hace lo mismo en la línea del cursor. Los puntos de
interrupción se mueven con el texto que se edita encima de ellos.
Run → Depurar en el cursor (⌃⇧D, Mayús+F9 en Linux), o un ⌥-clic
(Alt-clic en Linux) en una marca de ejecución, ejecuta la prueba o el
main bajo un depurador: debugpy para Python, Delve para Go, lldb-dap
para Rust — después de que cargo haya compilado la prueba o el
programa, con sus mensajes en la consola de depuración.
El panel de depuración se abre bajo el editor. Cuando el programa se
detiene en un punto de interrupción, su línea se tiñe y el archivo se
abre ahí; el panel lista la pila del hilo que se detuvo, las variables
del marco elegido en ella — un valor estructurado se abre para mostrar
lo que contiene — y la salida del programa, con un campo que evalúa una
expresión en ese marco. Continuar (F9, F5 en Linux), Paso por
encima (F8, F6 en Linux), Paso adentro (F7), Paso afuera (⇧F8,
Mayús+F7 en Linux) y Detener la depuración (⇧⌘F2, Ctrl+Mayús+F2 en
Linux) están en el menú Run y en el panel. Un adaptador que no está
instalado se nombra, con la orden que lo instala; un programa que no
arranca dice qué suele retenerlo — en macOS, el permiso que necesita un
depurador para tomar el control de un programa, que concede el modo de
desarrollador (DevToolsSecurity -enable).
Todavía no: la depuración solo empieza desde una prueba o un main que
encuentran las marcas de ejecución, en Rust, Go y Python; no se puede
elegir el adaptador de un lenguaje; no hay forma de engancharse a un
programa en marcha, ni puntos de interrupción condicionales, ni lista
de expresiones vigiladas; y los puntos de interrupción no se conservan
entre reinicios.
Markdown y prosa
Los documentos Markdown abren con una vista previa viva junto al texto, y el corrector ortográfico de prosa — apagado hasta que elijas un diccionario — marca las faltas en púrpura, distinto de los diagnósticos. En código solo mira los comentarios; los identificadores nunca se marcan.
Ajustes
Los ajustes son un archivo JSON plano que la ventana edita; el archivo es la escotilla de escape, y está vigilado, así que una edición en otro editor se aplica al instante.
Proyectos decide cómo se encuentran las raíces, qué oculta el árbol y qué ajustes del editor sobrescribe una raíz.
Los nombres ocultos son patrones glob, editados uno por línea, con un menú que añade un preajuste con nombre en un clic.
Presets edita esos conjuntos con nombre del mismo modo. Empiezan como integrados; edita cualquiera y tu lista toma el mando, así que el que borres sigue borrado hasta que restaures los integrados. Esta pantalla y la siguiente no tienen imagen del entorno GTK porque allí no son pantallas: los presets están dentro de Projects, y los preprocesadores dentro de Language Servers.

Servidores de lenguaje sobrescribe qué comando sirve un lenguaje, para todos los proyectos o para una raíz.
Preprocesadores ejecuta formateadores antes de cada guardado: un comando por línea, cada uno leyendo el documento por la entrada estándar y devolviéndolo por la salida estándar.

Cosas pequeñas
⇧⌘N empieza un documento nuevo en el lenguaje que elijas, filtrado desde el teclado, para que el coloreado funcione antes del primer guardado.
Y el panel Acerca de dice qué compilación estás usando — una versión real, incluso para una compilación local.



































































