Home - OXY2DEV/ui.nvim GitHub Wiki
💻 ui.nvim
A blueprint/template/guide for ricing Neovim's UI using Lua
.
📚 Table of contents
📐 Architecture
ui.lua ─── vim.ui_attach() ┬┬─> cmdline.lua ──> handle() ──> state change ──> __render() | __close()
│└─> message.lua ──> handle() ──> __add() | __replace() | __confirm() | __list() ──> __render()
└──> popup.lua ──> handle() ──> state change ──> __render()
───> linegrid.lua ──> handle()
For the sake of making things easy to understand and simple to debug/test, the plugin follows a simple tree-like file structure.
It's flow is also linear(in most cases).
You can visualize the files like so,
nvim
↓
plugin/ui.lua
│ ↓
│ ui.lua ┬┬┬─> cmdline.lua
│ ││└─> message.lua
│ │└──> popup.lua
│ └───> linegrid.lua
│
│ ─> log.lua ─> # Logger connects to all the files.
│ <─ utils.lua <─ # Utilities are used by all other files.
│
└─> highlight.lua
To prevent needing to call
setup()
, the setup function gets called inplugin/ui.lua
. Also, everything is loaded afterVimEnter
to reduce load time.
Everything starts at the vim.ui_attach()
function in ui.lua
. The UI events captured by it gets sent to one of the sub-modules(ui/cmdline.lua
, ui/message.lua
, ui/popup.lua
, ui/linegrid.lua
).
A map(see here) is used to determine the sub-module an event is supposed to go to.
📝 Event handling
Each sub-module has a handle()
function for handling various event types. A setup()
function may optionally exist within the sub-module(s) that will get called when the plugin loads.
Event callbacks wrapped in a pcall()
to prevent internal errors from disrupting the user.
🔰 Command-line
The command-line(aka cmdline.lua
) sub-module works by updating a command-line state variable(see here).
The state later gets read by the __render()
function which populates a buffer with the necessary lines of text. This buffer then gets shown in a window.
In most cases the
__render()
function gets scheduled(instead of immediately executing). However, when commands have previews(e.g.:s/
) it gets executed immediately.
🔰 Messages
The messages sub-module(aka message.lua
) works by using a table(see here) to store messages.
Messages initially gets stored in the
message.visible
table which represents the messages that will be shown to the user. Each message entry later gets removed from this table, which hides them from the user.Most messages gets also stored in
message.history
table. You can view them via:messages
command and using the internal message history.
🔰 Completion
The completion sub-module(aka popup.lua
) is used to show completions. It works by maintaining a completion state(like the command-line).
When __render()
gets called it reads each entry in the completion menu and writes them to a buffer which gets shown in the completion/pop-up window.
🔰 Line-grid
Currently has no use.