Things I've learned building a modern TUI Framework
The development of the Textual framework faces challenges with emoji rendering, emphasizing smooth animations, efficient data handling, and the use of `lru_cache` and the fractions module for performance and accuracy.
Read original articlethe terminal's handling of emojis is inconsistent and unpredictable. This has posed significant challenges for the development of Textual, particularly in ensuring proper formatting and rendering of text that includes emojis. The author shares several insights gained from building the Textual framework, emphasizing the importance of smooth animations, efficient data handling with Python's dict views, and the benefits of using immutable objects. The use of the `lru_cache` decorator is highlighted for its performance advantages, particularly in functions that are called frequently. The author also discusses the utility of the fractions module to avoid floating-point inaccuracies in layout calculations. Additionally, the article notes the value of using Unicode art for documentation clarity and the complexities involved in emoji support, which complicates text rendering due to varying character widths and multi-codepoint representations. Overall, the insights reflect a blend of technical challenges and solutions encountered in the development of a modern terminal user interface framework.
- Smooth animations in terminals can be achieved by overwriting content instead of clearing it.
- Utilizing `lru_cache` can significantly enhance performance for frequently called functions.
- Immutable objects simplify reasoning, caching, and testing in code.
- The fractions module helps avoid floating-point errors in calculations.
- Emoji support in terminals remains problematic due to inconsistent rendering and character width issues.
Related
Advanced text features and PDF
The post explores complex text features in PDFs, covering Unicode, glyph representation, kerning, and font challenges. It emphasizes tools like Harfbuzz and CapyPDF for accurate text handling in PDFs.
Beyond monospace: the search for the perfect coding font
Designing coding fonts involves more than monospacing. Key considerations include hyphens resembling minus signs, aligning symbols, distinguishing zero from O, and ensuring clarity for developers and type designers. Testing with proofing strings is recommended.
Chr – terminal editor inspired by Turbo Pascal editor from 1997
A terminal-based text editor "chr" on GitHub mimics desktop editors' shortcuts, blending modern GUI with retro text mode. Developed with Tui Widget, it welcomes contributions. Installation involves cloning, building, and compiling.
Entering text in the terminal is complicated
The article delves into text input complexities in terminals, categorizing input modes and offering tips like using Ctrl+A for line navigation. Understanding input systems enhances efficiency in the command line.
How I Program in 2024
Kartik Agaram reflects on his programming journey, advocating for minimalist software design, emphasizing simplicity, context awareness, and the potential benefits of data-oriented design to improve software quality and adaptability.
- Challenges with Unicode and emoji rendering are prevalent, with many developers sharing their frustrations and experiences.
- There is a desire for more modern terminal interfaces that could simplify text formatting and improve usability.
- Some users express skepticism about the reactive design approach of Textual, preferring more straightforward UI frameworks.
- Accessibility issues are raised, particularly regarding animations and Unicode features that may hinder screen reader functionality.
- Overall, there is a mix of interest and skepticism about the utility and future of TUI frameworks like Textual.
Alright, so we're using some bastardization of CSS as well? That might be going a little bit too far. The react model already breaks the idea of CSS in a lot of ways, preferring standardized components. Sure, developers still use CSS to customize components, but I view that more as a side effect of how react evolved rather than as a justifiable architectural choice. But as long as you don't have to use CSS I suppose it's fine.
Last I tried it, you do have to use CSS. There are no good standard components, so you will be making your own, and instead of having components be one nice self encapsulated Python class the standard docs use things like list components and then style them with an external style sheet.
For those reasons textual just isn't for me yet. In python there should be one, and preferably only one, obvious way to do something. By mirroring react so closely they're also mirroring what I see as the JavaScript communities biggest vice.
For example, YouTube link in the article showed a possibility to display table with highlighting cells. Why would I need that as TUI? Probably if I want to navigate through table with highlighting active cell I would also need a bunch of other stuff and eventually I would need a proper GUI.
This is how games were written back in the day before DirectX was a thing. You'd write directly to the frame buffer and instead of clearing and redrawing, you'd redraw what changed and what was around and under it (because there was no time to refresh the entire view in time in addition to everything else you need to do)
I am likely just dense and uncreative, but the truth is, when I switched from DOS to Linux in the 90s, I was never again as productive as I happened to be with B800. Granted, it likely took me a long time to understand the need for double buffering and the difference between a local/direct text mode vs a terminal, let alone escape sequences. But still. Whenever I tried to do something directly in ncurses, I pretty much gave up due to a distinct feeling of being unhappy. Completely different to what I was able to do with the simple ideal of B800.
https://github.com/ArthurSonzogni/FTXUI
It's a nice tool to build interactive dashboards with both keyboard and mouse support.
[0]: https://xdsl.dev/ [1]: https://marimo.io/
https://yoavmoshe.com/blog/learning-swedish-with-sway-and-an...
Rather than using this as a heuristic, couldn't you simply use this whenever you need to determine the width of a string? Write it to the terminal, if it ends up going farther than you expected, then you need to wrap it somewhere. I used a trick like this at one point after I got annoyed with wcwidth.
Of course that would lead to not recognizing weird color codes and so on, but perhaps there could be a plugin system, where one could add a plugin that transforms color codes and such in the output into XML tree representation.
And then one could perhaps log the whole thing in various formats: Only visible text with colors, without colors, whole XML tree, or as JSON, or whatever other format it translates well to. Also could be extended via plugin.
But bare bones it merely treats everything as text.
Not just emojis. Recently I've had some fun trying weird Unicode characters in different terminals (e.g. 𒐫):
- QTerminal/Konsole: Tofu
- Xfce terminal: Results in overlaps with characters that comes after it.
- Alacritty: Similar to Xfce terminal, but glitches when the cursor/glyph moves.
- COSMIC term: No overlapping glyphs, except that the line then wraps only after it grows out of screen.
- Kitty/WezTerm: Scales the glyph to fit it into a single column. (Barely legible.)
I don't even known what to expect. It is indeed a mess over there.
For layout concerns, fractions are probably a more natural fit (things like 1/3), but Decimal is a great floating point default for a lot of problems. They aren't exact, but a lot of the "normal" floating point weirdness goes away and your results look a lot more human. Highly recommend if you don't have a perf reason not to.
I'm adding that to my CLI project. https://youtu.be/NxsaHxON350?si=319RyQPsb5AVDQj9
Thanks to textualize, I can interact with the external world with full control in a black box.
If you care about accessibility even one bit, for the love of god, please, don't use any of the features this post mentions.
Things like animation or unicode diagrams break screen readers in horrible ways.
their slow as hell and incredibly inefficient to build graphics on top of
> but many are powered by the same graphics technologies used in video games
what does that mean? obviously they have to render text to graphics at some point
> The first trick is "overwrite, don't clear". If you clear the "screen" and then add new content, you risk seeing a blank or partially blank frame for a brief moment.
> The second trick would be to write new content in a single write to standard output.
its just luck when any of these work
> The third trick would be to use the Synchronized Output protocol;
this could work...
> With these three tricks in place you can create very smooth animation as long as you can deliver updates at regular intervals. Textual uses 60fps as a baseline. Any more than that probably isnt going to be noticeable.
no, anything above 60hz will be noticeable more smooth and less laggy. also this isnt a question about bigger=better. youll notice jank even if you run 75fps on 60hz or 60fps on 75hz, and of course with unsynchronized rendering there will be jank and other artifacts even with Xfps on Xhz.
> Now that you can have smooth animation in the terminal, the question becomes should you?
nothing you demonstrated was smooth, just better than current broken (terminal) shit. and no, because the thing terminals miss out on is being able to scroll at just a constant pixel/time rate and actually follow the mouse precisely and without lag. as you can see in the video you cant do this because the terminal cant do this period because they can only move one font width/height per step. then if we actually explore this issue well soon find out a 125hz mouse polling rate adds tons of jank, and well discover 60hz is too slow to be smooth even with perfect sync, then that you need a CRT to have legible text at such a slow framerate. your video looks like a slightly faster windows 3.0. which is good for a terminal, but bad compared to what graphics could do even 20 years ago (at 60hz), no your not scrolling at 60hz, because thats impossible in the terminal.
none of this means i want what Windows / GTK / KDE / android / ... came up with where you press a button and the program then starts slowly animating something like its (ironically) a type writer instead of just doing what i said. you lose your position in scrolling because its done wrong, the "smooth scrolling" shit in firefox or whatever is just a poor (oblivious) attempt at the solution
Related
Advanced text features and PDF
The post explores complex text features in PDFs, covering Unicode, glyph representation, kerning, and font challenges. It emphasizes tools like Harfbuzz and CapyPDF for accurate text handling in PDFs.
Beyond monospace: the search for the perfect coding font
Designing coding fonts involves more than monospacing. Key considerations include hyphens resembling minus signs, aligning symbols, distinguishing zero from O, and ensuring clarity for developers and type designers. Testing with proofing strings is recommended.
Chr – terminal editor inspired by Turbo Pascal editor from 1997
A terminal-based text editor "chr" on GitHub mimics desktop editors' shortcuts, blending modern GUI with retro text mode. Developed with Tui Widget, it welcomes contributions. Installation involves cloning, building, and compiling.
Entering text in the terminal is complicated
The article delves into text input complexities in terminals, categorizing input modes and offering tips like using Ctrl+A for line navigation. Understanding input systems enhances efficiency in the command line.
How I Program in 2024
Kartik Agaram reflects on his programming journey, advocating for minimalist software design, emphasizing simplicity, context awareness, and the potential benefits of data-oriented design to improve software quality and adaptability.