<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="../assets/xml/rss.xsl" media="all"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Bitácora de Vuelo (Publicaciones sobre VSCode)</title><link>http://blog.taniquetil.com.ar/</link><description></description><atom:link href="http://blog.taniquetil.com.ar/categories/vscode.xml" rel="self" type="application/rss+xml"></atom:link><language>es</language><copyright>Contents © 2025 &lt;a href="mailto:facundo@taniquetil.com.ar"&gt;Facundo Batista&lt;/a&gt; CC BY-NC-SA</copyright><lastBuildDate>Fri, 30 May 2025 08:59:50 GMT</lastBuildDate><generator>Nikola (getnikola.com)</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>El tamaño sí importa</title><link>http://blog.taniquetil.com.ar/posts/0875/</link><dc:creator>Facundo Batista</dc:creator><description>&lt;section id="un-poco-de-contexto"&gt;
&lt;h2&gt;Un poco de contexto&lt;/h2&gt;
&lt;p&gt;Resulta que estoy haciendo una interfaz gráfica para Neovim. Hay millón, sí, ya sé, pero cada una tiene su quilombo. Y mi idea igual no es hacer la "interfaz gráfica definitiva", sino aprender en el proceso.&lt;/p&gt;
&lt;p&gt;&lt;code class="docutils literal"&gt;&amp;lt;nerd&amp;gt;&lt;/code&gt; Vengo aprendiendo un montón, ya que estamos, es re divertido este "proyecto mascota". &lt;code class="docutils literal"&gt;&amp;lt;/nerd&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;El escollo o tema más importante que me encontré hasta ahora que no sé cómo resolver (estoy cada vez más convencido de que no hay una "manera correcta" de resolverlo) es cómo manejar los caracteres anchos en una grilla de caracteres monoespaciados.&lt;/p&gt;
&lt;p&gt;A ver, vamos por partes (como diría mi amigo Jack).&lt;/p&gt;
&lt;p&gt;Estoy haciendo una interfaz gráfica para Neovim. Neovim es un editor de textos muy usado para programar (entre otras muchas funciones) y tiene una interfaz muy limpia originalmente pensada para la terminal. Y las terminales (la mayoría, anywyay) usan tipografías monoespaciadas.&lt;/p&gt;
&lt;p&gt;Una tipografía monoespaciada es aquella donde sus caracteres ocupan el mismo ancho. Si estás leyendo esto en mi blog, vas a ver que la tipografía está orientada a la "facilidad de lectura de textos" y los caracteres tienen distinto ancho. Mirá el ancho de las i y las m en la siguiente secuencia: mimimim. Y compará con la siguiente secuencia donde estoy forzando que use una tipografía monoespaciada: &lt;code class="docutils literal"&gt;mimimim`&lt;/code&gt;. La elección para estos ejemplos de la m y la i no es casual, la i es bastante finita, y se considera que la &lt;code class="docutils literal"&gt;M&lt;/code&gt; tiene el ancho completo.&lt;/p&gt;
&lt;p&gt;Las tipografías monoespaciadas son muy importantes para programar en casi cualquier lenguaje. Este código "tiene sentido":&lt;/p&gt;
&lt;pre class="literal-block"&gt;def test_levels_assert_ok_exception(logs):
    try:
        raise ValueError("test error")
    except ValueError:
        logger.exception("test message")
    assert "test.message" in logs.error
    assert "ValueError" in logs.error
    assert "test.error" in logs.error&lt;/pre&gt;
&lt;p&gt;El mismo código en una tipografía de ancho variable queda una porquería (especialmente en Python donde la indentanción importa, pero quedaría igual de feo en cualquier otro lenguaje).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="el-problema"&gt;
&lt;h2&gt;El problema&lt;/h2&gt;
&lt;p&gt;Todo muy lindo. Pero ahora vamos a la realidad. En el planeta tenemos un montón de caracteres que &lt;em&gt;son más anchos que una M&lt;/em&gt; (lo dejo escrito así genérico porque no queremos caernos en un agujero de conejo). Y no sólo caracteres de idiomas escritos. Unicode cubre todo eso pero también, por ejemplo, emoticones o &lt;em&gt;dibujitos&lt;/em&gt; de todo tipo.&lt;/p&gt;
&lt;p&gt;Vamos al caso de estos 3 caracteres: el "FULL STOP" (o más conocido "punto"), "HEAVY MULTIPLICATION X", y "CJK UNIFIED IDEOGRAPH-6614": . ✖  昔 -- o en monoespaciado: &lt;code class="docutils literal"&gt;. ✖  昔&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Los nombre en mayúsculas que puse en la oración anterior son los nombres formales que le da Unicode a esos caracteres. Y en relación a lo que venimos hablando, Unicode nos da también un dato importante: el "ancho inherente" del carácter, un tema para nada trivial, al punto que Unicode &lt;a class="reference external" href="https://www.unicode.org/reports/tr11/"&gt;tiene todo un anexo&lt;/a&gt; al respecto.&lt;/p&gt;
&lt;p&gt;Como gran parte de la especificación de Unicode está dentro de Python, podemos ver sencillamente esos valores para los caracteres en cuestión:&lt;/p&gt;
&lt;pre class="literal-block"&gt;&amp;gt;&amp;gt;&amp;gt; unicodedata.east_asian_width(".")
'Na'
&amp;gt;&amp;gt;&amp;gt; unicodedata.east_asian_width("✖")
'N'
&amp;gt;&amp;gt;&amp;gt; unicodedata.east_asian_width("昔")
'W'&lt;/pre&gt;
&lt;p&gt;¿Y qué significa eso? No voy a entrar en todo el detalle, ahí ya les dejé el Anexo si quieren explorar. Pero básicamente Unicode nos dice que hay caracteres "wide", "fullwidth", "narrow", "halfwidth", "ambiguous", y "neutrals". Un quilombo. Que podemos reducir un poco haciendo una simplificación: tomamos algunos como anchos y otros como angostos.&lt;/p&gt;
&lt;p&gt;Volviendo a los tres casos nuestros, el punto es Na (angosto), la cruz pesada es N (neutra), y el ideograma es W (ancho). Y más allá de esas características "formales", se puede notar visualmente que los anchos no son los mismos.&lt;/p&gt;
&lt;p&gt;La dificultad real que me llevó a estudiar todo esto, en el contexto de hacer una interfaz gráfica a Neovim, es: ¿cómo meto caracteres anchos en lo que a priori sería una grilla regular? ¿qué hago cuando el carácter ancho me &lt;em&gt;rompe la columna&lt;/em&gt;? ¿hay algo que se puede hacer que tenga sentido o que se considere "correcto"?&lt;/p&gt;
&lt;/section&gt;
&lt;section id="la-exploracion"&gt;
&lt;h2&gt;La exploración&lt;/h2&gt;
&lt;p&gt;¿Qué hacen otros editores con este bardo?&lt;/p&gt;
&lt;p&gt;Los tres que estuve estudiando son Neovim mismo en la terminal, neovim-qt (una interfaz gráfica hecha en Qt que se comporta muy muy parecida a Neovim en la terminal), y Visual Studio Code. Para simplificar, de los dos primeros voy a mostrar sólo a neovim-qt, porque se comportan igual.&lt;/p&gt;
&lt;p&gt;Miren lo que hace neovim-qt (o Neovim mismo en la terminal):&lt;/p&gt;
&lt;img alt="Screenshot y ampliado de cómo se comporta neovim-qt" src="http://blog.taniquetil.com.ar/images/carancho/nvimqt.png"&gt;
&lt;p&gt;La primer línea tiene al &lt;code class="docutils literal"&gt;.&lt;/code&gt; como referencia; sabemos que es angosto y cómo debería comportarse. En la segunda línea tenemos el ideograma: como Unicode dice que es ancho, ocupa dos espacios; fíjense que el ideograma ocupa todo el ancho del par &lt;code class="docutils literal"&gt;.P&lt;/code&gt; de arriba, y luego la &lt;code class="docutils literal"&gt;P&lt;/code&gt; está encolumnada con la &lt;code class="docutils literal"&gt;y&lt;/code&gt; de arriba. En la tercer línea tenemos la cruz pesada: Unicode dice que es angosta, pero el &lt;em&gt;dibujo&lt;/em&gt; ocupa un montón! Mala suerte, en este caso se respeta el ancho, mirá como la &lt;code class="docutils literal"&gt;P&lt;/code&gt; está encolumnada con la &lt;code class="docutils literal"&gt;P&lt;/code&gt; de la primer línea, pero el problema es que el carácter excedido en ancho queda &lt;em&gt;pisado&lt;/em&gt; por la letra siguiente.&lt;/p&gt;
&lt;p&gt;Por otro lado, esto es lo que hace Visual Studio Code:&lt;/p&gt;
&lt;img alt="Screenshot y ampliado de cómo se comporta VSC" src="http://blog.taniquetil.com.ar/images/carancho/vscode.png"&gt;
&lt;p&gt;En la primera línea no hay sorpresas. En la segunda vemos que el ideograma tiene el ancho que ocupa, a nivel dibujo, pero luego el espacio contra la &lt;code class="docutils literal"&gt;P&lt;/code&gt; no está exagerado: esto es porque VSCode no hizo que el ideograma ocupara "dos espacios", sino sólo lo que ocupó el dibujo en sí. Esto también lo vemos en la tercer línea, donde más allá que Unicode diga que es un carácter angosto, VSCode dibuja la cruz pesada al ancho que tenga y luego sigue con el resto del texto. Claramente esta forma de renderizar el texto queda más &lt;em&gt;lindo&lt;/em&gt;, pero rompe totalmente las columnas: fíjense como se pierde la alineación vertical entre las tres líneas.&lt;/p&gt;
&lt;p&gt;¿Hay valor en mantener en lo posible la alineación de las columnas? &lt;code class="docutils literal"&gt;&lt;span class="pre"&gt;neovim-qt&lt;/span&gt;&lt;/code&gt; mismo en algún punto la rompe porque si ponés un carácter en dos espacios, parece todo ordenadito pero realmente las columnas están rotas, aunque no se nota tanto.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="entonces-que-hago"&gt;
&lt;h2&gt;Entonces, ¿qué hago?&lt;/h2&gt;
&lt;p&gt;Por lo pronto, puedo implementar cualquiera de las dos soluciones que vimos recién.&lt;/p&gt;
&lt;p&gt;La primera, como &lt;code class="docutils literal"&gt;&lt;span class="pre"&gt;nvim-qt&lt;/span&gt;&lt;/code&gt;, con los anchos que indica Unicode:&lt;/p&gt;
&lt;img alt="Ocupando uno o dos espacios, según su ancho" src="http://blog.taniquetil.com.ar/images/carancho/vym-unicode.png"&gt;
&lt;p&gt;&lt;em&gt;(tengo esos puntitos azules porque todavía tengo en desarrollo todo lo que es "dibujar la grilla", después los voy a sacar)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Un detalle: a diferencia de &lt;code class="docutils literal"&gt;&lt;span class="pre"&gt;nvim-qt&lt;/span&gt;&lt;/code&gt;, en vez de que el caracter de después tape completamente al anterior, estoy haciendo que los dibujos de los caracteres se superpongan... creo que queda mejor, pero no es definitivo.&lt;/p&gt;
&lt;p&gt;La segunda solución, como VSCode, con el tamaño natural de los caracteres que se escapan del &lt;em&gt;ancho angosto&lt;/em&gt;:&lt;/p&gt;
&lt;img alt="A lo que ocupe el glifo, si se escapa de lo angosto" src="http://blog.taniquetil.com.ar/images/carancho/vym-natural.png"&gt;
&lt;p&gt;Hay una tercera opción, que se le ocurrió a Felipe, que se basa en el ancho real de cada glifo, pero luego ajustando a que ocupe uno o dos espacios según corresponda. Esta tiene la ventaja que todos los caracteres se verán bien (como en VSCode), y que las columnas parecen ordenaditas (como en neovim-qt), aunque sufre el mismo problema de que las columnas no están &lt;em&gt;realmente&lt;/em&gt; alineadas.&lt;/p&gt;
&lt;img alt="Acomodando los anchos en cantidad de espacios fijos" src="http://blog.taniquetil.com.ar/images/carancho/vym-expandido.png"&gt;
&lt;p&gt;Y una cuarta opción también, idea mía: llevar todo &lt;strong&gt;todo&lt;/strong&gt; a un sólo espacio. La ventaja es indiscutible: al tener siempre un carácter por espacio, la grilla queda perfecta a nivel alineación de columnas. Pero los caracteres al achicarse pierden mucho detalle, y creo que al final no es práctico.&lt;/p&gt;
&lt;img alt="Todo a un sólo espacio" src="http://blog.taniquetil.com.ar/images/carancho/vym-achicado.png"&gt;
&lt;p&gt;Cabe acotar que Neovim espera que la GUI funcione como la primer manera ("unicode"), porque sino se rompen otras cosas que el editor dibuja "alrededor de la grilla del código"; en la siguiente imagen (del segundo caso, "natural") se puede ver qué mal que queda la barra vertical de la derecha que marca 99 columnas, y cómo se desplaza toda la línea que tiene la cruz pesada al principio:&lt;/p&gt;
&lt;img alt="Neovim espera que la grilla se comporte de una manera específica" src="http://blog.taniquetil.com.ar/images/carancho/vym-natural-raro.png"&gt;
&lt;p&gt;Si voy a mantener que Neovim haga esos dibujos de alrededor, tengo que hacer que la GUI se comporte sí o sí de la primer manera ("unicode"), pero quizás en un futuro haga yo mismo desde la GUI esos dibujos de "asistencia", lo cual me liberaría a dibujar los anchos como yo quiera (y esos otros dibujos quedarían más elegantes, por ejemplo la línea que marca el límite de columnas que sea una línea, y no un caracter pintado).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="conclusiones"&gt;
&lt;h2&gt;Conclusiones&lt;/h2&gt;
&lt;p&gt;No tengo una decisión tomada. No me parece que haya una forma que sea claramente mejor que el resto. Todas tienen algún problema.&lt;/p&gt;
&lt;p&gt;Pero después de todo este análisis, lo próximo que voy a hacer es usar el modo "unicode", el que usa &lt;cite&gt;nvim-qt&lt;/cite&gt; y que es mejor soportado por Neovim, ya que en la primera etapa (al menos) voy a mantener los "dibujos de asistencia de alrededor" hechos por Neovim mismo, así que no quiero romper eso.&lt;/p&gt;
&lt;p&gt;Tampoco me queda claro que las otras opciones sean mejores. Neovim eligió ese modo por alguna razón, aunque quizás esa razón no sea la más importante en este momento/contexto (quizás porque Vim hacía lo mismo, o quizás porque la interfaz primaria es la terminal).&lt;/p&gt;
&lt;p&gt;VSCode eligió la otra solución, la "natural", pero que queden las columnas levemente desalineadas es horrible. Aunque quizás eso no sea un problema ya que al final les hispanoparlantes usamos normalmente caracteres "angostos", especialmente para programar... pero después metiste un emoji y perdiste.&lt;/p&gt;
&lt;p&gt;En fin. Si tienen más info sobre este tema, es bienvenida. ¡Gracias!&lt;/p&gt;
&lt;/section&gt;</description><category>font</category><category>glifos</category><category>GUI</category><category>Neovim</category><category>PyQt</category><category>Qt</category><category>tipografía</category><category>Unicode</category><category>VSCode</category><guid>http://blog.taniquetil.com.ar/posts/0875/</guid><pubDate>Thu, 29 May 2025 20:57:00 GMT</pubDate></item></channel></rss>