156 lines
No EOL
6.2 KiB
Text
156 lines
No EOL
6.2 KiB
Text
---
|
|
.title = "Architecture",
|
|
.date = @date("2025-07-06T00:00:00"),
|
|
.author = "Igor Támara",
|
|
.layout = "tutorial.shtml",
|
|
.draft = false,
|
|
.custom = {
|
|
.githubedit = "/docs/architecture.smd",
|
|
}
|
|
---
|
|
|
|
This document describes in a general way, concepts that help to
|
|
understand how the code is organized and where to look at when starting
|
|
to contribute developing Flow Control. Make sure you have read
|
|
first [help.md](https://github.com/neurocyte/flow/blob/master/help.md)
|
|
and use the editor at least in flow mode. We recommend reading the
|
|
[deepwiki description](https://deepwiki.com/neurocyte/flow) for a more
|
|
in depth documentation and joining
|
|
[Discord](https://discord.com/invite/4wvteUPphx) to ask from the
|
|
simplest. If something does not look accurate on this documentation or
|
|
in deepwiki. Do not hesitate to ask in the channels and
|
|
[open a PR](https://github.com/neurocyte/flow-website/pulls) to improve
|
|
anything.
|
|
|
|
[]($section.id("internals"))
|
|
## Internals
|
|
|
|
The foundational unit is the `Buffer` that holds the document in memory;
|
|
there might be various opened files, each one loaded in a buffer.
|
|
A buffer can be ephemeral, meaning, it is not related to a file, that
|
|
might be the product of a `Task` run. Buffers are implementations of
|
|
ropes that offer multiple services such as insert characters, load from
|
|
file, write to file, load from string, return as string, tell if it has
|
|
unsaved changes(dirty), among many others. A buffer can have multiple
|
|
`Selections` and `Cursors` interacting with it. The `Buffer Manager`
|
|
offers services around the set of buffers.
|
|
|
|
A `Project` initially is the directory where flow is opened at, once
|
|
opened, it starts processes to discover the files under the directory
|
|
hierarchy, interact with lsp and git. When flow is opened, only one
|
|
active project is loaded in the current session. The `Project Manager`
|
|
offers services around the set of projects.
|
|
|
|
[]($section.id("commands"))
|
|
## Editor commands and modes
|
|
|
|
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`
|
|
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.
|
|
|
|
[]($section.id("tui"))
|
|
## Text user interface
|
|
|
|
`Tui` governs it all offering support for
|
|
[palettes](/docs/architecture/palette) that are known in other
|
|
environments as pickers, as well as offering information through a
|
|
set of `_views` (i.e. `logview`, `inputview`, `inspector_view`) and
|
|
`status` (i.e. `tabs`, `clock`, `branch`, `linenum`), in the statusbar
|
|
[minimodes](/docs/architecture/minimode) will be present too, those
|
|
that receive more keypresses to offer additional functionality, such
|
|
as finding in files, finding in the current buffer, open files
|
|
and replacing a character.
|
|
|
|
[]($section.id("oses"))
|
|
## Operating systems and UI
|
|
|
|
[libvaxis](https://github.com/rockorager/libvaxis) is in charge of
|
|
rendering the text and all the interface in Linux, MacOS, FreeBSD,
|
|
and Android via Termux, while in Windows there is an special GUI.
|
|
|
|
[]($section.id("thespian"))
|
|
## Communication between components
|
|
|
|
[Thespian](https://github.com/neurocyte/thespian) is in charge of
|
|
processes synchronization and allows sending
|
|
[messages between different flow components](/docs/architecture/inner_data_exchange),
|
|
for example, when a widget needs updating information from changing
|
|
states of internal data and when components or external processes take
|
|
time and need to return an answer, all this without blocking the user
|
|
interface. Tree-sitter queries to highlight the current file of a
|
|
particular language and LSPs usually take time by the nature of
|
|
operations they perform, integration with git and running a `shell`
|
|
command via a `task` all are coordinated thanks to the infrastructure
|
|
that Thespian provides.
|
|
|
|
[]($section.id("languages"))
|
|
## Programming languages support
|
|
|
|
There are plenty of programming languages that use tree-sitter via
|
|
[flow-syntax](https://github.com/neurocyte/flow-syntax) and whose
|
|
language servers and formatters are configured via `file_type_lsp`.
|
|
Currently one Language Server is supported for each language.
|
|
|
|
[]($section.id("facilities"))
|
|
## Facilities
|
|
|
|
The clipboard is used for copy, paste operations and there is also
|
|
support to use the system clipboard, copying and pasting to/from it.
|
|
|
|
[]($section.id("logging"))
|
|
### Logging support
|
|
|
|
Logging support offers various levels to give feedback for several
|
|
actions that ease developing Flow itself and also are used to offer
|
|
feedback via `logview`. To view logs use `f11` to toggle the
|
|
previous messages, or alternatively, open flow with the option
|
|
`--show-logs`.
|
|
|
|
To log something, first, `import log`
|
|
|
|
```zig
|
|
const log = @import("log");
|
|
```
|
|
|
|
Instantiate the logger, replacing prefix with something meaningful to
|
|
differentiate from other logging messages.
|
|
|
|
```zig
|
|
const logger = log.logger("prefix");
|
|
defer logger.deinit();
|
|
```
|
|
|
|
Log something
|
|
|
|
```zig
|
|
logger.print("{} unsaved buffer(s) remaining", .{remaining});
|
|
```
|
|
|
|
[]($section.id("show_input"))
|
|
### View key presses
|
|
|
|
There are situations when you press some keys without the expected
|
|
behavior happening, to review if flow is getting the keys, the
|
|
[keybindings are associated](/docs/architecture/keybind), and are
|
|
executing the [desired command](/docs/architecture/command), or maybe
|
|
your desktop environment or something else is capturing them, you will
|
|
want to invoke flow with the option `--show-input`.
|
|
|
|
[]($section.id("next"))
|
|
## Next steps
|
|
|
|
* [Configure some keybinds](/docs/architecture/keybind)
|
|
* [Guidelines for contributions](/docs/contributing)
|
|
* [Create your own commands](/docs/architecture/command)
|
|
* [Take a peek on testing](/docs/testing)
|
|
* [Back to docs](/docs) |