I'm happy more people are interested in this critique! And thanks for d12frosted for joining the discussion.
I was searching for what's the latest in emacs widgets developments because I was interested in using widgets. Emacs Customize for example, renders text-based widgets in an editable buffer, which is very uncommon nowadays. Emacs seems like the best candidate for this kind of interactivity. I'm sure it's possible in other editors, but with significantly more effort and significantly slower rendering. I also considered lem, but the barrier also seems much higher.
His post also led me to his vui.el project, but I ended up not trying it, since after understanding the tradeoffs, I pushed the widget code creation to an LLM. I still get frequent unbalanced parentheses errors so I still stay close to the defaults.
The PoC is about testing a method to render a widgets-based, json-schema-validated input form that you can embed dynamically into an emacs buffer, enter the data, then do something post-validation. If anyone's interested, here's the latest state of the LLM-generated and human-fixed code: https://gist.github.com/whacked/6875c5117b48528e619755e13e24...
When drawing outlines, tables, etc, I hope the new approach (vui) uses real Unicode box-drawing characters and not - | + etc. It's high time TUI people raise their standards a bit and consider unbroken lines (no gaps) a requirement rather than a luxury!
For those interested, this guy is revamping the Emacs widget library with something more modern and platform agnostic, based on SDL: https://appetrosyan.github.io/posts/
Interesting, thanks for sharing! I've had thoughts about making vui.el backend-agnostic so it could target different widget implementations (like xwidgets or even native-GUI). An SDL-based widget library could potentially be one of those backends. Need to dig into appetrosyan's work before I can say anything intelligent about it though. And of course, it was an idea and I am unlikely to dive deep without practical need (time is limited, sadly).
Yes, copied it in to my scratch buffer to read it, not readable in the browser at all with a dark background. It did then make all the elisp nice to look at.
I clicked through hoping you were wrong, saw the first page, and thought, ah, this is legible... then I got to the code blocks and was completely blinded.
I'm not sure what to tell authors of such pages...
I only have a limited experience with GUI Widgets - by using JavaFX through `cljfx`
- vui.el seems like the right idea - You have a widget library, and then you add state management, you add layout management etc. It's sort of a blessing widget is simple enough to be reused this way
- ECS and inheritance. I have personally never really hit on this limitation. It's there in the abstract.. but don't GUIs generally fit the OO paradigm pretty well? Looking at the class tree for JavaFX, I don't see any really awkward widgets that are ambiguously placed.
- State Management. This can be bolted on - like with vui.el. But to me this feels like something that should be independent of GUIs. Something like Pathom looks more appealing to me here
- "Not a full reactive framework - Emacs doesn't need that complexity" .. why not? Maybe the library internals are complex, but it makes user code much simpler, no?
On vui.el's approach - yes, the blessing is that widget.el is simple enough to build on. It does the "rendering" and some "behaviour", vui.el handles the rest.
On ECS vs OO - I'll admit I don't have enough experience to speak about UI paradigms in general. But my critique of widget.el is that inheritance hierarchies don't compose well when you need orthogonal behaviors. Composition feels more natural to me - could be just how my brain works, but it scales better in my experience.
On state management being independent - I'd be curious to hear more. Pathom is interesting for data-driven architectures. vui.el's state is intentionally minimal and Emacs-native, but you're right it could potentially be decoupled further.
On "why not full reactive" - to clarify what vui.el has: React-style hooks with explicit dependency tracking (vui-use-effect, vui-use-memo, etc.), state changes trigger re-renders, batching for multiple updates. What it doesn't have: automatic dependency inference or fine-grained reactivity where only specific widgets update. The tradeoff was debuggability - explicit deps are easier to trace than magic. But I'm open to being wrong here. What would you want from a reactive layer?
> The buffer is the UI, rendered by Emacs's extremely optimised text display machinery
Doesn't emacs lag like crazy in files with large lines. Why is this still a problem? Every modern editor handles this gracefully. I remember reading something about using regexes for syntax highlighting. This looks like a problem in the rendering layer which shouldn't be too hard to fix without touching the core engine. Are there any other problems that make it difficult to fix without disabling any useful features?
The long-line issue is real, though my statement was specifically about building UIs with widgets/overlays/text properties - not handling arbitrary files. In that context, Emacs's display engine is genuinely well-optimized: it handles overlays, faces, text properties, and redisplay regions efficiently.
When you're building a UI, you control the content. Lines are short by design (form fields, buttons, lists). The pathological case of a 50KB minified JSON line simply doesn't occur.
The long-line problem stems from how Emacs calculates display width for bidirectional text and variable-pitch fonts - it needs to scan the entire line. That's orthogonal to rendering widgets or interactive buffers.
Right- but if you have a long line that is, for example, a JSON object, then surely it can't be properly be validated or syntax-highlighted before the entire line is scanned?
I do agree that Emacs can be slower than the terminal when handling long lines/files, although (depending on your case) this can be easily mitigated by running a terminal inside of Emacs.
Generally though, for everyday use, Emacs feels a lot snappier than VSCode.
Good point. Though for widget UIs you're typically rendering structured data you control, not parsing arbitrary text files. The syntax highlighting / validation concern applies to editing code, not to building interactive interfaces.
> Generally though, for everyday use, Emacs feels a lot snappier than VSCode.
The buffer is the UI, rendered by Emacs's extremely optimised text display machinery
The author is known in the community as a mere packager whose knowledge of the nitty-gritty derives entirely from hearsay. Perhaps he read the long-winded preamble to xdisp.c written in 1995 boasting of all manner of optimisations. But they were written so long ago, almost no one believes most of them matter anymore, what with thirty years of bitrot.
So long mode is the best fix for this issue but it disables syntax highlighting and line numbers. Vscode can handle long lines just fine without disabling anything.
I'm happy more people are interested in this critique! And thanks for d12frosted for joining the discussion.
I was searching for what's the latest in emacs widgets developments because I was interested in using widgets. Emacs Customize for example, renders text-based widgets in an editable buffer, which is very uncommon nowadays. Emacs seems like the best candidate for this kind of interactivity. I'm sure it's possible in other editors, but with significantly more effort and significantly slower rendering. I also considered lem, but the barrier also seems much higher.
His post also led me to his vui.el project, but I ended up not trying it, since after understanding the tradeoffs, I pushed the widget code creation to an LLM. I still get frequent unbalanced parentheses errors so I still stay close to the defaults.
The PoC is about testing a method to render a widgets-based, json-schema-validated input form that you can embed dynamically into an emacs buffer, enter the data, then do something post-validation. If anyone's interested, here's the latest state of the LLM-generated and human-fixed code: https://gist.github.com/whacked/6875c5117b48528e619755e13e24...
When drawing outlines, tables, etc, I hope the new approach (vui) uses real Unicode box-drawing characters and not - | + etc. It's high time TUI people raise their standards a bit and consider unbroken lines (no gaps) a requirement rather than a luxury!
Argh, a few screenshots would’ve been nice. There’s none to be found in vui.el’s repository.
Agreed, especially since org-mode (which I bet this blog post was written in) supports (inline) images in its exporters.
For those interested, this guy is revamping the Emacs widget library with something more modern and platform agnostic, based on SDL: https://appetrosyan.github.io/posts/
His posts are very insightful.
Interesting, thanks for sharing! I've had thoughts about making vui.el backend-agnostic so it could target different widget implementations (like xwidgets or even native-GUI). An SDL-based widget library could potentially be one of those backends. Need to dig into appetrosyan's work before I can say anything intelligent about it though. And of course, it was an idea and I am unlikely to dive deep without practical need (time is limited, sadly).
This site is quite illegible if your system is set to prefers dark theme.
Yes, copied it in to my scratch buffer to read it, not readable in the browser at all with a dark background. It did then make all the elisp nice to look at.
~M-x eww~ works nicely too.
sorry for that! added a dark theme, feedback is welcome :pray:
I clicked through hoping you were wrong, saw the first page, and thought, ah, this is legible... then I got to the code blocks and was completely blinded.
I'm not sure what to tell authors of such pages...
easy :) ask for dark theme; will try to implement one soon ;)
update: added; turns out I almost finished it before on a local branch but didn't push to master
I only have a limited experience with GUI Widgets - by using JavaFX through `cljfx`
- vui.el seems like the right idea - You have a widget library, and then you add state management, you add layout management etc. It's sort of a blessing widget is simple enough to be reused this way
- ECS and inheritance. I have personally never really hit on this limitation. It's there in the abstract.. but don't GUIs generally fit the OO paradigm pretty well? Looking at the class tree for JavaFX, I don't see any really awkward widgets that are ambiguously placed.
- State Management. This can be bolted on - like with vui.el. But to me this feels like something that should be independent of GUIs. Something like Pathom looks more appealing to me here
- "Not a full reactive framework - Emacs doesn't need that complexity" .. why not? Maybe the library internals are complex, but it makes user code much simpler, no?
Good points, thanks for engaging thoughtfully.
On vui.el's approach - yes, the blessing is that widget.el is simple enough to build on. It does the "rendering" and some "behaviour", vui.el handles the rest.
On ECS vs OO - I'll admit I don't have enough experience to speak about UI paradigms in general. But my critique of widget.el is that inheritance hierarchies don't compose well when you need orthogonal behaviors. Composition feels more natural to me - could be just how my brain works, but it scales better in my experience.
On state management being independent - I'd be curious to hear more. Pathom is interesting for data-driven architectures. vui.el's state is intentionally minimal and Emacs-native, but you're right it could potentially be decoupled further.
On "why not full reactive" - to clarify what vui.el has: React-style hooks with explicit dependency tracking (vui-use-effect, vui-use-memo, etc.), state changes trigger re-renders, batching for multiple updates. What it doesn't have: automatic dependency inference or fine-grained reactivity where only specific widgets update. The tradeoff was debuggability - explicit deps are easier to trace than magic. But I'm open to being wrong here. What would you want from a reactive layer?
Oh, that's the guy who does `homebrew-emacs-plue` --- my preferred distribution of Emacs!
Thank whoever for posting this.
vui.el, nice!
> The buffer is the UI, rendered by Emacs's extremely optimised text display machinery
Doesn't emacs lag like crazy in files with large lines. Why is this still a problem? Every modern editor handles this gracefully. I remember reading something about using regexes for syntax highlighting. This looks like a problem in the rendering layer which shouldn't be too hard to fix without touching the core engine. Are there any other problems that make it difficult to fix without disabling any useful features?
The long-line issue is real, though my statement was specifically about building UIs with widgets/overlays/text properties - not handling arbitrary files. In that context, Emacs's display engine is genuinely well-optimized: it handles overlays, faces, text properties, and redisplay regions efficiently.
When you're building a UI, you control the content. Lines are short by design (form fields, buttons, lists). The pathological case of a 50KB minified JSON line simply doesn't occur.
The long-line problem stems from how Emacs calculates display width for bidirectional text and variable-pitch fonts - it needs to scan the entire line. That's orthogonal to rendering widgets or interactive buffers.
Right- but if you have a long line that is, for example, a JSON object, then surely it can't be properly be validated or syntax-highlighted before the entire line is scanned?
I do agree that Emacs can be slower than the terminal when handling long lines/files, although (depending on your case) this can be easily mitigated by running a terminal inside of Emacs.
Generally though, for everyday use, Emacs feels a lot snappier than VSCode.
Good point. Though for widget UIs you're typically rendering structured data you control, not parsing arbitrary text files. The syntax highlighting / validation concern applies to editing code, not to building interactive interfaces.
> Generally though, for everyday use, Emacs feels a lot snappier than VSCode.
+1
The buffer is the UI, rendered by Emacs's extremely optimised text display machinery
The author is known in the community as a mere packager whose knowledge of the nitty-gritty derives entirely from hearsay. Perhaps he read the long-winded preamble to xdisp.c written in 1995 boasting of all manner of optimisations. But they were written so long ago, almost no one believes most of them matter anymore, what with thirty years of bitrot.
Not every modern editor. Neovim bogs on long lines too.
https://emacs.stackexchange.com/questions/598/how-do-i-preve... has some answers (and solutions).
So long mode is the best fix for this issue but it disables syntax highlighting and line numbers. Vscode can handle long lines just fine without disabling anything.
so-long-mode is sophomoric garbage.