diff --git a/content/docs/architecture/command.smd b/content/docs/architecture/command.smd new file mode 100644 index 0000000..ce4f15d --- /dev/null +++ b/content/docs/architecture/command.smd @@ -0,0 +1,121 @@ +--- +.title = "Commands", +.date = @date("2025-10-15T00:00:00"), +.author = "Igor Támara", +.layout = "tutorial.shtml", +.draft = false, +.custom = { .githubedit = "https://github.com/neurocyte/flow-website/tree/master/content/docs/architecture/command.md"}, +--- + +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. + +## Previous notes + +Note: Flow is programmed with [zig](https://ziglang.org/), if you are familiar +with C, C++, Rust, there are differences and reasonings that +might find useful when [learning Zig](https://ziglang.org/learn/). If you +are coming from higher level programming languages such as Python, Ruby, +C#, Java, Golang, Typescript it will be an opportunity to learn about trades +of managing memory and fast responses and some lower level concepts present +in Zig. If you are brand new to programming, some general concepts will be +needed and practice in another language before getting into flow development. + +If you are new to Zig, it's a good idea to take a look at +[ziglings](https://ziglings.org/) to practice, as you learn the language. + +Maybe there is a [shell command invoked](/docs/architecture/keybind#shell) with a +keybinding that can help in the task you are aiming at before developing +flow itself. + +## Understanding and creating commands + +A command is a function with a type like + +```zig +pub fn copy(self: *Self, _: Context) Result +``` + +and a `Meta` definition with the same name and suffix `_meta`. + +```zig +pub const copy_meta: Meta = .{ .description = "Copy selection to clipboard" }; +``` + +`copy` command is defined in `editor.zig`, which copies the current +selections into the pimp internal clipboard. Commands are available +to all the modes if defined as pub. + +`meta` holds the description appearing in the command palette and optionally +has arguments, the most common, an integer, that usually constitutes a +repetition parameter, targeting vim, emacs and helix modes. As you dig in, +there might be particularities on the parameters accepted for a given +command. + +## Invoking another command + +Commands can be bound to mnemonics in modes by convention. For example, in +Vim Mode `vim.zig`, `q` corresponds to (quit), the most famous one. + +```zig +pub fn q(_: *void, _: Ctx) Result { + try cmd("quit", .{}); +} +pub const q_meta: Meta = .{ .description = "q (quit)" }; +``` + +Looking more closely, the first parameter in this case is of `*void` type, +given that this command is defined in `vim.zig` which is calling the `quit` +command defined in `editor.zig`. `cmd` takes care of routing and finding +the command wherever it is defined. + +## Chaining commands + +Chaining commands is also common, and, by the way, swift. This is a sample +of applying first `save_file` command and then, the command `quit`. + +```zig +pub fn wq(_: *void, _: Ctx) Result { + try cmd("save_file", command.fmt(.{ "then", .{ "quit", .{} } })); +} +pub const wq_meta: Meta = .{ .description = "wq (write file and quit)" }; +``` + +Sometimes [keybinding](/docs/architecture/keybind) is enough to accomplish +a compound of already present commands, in others, zig programming is the +path to be taken. + +# More in depth commands + +Is common to define private functions in a given module that are invoked from +commands, as usual, functions are meant to be reused and help organize code. + +For example, in hx mode `helix.zig` the `select_to_char_left_helix` command +uses the functions `helix_with_selections_const_arg` which iterates over all +cursels and applies the `select_cursel_to_char_left_helix` function. + +```zig +pub fn select_to_char_left_helix(_: *void, ctx: Ctx) Result { + try helix_with_selections_const_arg(ctx, &select_cursel_to_char_left_helix); +} +``` + +## Sending parameters to commands + +`cmd` is in charge of finding a command given its name, and parameters sent +to commands are vary for each command, for example, when interacting with +the clipboard, the messages sent are multiple chunks of information, for +now an example of such usage can be seen in a function that fetches contents +from the clipboard. + + + +There are more advanced topics related to commands that are covered in the +[editor](/docs/architecture/editor), that deeps in specific details of +the editor and its interaction with cursors, selections and buffers +modifications, among others. + +Learning about interactions with the buffer and editor is present in +[minimodes](/docs/architecture/minimode). diff --git a/content/docs/architecture/editor.smd b/content/docs/architecture/editor.smd new file mode 100644 index 0000000..f96ec87 --- /dev/null +++ b/content/docs/architecture/editor.smd @@ -0,0 +1,76 @@ +--- +.title = "Editor", +.date = @date("2025-10-19T00:00:00"), +.author = "Igor Támara", +.layout = "tutorial.shtml", +.draft = false, +.custom = { .githubedit = "https://github.com/neurocyte/flow-website/tree/master/content/docs/architecture/editor.md"}, +--- + +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 view. + +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` has a cursor and optionally a Selection. + +Most of editor operations act on the set of CurSels, the Primary +Cursor is in fact a CurSel, as opposed to what we previously +mentioned. + +To complete the editor scenario, `Marks` have the potential +to become selections, and behind the scenes CurSels and are +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, the +beginning has been reached when interacting with a Cursor. + +## Editor Commands + +We mentioned earlier that most of the operations work on all +the cursors and selections, there are various commands that +will use functions that iterate over 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 `` to +get the root of it to find and position the cursors. While +we will use `` when the buffer is to be modified. + +## Moving + + + +## Selections + +## Modifying the buffer + + +[Discord](https://discord.com/invite/4wvteUPphx) and +[Github issues](https://github.com/neurocyte/flow/issues) are the +main channels to do so. + diff --git a/content/docs/architecture/keybind.smd b/content/docs/architecture/keybind.smd new file mode 100644 index 0000000..82d950d --- /dev/null +++ b/content/docs/architecture/keybind.smd @@ -0,0 +1,145 @@ +--- +.title = "Keybinding", +.date = @date("2025-10-19T00:00:00"), +.author = "Igor Támara", +.layout = "tutorial.shtml", +.draft = false, +.custom = { .githubedit = "https://github.com/neurocyte/flow-website/tree/master/content/docs/architecture/keybind.md"}, +--- + +If you are here, it's possible that you already have edited your +own keybinds to suit your needs and are looking for some advanced +topics to extend your use cases and make everything easier and +fluid when in Flow. If you have not, take a peek to learning how +to do it. + +Using the command palette `Ctrl+Shift+p` and typing **Edit key bindings**, +takes you to the json file to extend Flow configuring +keybindings to suit your needs. + +[]($section.id('tldr')) +## ;TLDR; + +Once you open the corresponding json file, locate inside the imode +(internal mode) that will accept the key or keys/combo and add an +array, where the first element is the combination to map to the +commands that will happen, the array accepts strings like in + +```js +["ctrl+alt+shift+p", "open_command_palette"] +``` + +To avoid screwing up the combinations, and putting Flow in an unusable +state derived from a wrong mapping of key combinations, read on. + +## Resetting keys to factory defaults + +User configured keybindings are stored in Flow's configuration +directory under `keys/mode.json` where mode can be `flow`, +`emacs`, `vim`, `helix` or customized ones. Removing the keys +directory or the particular mode file can take you out from a +broken state. + +## Keybinds for each mode + +Keybinds are edited per mode, and other modes inherit what is +defined in your `flow.json` keybindings. Each mode override keybindings +of its parent mode. For example, if you are in **emacs** mode you will +be redirected to `emacs.json` and it will override the keybindings from +flow. + +[introducing keybindings](/devlog/2024#2024-12-05T20:55:00) showcases +how to get to edit keybindings. + +## Keybindings hierarchy + +Some terminology + +* **Mode**: Stored in a json file, like flow mode declared in `flow.json`. +* **Imode**: under the json file. +* **Major Imode**: `project` or descendant from `project`. +* **Minimodes**: To be used momentarily and do not inherit from `project`. + +In general a keybinding json shows this hierarchy: + +``` +Mode > Imode > press > Key and commands +map > map > array > array(array(string,numbers),strings,numbers) +``` + +`Mode` is the json file that holds a map, where each +entry has a map called `press` that is an array of +arrays. + +`project` is the main imode in `flow.json` and it can be +noticed that `normal` imode `inherit`s from `project`, +some modes have `release`, usually one will be using +only `press` inside `normal` imode or the specific mode +if inside `vim`, `helix` or `emacs` modes. + +Looking further, it can be seen that +[minimodes](/docs/architecture/minimode) have their +keybinding mappings defined in a particular imode. + +As stated previously, there is a mode hierarchy, the main mode +is flow and other modes inherit from it. We remind that also +imodes have a hierarchy and it's common for major imodes to be +descendants from `project`. + +## Adding a Keybinding + +The most basic case to map a keybind to a command was covered in +[TLDR](#tldr) which used the combination of three keys pressed +simultaneously `ctrl`, `shift` and `p`, all of them where combined +with `+` to execute the command `open_command_palette`. + +A common use case is to add a keybinding to invoke an already +existing command and chain it to another, making Flow more suited to your +own needs. + +[]($section.id('shell')) +## Running shell commands + +For example, `f5` by default is used to run `zig build test` +outputting its results to a *scratch buffer* called `test`. + +```js +["f5", ["create_scratch_buffer", "*test*"], ["shell_execute_insert", "zig", "build", "test"]], +``` + +Note that: + +The keybind is `f5`, which maps to the `f5` keycode. is invoking +`create_scratchbuffer`, receiving the parameter `*test*` which +results in creating a scratch buffer if didn't exist. And +then executing the command `shell_execute_insert` that receives +the paramaters `zig`, `build`, `test`. This latter command is +executing a shell command called `zig` with the parameters +`build` and `test`; if you don't have zig installed, it will +not work, and you might want to remap f5 to a different shell +command. + +``` +[ + "f5", + [ + "create_scratch_buffer", + "*test*" + ], + [ + "shell_execute_insert", + "zig", + "build", + "test" + ] +] +``` + +Observe [tasks running](/devlog/2025#2025-01-26T22:11:00) and maybe +consider using more keybindings or running tasks for your projects. + +Probably binding commands is good, but maybe there is a feature in +other texts editors that you miss and would love to have it at +your fingertips. Then it's Zig time: +[Adding commands](/docs/architecture/command) to flow. + diff --git a/content/docs/architecture/palette.smd b/content/docs/architecture/palette.smd new file mode 100644 index 0000000..c5b8597 --- /dev/null +++ b/content/docs/architecture/palette.smd @@ -0,0 +1,24 @@ +--- +.title = "Palettes", +.date = @date("2025-10-20T00:00:00"), +.author = "Igor Támara", +.layout = "tutorial.shtml", +.draft = false, +.custom = { .githubedit = "https://github.com/neurocyte/flow-website/tree/master/content/docs/architecture/palette.md"}, +--- + +Palettes are overlay menus that allow to select an item from the +presented list, applying a command with the selected element, +optionally deleting the selected item; it's possible to close +the palette without selecting(cancel), filter the elements, and +having special elements that trigger different actions. + +To get the most of this section, it's recommended to have +read about [commands](/docs/architecture/command), and optionally +[minimodes](/docs/architecture/minimode). + +See +[clipboard history palette](https://github.com/neurocyte/flow/commit/634a18cb5685a3c3fcfc08301306e628d33c3256) + + +