Skip to content

Commit

Permalink
docs: add previewer and preloader docs
Browse files Browse the repository at this point in the history
  • Loading branch information
sxyazi committed Jan 14, 2024
1 parent 40d2c19 commit 1c084ec
Show file tree
Hide file tree
Showing 7 changed files with 159 additions and 15 deletions.
4 changes: 2 additions & 2 deletions docs/configuration/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
27 changes: 26 additions & 1 deletion docs/configuration/yazi.md
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand All @@ -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).
Expand Down
9 changes: 2 additions & 7 deletions docs/plugins/common.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ sidebar_position: 1
description: Learn how to use Yazi's Lua API.
---

# Common (Work in progress)
# Common

## Shared

Expand Down Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion docs/plugins/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ sidebar_position: 3
description: Learn how to use Yazi's Lua API.
---

# Config (Work in progress)
# Config

TODO

Expand Down
2 changes: 1 addition & 1 deletion docs/plugins/layout.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
128 changes: 126 additions & 2 deletions docs/plugins/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -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/
Expand All @@ -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.
2 changes: 1 addition & 1 deletion docs/plugins/utils.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ sidebar_position: 4
description: Learn how to use Yazi's Lua API.
---

# Utils (Work in progress)
# Utils

## ya

Expand Down

0 comments on commit 1c084ec

Please sign in to comment.