116 lines
3.7 KiB
Text
116 lines
3.7 KiB
Text
---
|
|
.title = "Minimodes",
|
|
.date = @date("2025-10-15T00:00:00"),
|
|
.author = "Igor Támara",
|
|
.layout = "tutorial.shtml",
|
|
.draft = false,
|
|
.custom = {
|
|
.githubedit = "/docs/architecture/minimode.smd",
|
|
.codepath ="src/tui/mode/mini/",
|
|
},
|
|
---
|
|
|
|
Minimodes add functionality to the editor, are opened for short periods
|
|
of time and have their own set of keybindings to execute an specific
|
|
action, i.e. find something in the current buffer or in project files,
|
|
open/save a file, and, in modal modes(like vim and helix), as receiving
|
|
a number as a prefix to repeat an action many times.
|
|
|
|
[]($section.id("anatomy"))
|
|
## Anatomy of minimodes
|
|
|
|
To create a minimode it's needed:
|
|
|
|
* A Keybinding
|
|
* An Action mapping
|
|
* A Minimode definition
|
|
|
|
[]($section.id("keybind"))
|
|
### Keybinding
|
|
|
|
When a key or a keystroke(set of keys) are pressed, the associated
|
|
minimode gets activated and will start to capture the key/strokes
|
|
until a special keybinding makes it exit, or an specific action exits
|
|
the minimode. Head to `src/keybind/builtin/flow.json`(flow keybinds)
|
|
and look for `mini_find`, where you will know which specific actions
|
|
are triggered by the keybindings of the `find` minimode.
|
|
|
|
[]($section.id("mapping"))
|
|
### Action mapping
|
|
|
|
Actions executed by each minimode are stored one per file under
|
|
`src/tui/mode/mini/`. The command that opens the door to the minimode
|
|
is linked from `src/tui/tui.zig` which calls the minimodes dynamically
|
|
when needed.
|
|
|
|
Look for `mini` inside `tui.zig` to find out which minimodes are present
|
|
and where to look, to learn how each minimode does its own task.
|
|
|
|
[]($section.id("definition"))
|
|
### Minimode definition
|
|
|
|
Possibly the simplest minimode that does not require defining a
|
|
particular widget is the `replace` minimode, used in
|
|
[helix](/docs/mode/helix) and vim mode. To enter the minimode in
|
|
Helix while in `NOR` or `INS` use the keybind **r**; it consumes
|
|
another key and replaces the current character under the main cursor
|
|
with the immediately pressed key after **r**. If there are multiple
|
|
selections, all the characters are replaced by the one typed after
|
|
**r**.
|
|
|
|
- The minimode needs to expose a `create` function with type
|
|
|
|
```zig
|
|
pub fn create(Allocator,command.Context) !struct { tui.Mode, tui.MiniMode }
|
|
```
|
|
Which is in charge of registering the minimode to be able to receive
|
|
events and will offer the minimode name, the one that appears in the
|
|
lower status bar while it is active, to let it be known that the
|
|
minimode is active. This is where all the instatiations are made. Which
|
|
leads to
|
|
|
|
- The `deinit` function whose type is
|
|
|
|
```zig
|
|
pub fn deinit(*Self)
|
|
```
|
|
|
|
- A `receive` function that will route events received casting the
|
|
type:
|
|
|
|
```zig
|
|
pub fn receive(*Self, tp.pid_ref, tp.message) error{Exit}!bool
|
|
```
|
|
|
|
- A `commands` field that will expose the minimode `Collection` of
|
|
`Commands`.
|
|
|
|
- An special command `mini_mode_insert_code_point` as an element of the
|
|
commands collection with type:
|
|
|
|
```zig
|
|
pub fn mini_mode_insert_code_point(*Self, Ctx) Result
|
|
```
|
|
|
|
acting as the default handler of the key presses that the minimode will
|
|
receive when there is no other keybind defined for the minimode.
|
|
|
|
All the keys were handled and managed by the default "invisible" widget
|
|
that processes the keys for the minimode. And there is room for custom
|
|
widgets.
|
|
|
|
[]($section.id("custom_widgets"))
|
|
## A custom widget
|
|
|
|
When there is a need for an specialized widget, it's possible to
|
|
define one, for example, the `file_browser` is used to load and
|
|
save files, and `numeric_input` is used to set the tab width for
|
|
example(look for it in the command palette `:`).
|
|
|
|
[]($section.id("next"))
|
|
## Next steps
|
|
|
|
* Create [palettes](/docs/architecture/palette)
|
|
* Review [commands](/docs/architecture/command)
|
|
* Adjust [keybindings](/docs/architecture/keybind)
|
|
* To [architecture](/docs/architecture)
|