btv.view
btv.view.component(def)
btv.view.component(def) — the view-backed component (a focus-taking btv.view buffer): the
common case (file tree, list, modal dialog). Sugar over btv.component with the view
backend; mount(opts) takes the view surface options (name / filetype / dock / split /
float), plus persist = "<id>" (+ optional namespace) to make the view survive a
restart — see the Persistence note on btv.component above.
Defined in component.lua.
btv.view.actions.confirm()
No documentation comment in the prelude.
Defined in view.lua.
btv.view.create(opts)
btv.view.create{ name?, filetype?, persist?, namespace? } -> handle. Mints the backing
read-only buffer (off-screen until mounted) and returns the handle. filetype drives
treesitter / decoration on the view buffer.
persist opts the view into cross-session restore: it is a stable, plugin-chosen string
id (instance-unique within the plugin) that core round-trips through the workspace
session — recording only (namespace, id) + the view’s slot, never its content. On
restore core reserves the slot and hands the id back via btv.view.on_restore, and the
plugin (which keyed its own btv.shada.plugin() store by the same id) rebuilds the
content. Absent ⇒ the view is ephemeral (today’s behavior — not persisted). The owning
namespace is auto-derived from the calling plugin’s location (same resolver as
btv.shada.plugin()); opts.namespace is the escape hatch for a context that attributes
to no runtimepath entry (a bare :lua / RPC / test) and is an error from a real plugin
file — exactly the btv.shada.plugin(dev_namespace) contract.
Defined in view.lua.
btv.view.pending_restores()
btv.view.pending_restores() -> the views a session restore reserved a slot for but that
no plugin has adopted yet, each { namespace=, id=, win= } (win is the reserved
window). The pull primitive behind btv.view.on_restore and the black-box test hook.
Refreshed each tick from core’s btv._view_pending mirror.
Defined in view.lua.
btv.view.on_restore(fn, namespace)
btv.view.on_restore(fn[, namespace]) — register THIS plugin’s restorer for persisted
views, AND immediately claim any slot already reserved for it. After a session restore,
core reserves a slot (a placeholder window) for every persisted view the plugin had open;
each reserved slot whose owning namespace matches is dispatched to fn(id, place):
idis the plugin-chosen persist string (the same one passed tocreate{ persist=}),place(view)drops a freshly-created view into the reserved window. The plugin keyed its ownbtv.shada.plugin()store byid, so it reads its saved state back and rebuilds the view’s content before callingplace. The owning namespace is resolved from the caller’s location; the optionalnamespacearg is the escape hatch for a no-attribution context (a bare:lua/ RPC / test), the same contract as create’s.
Call it whenever the plugin has finished loading — it is safe to register LATE. A plugin
loaded via btv.plugins({ config = … }) runs its config (and this call) on a tick after
the server’s boot restore dispatch, so that pass never sees its handler; the drain-now loop
below adopts the still-reserved slot at registration time instead. (Slots are reserved at
shada_load, before any plugin code runs, so they are already present in the live
btv._view_pending mirror whenever this is called.) Orphan slots are not reaped until every
eager plugin load has settled (see btv._maybe_collapse_view_restores), so a late handler
reliably gets its chance.
Defined in view.lua.
view:set_lines(lines)
:set_lines(lines) — replace the view’s content wholesale.
Defined in view.lua.
view:set_userdata(list)
:set_userdata(list) — opaque per-line data, parallel to the lines (1-based). The
entry for the selected line is handed to on_select. Pure Lua state.
Defined in view.lua.
view:on_select(fn)
:on_select(fn) — fn(line, userdata) fires on <CR> / confirm / double-click, with
the 1-based cursor line and that line’s userdata entry.
Defined in view.lua.
view:on_close(fn)
:on_close(fn) — fn() fires when the USER closes the view’s window (:q / :close /
<C-w>c on the view buffer), letting the owner tear down a group of related views
(e.g. close every diff pane when one is :q’d). It does NOT fire on a programmatic
:unmount() / :close() — only the user close path records it — so the handler can
freely close other views without recursion. Pure Lua state.
Defined in view.lua.
view:bufnr()
:bufnr() — the backing buffer number (from the mirror), or false before the
view’s buffer exists: it is created after the chunk that creates the view. false,
not nil, so it can’t pass for an absent option: { buffer = view:bufnr() } would
otherwise read as “no buffer” and bind globally. The buffer APIs refuse false
loudly. Wait for the number with
btv.wait_for(function() return view:bufnr() end), or give btv.keymap.set the
view itself ({ buffer = view }), which binds once the buffer exists.
Defined in view.lua.
view:winid()
:winid() — the window currently showing the view (from the mirror), or nil while the
view is unmounted. The target for window-local options (vim.wo[winid]).
Defined in view.lua.
view:set_decor(ns, marks)
:set_decor(ns, marks) — replace namespace ns’s decoration on the view buffer
with marks. Each mark is { line, col, <extmark opts> } (0-based line/col,
then any nvim_buf_set_extmark opt: hl_group, end_col, virt_text,
sign_text, gutter_text, priority, …). A no-op (warned) before the buffer exists.
Defined in view.lua.
view:mount(opts)
:mount(opts) — show the view. opts.dock = "left"|"right"|"top"|"bottom" mounts it in
that dock (opts.size columns/rows); opts.tab = true mounts it as the sole window of
a fresh tab page (no split — the view fills the tab; closing it closes the tab);
opts.split = "vsplit"|"split" mounts it in a split of the main editor area;
opts.here = true mounts it in the current window, in place of what that shows (no new
window or tab: :q of a sole window quits the editor);
opts.float = { … } mounts it in a floating window. Mounting focuses the view.
The float table takes width / height (inner size; required) — cells (a
number) or a viewport fraction ("50vw" / "30vh" / "50%"), which reflows on
resize — relative ("editor"|"win"|"cursor", default "editor"; "editor" is
the WHOLE screen, dock bands included, so a centered float centers on the screen
rather than on whatever region happens to be focused), and either the
high-level align ("top-left"|"top"|"top-right"|"left"|"center"|"right"|
"bottom-left"|"bottom"|"bottom-right") + margin (a gap from the edges: a number
— the vertical gap, the horizontal sides getting 2x to look even since cells are
~2x taller than wide — or an explicit {vertical, horizontal} / {top, right,
bottom, left} / {top=, …}), or the
low-level anchor ("NW"|"NE"|"SW"|"SE", default "NW") + row / col (offset,
default 0). Plus border (default "rounded"), title, zindex, focusable, and
grab. grab (default true) hard-locks focus to the float
like the bottom panel — <C-w> can’t leave it and unmount restores the prior window —
which is what a modal dialog (a checkbox list, a confirm) wants; pass grab = false for
a non-modal floating panel that focus can leave.
Defined in view.lua.
view:place_in(win)
:place_in(win) — retarget window win to this view’s backing buffer, instead of
opening a fresh window like :mount: a session restore’s reserved slot (a placeholder
window for a persisted view), or any other. This is what the place
argument handed to an btv.view.on_restore handler calls
(place = function(view) view:place_in(win) end), so a plugin rarely calls it directly.
Defined in view.lua.
view:unmount()
:unmount() — remove the view from view, keeping it (and its content) alive for a
later :mount.
Defined in view.lua.
view:focus()
:focus() — move focus to the window showing the view.
Defined in view.lua.
view:line()
:line() — the view’s 1-based cursor line (from the mirror), valid while the view
is focused. nil before the buffer exists.
Defined in view.lua.
view:cursor()
:cursor() — the view’s cursor as (line, col). col is always 0 in v1 (a view’s
cursor rests at column 0); the line is :line().
Defined in view.lua.
view:set_cursor(line)
:set_cursor(line) — focus the view and move its cursor to 1-based line (clamped
to the content; column 0). The reveal / find-file primitive — the one sanctioned
cursor write; ordinary navigation is plain normal-mode motion.
Defined in view.lua.
view:redraw()
:redraw() — request a repaint. The editor already repaints at the end of every
input batch / drained chunk, so this is a no-op kept for API completeness (and so
a plugin can express intent at the call site).
Defined in view.lua.
view:close()
:close() — unmount the view and drop its backing buffer and registry entry.
Defined in view.lua.