-
Notifications
You must be signed in to change notification settings - Fork 4
Home

A blueprint/template/guide for ricing Neovim's UI using Lua
.
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.
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.
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.
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.
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.
Currently has no use.