Live data from Hacker News

Things I've learned building a modern TUI Framework (2022)

textualize.io

71–80 of 127 posts

Re: Things I've learned building a modern TUI Framework (2022)

#71
post #38

Earlier quoted context omitted.

> Textual internally keeps a browser like DOM structure, which means it could in theory offer browser-like support for screen readers while keeping all the features offered to sighted user. But it would require a protocol to allow the app to send structured information so that the screen reader has more to work with than a matrix of characters. Isn't it possible to expose this content via a publicly accessible API th…

De nada! > Isn't it possible to expose this content via a publicly accessible API that screen readers could simply hook into? Definitely possible from a technical standpoint, but I don't know of anyone who has done that. Maybe one day, Textual could provide that solution.

> Definitely possible from a technical standpoint

Yes and no, it would be possible, but only if the terminal emulator, the operating system's accessibility API, the screen reader and the library supported it. The library needs to output the right information via escape codes, the terminal emulator needs to expose it via the OS API, the OS API needs to have support for it, and the screen reader needs to know what to do with the information. I believe you could wrangle the existing a11y APIs and make it work, but you'd still need to implement support for it in emulators, libraries and screen readers. Not to mention that you'd actually have to design the standard and write a spec for it.

This would be slightly easier to do for terminal screen readers, which run directly inside a terminal emulator (kind of like Tmux) and pass most commands and keys unmodified, generating speech in the meantime.

Re: Things I've learned building a modern TUI Framework (2022)

#72
post #53

This TUI looks pretty, but I cannot imagine situation, when I would actually use it and be ready to pay for it. Probably I am not living in a right environment for it. But in my experience, either people are happy with something truly minimalistic or they try to please a user with GUI right away. For example, YouTube link in the article showed a possibility to display table with highlighting cells. Why would I need t…

The use case is something like medical billing entry where people are trained to know all of the billing codes and they still use an AS400 green screen console. The employees work by keyboard shortcuts and are extremely efficient, and every time someone tries to replace the AS400 with a modern web app, their productivity drops 100x. It’s the same scenario as a vim/emacs wizard vs a slick looking GUI that doesn’t have…

The solution to manual medical billing is to have computers do the billing. The system can be configured via GUI with rules about billing codes, payers, DX codes, etc. and then the rest of the system Just Does It.

(I work at a company automating medical billing.)

Re: Things I've learned building a modern TUI Framework (2022)

#74
> There is a heuristic where you write various sequences and ask the terminal for the cursor position, which should make an educated guess as the Unicode version. Unfortunately from testing we've discovered that terminals still render emoji unpredictably even if you think you know the Unicode database used.

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.

Re: Things I've learned building a modern TUI Framework (2022)

#75
RE Fractions, for _many people_, decimal.Decimal will work very well.

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.

Re: Things I've learned building a modern TUI Framework (2022)

#77
> terminals are fast

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

Re: Things I've learned building a modern TUI Framework (2022)

#78
post #9

It's funny how every TUI developer eventually stumbles over Unicode and then handling international characters and emojis correctly turns into its own project close to the same scope of (or even bigger than) the original TUI project. It happened to me on rivo/tview and through the resulting rivo/uniseg package, I learned that all other TUI library maintainers deal with the same issues. Finally, everyone invents their…

Are there any libraries in place which can normalize all emojis down to a single symbol?

It doesn't matter; what matters is that both your (terminal-manipulating) program and terminal emulator agree on the symbols widths. Considering that they usually won't (lots of terminal emulators have their own hand-crafted, statically linked wcwidth/wcswidth functions; the readline library also has them hard-coded, by the way), it's quite frustrating.

Re: Things I've learned building a modern TUI Framework (2022)

#79
post #65
post #58

Earlier quoted context omitted.

If you think that react (and FRP in general) is not a good way to build UIs, what is, in your opinion?

I don't agree that React is FRP. FRP is a generic solution that builds data-UI synchronization around data, and assumes that incremental UI updates will be written in UI code. React puts data-UI synchronization code inside UI components and provides an Immediate Mode-like API to avoid writing incremental updates in UI code.

In your world, the incremental UI code lives in the react library, and react applications aren’t UI code, they’re just FRP data transformations.

Re: Things I've learned building a modern TUI Framework (2022)

#80
post #9

It's funny how every TUI developer eventually stumbles over Unicode and then handling international characters and emojis correctly turns into its own project close to the same scope of (or even bigger than) the original TUI project. It happened to me on rivo/tview and through the resulting rivo/uniseg package, I learned that all other TUI library maintainers deal with the same issues. Finally, everyone invents their…

The state of the art here is to detect mode 2027, and enable it when supported. This lets you know the terminal will handle graphemes properly. I maintain two TUI libraries which use this technique and emoji support has been (nearly) great. (One of which uses your uniseg library!) https://mitchellh.com/writing/grapheme-clusters-in-terminals

I personally don't think this mode is all that very useful, to be fair. First of all, the grapheme clustering is not set in stone, it's been changed from one Unicode standard version to other.

Second, and this is mostly because my personal use cases are very humble, a much, much simple to implement workaround, for everyone involved, would be a couple of OSC sequences which would mark a part of output text as the prompt (when terminal is in canonical/cooked mode), so that a huge chunk of readline could be simply thrown away.

So your program could just print a prompt, and then simply read the cooked line. In the meanwhile, the terminal emulator would handle line editing, line-wrapping and asynchronous output: if you keep outputing text to the terminal while a prompt is active, the terminal would clear the prompt and the unfinished line, print the text, then re-display the prompt and the line; basically what all "async readline" libraries do already with rl_clear/rl_redisplay — but doing it in the terminal would take care of this properly, because the terminal definitely knows how wide all the symbols it itself thinks are. And the tab completion could be supported by returning a -terminated line to the program, instead of an -terminated line.

Unfortunately, I don't think something like this can actually become even moderately widely adopted.

Edit: Or, you know, maybe we could extend terminfo? Like, introduce twcswidth() function that would take your string, and the somehow encoded Unicode grapheme clustering data that the current terminal is actually using which you can query from terminfo, and return the number of screen cells it would take on this terminal.

Post reply on HN