153 lines
5.5 KiB
Text
153 lines
5.5 KiB
Text
---
|
|
.title = "Editor",
|
|
.date = @date("2025-10-19T00:00:00"),
|
|
.author = "Igor Támara",
|
|
.layout = "tutorial.shtml",
|
|
.draft = false,
|
|
.custom = {
|
|
.githubedit = "docs/architecture/editor.md",
|
|
.prevurl = "docs/command",
|
|
.prevtext = "Commands",
|
|
.topurl = "docs/architecture",
|
|
.toptext = "Architecture",
|
|
.nexturl = "docs/architecture/minimode",
|
|
.nexttext = "Mini modes",
|
|
.codepath ="src/tui/editor.zig",
|
|
},
|
|
---
|
|
|
|
The `editor` coordinates visualization and modification of
|
|
buffer contents, multiple cursors, selections and marks.
|
|
|
|
To get the most of this section, it's recommended to have
|
|
read the [architecture briefing](/docs/architecture), about
|
|
[commands](/docs/architecture/command) and
|
|
[keybinds](/docs/architecture/keybind).
|
|
|
|
## Some concepts
|
|
|
|
The `primary Cursor` is presented always in the `Editor`,
|
|
signaling the part of the `Buffer` that can be modified and
|
|
manipulated as you see it. It scrolls on the current visible
|
|
portion of the buffer.
|
|
|
|
Other cursors can be in the `View` or in regions outside the
|
|
current view, depending on the size of both the buffer and
|
|
the editor in your device.
|
|
|
|
A `Selection` has two cursors that are not visible, they mark
|
|
the begin and the end of the selection, and CurSels are actually
|
|
what allow to have the concept of a cursor with a selection. A
|
|
`Cursel` is composed by a cursor and optionally a Selection.
|
|
|
|
Most of editors operations act on the set of CurSels and the
|
|
Primary Cursor is a particular case of the general case. And
|
|
as a note, the Primary Cursor is in fact a CurSel.
|
|
|
|
To complete the editor scenario, `Marks` have the potential
|
|
to become selections; the marks become evident to the eye
|
|
when in search mode, they are seen as the primary cursor
|
|
is positioned over an occurrence with a different color
|
|
according to the theme.
|
|
|
|
The Editor will be acting on Buffer.Root which is the root of
|
|
the tree representing the document that is being edited. The API
|
|
of the Buffer.Root is stable and offers the necessary to insert,
|
|
delete and move along the buffer, knowing if the end or the
|
|
beginning of the document have been reached when interacting
|
|
with a Cursor.
|
|
|
|
Cursors, Selections and Cursels don't know about the buffer, and
|
|
they need to receive a reference to them to have positions and
|
|
also sometimes receive metrics from the editor that help determine
|
|
if a cursor is about to exit boundaries of the buffer and have
|
|
everything "in place".
|
|
|
|
## Editor Commands
|
|
|
|
We mentioned earlier that most of the operations work on all
|
|
the cursors and selections, moreover, there are various
|
|
commands acting over the set of cursors, selections, cursels
|
|
or marks. Given said this, we will be using functions as
|
|
parameters in most of the situations. Functional programming
|
|
languages are popular in these scenarios, to name a prominent
|
|
one, Emacs and emacs lisp.
|
|
|
|
If the buffer is not to be modified, we will be using the
|
|
method `buf_root` to get the root of the buffer to find and
|
|
position the cursors. In the other hand, we will use
|
|
`buf_for_update()` when the buffer is to be modified.
|
|
|
|
The benefit of sending functions as parameters is that code
|
|
is reused and the codebase can grow without much sacrifice
|
|
when adding new functionalities, because one would be
|
|
thinking only in the current cursor and if required, the
|
|
operation will be applied to all the cursors, the same applies
|
|
to selections, cursels and marks.
|
|
|
|
## Moving
|
|
|
|
For example, to move the cursors a page up, we can look at
|
|
the command `move_page_up`, which uses the method
|
|
`with_cursors_and_view_const` sending the function
|
|
`move_cursor_page_up`.
|
|
|
|
Looking inside `with_cursors_and_view_const`, it iterates
|
|
over all the cursors and invokes `with_cursor_and_view_const`,
|
|
sending a cursor as a parameter, that function, will invoke
|
|
`move_cursor_page_up` whose commitment is to use the method
|
|
`move_page_up` from the cursor, sending the view and the
|
|
metrics of the editor.
|
|
|
|
The family of `move` functions is big, look for the methods
|
|
whose name has the word move in them. with the command palette
|
|
is possible to get a glimpse of them.
|
|
|
|
## Selections
|
|
|
|
There are naming conventions for the functions that help
|
|
understanding what each one is doing, there has been taken
|
|
great deal of care to maintain consistency that needs to be
|
|
followed to make it easier to continue extending on
|
|
functionalities.
|
|
|
|
Look at the following set of functions, all of them act on
|
|
cursors, cursels and selections, in singular and plural, and
|
|
some of them receive arguments, the repeat functions act
|
|
many times over the set of the group that they are intended
|
|
to do so. The parameters and following the calls from one
|
|
to another will let you navigate and get the hang of their
|
|
usage.
|
|
|
|
```zig
|
|
fn with_cursor_const
|
|
fn with_cursel_const
|
|
fn with_cursels_const
|
|
fn with_selection_const
|
|
fn with_cursor_const_arg
|
|
fn with_cursors_const_arg
|
|
fn with_cursors_const_once
|
|
fn with_selection_const_arg
|
|
fn with_cursors_const_repeat
|
|
fn with_selections_const_arg
|
|
fn with_cursor_and_view_const
|
|
fn with_selections_const_once
|
|
fn with_cursors_and_view_const
|
|
fn with_selections_const_repeat
|
|
fn with_selection_and_view_const
|
|
fn with_selections_and_view_const
|
|
```
|
|
|
|
## Modifying the buffer
|
|
|
|
The `select` family of functions is bigger than the set of `move`
|
|
functions, in contrast, the `cut`, `delete`, `insert`, `paste`
|
|
looks smaller, and this is accomplished making composition of
|
|
functions. Usually when modifying something, first there is
|
|
a process to locate the cursor, cursel o selection in the proper
|
|
place and then applying the modification.
|
|
|
|
[Discord](https://discord.com/invite/4wvteUPphx) and
|
|
[Github issues](https://github.com/neurocyte/flow/issues) are the
|
|
main channels to do so.
|
|
|