El artículo de Alexis Bingessner,
"La representación de texto te odia", publicado hace un mes
, está muy cerca de mí.
En 2017, estaba desarrollando un editor de texto interactivo en un navegador. Insatisfecho con las bibliotecas ContentEditable existentes, pensé: “¡Oye, solo vuelvo a realizar la selección de texto! ¿Es difícil? Yo era joven Ingenuo. Pensé que podría manejarlo en dos semanas. De hecho, un intento de resolver este problema tomó varios años de mi vida, incluido un año de trabajo remunerado desde la mañana hasta la tarde para desarrollar un editor de texto para el nuevo sistema operativo.
En el trabajo, tuve la suerte de aprender mucho de
mentores con vasta experiencia en este campo . He escuchado muchas, muchas historias de miedo. Incluyendo un ingeniero que admitió una aplicación de Windows con una implementación personalizada de un campo de texto y quería cambiar de una API de entrada de texto obsoleta a una nueva versión. Aquí hay una
lista de interfaces de entrada
de texto en esta nueva versión:

Así es, 128 interfaces para ingresar texto. Estoy casi seguro de que hay ocho (8) diferentes tipos de bloqueos para solucionar problemas de concurrencia, aunque honestamente no leí su documentación, así que no me cite sobre esto. Ese ingeniero, año y medio (¡a tiempo completo!) Modificó su editor, pero al final falló y permaneció en la antigua API.
Escribir es difícil.
Alexis a veces menciona la selección de texto, pero su experiencia personal está más relacionada con la representación. Como persona, por otro lado, puedo agregar algunos puntos sobre la entrada.
Movimiento del cursor vertical
Ya cubrí esto en un
artículo anterior , pero podemos repetirlo rápidamente aquí.
En este ejemplo, si presiona hacia arriba, el cursor va al comienzo de la línea, antes de la palabra
hola . Hasta ahora, todo es bastante razonable. Pero si presiona hacia arriba y luego hacia abajo, el cursor saltará primero delante de
hola , y luego se parará después de
algunos .
Esto puede no parecer muy lógico. ¿Preguntas por qué salta a la derecha? Bueno, con movimientos verticales, cada cursor recuerda la posición
x en píxeles, y solo se actualiza cuando se presiona hacia la izquierda o la derecha, y no hacia arriba y hacia abajo. El mismo comportamiento evita que los cursores se muevan hacia la izquierda cuando se mueven verticalmente a través de líneas cortas.
Proximidad
Bien, ahora sabemos que cuando seleccionamos texto, tenemos
dos partes de estado: el desplazamiento de bytes dentro de la línea y la coordenada
x en píxeles, mencionados anteriormente. ¿Se resolvió el problema? Pues no.
Considere dos posiciones de cursor en una línea muy larga:
Como
loooooooooong es una palabra, dos posiciones del cursor tienen
exactamente el mismo desplazamiento de bytes en la cadena . No hay nueva línea entre ellos, ya que la línea está suavemente envuelta. Nuestros cursores necesitan un bit extra que les diga a qué línea ir. La mayoría de los sistemas llaman a este bit de afinidad. También se usa en un texto bidireccional mixto, del que hablaremos pronto.
Modificadores Emoji
Supongamos que le envío un mensaje a un amigo. Para expresar mis sentimientos quiero agregar un emoji divertido. Entro en el área de texto un pulgar hacia arriba,
a
letra
a
y un modificador de emoji para el tono de piel. Se ve así:
Oh, no quería escribir una carta. Coloco el cursor después y hago clic en Retroceso. Que va a pasar Vi varias opciones, dependiendo del editor.

