Skip to content

refactor(renderer): rework view renderer (add cache, highlights)#302

Draft
nqrk wants to merge 34 commits intoj-hui:mainfrom
nqrk:feat-renderv2
Draft

refactor(renderer): rework view renderer (add cache, highlights)#302
nqrk wants to merge 34 commits intoj-hui:mainfrom
nqrk:feat-renderv2

Conversation

@nqrk
Copy link

@nqrk nqrk commented Jan 19, 2026

WIP

The title might be slightly inaccurate, but this pull request primarily refactors the rendering pipeline and includes changes to the notification poller.
Main focus is to bring up new features while trying to reduces memory usage.

I will update the desc soon™ to reflect recent changes..

nqrk added 9 commits January 19, 2026 03:41
Cache group separator, header and messages to reduce rendering work.

The renderer now reuse previous tokens when:
    - window was not resized (width)
    - same item count, icon or group name
    - tokens did not reach ttl expiration (see model.tick)
Lines are now rendered using array of words composed of only non-space characters.
Spacing is added on the fly by calculating the start and the end position of each words.
Fidget now automatically reflows lines that exceed max_width via word-break.
Annotes indentation is set by default to "annote" (see options.align)

This is the first step toward introducing tree-sitter highlight inside the renderer.
Related to j-hui#159
Implements tree-sitter highlight to rendered tokens.
Default highlight is set to "markdown_inline".

Toggle default notification highlight:
    - notification.view.highlight = string|false

Hide concealed markdown tags:
    - notification.view.hide_conceal = boolean
The highlight function can now reuse previously generated hl tokens.
@nqrk nqrk changed the title refactor(renderer): rework view renderer (+ cache, highlights) refactor(renderer): rework view renderer (add cache, highlights) Jan 19, 2026
@nqrk nqrk marked this pull request as draft January 20, 2026 21:54
nqrk added 15 commits January 31, 2026 04:48
Reorganise view render to return a "Notification".
This is the first step to introduce per-message options via notify.
Related to j-hui#244
Position of the text inside the window can be changed with:
    - notification.view.text_position = "left"|"right"

If in future change, we want to implement different window position or a double notification
window (by duplicating states), each message can be aligned independently under "eol" or "eol_right_align".
Related to j-hui#244
A notification can now have different visual properties.
This apply only to text inside the window, for now only one window is supported.

Users can now let each message be independently aligned to the left or right:
    - `vim.notify([[block of code]], nil, { position = "left" })`

Message header (group name, sep etc) takes value from config instead.
When editor size is cached and a notification is draw while "window.max_width" value changes,
the renderer still uses the previously cached width and lays out the lines based on a wrong value.
Lines would overflow when message position is set to "left" and max_width suddenly change without editor size changing.
Users can now let each message be independently highlighted with different language:
    - `vim.notify([[block of code]], nil, { lang = "lua" })`
Cached items are now properly dereferenced when unused.

When a notification reaches its ttl expiration it is removed from the cache.
When the notification window closes, all items (including headers) are cleared
from the cache except for the "default" group header and separator.
+ minor improvement with rehashing and table allocation inside the render loop.
Cache "highlights" queries and reuse them when parsing the same language.
+ minor improvement in the duplicate items detection loop.
Uses nvim "right_align" text position instead of computing padding ourselves.
Integrate with external plugins when loading window config.
Poller now allocates one timer and manages it throughout the entire fidget lifecycle.
Timer resources are freed after each reset of the notification subsystem state.
nqrk added 7 commits February 12, 2026 22:32
Polls frame time using high-resolution timestamps (in nanoseconds).
Converts "item.last_updated" to unix time before storing item to history buffer.
Removes repeated allocations caused by frequent accesses to editor column value.
Now updates cached columns only during window resize events, this reduces memory
usage inside the rendering loop (see view.window_max)
Add a lock to skip rendering when the state remains constant.

A constant state occurs when:
    - No notification changes (in groups)
    - Window id and dimensions remain unchanged

Now we render only when necessary and reduces the memory usage
during frequent polling with small poll rates.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant