Compare commits
4 commits
836d5e0f93
...
77b458d4c2
| Author | SHA1 | Date | |
|---|---|---|---|
| 77b458d4c2 | |||
|
|
7f53e5f523 | ||
|
|
66bd859993 | ||
|
|
7a61aa499e |
7 changed files with 98 additions and 92 deletions
|
|
@ -15,6 +15,17 @@ them.
|
|||
You can [subscribe to this page via RSS]($link.page('devlog').alternative('rss')) and find more
|
||||
devlog entries in the [archive](/devlog/).
|
||||
|
||||
## [textDocument/documentSymbol]($section.id("2025-11-19T10:39:21+01:00"))
|
||||
|
||||
Flow now has a symbol browser for the current document based on the LSP `textDocument/documentSymbol`
|
||||
request. Open it in flow mode with `ctrl+shift+\`. As usual the list can be filtered with a fuzzy
|
||||
query. Navigating in the list will preview the location of the symbol in the document. Selecting
|
||||
a symbol will jump to it. The preview function is nice to quickly view another symbol without
|
||||
jumping away for your current file location.
|
||||
|
||||
[]($image.asset('2025-11-19.png'))
|
||||
|
||||
|
||||
## [centered view]($section.id("2025-11-17T20:56:38+01:00"))
|
||||
|
||||
For very wide screens you can now center the view with `ctrl+k x`, or the command
|
||||
|
|
|
|||
BIN
content/devlog/2025/2025-11-19.png
Normal file
BIN
content/devlog/2025/2025-11-19.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 620 KiB |
|
|
@ -11,9 +11,9 @@
|
|||
---
|
||||
|
||||
Commands are actions triggered to operate on buffers primarily. They are
|
||||
present in `editor`, `tui`, `mode` and `minimodes`, it's possible to
|
||||
find commands in other places, which will become evident when the need
|
||||
arises.
|
||||
present in [editor](/docs/architecture/editor), `tui`, `mode` and
|
||||
`minimodes`, it's possible to find commands in other places, which
|
||||
will become evident when the need arises.
|
||||
|
||||
## Previous notes[]($section.id('notes'))
|
||||
|
||||
|
|
@ -160,6 +160,11 @@ pub fn select_to_char_left_helix(_: *void, ctx: Ctx) Result {
|
|||
|
||||
## [Next steps]($section.id('next'))
|
||||
|
||||
[Editor](/docs/architecture/editor) has a walkthrough when working with
|
||||
selections, modifying the contents of the editor and deepens in concepts
|
||||
that allow understand how the internal interactions happen when editing
|
||||
a document.
|
||||
|
||||
[Minimodes](/docs/architecture/minimode) pass arguments to the editor,
|
||||
if you wonder how to go beyond the current buffer window, when there
|
||||
are actions like going to a specific line or when searching or
|
||||
|
|
|
|||
|
|
@ -16,42 +16,38 @@ To get the most of this section, it's recommended to have read the
|
|||
[keybinds](/docs/architecture/keybind) at least.
|
||||
|
||||
A word of warning: Flow code evolves and it is possible that some code
|
||||
exposed here is older than the current one. Always refer to
|
||||
[master](https://github.com/neurocyte/flow) in doubt.
|
||||
exposed here is older than the current one. If in doubt, always refer to
|
||||
[master](https://github.com/neurocyte/flow).
|
||||
|
||||
[]($section.id("concepts"))
|
||||
## Some concepts
|
||||
## [Some concepts]($section.id("concepts"))
|
||||
|
||||
The [editor](#editor_concept) coordinates visualization and
|
||||
modification of buffer contents, multiple cursors, selections and
|
||||
marks.
|
||||
modification of buffer contents, multiple [cursors](#cursor_concept),
|
||||
[selections](#selection_concept) and [marks](#mark_concept).
|
||||
|
||||
We will delve in editor concepts, buffer inner manipulation with ropes
|
||||
is not covered here.
|
||||
|
||||
[]($section.id("tui_editor"))
|
||||
### Editor and TUI
|
||||
### [Editor and TUI]($section.id("tui_editor"))
|
||||
|
||||
During this section we will refer to the concept of the editor as the
|
||||
one capable of modifying buffer contents, the visible gutters and
|
||||
line numbers as other terminal user interface (TUI) is covered in
|
||||
another chapter.
|
||||
|
||||
[]($section.id("view_concept"))
|
||||
### View
|
||||
### [View]($section.id("view_concept"))
|
||||
|
||||
`View` holds the information about the area of the buffer that is
|
||||
currently visible in the screen by the user. Is related to the
|
||||
[primary cursor](#cursor_concept).
|
||||
|
||||
[]($section.id("cursor_concept"))
|
||||
### Cursor
|
||||
### [Cursor]($section.id("cursor_concept"))
|
||||
|
||||
The `primary Cursor` holds a position in the Buffer, the `Editor`
|
||||
makes the link between both of them, signaling the part of the `Buffer`
|
||||
that can be modified and manipulated as you see it. It scrolls on the
|
||||
current visible portion [view](#view_concept) of the buffer, when
|
||||
manipulated with the keyboard, the mouse can change the move the view
|
||||
manipulated with the keyboard, the mouse on its own can move the view
|
||||
while the primary mouse is off-screen; when keystrokes arrive to the
|
||||
editor, the view focuses to the primary cursor to make it visible and
|
||||
available to be used.
|
||||
|
|
@ -67,10 +63,9 @@ Cursors visibility depends on the size of both the buffer contents and
|
|||
the editor in your device.
|
||||
|
||||
Most of editors operations act on the set of CurSels and the Primary
|
||||
Cursor is a [CurSel](#cursel_concept).
|
||||
Cursor is really a [CurSel](#cursel_concept).
|
||||
|
||||
[]($section.id("selection_concept"))
|
||||
### Selection
|
||||
### [Selection]($section.id("selection_concept"))
|
||||
|
||||
A selection is represented by begin and end [cursors](#cursor_concept)
|
||||
and offers basic functions that will constitute the changes needed with
|
||||
|
|
@ -80,31 +75,25 @@ services and [commands](/docs/architecture/command).
|
|||
A `Selection` has two cursors that are not visible, they mark the begin
|
||||
and the end of the selection.
|
||||
|
||||
|
||||
[]($section.id("cursel_concept"))
|
||||
### CurSel
|
||||
### [CurSel]($section.id("cursel_concept"))
|
||||
|
||||
The CurSel is what is presented to user, holding a
|
||||
[cursor](#cursor_concept) and optionally a
|
||||
[selection](#selection_concept).
|
||||
[selection](#selection_concept) which allows to have the concept of a
|
||||
cursor with a selection.
|
||||
|
||||
|
||||
[]($section.id("mark_concept"))
|
||||
### Mark
|
||||
what allow to have the concept of a cursor with a selection. A `Cursel`
|
||||
is composed by a cursor and optionally a Selection.
|
||||
### [Mark]($section.id("mark_concept"))
|
||||
|
||||
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.
|
||||
|
||||
[]($section.id("editor_concept"))
|
||||
### Editor
|
||||
### [Editor]($section.id("editor_concept"))
|
||||
The Editor will be acting on Buffer.Root which is the root of the tree
|
||||
representing the document that is being edited. API 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
|
||||
buffer, knowing if the end or the beginning of the document has been
|
||||
reached when interacting with a Cursor.
|
||||
|
||||
Cursors, Selections and Cursels don't know about the buffer, and they
|
||||
|
|
@ -113,15 +102,14 @@ restrictions and usually receive `metrics` from the editor that help
|
|||
determine if a cursor is about to exit the boundaries of the buffer
|
||||
and be inside bounds.
|
||||
|
||||
[]($section.id("commands"))
|
||||
## Editor Commands
|
||||
## [Editor Commands]($section.id("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. Flow is
|
||||
scenarios, to name a prominent one, emacs lisp from Emacs. Flow is
|
||||
inspired on it and others.
|
||||
|
||||
If the buffer is not to be modified, we will be using the method
|
||||
|
|
@ -135,10 +123,10 @@ 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.
|
||||
|
||||
[]($section.id("moving"))
|
||||
## Moving
|
||||
## [Moving]($section.id("moving"))
|
||||
|
||||
For example, to move the cursors a page up, we can look at the command
|
||||
For example, to move the cursors a page up, we can look at the
|
||||
[command](/docs/architecture/command)
|
||||
`move_page_up`,
|
||||
|
||||
>[]($block.attrs('line-numbers-js'))
|
||||
|
|
@ -171,8 +159,8 @@ Looking inside `with_cursors_and_view_const`
|
|||
>```
|
||||
|
||||
It iterates over all the cursors and invokes
|
||||
`with_cursor_and_view_const`, sending the `move` function, a cursor,
|
||||
remember that the function passed was `move_cursor_page_up` as seen
|
||||
`with_cursor_and_view_const`, sending the `move` function, a cursor;
|
||||
remember that the function passed was `move_cursor_page_up` as shown
|
||||
previously.
|
||||
|
||||
The commitment of `move_cursor_page_up` is to use the method
|
||||
|
|
@ -185,11 +173,10 @@ fn move_cursor_page_up(root: Buffer.Root, cursor: *Cursor, view: *const View, me
|
|||
```
|
||||
|
||||
The `move` functions set is numerous, look for the methods whose name
|
||||
have the word `move` in them. with the command palette is possible to get
|
||||
have the word `move` in them. With the command palette is possible to get
|
||||
a glimpse of the available functions present(ctrl+f2).
|
||||
|
||||
[]($section.id("selecting"))
|
||||
## Selections
|
||||
## [Selections]($section.id("selecting"))
|
||||
|
||||
Function naming conventions help understand the purpose of each one,
|
||||
there has been taken great deal of care to maintain consistency, it's
|
||||
|
|
@ -209,6 +196,7 @@ pub fn select_up(self: *Self, ctx: Context) Result {
|
|||
}
|
||||
pub const select_up_meta: Meta = .{ .description = "Select up", .arguments = &.{.integer} };
|
||||
```
|
||||
|
||||
It's meta is guiding about the integer argument that the command can
|
||||
make use of. Invokes `with_selections_const_repeat` passing the
|
||||
function `move_cursor_up` as parameter and also the context, which
|
||||
|
|
@ -238,12 +226,14 @@ the `while`, then for each repetition, the set of cursels is iterated,
|
|||
cursels hold cursors and selections, applying `with_selection_const`
|
||||
function, passing `root`(the buffer), `move_cursor_up` function, cursel
|
||||
and metrics as parameters. Note that after the function is applied to
|
||||
each cursel, self.collapse_cursors() is invoked, given that it's
|
||||
possible that some cursors in the operation have overlapped. With each
|
||||
cursel operation there is also a tracking of possible fails, continuing
|
||||
gracefully, one of such fails can be happening because come cursels
|
||||
might have been reaching the beginning of the buffer and there might be
|
||||
other cursels that have not yet reached the beginning of the file.
|
||||
each cursel, `self.collapse_cursors()` is invoked, given that it's
|
||||
possible that some cursors in the operation have overlapped.
|
||||
|
||||
With each cursel operation there is also a tracking of possible fails,
|
||||
continuing gracefully, one of such fails can be happening because some
|
||||
cursels might have been reaching the beginning of the buffer and there
|
||||
might be other cursels that have not yet reached the beginning of the
|
||||
file.
|
||||
|
||||
```zig
|
||||
pub fn with_selection_const(root: Buffer.Root, move: cursor_operator_const, cursel: *CurSel, metrics: Buffer.Metrics) error{Stop}!void {
|
||||
|
|
@ -264,12 +254,12 @@ applied with its method `check_selection`.
|
|||
Flow allows navigating the code with `goto_definition` and `references`
|
||||
commands to deepen the understanding and following the different calls.
|
||||
|
||||
[]($section.id("modifying"))
|
||||
## Modifying the buffer
|
||||
## [Modifying the buffer]($section.id("modifying"))
|
||||
|
||||
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.
|
||||
functions, in contrast, the `cut`, `delete`, `insert`, `paste` set
|
||||
looks smaller, and this is accomplished making composition of functions.
|
||||
|
||||
Usually when modifying something, first there is a process to locate
|
||||
the cursor, cursel or selection in the proper place and then applying
|
||||
the modification. There are cases when there is need to locate and
|
||||
|
|
@ -277,7 +267,7 @@ act right away.
|
|||
|
||||
When additions, changes and removal of buffer contents, editor offers
|
||||
the method `buf_for_update`; we will look first to the method
|
||||
`to_upper_cursel`, which by default in Flow, takes a CurSel, if it has
|
||||
`to_upper_cursel`, which by default in Flow, takes a CurSel; if it has
|
||||
no selection, the word that it is stepped on, if any, is selected and
|
||||
gets uppercased.
|
||||
|
||||
|
|
@ -332,10 +322,10 @@ pub fn to_upper(self: *Self, _: Context) Result {
|
|||
pub const to_upper_meta: Meta = .{ .description = "Convert selection or word to upper case" };
|
||||
```
|
||||
|
||||
via `with_cursels_mut_once` receives a buffer that will be modified
|
||||
`with_cursels_mut_once` receives a buffer that will be modified
|
||||
and returns one with modifications, updating what is presented with
|
||||
the method `update_buf` and an allocator. The previously described
|
||||
`to_upper_cursel` is sent
|
||||
function `to_upper_cursel` is sent
|
||||
|
||||
>[]($block.attrs('line-numbers-js'))
|
||||
>```zig
|
||||
|
|
@ -357,9 +347,10 @@ Worth to note that the modified `root` is being passed to the function
|
|||
`with_cursel_mut` on each iteration over the cursels along with the
|
||||
allocator and as described previously in selection functions, tracking
|
||||
if there is some fail an error is popped up, whilst everything was
|
||||
successful, the modified `root` is returned. Now time to see the
|
||||
method `with_cursel_mut` that receives the pointer to `to_upper_cursel`
|
||||
along with root, cursel and allocator.
|
||||
successful, the modified `root` is returned.
|
||||
|
||||
Now time to see the method `with_cursel_mut` that receives the pointer
|
||||
to `to_upper_cursel` along with root, cursel and allocator.
|
||||
|
||||
```zig
|
||||
fn with_cursel_mut(self: *Self, root: Buffer.Root, op: cursel_operator_mut, cursel: *CurSel, allocator: Allocator) error{Stop}!Buffer.Root {
|
||||
|
|
@ -370,17 +361,17 @@ fn with_cursel_mut(self: *Self, root: Buffer.Root, op: cursel_operator_mut, curs
|
|||
As seen, the only task for `with_cursel_mut` is providing the required
|
||||
elements to let `to_upper_cursel` do what was described previously.
|
||||
|
||||
## Adding functionalities to the editor
|
||||
## [Adding functionalities to the editor]($section.id("adding"))
|
||||
|
||||
As shown, the basics to manipulate the buffer via the editor involves
|
||||
reviewing if cursors, marks, selections are to be modified, changed or
|
||||
if the contents are. Picking functions for it and focusing on the
|
||||
task for a single cursel, cursor or selection is key and the use of the
|
||||
already present functions will allow to act on multiple elements at
|
||||
once.
|
||||
once. By convention functions with name `mut` will modify the buffer while
|
||||
`const` will not.
|
||||
|
||||
[]($section.id("next"))
|
||||
## Next steps
|
||||
## [Next steps]($section.id("next"))
|
||||
|
||||
* [minimodes](/docs/architecture/minimode) invoke
|
||||
[commands](/docs/architecture/minimode) defined in the editor
|
||||
|
|
|
|||
|
|
@ -43,18 +43,27 @@ offers services around the set of projects.
|
|||
## [Editor commands and modes]($section.id("commands"))
|
||||
|
||||
When a buffer is active, it has an Editor
|
||||
attached to it; an editor might have associated tree-sitter support,
|
||||
given the file type detected, and offers common services that are aimed
|
||||
to be used by `Commands` to manipulate the contents of a buffer at a
|
||||
higher level, the selections, cursors, cursor selections `CurSel` and
|
||||
the `View`. [Commands](/docs/architecture/command) are used by `Modes`
|
||||
attached to it; an [editor](/docs/architecture/editor) might have
|
||||
associated tree-sitter support, given the file type detected, and
|
||||
offers common services that are aimed to be used by `Commands` to
|
||||
manipulate the contents of a buffer at a higher level, the
|
||||
[selections](/docs/architecture/editor#selection_concept),
|
||||
[cursors](/docs/architecture/editor#cursor_concept),
|
||||
cursor selections
|
||||
([CurSel](/docs/architecture/editor#cursel_concept)),
|
||||
[markers](/docs/architecture/editor#mark_concept) and the
|
||||
[view](/docs/architecture/editor#view_concept).
|
||||
|
||||
[Commands](/docs/architecture/command) are used by `Modes`
|
||||
with [Keybindings](/docs/architecture/keybind). The main mode is Flow
|
||||
and the keybindings can be used to map to a mode built up entirely on
|
||||
solely calling already created commands. An example of a mode
|
||||
created by command composition is `Emacs` mode, for instance, it's
|
||||
possible to create a nano mode with just keybindings. In the other hand,
|
||||
`Vim` and [Helix](/docs/mode/helix) modes have particular definitions
|
||||
for commands that interact with the buffers, being modal editors.
|
||||
solely calling already created commands.
|
||||
|
||||
An example of a mode created by command composition is `Emacs` mode,
|
||||
for instance, it's possible to create a nano mode with just keybindings.
|
||||
In the other hand, `Vim` and [Helix](/docs/mode/helix) modes have
|
||||
particular definitions for commands that interact with the buffers,
|
||||
being modal editors.
|
||||
|
||||
## [Text user interface]($section.id("tui"))
|
||||
|
||||
|
|
|
|||
|
|
@ -12,8 +12,7 @@
|
|||
|
||||
This document describes Helix Mode implementation.
|
||||
|
||||
[]($section.id('what'))
|
||||
## What and what not
|
||||
## [What and what not]($section.id('what'))
|
||||
|
||||
The first and biggest difference is that Flow has a mode that emulates
|
||||
Helix, or at least has equivalent of the worthiest actions that can be
|
||||
|
|
@ -31,12 +30,11 @@ make sure to review
|
|||
[other issues](https://github.com/neurocyte/flow/issues?q=is%3Aissue%20state%3Aopen%20label%3Ahelix-mode)
|
||||
to avoid repeating or see in [Discord](https://discord.gg/kzJC9fA7)
|
||||
to ask if there is a workaround, or anyone else is interested in
|
||||
porting your requirement, adding a reaction to an issue offers
|
||||
porting your requirement; adding a reaction to an issue offers
|
||||
awareness on what to implement or to get higher priority, remember that
|
||||
it's possible to bounce back to Flow(f4) mode if needed.
|
||||
it is possible to bounce back to Flow(f4) mode if needed.
|
||||
|
||||
[]($section.id('enhancing'))
|
||||
## Enhancing hx mode
|
||||
## [Enhancing hx mode]($section.id('enhancing'))
|
||||
|
||||
This is a programmer's editor, you are more than welcome to enhance to
|
||||
suit your needs that maybe coincide with others.
|
||||
|
|
@ -50,8 +48,7 @@ particular work to make it real is `src/tui/mode/helix.zig`, adding
|
|||
a `command` and the corresponding `meta` is what is required.
|
||||
[More on commands](/docs/architecture/command).
|
||||
|
||||
[]($section.id('pickers'))
|
||||
### Pickers
|
||||
### [Pickers]($section.id('pickers'))
|
||||
|
||||
Flow hx mode offers most of the Helix pickers functionalities with
|
||||
`panels` and [palettes](/docs/architecture/palette). Example of panels
|
||||
|
|
@ -60,20 +57,12 @@ in files). Examples of `palettes` are `space` `b` to pick a buffer or
|
|||
`space` `f` to open a file in your project. Panels open below the
|
||||
editor while palettes open overlapping the working area.
|
||||
|
||||
One medium sized project is to create a **Helix picker** widget that
|
||||
has one input widget with two panels, on the left, the list of options
|
||||
and, on the right, the preview of the selected option. The input
|
||||
widget reacts to various keybindings to manipulate the objects inside
|
||||
both panels with filtering. `src/tui/mode/overlay/palette.zig`
|
||||
implements much of the required functionality.
|
||||
|
||||
[]($section.id('next'))
|
||||
## Next steps
|
||||
## [Next steps]($section.id('next'))
|
||||
|
||||
Said all of this, it's possible to start contributing via pull
|
||||
requesting [keybinds](/docs/architecture/keybind),
|
||||
[commands](/docs/architecture/command),
|
||||
[palettes](/docs/architecture/palette), or the **hx picker**.
|
||||
[palettes](/docs/architecture/palette), or anything you wish were here.
|
||||
|
||||
More about the [architecture](/docs/architecture) or jump to
|
||||
[contribution guidelines](/docs/contributing).
|
||||
|
|
|
|||
|
|
@ -18,14 +18,15 @@
|
|||
<ul>
|
||||
<li><a href="$site.page('docs/contributing').link()">contributing</a></li>
|
||||
<li><a href="$site.page('docs/testing').link()">testing</a></li>
|
||||
<li><a href="$site.page('docs/architecture').link()">architeture</a></li>
|
||||
<li><a href="$site.page('docs/architecture').link()">architecture</a></li>
|
||||
<li><ul>
|
||||
<li><a href="$site.page('docs/architecture/keybind').link()">keybind</a></li>
|
||||
<li><a href="$site.page('docs/architecture/command').link()">command</a></li>
|
||||
<!-- <li><a href="$site.page('docs/architecture/editor').link()">editor</a></li> -->
|
||||
<li><a href="$site.page('docs/architecture/editor').link()">editor</a></li>
|
||||
<li><a href="$site.page('docs/architecture/minimode').link()">minimode</a></li>
|
||||
<li><a href="$site.page('docs/architecture/palette').link()">palette</a></li>
|
||||
<li><a href="$site.page('docs/architecture/inner_data_exchange').link()">exchanging data</a></li></ul></li>
|
||||
<li><a href="$site.page('docs/mode/helix').link()">hx mode</a></li>
|
||||
<li><a href="https://deepwiki.com/neurocyte/flow" target="_alt">deepwiki</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue