Skip to content

Feature request ⚡: attach to a UI client and consume redraw events #37

Description

@gorillamoe

Try if this is feasible to get the same functionality as we currently have.

This could open up the possibility to have the real representation of what the user sees in the complete Neovim instance, including:

  • Every visible grid
  • Exact cell contents
  • Highlight IDs
  • Window placement
  • Floating windows
  • Statuslines, tablines, cmdline, popupmenu
vim.api.nvim_ui_attach(width, height, {
  ext_linegrid = true,
  ext_multigrid = true,
  ext_hlstate = true,
  ext_termcolors = true,
})

Per redraw event we should get batches like this:

{
  { "grid_resize", grid, width, height },
  { "grid_line", grid, row, col, cells },
  { "grid_clear", grid },
  { "grid_cursor_goto", grid, row, col },
  { "win_pos", grid, win, row, col, width, height },
  { "hl_attr_define", id, rgb_attrs, cterm_attrs },
}

In each grid_line the cells contain:

{ text, hl_id, repeat }
  • Handles wide chars
  • Handles tabs
  • Already includes virtual text, folds, conceal, etc.

This is probably how the layout looks like:

Neovim Scene
├── Grid 1 (main window)
│   ├── Cell[row][col] → { text, style }
├── Grid 2 (statusline)
├── Grid 3 (floating LSP hover)
├── Grid 4 (cmdline)
  • Resolve win_pos → absolute screen coordinates
  • Paint grids back-to-front
  • Apply highlight attributes

This gets us:

  • Splits
  • Floats
  • Borders
  • Statuslines
  • Tabline
  • Cmdline
  • Popup menu

We should cache the highlight ids we receive, because they probably don't change:

hl_attr_define(id, {
  foreground = 0xRRGGBB,
  background = 0xRRGGBB,
  bold = true,
  italic = true,
  underline = true,
})

For caching, we might go with cache highlight ids by default and even reuse them for consecutive :Snap calls.

But we should implement a way to force the rebuilt of that cache.

This is probably an edge case scenario, but people who want to take snaps of themes or developer of themes might benefit from this, because here, the highlight ids might stay the same, but the styling might change "all the time".

I think the best way to approach this is by having the :Snap command not only work with :Snap [type] like :Snap image, but also parse additional arguments as key value pairs if it includes a =, or just consume them as instructions if no = is found.

So both :Snap image cache=false and :Snap image nocache would work.

I think, we should implement the complete parsing of arguments, but only go with the nocache instruction for this feature. This can also be extended afterwards, if needed.

Every cell references a highlight ID → CSS mapping.

Check if we can also track/query and resolve:

  • grid_cursor_goto
  • mode_change
  • busy_start / busy_stop
  • Cursor block rendering
  • Insert-mode caret
  • Blinking

No activity

Activity on this issue will appear here.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions