From 1c084ec392d19626c270409c0dd4aa6938717729 Mon Sep 17 00:00:00 2001 From: sxyazi Date: Sun, 14 Jan 2024 22:41:44 +0800 Subject: [PATCH] docs: add previewer and preloader docs --- docs/configuration/overview.md | 4 +- docs/configuration/yazi.md | 27 ++++++- docs/plugins/common.md | 9 +-- docs/plugins/config.md | 2 +- docs/plugins/layout.md | 2 +- docs/plugins/overview.md | 128 ++++++++++++++++++++++++++++++++- docs/plugins/utils.md | 2 +- 7 files changed, 159 insertions(+), 15 deletions(-) diff --git a/docs/configuration/overview.md b/docs/configuration/overview.md index 3dc1bcf8..1f420ed1 100644 --- a/docs/configuration/overview.md +++ b/docs/configuration/overview.md @@ -17,12 +17,12 @@ You can find the default configuration files at https://github.com/sxyazi/yazi/t To override any of the defaults, begin by copying the appropriate file (from the directory linked above) to: -- `~/.config/yazi/` on Unix/Unix-like systems. +- `~/.config/yazi/` on Unix-like systems. - `C:\Users\USERNAME\AppData\Roaming\yazi\config\` on Windows. For example, to edit your keybindings, start by copying the [`keymap.toml` file](https://github.com/sxyazi/yazi/blob/main/yazi-config/preset/keymap.toml) to: -- `~/.config/yazi/keymap.toml` on Unix/Unix-like systems. +- `~/.config/yazi/keymap.toml` on Unix-like systems. - `C:\Users\USERNAME\AppData\Roaming\yazi\config\keymap.toml` on Windows. ## Custom config directory diff --git a/docs/configuration/yazi.md b/docs/configuration/yazi.md index 0f266bca..5afef105 100644 --- a/docs/configuration/yazi.md +++ b/docs/configuration/yazi.md @@ -127,7 +127,7 @@ rules = [ Available rule parameters are as follows: - name (String): Glob expression for matching the file name. Case insensitive by default, add `\s` to the beginning to make it sensitive. -- mime (String): Glob expression for matching the MIME type. Case insensitive by default, add `\s` to the beginning to make it sensitive. +- mime (String): Glob expression for matching the mime-type. Case insensitive by default, add `\s` to the beginning to make it sensitive. - use (String): Opener name corresponding to the names in the [`[opener]` section](#opener). ## [tasks] @@ -142,6 +142,31 @@ Available rule parameters are as follows: - image_alloc: Maximum memory allocation limit (in bytes) for decoding a single image, `0` for unlimited. - image_bound(`[width, height]`): Maximum image size (in pixels) for decoding a single image, `0` for unlimited. +## [plugin] + +### Previewer + +You can prepend or append new preview rules to the default `previewers` under `[plugin]` using `prepend_previewers` and `append_previewers`. +Here are the available options for a single rule: + +- `name` (String): Glob expression for matching the file name. Case insensitive by default, add `\s` to the beginning to make it sensitive. +- `mime` (String): Glob expression for matching the mime-type. Case insensitive by default, add `\s` to the beginning to make it sensitive. +- `exec` (String): The name of the Lua plugin to be executed +- `sync` (Boolean): Whether to execute synchronously, the default is `false` + +### Preloader + +You can prepend or append new preview rules to the default `previewers` under `[plugin]` using `prepend_previewers` and `append_previewers`. +Here are the available options for a single rule: + +- `name` (String): Glob expression for matching the file name. Case insensitive by default, add `\s` to the beginning to make it sensitive. +- `mime` (String): Glob expression for matching the mime-type. Case insensitive by default, add `\s` to the beginning to make it sensitive. +- `cond` (String): Conditional expression – Only rules that meet this condition and satisfy either the `name` or `mime` will be applied. For example, `A & B` means A and B, and `A | !B` means A or not B. Here are the available factors: + - `mime`: This file has a mime-type +- `exec` (String): The name of the Lua plugin to be executed +- `multi` (Boolean): Whether to preload multiple files at once +- `prio` (String): Preload priority, `low`, `normal` or `high`. The default is `normal` if not specified. + ## [input] You can customize the title and position of each `Input`. As for position, it consists of two parts: [Origin](#origin) and [Offset](#offset). diff --git a/docs/plugins/common.md b/docs/plugins/common.md index fa2bda02..d5ba1bde 100644 --- a/docs/plugins/common.md +++ b/docs/plugins/common.md @@ -3,7 +3,7 @@ sidebar_position: 1 description: Learn how to use Yazi's Lua API. --- -# Common (Work in progress) +# Common ## Shared @@ -76,17 +76,12 @@ Properties: ## App data -The sync context accompanies the entire app lifecycle, you can access all app data through the `cx` within it: +You can access all app data through the `cx` within [Sync context](./overview.md#sync-context): - `cx.active`: The active tab, which is a [tab::Tab](#tabtab) - `cx.tabs`: All of tabs, which is a [manager::Tabs](#managertabs) - `cx.tasks`: All of tasks, which is a [tasks::Tasks](#taskstasks) -which is active during UI rendering (UI plugins) and when executing sync functional plugins (`plugin --sync` command). - -For better performance, the sync context is created only at the app's start and remains singular throughout. Thus, plugins running within this context share states, -prompting plugin developers to create separate namespaces for their plugins to prevent global space contamination. - ### `tab::Mode` Visual mode status. diff --git a/docs/plugins/config.md b/docs/plugins/config.md index b46ccc89..4bb559e9 100644 --- a/docs/plugins/config.md +++ b/docs/plugins/config.md @@ -3,7 +3,7 @@ sidebar_position: 3 description: Learn how to use Yazi's Lua API. --- -# Config (Work in progress) +# Config TODO diff --git a/docs/plugins/layout.md b/docs/plugins/layout.md index ea0abd29..4b70d333 100644 --- a/docs/plugins/layout.md +++ b/docs/plugins/layout.md @@ -3,7 +3,7 @@ sidebar_position: 2 description: Learn how to use Yazi's Lua API. --- -# Layout (Work in progress) +# Layout Paragraph, List, Bar, Border, and Gauge are renderable widgets; others need to be placed within any of them. diff --git a/docs/plugins/overview.md b/docs/plugins/overview.md index 23789c84..34e5d26c 100644 --- a/docs/plugins/overview.md +++ b/docs/plugins/overview.md @@ -9,11 +9,11 @@ description: Learn how to extend Yazi with Lua plugins. You can extend Yazi's functionality through Lua plugins, which need to be placed in the `plugins` subdirectory of Yazi's configuration directory, so either: -- `~/.config/yazi/plugins/` on Unix/Unix-like systems. +- `~/.config/yazi/plugins/` on Unix-like systems. - `C:\Users\USERNAME\AppData\Roaming\yazi\config\plugins\` on Windows. ``` -. +~/.config/yazi/ ├── init.lua ├── plugins/ │   ├── fzf.yazi/ @@ -28,3 +28,127 @@ For instance, the structure of the `zoxide.yazi` plugin is as: zoxide.yazi/ └── init.lua ``` + +You can use a plugin in two ways: + +- Functional plugin: Bind the `plugin` command to a key in `keymap.toml`, and activate it by pressing the key. +- Custom previewers, preloaders: Configure them as `previewers` or `preloaders` in your `[plugin]` of `yazi.toml`. + +## Sync vs Async + +The plugin system is designed with an async-first philosophy. Therefore, unless specifically specified, such as the `--sync` for the `plugin` command, all plugins run in an async context. + +There is one exception - all `init.lua` are synchronous, which includes: + +- The `init.lua` for Yazi itself, i.e. `~/.config/yazi/init.lua`. +- The `init.lua` for each plugin, e.g. `~/.config/yazi/plugins/zoxide.yazi/init.lua`. + +This is because `init.lua` is commonly used to initialize plugin configurations, and this process is synchronous: + +```lua +-- ~/.config/yazi/init.lua + +-- Initialize the zoxide plugin +-- Which needs `~/.config/yazi/plugins/zoxide.yazi/init.lua` to export a `setup` function +require("zoxide").setup { + foo = "hello", + bar = "world", + -- ... +} +``` + +### Sync context + +The sync context accompanies the entire app lifecycle, which is active during UI rendering (UI plugins), and on executing sync functional plugins (`plugin` command with `--sync`). + +For better performance, the sync context is created only at the app's start and remains singular throughout. Thus, plugins running within this context share states, +prompting plugin developers to create separate namespaces for their plugins to prevent global space contamination. + +### Async context + +When a plugin is executed asynchronously, an isolated async context is created for it automatically. + +In this context, you can use all the async functions supported by Yazi, and it operates concurrently with the main thread, ensuring that the main thread is not blocked. + +You can also obtain a small amount of app data from the sync context by calling a "sync function" (will supported in the next target, v0.2.1): + +```lua +-- ~/.config/yazi/plugins/my-async-plugin.yazi/init.lua + +local get_hovered_url = sync(function() + -- You can access all app data through the `cx`, + -- within the `sync()` block, in a async plugin + local h = cx.active.current.hovered + return h and tostring(h.url) or "" +end) + +return { + entry = function() + local h = get_hovered_url() + -- Do some time-consuming work, such as reading file, network request, etc. + -- It will execute concurrently with the main thread + end, +} +``` + +## Interface + +### Previewer + +```lua +return { + peek = function(self) return end, + seek = function(self) return end, +} +``` + +A previewer needs to return an table that implements the `peek` and `seek` functions. Both functions take a table parameter `self` and do not return any values. + +When the user presses `j` or `k` to switch between hovering files, `peek` is called, with: + +- `file`: The file to be previewed. +- `skip`: The number of units to skip. The units largely depend on your previewer, such as lines for code and percentages for videos. +- `area`: The Rect of the available preview area. +- `window`: The Rect of the entire terminal window. + +When the user presses `Alt-j` or `Alt-k` to scroll the preview of this file, `seek` is called, with: + +- `file`: The file being scrolled. +- `area`: The Rect of the available preview area. + +The task of `peek` is to draw in the preview area based on the values of `file` and `skip`. This process is asynchronous. + +The task of `seek` is to change the value of `skip` based on user behavior and trigger `peek` again. It is synchronous, meaning you can access app data through `cx`. + +Here are some preset previewers and preloaders you can refer to: [Yazi Preset Plugins](https://github.com/sxyazi/yazi/tree/main/yazi-plugin/preset/plugins) + +### Preloader + +```lua +return { + preload = function(self) + return 1 + end, +} +``` + +You need to return an table that implements the `preload` function, it receives a `self` parameter, which is a table with the same fields as [`peek`](#previewer). It has the following return values: + +| Binary | Decimal | | +| ------ | ------- | ----------------------- | +| `0 0` | 0 | Failure, don't continue | +| `0 1` | 1 | Success, don't continue | +| `1 0` | 2 | Failure, continue | +| `1 1` | 3 | Success, continue | + +When "continue" is set, the preloader can reload the files that have already been loaded at the next time point, such as when the user scrolls, leading to a page switch. This is usually done for the either: + +- Retrying in case of file loading failure +- Refreshing the file status upon successful loading + +Yazi will automatically invoke the `preload` concurrently for each file that matches the preload rules on the page. + +When the user specifies `multi = true` for it, the plugin allows preloading multiple files at once. In this case, `self.file` will be replaced by `self.files`. + +Typically, a preloader only needs to implement one of them - either single or multiple. This depends on the specific task and the magnitude of the workload. +If it truly requires loading multiple files at once, the user needs to be prompted to enable the `multi` option for it. diff --git a/docs/plugins/utils.md b/docs/plugins/utils.md index 298e374b..6f1db2a9 100644 --- a/docs/plugins/utils.md +++ b/docs/plugins/utils.md @@ -3,7 +3,7 @@ sidebar_position: 4 description: Learn how to use Yazi's Lua API. --- -# Utils (Work in progress) +# Utils ## ya