Open-Source Wikis

/

Neovim

/

API

/

UI events

neovim/neovim

UI events

UIs (TUI, Neovide, vimr, gnvim, anything else) attach to the editor by calling nvim_ui_attach(width, height, opts). From that point the editor sends redraw notifications carrying batches of UI events. This page is a tour of the protocol; the canonical reference is runtime/doc/api-ui-events.txt.

The attach handshake

local nvim_ui_attach = function(opts)
    -- opts is a dict; common flags:
    --   ext_linegrid      = true   (modern grid protocol; almost always set)
    --   ext_multigrid     = true   (one grid per window)
    --   ext_popupmenu     = true   (UI draws the popup menu)
    --   ext_tabline       = true   (UI draws the tabline)
    --   ext_cmdline       = true   (UI draws the command line)
    --   ext_wildmenu      = true
    --   ext_messages      = true   (UI receives messages as events)
    --   ext_termcolors    = true   (UI tells the editor what 16 ANSI colors to render)
    --   stdin_fd, stdin_tty, stdout_tty
    --   override = false           (replace any existing UI of the same kind)
end

The opts dict signals which "extensions" the UI handles. For each extension the UI opts into, the editor sends events of that category instead of attempting to render that surface itself. A bare TUI typically only sets ext_linegrid.

After attach, the editor sends a single redraw notification containing every UI event for the current state. Subsequent notifications carry deltas.

Where it lives

  • src/nvim/api/ui_events.in.h — prototype list. Not compiled directly.
  • src/gen/gen_api_ui_events.lua — generator. Produces the per-event server-side dispatch and metadata.
  • src/nvim/ui.c — server-side multiplexer. ui_call_<event> enqueues the event and dispatches to attached UIs.
  • src/nvim/api/ui.c — RPC bridge. Encodes events as msgpack notifications.
  • src/nvim/tui/tui.c — the TUI consumer.
  • runtime/doc/api-ui-events.txt — generated docs.

Adding an event

  1. Add the prototype to ui_events.in.h. Use Boolean / Integer / Float / String / Object for parameter types.
  2. Run make. The generator emits ui_call_my_event(...) and registers the metadata.
  3. In the editor, call ui_call_my_event(...) at the right moment.
  4. Add a TUI handler in tui.c (so the bundled UI doesn't break).
  5. Document in the doc comment; the doc generator picks it up.
  6. Bump NVIM_API_LEVEL if it hasn't already been bumped this cycle.

runtime/doc/dev_arch.txt cites commit d3a8e9217f39c59dd7762bd22a76b8bd03ca85ff as a worked example of adding a UI event.

Event categories

Grid (always on)

The default rendering protocol. ext_linegrid enables the modern variant, and as of v0.10 it is on by default for any UI that doesn't explicitly opt out.

Event Meaning
grid_resize(grid, width, height) Grid was resized.
grid_clear(grid) Clear the grid.
grid_line(grid, row, col_start, cells, wrap) Update a run of cells. The hot-path event.
grid_cursor_goto(grid, row, col) Move the cursor.
grid_scroll(grid, top, bot, left, right, rows, cols) Scroll a region.
grid_destroy(grid) A previously-announced grid is gone.
default_colors_set(rgb_fg, rgb_bg, rgb_sp, cterm_fg, cterm_bg) Default colors.
hl_attr_define(id, rgb_attr, cterm_attr, info) Define an attribute id used by grid_line.
hl_group_set(name, id) Map a highlight group name to an id.

grid_line is the busy event. It carries an array of cells; each cell is [text, hl_id (optional), repeat (optional)]. UIs decode it into their own buffer.

Multigrid (ext_multigrid)

Adds events for per-window grids and float positioning:

Event Meaning
win_pos, win_float_pos, win_external_pos Position a window's grid relative to the screen.
win_hide, win_close Hide / destroy a window grid.
win_viewport, win_viewport_margins Viewport metadata for a window.
msg_set_pos Position the message grid (status line area).

When a UI doesn't opt into multigrid, the server runs ui_compositor.c to flatten everything onto a single grid before sending events.

Event Meaning
popupmenu_show(items, selected, row, col, grid) Open the menu.
popupmenu_select(selected) Selection changed.
popupmenu_hide() Close.

The completion menu and inputlist() all flow through here.

Cmdline (ext_cmdline)

Event Meaning
cmdline_show, cmdline_pos, cmdline_special_char, cmdline_hide Command-line state.
cmdline_block_show, cmdline_block_append, cmdline_block_hide Multi-line :if ... :endif style.

Messages (ext_messages)

Event Meaning
msg_show(kind, content, replace_last, history, append) A message.
msg_clear() Clear the area.
msg_history_show(entries) The :messages history.

When ext_messages is set, the message area is owned by the UI.

Tabline (ext_tabline)

Event Meaning
tabline_update(curtab, tabs, current_buffer, buffers) Tab-bar state.

Wildmenu (ext_wildmenu)

Event Meaning
wildmenu_show, wildmenu_select, wildmenu_hide Cmdline completion popup.

Mode and status

Event Meaning
mode_change(mode, mode_idx) Mode changed (MODE_NORMAL, MODE_INSERT, ...).
mode_info_set(cursor_style_enabled, mode_info) Cursor styles per mode.
busy_start, busy_stop The editor is busy / done.
mouse_on, mouse_off Cursor visibility hints.
bell, visual_bell Bells.
flush() Flush buffered events. UIs should redraw at this point.

Misc

Event Meaning
set_title(title), set_icon(icon) Window title and icon name.
option_set(name, value) An option that affects display has changed.
update_menu() The menu (Vim's :menu) has been edited.
suspend(), update_fg/bg/sp Older events; mostly compatibility.

Flush

Events arrive in batches in a single redraw notification. The events within a batch are not all rendered immediately by the UI — the convention is to apply them to internal state, and only paint to the screen when the flush event is seen. This is what makes complex updates atomic from the user's perspective.

ui_attach (Lua)

The same protocol is exposed in-process via vim.ui_attach(namespace, {ext_*=true}, callback). The callback receives (event_name, ...) for every UI event matching the requested extensions. Used by tests (test/functional/ui/screen.lua) and by Lua plugins that re-render some surface in their own way.

See also

  • TUI — the consumer side of this protocol.
  • API and msgpack-rpc — how events are dispatched on the wire.
  • UI providers (vim.ui)vim.ui_attach plus the higher-level vim.ui.* overrideable primitives.
  • runtime/doc/api-ui-events.txt — generated reference.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

UI events – Neovim wiki | Factory