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)
endThe 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
- Add the prototype to
ui_events.in.h. UseBoolean/Integer/Float/String/Objectfor parameter types. - Run
make. The generator emitsui_call_my_event(...)and registers the metadata. - In the editor, call
ui_call_my_event(...)at the right moment. - Add a TUI handler in
tui.c(so the bundled UI doesn't break). - Document in the doc comment; the doc generator picks it up.
- Bump
NVIM_API_LEVELif 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.
Popup menu (ext_popupmenu)
| 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_attachplus the higher-levelvim.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.