- Mal # 1 puede parecer correcto. Pero así es como funciona un editor de texto con soporte para la representación de emoji heredados, por ejemplo, Sublime Text. Esto es malo porque el emoji de dedo ligero se codifica como un dedo amarillo, seguido inmediatamente por un modificador de tono de piel. No se combinan en un solo símbolo, como se esperaba. Incluso si copio el dedo ligero de otra aplicación, todavía no se mostrará correctamente, como aquí.
- Malo # 2 es lo que Chrome 77 hace en la barra de direcciones. No en páginas web, sino solo en la barra de direcciones. Este no es un problema de representación, ya que funciona copiar y pegar emoji con tono de piel. En cambio, Chrome elimina la letra, y al notar el modificador que sigue a la letra, también la elimina. Ups
- Mal # 3 coincide con la especificación Unicode de cómo se deben fusionar los emoji. Pero esto es bastante incomprensible para los usuarios y, por cierto, debes mover el cursor para que no se atasque a la mitad del emoji.
Todas las opciones son malas, por lo que puede suponer que probablemente haya una cuarta opción. Hay! Muchos editores, como TextEdit, ni siquiera le permiten colocar el cursor después de la letra, ya que el modificador de tono de piel se considera como una sola unidad con el carácter anterior. Esto tiene sentido en el contexto de emoji e incluso funciona bien en este caso, pero ¿qué pasa si el primer carácter de la cadena indica el modificador?
Ahora el modificador cambia el carácter de nueva línea. ¡TextEdit no le permitirá colocar el cursor al comienzo de la segunda línea! Personalmente considero esta decisión "también mala".
También puede haber notado que el pulgar hacia arriba se ha convertido en el pulgar hacia abajo. Lo hice yo mismo para reflejar mis sentimientos sobre toda la situación.
Por cierto, TextEdit específicamente hace que el cursor en la primera línea tenga
muchos errores. Por ejemplo, ¿adivina qué sucede si presiono
4
aquí?
Si También podría pensar que hay espacios entre los números. No estan ahi.
Texto bidireccional
Alexis menciona selecciones divididas en texto bidireccional mixto, como en este ejemplo de TextEdit:
Esto realmente tiene sentido, ya que el idioma árabe en las líneas está codificado de derecha a izquierda, por lo que la selección parece estar dividida, pero los bytes son un rango continuo.
Por lo tanto, es un poco sorprendente que podamos obtener esta selección:
Sí, es visualmente continuo, pero está separado por bytes. Si, es malo. Algunos editores hacen esto si selecciona texto con las teclas de flecha en lugar del mouse. Una alternativa es intercambiar las teclas izquierda / derecha dentro del texto con la dirección de derecha a izquierda, lo que también es malo. No hay buenas opciones aquí.
Como beneficio adicional, intente comprender lo que está sucediendo aquí:
Señor ... no quiero comentar sobre esto.
Lo que pasa con los métodos de entrada
El software que traduce las pulsaciones de teclas en entrada se denomina método de entrada o editor de métodos de entrada. Para el alfabeto latino, este no es un software muy interesante, ya que cada pulsación de tecla está directamente asociada con la inserción de un carácter. Pero en muchos guiones, los caracteres no caben en el teclado, por lo que debe ser creativo. Por ejemplo, en algunos métodos de entrada para el idioma chino, el usuario ingresa sonidos y obtiene una lista de caracteres similares en sonido:
Este campo a veces se denomina región de composición, y a menudo aparece
sobre el texto subrayado . A veces el método de entrada tiene que darle estilo. Por ejemplo, el método de entrada japonés en Android usa el color de fondo para crear un área para compartir oraciones:
(¡Gracias a Shae por la captura de pantalla!)¿Todas estas selecciones y áreas de composición interactúan con el texto bidireccional? No pensemos en eso.
Los métodos de entrada deberían funcionar en todas partes,
incluso dentro del terminal :
Nada irá a Vim hasta que se seleccione un carácter chino de la lista. Probablemente piense: "¿Pero cómo funciona en el modo de comando Vim?" No muy bien Esta es la razón por la cual el ingreso de texto en Internet y las pulsaciones de teclas son eventos separados. En la consola, se mezclan, causando problemas.
Este es solo un ejemplo de muchos métodos de ingreso de texto diferentes. (¡No olvide los métodos de entrada sin teclado, como la voz y la escritura a mano!) Afortunadamente, el sistema operativo le proporciona todos estos métodos. Pero, desafortunadamente, su cuadro de texto debe decir el protocolo general de entrada de texto utilizado por todos estos métodos. Para Windows, estas son las 128 interfaces enumeradas al principio del artículo. En otros sistemas operativos, las interfaces son más simples, pero aún son difíciles de implementar.
También puede observar que el método de entrada es un proceso separado, por lo que tanto el método de entrada como la aplicación pueden realizar cambios en el estado del campo de texto. Este es en realidad un protocolo de edición en paralelo. Windows resuelve el problema con ocho (8) tipos de bloqueos. Aunque mantener un bloqueo a través de los límites del proceso puede parecer dudoso, la mayoría de las otras plataformas intentan usar heurísticas imperfectas para solucionar problemas de concurrencia. O simplemente esperan que la condición de la carrera no suceda. En mi experiencia, la oración no es una primitiva muy efectiva del paralelismo.
¿Por qué todo es tan complicado?
Jonathan Blow, en una conferencia sobre degradación de software, menciona al
editor de texto Ken Thompson , que escribió en una semana. La mayor parte del código en este artículo es complejidad introducida al azar. ¿Windows realmente necesita 128 interfaces y 8 tipos de bloqueos para la entrada de texto? De ninguna manera ¿Son los errores en TextEdit el resultado de un modelo de edición complejo? Si ¿Es preocupante la dispersión de errores en los programas modernos? Al menos para mí lo es.
Sin embargo, el editor de Ken Thompson también fue mucho, mucho más simple de lo que esperamos de los editores de texto modernos. Unicode admite casi todos los idiomas vivos del mundo (hay alrededor de 7,000 de ellos), y muchos más están muertos. Existen diferentes scripts, instrucciones de texto y métodos de entrada, cada uno de los cuales impone restricciones complejas (y en algunos casos insolubles) a cualquier editor. Pero también debe admitir lectores de pantalla.
La enorme complejidad se acumula
inevitablemente , y en este artículo solo la tocamos un poco. Este es un verdadero milagro de programación que puede simplemente colocar
<textarea>
en una página web y proporcionar instantáneamente entrada de texto para cada usuario de Internet en todo el mundo.