Auto generate some API docs from init.lua

This is the beginning of the xplr documentation revolution.

Closes: https://github.com/sayanarijit/xplr/issues/445
pull/455/head
Arijit Basu 2 years ago committed by Arijit Basu
parent 0cfeed7660
commit ca211bb073

@ -4,22 +4,28 @@
- [Quickstart][2]
- [Install][3]
- [Post Install][4]
- [Awesome Hacks][30]
- [Configuration][5]
- [General][6]
- [Node Types][10]
- [Layouts][9]
- [Modes][7]
- [Concept][32]
- [Key Bindings][27]
- [Configure Key Bindings][28]
- [Default Key Bindings][14]
- [Debug Key Bindings][29]
- [General Config][6]
- [Modes][7]
- [Node Type][33]
- [Layout][34]
- [Mode][35]
- [Message][8]
- [Layouts][9]
- [Node Types][10]
- [Borders][31]
- [Style][11]
- [Sorting][12]
- [Filtering][13]
- [Column Renderer][26]
- [Lua Function Calls][36]
- [Environment Variables and Pipes][37]
- [Awesome Hacks][30]
- [Plugin][15]
- [Installing Plugins][16]
- [Writing Plugins][17]
@ -63,3 +69,9 @@
[29]: debug-key-bindings.md
[30]: awesome-hacks.md
[31]: borders.md
[32]: concept.md
[33]: node-type.md
[34]: layout.md
[35]: mode.md
[36]: lua-function-calls.md
[37]: environment-variables-and-pipes.md

@ -265,7 +265,7 @@ xplr.config.general.table.col_widths = {
```
[1]: #table-renderer-argument
[2]: layouts.md#table
[2]: layout.md#table
[3]: #parent
[4]: #relative_path
[5]: #absolute_path
@ -296,4 +296,4 @@ xplr.config.general.table.col_widths = {
[30]: #permission
[31]: #resolved-node-metadata
[32]: general-config.md#tabletree
[33]: node_types.md#meta
[33]: node_type.md#meta

@ -0,0 +1,30 @@
# Concept
These are the concepts that make xplr probably the most hackable terminal file
explorer.
- [Key Bindings][1]
- [Node Type][2]
- [Layout][3]
- [Mode][4]
- [Message][5]
- [Borders][6]
- [Style][7]
- [Sorting][8]
- [Filtering][9]
- [Column Renderer][10]
- [Lua Function Calls][11]
- [Environment Variables and Pipes][12]
[1]: key-bindings.md
[2]: node-type.md
[3]: layout.md
[4]: mode.md
[5]: message.md
[6]: borders.md
[7]: style.md
[8]: sorting.md
[9]: filtering.md
[10]: column-renderer.md
[11]: lua-function-calls.md
[12]: environment-variables-and-pipes.md

@ -1,41 +1,25 @@
# Configuration
xplr can be configured using [Lua][1] via a special file
named `init.lua`
([example][2]), which
can be placed in `~/.config/xplr/` (user specific) or `/etc/xplr/` (global)
depending on the use case.
xplr can be configured using [Lua][3] via a special file named `init.lua`,
which can be placed in `~/.config/xplr/` (local to user) or `/etc/xplr/`
(global) depending on the use case.
When a user specific configuration is available, the global configuration file
will be ignored.
However, it's also possible to place the file anywhere, with any name and use
the command-line argument `-c` / `--config` to specify its path explicitely. In
that case, both `~/.config/xplr/init.lua` and `/etc/xplr/init.lua` will be
ignored.
## How Config Is Loaded
When xplr loads, it first executes the built-in
[init.lua][2] to set
the default values, which is then overwritten by another config file, if found
When xplr loads, it first executes the [built-in init.lua][1] to set the
default values, which is then overwritten by another config file, if found
using the following lookup order:
**--config /path/to/init.lua** > **~/.config/xplr/init.lua** > **/etc/xplr/init.lua**
1. `--config /path/to/init.lua`
2. `~/.config/xplr/init.lua`
3. `/etc/xplr/init.lua`
## config
The first one found will be loaded by xplr and the lookup will stop.
The xplr configuration, exposed as `xplr.config` Lua API contains the
following fields:
The loaded config can be further extended using the `-C` or `--extra-config`
command-line option.
- [general][3]
- [modes][4]
- [layouts][5]
- [node_types][6]
> **NEED HELP:** Auto generate rest of the docs from [src/init.lua][1]
> using [docs/script/generate.lua][2].
[1]: https://www.lua.org/
[2]: https://github.com/sayanarijit/xplr/blob/main/src/init.lua
[3]: general-config.md
[4]: modes.md
[5]: layouts.md
[6]: node_types.md
[1]: https://github.com/sayanarijit/xplr/blob/main/src/init.lua
[2]: https://github.com/sayanarijit/xplr/blob/main/docs/script/generate.lua
[3]: https://www.lua.org

@ -218,9 +218,9 @@ Visit [Awesome Plugins][27] for more [integration][28] options.
[19]: install.md
[20]: post-install.md
[21]: https://github.com/junegunn/fzf
[22]: message.md#environment-variables
[23]: message.md#input-pipe
[24]: message.md#output-pipes
[22]: mode.md#environment-variables
[23]: mode.md#input-pipe
[24]: mode.md#output-pipes
[25]: https://s3.gifyu.com/images/xplr-fzf.gif
[26]: https://gifyu.com/image/tW86
[27]: awesome-plugins.md

@ -0,0 +1,129 @@
# Environment Variables and Pipes
Alternative to `CallLua`, `CallLuaSilently` messages that call Lua functions,
there are `Call`, `CallSilently`, `BashExec`, `BashExecSilently` messages
that call shell commands.
However, unlike the Lua functions, these shell commands have to read the useful
information and send messages via environment variables and temporary files
called "pipe"s. These environment variables and files are only available when
a command is being executed.
Visit the [**fzf integration tutorial**][19]
for example.
### Environment variables
To see the environment variables, invoke the shell by typing `:!` in default
mode and run the following command:
```
env | grep ^XPLR_
```
You will see something like:
```
XPLR_FOCUS_INDEX=0
XPLR_MODE=action to
XPLR_PIPE_SELECTION_OUT=/run/user/1000/xplr/session/122278/pipe/selection_out
XPLR_INPUT_BUFFER=
XPLR_PIPE_GLOBAL_HELP_MENU_OUT=/run/user/1000/xplr/session/122278/pipe/global_help_menu_out
XPLR_PID=122278
XPLR_PIPE_MSG_IN=/run/user/1000/xplr/session/122278/pipe/msg_in
XPLR_PIPE_LOGS_OUT=/run/user/1000/xplr/session/122278/pipe/logs_out
XPLR_PIPE_RESULT_OUT=/run/user/1000/xplr/session/122278/pipe/result_out
XPLR_PIPE_HISTORY_OUT=/run/user/1000/xplr/session/122278/pipe/history_out
XPLR_FOCUS_PATH=/home/sayanarijit/Documents/GitHub/xplr/docs/en/book
XPLR_SESSION_PATH=/run/user/1000/xplr/session/122278
XPLR_APP_VERSION=0.14.3
XPLR_PIPE_DIRECTORY_NODES_OUT=/run/user/1000/xplr/session/122278/pipe/directory_nodes_out
```
The environment variables starting with `XPLR_PIPE_` are the temporary files
called "pipe"s.
#### Input pipe
Current there is only one input pipe.
- [XPLR_PIPE_MSG_IN][20]
#### Output pipes
`XPLR_PIPE_*_OUT` are the output pipes that contain data which cannot be
exposed directly via environment variables, like multi-line string.
- [XPLR_PIPE_SELECTION_OUT][21]
- [XPLR_PIPE_GLOBAL_HELP_MENU_OUT][22]
- [XPLR_PIPE_LOGS_OUT][23]
- [XPLR_PIPE_RESULT_OUT][24]
- [XPLR_PIPE_HISTORY_OUT][25]
- [XPLR_PIPE_DIRECTORY_NODES_OUT][26]
#### XPLR_PIPE_MSG_IN
Append new-line delimited messages to this pipe in [YAML][27]
(or [JSON][7]) syntax. These messages will be read and
handled by xplr after the command execution.
#### XPLR_PIPE_SELECTION_OUT
New-line delimited list of selected paths.
#### XPLR_PIPE_GLOBAL_HELP_MENU_OUT
The full help menu.
#### XPLR_PIPE_LOGS_OUT
New-line delimited list of logs.
#### XPLR_PIPE_RESULT_OUT
New-line delimited result (selected paths if any, else the focused path)
#### XPLR_PIPE_HISTORY_OUT
New-line delimited list of last visited paths (similar to jump list in vim).
#### XPLR_PIPE_DIRECTORY_NODES_OUT
New-line delimited list of paths, filtered and sorted as displayed in the
[files table][28].
### Example: Using Environment Variables and Pipes
```lua
xplr.config.modes.builtin.default.key_bindings.on_key.space = {
help = "ask name and greet",
messages = {
{
BashExec = [===[
echo "What's your name?"
read name
greeting="Hello $name!"
message="$greeting You are inside $PWD"
echo LogSuccess: '"'$message'"' >> "${XPLR_PIPE_MSG_IN:?}"
]===]
}
}
}
-- Now, when you press "space" in default mode, you will be prompted for your
-- name. Enter your name to receive a nice greeting and to know your location.
```
[7]: https://www.json.org
[19]: configure-key-bindings.md#tutorial-adding-a-new-mode
[20]: #xplr_pipe_msg_in
[21]: #xplr_pipe_selection_out
[22]: #xplr_pipe_global_help_menu_out
[23]: #xplr_pipe_logs_out
[24]: #xplr_pipe_result_out
[25]: #xplr_pipe_history_out
[26]: #xplr_pipe_directory_nodes_out
[27]: https://www.yaml.org
[28]: layout.md#table

@ -2,7 +2,10 @@
This configuration is exposed via the `xplr.config.general` API.
Until we figure out a way to auto generate this page from the code, please
refer to the comments in the default [init.lua][1].
For now, kindly refer to [**init.lua**][1]
> **NEED HELP:** Auto generate rest of the docs from [src/init.lua][1]
> using [docs/script/generate.lua][2].
[1]: https://github.com/sayanarijit/xplr/blob/main/src/init.lua
[2]: https://github.com/sayanarijit/xplr/blob/main/docs/script/generate.lua

@ -93,8 +93,8 @@ Some of the coolest features xplr provide beside the basic stuff:
[9]: https://github.com/sayanarijit/xplr/pull/397
[10]: message.md
[11]: configure-key-bindings.md
[12]: message.md#input-pipe
[13]: message.md#lua-function-calls
[12]: mode.md#input-pipe
[13]: lua-function-calls.md
[14]: awesome-plugins.md#integration
[15]: awesome-integrations.md
[16]: awesome-hacks.md

@ -0,0 +1,434 @@
# Layout
#### Example: Defining Custom Layout
[![layout.png][23]][24]
```lua
xplr.config.layouts.builtin.default = {
Horizontal = {
config = {
margin = 1,
horizontal_margin = 2,
vertical_margin = 3,
constraints = {
{ Percentage = 50 },
{ Percentage = 50 },
}
},
splits = {
"Table",
"HelpMenu",
}
}
}
```
A layout can be one of the following:
- ["Nothing"][8]
- ["Table"][9]
- ["InputAndLogs"][10]
- ["Selection"][11]
- ["HelpMenu"][12]
- ["SortAndFilter"][13]
- { [CustomContent][25] = { [title][33], [body][34] }
- { [Horizontal][14] = { [config][15], [splits][17] }
- { [Vertical][16] = { [config][15], [splits][17] }
### Nothing
This layout contains a blank panel.
### Table
This layout contains the table displaying the files and directories in the
current directory.
### InputAndLogs
This layout contains the panel displaying the input prompt and logs.
### Selection
This layout contains the panel displaying the selected paths.
### HelpMenu
This layout contains the panel displaying the help menu for the current mode in
real-time.
### SortAndFilter
This layout contains the panel displaying the pipeline of sorters and filters
applied of the list of paths being displayed.
### Horizontal
This is a special layout that splits the panel into two horizontal parts.
It contains the following information:
- [config][15]
- [splits][17]
### Vertical
This is a special layout that splits the panel into two vertical parts.
It contains the following information:
- [config][15]
- [splits][17]
## Layout Config
A layout config contains the following information:
- [margin][18]
- [horizontal_margin][19]
- [vertical_margin][20]
- [constraints][21]
### margin
Type: nullable integer
The width of the margin in all direction.
### horizontal_Margin
Type: nullable integer
The width of the horizontal margins. Overwrites the [margin][18] value.
### vertical_Margin
Type: nullable integer
The width of the vertical margins. Overwrites the [margin][18] value.
### constraints
Type: nullable list of [Constraint][22]
The constraints applied on the layout.
## Constraint
A constraint can be one of the following:
- { Percentage = int }
- { Ratio = { int, int } }
- { Length = { int }
- { LengthLessThanScreenHeight = int }
- { LengthLessThanScreenWidth = int }
- { LengthLessThanLayoutHeight = int }
- { LengthLessThanLayoutWidth = int }
- { Max = int }
- { MaxLessThanScreenHeight = int }
- { MaxLessThanScreenWidth = int }
- { MaxLessThanLayoutHeight = int }
- { MaxLessThanLayoutWidth = int }
- { Min = int }
- { MinLessThanScreenHeight = int }
- { MinLessThanScreenWidth = int }
- { MinLessThanLayoutHeight = int }
- { MinLessThanLayoutWidth = int }
TODO: document each constraint.
## splits
Type: list of [Layout][3]
The list of child layouts to fit into the parent layout.
## Custom Content
Custom content is a special layout to render something custom.
It contains the following information:
- [title][33]
- [body][34]
### title
Type: nullable string
The title of the panel.
### body
Type: [Content Body][26]
The body of the panel.
## Content Body
Content body can be one of the following:
- [StaticParagraph][27]
- [DynamicParagraph][28]
- [StaticList][29]
- [DynamicList][30]
- [StaticTable][31]
- [DynamicTable][32]
### Static Paragraph
A paragraph to render. It contains the following fields:
- **render** (string): The string to render.
#### Example: Render a custom static paragraph
```lua
xplr.config.layouts.builtin.default = {
CustomContent = {
title = "custom title",
body = {
StaticParagraph = { render = "custom body" },
},
},
}
```
### Dynamic Paragraph
A [Lua function][35] to render a custom paragraph.
It contains the following fields:
- **render** (string): The [lua function][35] that returns the paragraph to
render.
#### Example: Render a custom dynamic paragraph
```lua
xplr.config.layouts.builtin.default = {
CustomContent = {
title = "custom title",
body = { DynamicParagraph = { render = "custom.render_layout" } },
},
}
xplr.fn.custom.render_layout = function(ctx)
return ctx.app.pwd
end
```
### Static List
A list to render. It contains the following fields:
- **render** (list of string): The list to render.
#### Example: Render a custom static list
```lua
xplr.config.layouts.builtin.default = {
CustomContent = {
title = "custom title",
body = {
StaticList = { render = { "1", "2", "3" } },
},
},
}
```
### Dynamic List
A [Lua function][35] to render a custom list.
It contains the following fields:
- **render** (string): The [lua function][35] that returns the list to render.
#### Example: Render a custom dynamic list
```lua
xplr.config.layouts.builtin.default = {
CustomContent = {
title = "custom title",
body = { DynamicList = { render = "custom.render_layout" } },
},
}
xplr.fn.custom.render_layout = function(ctx)
return {
ctx.app.pwd,
ctx.app.version,
tostring(ctx.app.pid),
}
end
```
### Static Table
A table to render. It contains the following fields:
- **widths** (list of [Constraint][22]): Width of the columns.
- **col_spacing** (nullable int): Spacing between columns. Defaults to 1.
- **render** (list of list of string): The rows and columns to render.
#### Example: Render a custom static table
```lua
xplr.config.layouts.builtin.default = {
CustomContent = {
title = "custom title",
body = {
StaticTable = {
widths = {
{ Percentage = 50 },
{ Percentage = 50 },
},
col_spacing = 1,
render = {
{ "a", "b" },
{ "c", "d" },
},
},
},
},
}
```
### Dynamic Table
A [Lua function][35] to render a custom table.
It contains the following fields:
- **widths** (list of [Constraint][22]): Width of the columns.
- **col_spacing** (nullable int): Spacing between columns. Defaults to 1.
- **render** (string): The [lua function][35] that returns the table to render.
#### Example: Render a custom dynamic table
```lua
xplr.config.layouts.builtin.default = {
CustomContent = {
title = "custom title",
body = {
DynamicTable = {
widths = {
{ Percentage = 50 },
{ Percentage = 50 },
},
col_spacing = 1,
render = "custom.render_layout",
},
},
},
}
xplr.fn.custom.render_layout = function(ctx)
return {
{ "", "" },
{ "Layout height", tostring(ctx.layout_size.height) },
{ "Layout width", tostring(ctx.layout_size.width) },
{ "", "" },
{ "Screen height", tostring(ctx.screen_size.height) },
{ "Screen width", tostring(ctx.screen_size.width) },
}
end
```
## Content Renderer
It is a Lua function that receives [a special argument][36] as input and
returns some output that can be rendered in the UI. It is used to render
content body for the custom dynamic layouts.
## Content Renderer Argument
It contains the following information:
- [layout_size][37]
- [screen_size][37]
- [app][38]
### Size
It contains the following information:
- x
- y
- height
- width
Every field is of integer type.
### app
This is a lightweight version of the [Lua Context][39]. In this context, the
heavyweight fields like [directory_buffer][50] are omitted for performance
reasons.
Hence, only the following fields are avilable.
- [version][40]
- [pwd][41]
- [focused_node][42]
- [selection][43]
- [mode][44]
- [layout][45]
- [input_buffer][46]
- [pid][47]
- [session_path][48]
- [explorer_config][49]
## Also See:
- [xplr.config.layouts][51]
[1]: #builtin
[2]: #custom
[3]: #layout
[4]: #default
[5]: #no_help
[6]: #no_selection
[7]: #no_help_no_selection
[8]: #nothing
[9]: #table
[10]: #inputandlogs
[11]: #selection
[12]: #helpmenu
[13]: #sortandfilter
[14]: #horizontal
[15]: #layout-config
[16]: #vertical
[17]: #splits
[18]: #margin
[19]: #horizontal_margin
[20]: #vertical_margin
[21]: #constraints
[22]: #constraint
[23]: https://s6.gifyu.com/images/layout.png
[24]: https://gifyu.com/image/1X38
[25]: #custom-content
[26]: #content-body
[27]: #static-paragraph
[28]: #dynamic-paragraph
[29]: #static-list
[30]: #dynamic-list
[31]: #static-table
[32]: #dynamic-table
[33]: #title
[34]: #body
[35]: #content-renderer
[36]: #content-renderer-argument
[37]: #size
[38]: #app
[39]: lua-function-calls.md#lua-context
[40]: lua-function-calls.md#version
[41]: lua-function-calls.md#pwd
[42]: lua-function-calls.md#focused_node
[43]: lua-function-calls.md#selection
[44]: lua-function-calls.md#mode
[45]: lua-function-calls.md#layout
[46]: lua-function-calls.md#input_buffer
[47]: lua-function-calls.md#pid
[48]: lua-function-calls.md#session_path
[49]: lua-function-calls.md#explorer_config
[50]: lua-function-calls.md#directory_buffer
[51]: layouts.md

@ -1,496 +1,11 @@
# Layouts
#### Example: Defining Custom Layout
This configuration is exposed via the `xplr.config.layouts` API.
[![layout.png][23]][24]
For now, kindly refer to [**init.lua**][1]
```lua
xplr.config.layouts.builtin.default = {
Horizontal = {
config = {
margin = 1,
horizontal_margin = 2,
vertical_margin = 3,
constraints = {
{ Percentage = 50 },
{ Percentage = 50 },
}
},
splits = {
"Table",
"HelpMenu",
}
}
}
```
> **NEED HELP:** Auto generate rest of the docs from [src/init.lua][1]
> using [docs/script/generate.lua][2].
xplr layouts define the structure of the UI, i.e. how many panel we see,
placement and size of the panels, how they look etc.
This is configuration exposed via the `xplr.config.layouts` API. It contains
the following fields:
- [builtin][1]
- [custom][2]
The users can switch between these layouts at run-time.
## builtin
Type: mapping of string and [Layout][3]
This is exposed by the `xplr.config.layouts.builtin` API.
xplr by default provides the following builtin layouts:
- [default][4]
- [no_help][5]
- [no_selection][6]
- [no_help_no_selection][7]
### default
Type: [Layout][3]
This is the default layout we see when we run xplr.
### no_help
Type: [Layout][3]
This layout hides the help menu.
### no_selection
Type: [Layout][3]
This layout hides the selection panel.
### no_help_no_selection
Type: [Layout][3]
This layout hides both the help menu and the selection panel.
## custom
Type: mapping of string and [Layout][3]
This is exposed by the `xplr.config.layouts.custom` API.
It allows the users to define any custom layout.
Example:
```lua
xplr.config.layouts.custom.example = "Nothing"
xplr.config.general.initial_layout = "example"
-- when you load xplr, you should see a blank screen
```
## Layout
A layout can be one of the following:
- ["Nothing"][8]
- ["Table"][9]
- ["InputAndLogs"][10]
- ["Selection"][11]
- ["HelpMenu"][12]
- ["SortAndFilter"][13]
- { [CustomContent][25] = { [title][33], [body][34] }
- { [Horizontal][14] = { [config][15], [splits][17] }
- { [Vertical][16] = { [config][15], [splits][17] }
### Nothing
This layout contains a blank panel.
### Table
This layout contains the table displaying the files and directories in the
current directory.
### InputAndLogs
This layout contains the panel displaying the input prompt and logs.
### Selection
This layout contains the panel displaying the selected paths.
### HelpMenu
This layout contains the panel displaying the help menu for the current mode in
real-time.
### SortAndFilter
This layout contains the panel displaying the pipeline of sorters and filters
applied of the list of paths being displayed.
### Horizontal
This is a special layout that splits the panel into two horizontal parts.
It contains the following information:
- [config][15]
- [splits][17]
### Vertical
This is a special layout that splits the panel into two vertical parts.
It contains the following information:
- [config][15]
- [splits][17]
## Layout Config
A layout config contains the following information:
- [margin][18]
- [horizontal_margin][19]
- [vertical_margin][20]
- [constraints][21]
### margin
Type: nullable integer
The width of the margin in all direction.
### horizontal_Margin
Type: nullable integer
The width of the horizontal margins. Overwrites the [margin][18] value.
### vertical_Margin
Type: nullable integer
The width of the vertical margins. Overwrites the [margin][18] value.
### constraints
Type: nullable list of [Constraint][22]
The constraints applied on the layout.
## Constraint
A constraint can be one of the following:
- { Percentage = int }
- { Ratio = { int, int } }
- { Length = { int }
- { LengthLessThanScreenHeight = int }
- { LengthLessThanScreenWidth = int }
- { LengthLessThanLayoutHeight = int }
- { LengthLessThanLayoutWidth = int }
- { Max = int }
- { MaxLessThanScreenHeight = int }
- { MaxLessThanScreenWidth = int }
- { MaxLessThanLayoutHeight = int }
- { MaxLessThanLayoutWidth = int }
- { Min = int }
- { MinLessThanScreenHeight = int }
- { MinLessThanScreenWidth = int }
- { MinLessThanLayoutHeight = int }
- { MinLessThanLayoutWidth = int }
TODO: document each constraint.
## splits
Type: list of [Layout][3]
The list of child layouts to fit into the parent layout.
## Custom Content
Custom content is a special layout to render something custom.
It contains the following information:
- [title][33]
- [body][34]
### title
Type: nullable string
The title of the panel.
### body
Type: [Content Body][26]
The body of the panel.
## Content Body
Content body can be one of the following:
- [StaticParagraph][27]
- [DynamicParagraph][28]
- [StaticList][29]
- [DynamicList][30]
- [StaticTable][31]
- [DynamicTable][32]
### Static Paragraph
A paragraph to render. It contains the following fields:
- **render** (string): The string to render.
#### Example: Render a custom static paragraph
```lua
xplr.config.layouts.builtin.default = {
CustomContent = {
title = "custom title",
body = {
StaticParagraph = { render = "custom body" },
},
},
}
```
### Dynamic Paragraph
A [Lua function][35] to render a custom paragraph.
It contains the following fields:
- **render** (string): The [lua function][35] that returns the paragraph to
render.
#### Example: Render a custom dynamic paragraph
```lua
xplr.config.layouts.builtin.default = {
CustomContent = {
title = "custom title",
body = { DynamicParagraph = { render = "custom.render_layout" } },
},
}
xplr.fn.custom.render_layout = function(ctx)
return ctx.app.pwd
end
```
### Static List
A list to render. It contains the following fields:
- **render** (list of string): The list to render.
#### Example: Render a custom static list
```lua
xplr.config.layouts.builtin.default = {
CustomContent = {
title = "custom title",
body = {
StaticList = { render = { "1", "2", "3" } },
},
},
}
```
### Dynamic List
A [Lua function][35] to render a custom list.
It contains the following fields:
- **render** (string): The [lua function][35] that returns the list to render.
#### Example: Render a custom dynamic list
```lua
xplr.config.layouts.builtin.default = {
CustomContent = {
title = "custom title",
body = { DynamicList = { render = "custom.render_layout" } },
},
}
xplr.fn.custom.render_layout = function(ctx)
return {
ctx.app.pwd,
ctx.app.version,
tostring(ctx.app.pid),
}
end
```
### Static Table
A table to render. It contains the following fields:
- **widths** (list of [Constraint][22]): Width of the columns.
- **col_spacing** (nullable int): Spacing between columns. Defaults to 1.
- **render** (list of list of string): The rows and columns to render.
#### Example: Render a custom static table
```lua
xplr.config.layouts.builtin.default = {
CustomContent = {
title = "custom title",
body = {
StaticTable = {
widths = {
{ Percentage = 50 },
{ Percentage = 50 },
},
col_spacing = 1,
render = {
{ "a", "b" },
{ "c", "d" },
},
},
},
},
}
```
### Dynamic Table
A [Lua function][35] to render a custom table.
It contains the following fields:
- **widths** (list of [Constraint][22]): Width of the columns.
- **col_spacing** (nullable int): Spacing between columns. Defaults to 1.
- **render** (string): The [lua function][35] that returns the table to render.
#### Example: Render a custom dynamic table
```lua
xplr.config.layouts.builtin.default = {
CustomContent = {
title = "custom title",
body = {
DynamicTable = {
widths = {
{ Percentage = 50 },
{ Percentage = 50 },
},
col_spacing = 1,
render = "custom.render_layout",
},
},
},
}
xplr.fn.custom.render_layout = function(ctx)
return {
{ "", "" },
{ "Layout height", tostring(ctx.layout_size.height) },
{ "Layout width", tostring(ctx.layout_size.width) },
{ "", "" },
{ "Screen height", tostring(ctx.screen_size.height) },
{ "Screen width", tostring(ctx.screen_size.width) },
}
end
```
## Content Renderer
It is a Lua function that receives [a special argument][36] as input and
returns some output that can be rendered in the UI. It is used to render
content body for the custom dynamic layouts.
## Content Renderer Argument
It contains the following information:
- [layout_size][37]
- [screen_size][37]
- [app][38]
### Size
It contains the following information:
- x
- y
- height
- width
Every field is of integer type.
### app
This is a lightweight version of the [Lua Context][39]. In this context, the
heavyweight fields like [directory_buffer][50] are omitted for performance
reasons.
Hence, only the following fields are avilable.
- [version][40]
- [pwd][41]
- [focused_node][42]
- [selection][43]
- [mode][44]
- [layout][45]
- [input_buffer][46]
- [pid][47]
- [session_path][48]
- [explorer_config][49]
[1]: #builtin
[2]: #custom
[3]: #layout
[4]: #default
[5]: #no_help
[6]: #no_selection
[7]: #no_help_no_selection
[8]: #nothing
[9]: #table
[10]: #inputandlogs
[11]: #selection
[12]: #helpmenu
[13]: #sortandfilter
[14]: #horizontal
[15]: #layout-config
[16]: #vertical
[17]: #splits
[18]: #margin
[19]: #horizontal_margin
[20]: #vertical_margin
[21]: #constraints
[22]: #constraint
[23]: https://s6.gifyu.com/images/layout.png
[24]: https://gifyu.com/image/1X38
[25]: #custom-content
[26]: #content-body
[27]: #static-paragraph
[28]: #dynamic-paragraph
[29]: #static-list
[30]: #dynamic-list
[31]: #static-table
[32]: #dynamic-table
[33]: #title
[34]: #body
[35]: #content-renderer
[36]: #content-renderer-argument
[37]: #size
[38]: #app
[39]: message.md#lua-context
[40]: message.md#version
[41]: message.md#pwd
[42]: message.md#focused_node
[43]: message.md#selection
[44]: message.md#mode
[45]: message.md#layout
[46]: message.md#input_buffer
[47]: message.md#pid
[48]: message.md#session_path
[49]: message.md#explorer_config
[50]: message.md#directory_buffer
[1]: https://github.com/sayanarijit/xplr/blob/main/src/init.lua
[2]: https://github.com/sayanarijit/xplr/blob/main/docs/script/generate.lua

@ -0,0 +1,354 @@
# Lua Function Calls
xplr allows you to define lua functions using the `xplr.fn.custom` Lua API.
These functions can be called using messages like `CallLua`, `CallLuaSilently`.
When called the function receives a [special argument][14] that
contains some useful information. The function can optionally return a list of
messages which will be handled by xplr.
### Lua Context
This is a special argument passed to the lua functions when called using the
`CallLua`, `CallLuaSilently` messages.
It contains the following information:
- [version][29]
- [pwd][31]
- [focused_node][32]
- [directory_buffer][33]
- [selection][34]
- [mode][35]
- [layout][36]
- [input_buffer][37]
- [pid][38]
- [session_path][39]
- [explorer_config][40]
- [history][41]
- [last_modes][42]
### version
Type: string
xplr version. Can be used to test compatibility.
### pwd
Type: string
The present working directory/
### focused_node
Type: nullable [Node][44]
The node under focus.
### directory_buffer
Type: nullable [Directory Buffer][62]
The directory buffer being rendered.
### selection
Type: list of selected [Node][44]s
The selected nodes.
### mode
Type: [Mode][8]
Current mode.
### layout
Type: [Layout][11]
Current layout.
### input_buffer
Type: nullable string
The input buffer.
### pid
Type: integer
The xplr session PID.
### session_path
Type: string
The session path.
### explorer_config
[TODO][66]
### history
Type: [History][70]
### last_modes
Type: list of [Mode][8]
Last modes, not popped yet.
### parent
Type: string
The parent path of the node.
### relative_path
Type: string
The path relative to the parent, i.e. the file/directory name with extension.
### absolute_path
Type: string
The absolute path (without resolving symlinks) of the node.
### extension
Type: string
The extension of the node.
### is_symlink
Type: boolean
`true` if the node is a symlink.
### is_broken
Type: boolean
`true` if the node is a broken symlink.
### is_dir
Type: boolean
`true` if the node is a directory.
### is_file
Type: boolean
`true` if the node is a file.
### is_readonly
Type: boolean
`true` if the node is real-only.
### mime_essence
Type: string
The mime type of the node. For e.g. `text/csv`, `image/jpeg` etc.
### size
Type: integer
The size of the exact node. The size of a directory won't be calculated
recursively.
### human_size
Type: string
Like size but in human readable format.
### permissions
Type: [Permission][60]
The [permissions][60] applied to the node.
### canonical
Type: nullable [Resolved Node Metadata][61]
If the node is a symlink, it will hold information about the symlink resolved
node. Else, it will hold information the actual node. It the symlink is broken,
it will be null.
### symlink
Type: nullable [Resolved Node Metadata][61]
If the node is a symlink and is not broken, it will hold information about the
symlink resolved node. However, it will never hold information about the actual
node. It will instead be null.
### Node
A node contains the following fields:
- [parent][45]
- [relative_path][46]
- [absolute_path][47]
- [extension][48]
- [is_symlink][49]
- [is_broken][50]
- [is_dir][51]
- [is_file][52]
- [is_readonly][53]
- [mime_essence][54]
- [size][55]
- [human_size][56]
- [permissions][57]
- [canonical][58]
- [symlink][59]
### Directory Buffer
Directory buffer contains the following fields:
- [parent][45]
- [nodes][63]
- [total][64]
- [focus][65]
#### parent
Type: string
The parent path of the node.
#### nodes
Type: list of [Node][44]s
A list of visible nodes.
#### total
Type: int
The count of nodes being rendered.
#### focus
Type: int
The index of the node under focus. It can be `0` even when there's no node to
focus on.
### History
History contains the following fields:
- [loc][68]
- [paths][69]
#### loc
Type: int
Location of the current path in history.
#### paths
Type: list of string
Visited paths.
### Example: Using Lua Function Calls
```lua
-- Define the function
xplr.fn.custom.ask_name_and_greet = function(app)
print("What's your name?")
local name = io.read()
local greeting = "Hello " .. name .. "!"
local message = greeting .. " You are inside " .. app.pwd
return {
{ LogSuccess = message },
}
end
-- Map the function to a key (space)
xplr.config.modes.builtin.default.key_bindings.on_key.space = {
help = "ask name and greet",
messages = {
{ CallLua = "custom.ask_name_and_greet" }
}
}
-- Now, when you press "space" in default mode, you will be prompted for your
-- name. Enter your name to receive a nice greeting and to know your location.
```
[7]: https://www.json.org
[8]: modes.md#mode
[9]: modes.md#builtin
[10]: modes.md#custom
[11]: layouts.md
[12]: layouts.md#builtin
[13]: layouts.md#custom
[14]: #lua-context
[15]: filtering.md#filter
[16]: filtering.md
[17]: sorting.md#sorter
[29]: #version
[30]: #config
[31]: #pwd
[32]: #focused_node
[33]: #directory_buffer
[34]: #selection
[35]: #mode
[36]: #layout
[37]: #input_buffer
[38]: #pid
[39]: #session_path
[40]: #explorer_config
[41]: #history
[42]: #last_modes
[43]: configuration.md#config
[44]: #node
[45]: #parent
[46]: #relative_path
[47]: #absolute_path
[48]: #extension
[49]: #is_symlink
[50]: #is_broken
[51]: #is_dir
[52]: #is_file
[53]: #is_readonly
[54]: #mime_essence
[55]: #size
[56]: #human_size
[57]: #permissions
[58]: #canonical
[59]: #symlink
[60]: column-renderer.md#permission
[61]: column-renderer.md#resolved-node-metadata
[62]: #directory-buffer
[63]: #nodes
[64]: #total
[65]: #focus
[66]: https://docs.rs/xplr/latest/xplr/app/struct.ExplorerConfig.html
[67]: #history
[68]: #loc
[69]: #paths
[70]: #history-1

@ -852,492 +852,21 @@ Cursor based input operation can be one of the following:
- "DeleteNextWord"
- "DeleteLine"
## Lua Function Calls
xplr allows users to define lua functions using the `xplr.fn.custom` Lua API.
These functions can be called using messages like `CallLua`, `CallLuaSilently`.
When called the function receives a [special argument][14] that
contains some useful information. The function can optionally return a list of
messages which will be handled by xplr.
### Lua Context
This is a special argument passed to the lua functions when called using the
`CallLua`, `CallLuaSilently` messages.
It contains the following information:
- [version][29]
- [pwd][31]
- [focused_node][32]
- [directory_buffer][33]
- [selection][34]
- [mode][35]
- [layout][36]
- [input_buffer][37]
- [pid][38]
- [session_path][39]
- [explorer_config][40]
- [history][41]
- [last_modes][42]
### version
Type: string
xplr version. Can be used to test compatibility.
### pwd
Type: string
The present working directory/
### focused_node
Type: nullable [Node][44]
The node under focus.
### directory_buffer
Type: nullable [Directory Buffer][62]
The directory buffer being rendered.
### selection
Type: list of selected [Node][44]s
The selected nodes.
### mode
Type: [Mode][8]
Current mode.
### layout
Type: [Layout][11]
Current layout.
### input_buffer
Type: nullable string
The input buffer.
### pid
Type: integer
The xplr session PID.
### session_path
Type: string
The session path.
### explorer_config
[TODO][66]
### history
Type: [History][70]
### last_modes
Type: list of [Mode][8]
Last modes, not popped yet.
### parent
Type: string
The parent path of the node.
### relative_path
Type: string
The path relative to the parent, i.e. the file/directory name with extension.
### absolute_path
Type: string
The absolute path (without resolving symlinks) of the node.
### extension
Type: string
The extension of the node.
### is_symlink
Type: boolean
`true` if the node is a symlink.
### is_broken
Type: boolean
`true` if the node is a broken symlink.
### is_dir
Type: boolean
`true` if the node is a directory.
### is_file
Type: boolean
`true` if the node is a file.
### is_readonly
Type: boolean
`true` if the node is real-only.
### mime_essence
Type: string
The mime type of the node. For e.g. `text/csv`, `image/jpeg` etc.
### size
Type: integer
The size of the exact node. The size of a directory won't be calculated
recursively.
### human_size
Type: string
Like size but in human readable format.
### permissions
Type: [Permission][60]
The [permissions][60] applied to the node.
### canonical
Type: nullable [Resolved Node Metadata][61]
If the node is a symlink, it will hold information about the symlink resolved
node. Else, it will hold information the actual node. It the symlink is broken,
it will be null.
### symlink
Type: nullable [Resolved Node Metadata][61]
If the node is a symlink and is not broken, it will hold information about the
symlink resolved node. However, it will never hold information about the actual
node. It will instead be null.
### Node
A node contains the following fields:
- [parent][45]
- [relative_path][46]
- [absolute_path][47]
- [extension][48]
- [is_symlink][49]
- [is_broken][50]
- [is_dir][51]
- [is_file][52]
- [is_readonly][53]
- [mime_essence][54]
- [size][55]
- [human_size][56]
- [permissions][57]
- [canonical][58]
- [symlink][59]
### Directory Buffer
Directory buffer contains the following fields:
- [parent][45]
- [nodes][63]
- [total][64]
- [focus][65]
#### parent
Type: string
The parent path of the node.
#### nodes
Type: list of [Node][44]s
A list of visible nodes.
#### total
Type: int
The count of nodes being rendered.
#### focus
Type: int
The index of the node under focus. It can be `0` even when there's no node to
focus on.
### History
History contains the following fields:
- [loc][68]
- [paths][69]
#### loc
Type: int
Location of the current path in history.
#### paths
Type: list of string
Visited paths.
### Example: Using Lua Function Calls
```lua
-- Define the function
xplr.fn.custom.ask_name_and_greet = function(app)
print("What's your name?")
local name = io.read()
local greeting = "Hello " .. name .. "!"
local message = greeting .. " You are inside " .. app.pwd
return {
{ LogSuccess = message },
}
end
-- Map the function to a key (space)
xplr.config.modes.builtin.default.key_bindings.on_key.space = {
help = "ask name and greet",
messages = {
{ CallLua = "custom.ask_name_and_greet" }
}
}
-- Now, when you press "space" in default mode, you will be prompted for your
-- name. Enter your name to receive a nice greeting and to know your location.
```
## Environment Variables and Pipes
Alternative to `CallLua`, `CallLuaSilently` messages that call Lua functions,
there are `Call`, `CallSilently`, `BashExec`, `BashExecSilently` messages
that call shell commands.
However, unlike the Lua functions, these shell commands have to read the useful
information and send messages via environment variables and temporary files
called "pipe"s. These environment variables and files are only available when
a command is being executed.
Visit the [**fzf integration tutorial**][19]
for example.
### Environment variables
To see the environment variables, invoke the shell by typing `:!` in default
mode and run the following command:
```
env | grep ^XPLR_
```
You will see something like:
```
XPLR_FOCUS_INDEX=0
XPLR_MODE=action to
XPLR_PIPE_SELECTION_OUT=/run/user/1000/xplr/session/122278/pipe/selection_out
XPLR_INPUT_BUFFER=
XPLR_PIPE_GLOBAL_HELP_MENU_OUT=/run/user/1000/xplr/session/122278/pipe/global_help_menu_out
XPLR_PID=122278
XPLR_PIPE_MSG_IN=/run/user/1000/xplr/session/122278/pipe/msg_in
XPLR_PIPE_LOGS_OUT=/run/user/1000/xplr/session/122278/pipe/logs_out
XPLR_PIPE_RESULT_OUT=/run/user/1000/xplr/session/122278/pipe/result_out
XPLR_PIPE_HISTORY_OUT=/run/user/1000/xplr/session/122278/pipe/history_out
XPLR_FOCUS_PATH=/home/sayanarijit/Documents/GitHub/xplr/docs/en/book
XPLR_SESSION_PATH=/run/user/1000/xplr/session/122278
XPLR_APP_VERSION=0.14.3
XPLR_PIPE_DIRECTORY_NODES_OUT=/run/user/1000/xplr/session/122278/pipe/directory_nodes_out
```
The environment variables starting with `XPLR_PIPE_` are the temporary files
called "pipe"s.
#### Input pipe
Current there is only one input pipe.
- [XPLR_PIPE_MSG_IN][20]
#### Output pipes
`XPLR_PIPE_*_OUT` are the output pipes that contain data which cannot be
exposed directly via environment variables, like multi-line string.
- [XPLR_PIPE_SELECTION_OUT][21]
- [XPLR_PIPE_GLOBAL_HELP_MENU_OUT][22]
- [XPLR_PIPE_LOGS_OUT][23]
- [XPLR_PIPE_RESULT_OUT][24]
- [XPLR_PIPE_HISTORY_OUT][25]
- [XPLR_PIPE_DIRECTORY_NODES_OUT][26]
#### XPLR_PIPE_MSG_IN
Append new-line delimited messages to this pipe in [YAML][27]
(or [JSON][7]) syntax. These messages will be read and
handled by xplr after the command execution.
#### XPLR_PIPE_SELECTION_OUT
New-line delimited list of selected paths.
#### XPLR_PIPE_GLOBAL_HELP_MENU_OUT
The full help menu.
#### XPLR_PIPE_LOGS_OUT
New-line delimited list of logs.
#### XPLR_PIPE_RESULT_OUT
New-line delimited result (selected paths if any, else the focused path)
#### XPLR_PIPE_HISTORY_OUT
New-line delimited list of last visited paths (similar to jump list in vim).
#### XPLR_PIPE_DIRECTORY_NODES_OUT
New-line delimited list of paths, filtered and sorted as displayed in the
[files table][28].
### Example: Using Environment Variables and Pipes
```lua
xplr.config.modes.builtin.default.key_bindings.on_key.space = {
help = "ask name and greet",
messages = {
{
BashExec = [===[
echo "What's your name?"
read name
greeting="Hello $name!"
message="$greeting You are inside $PWD"
echo LogSuccess: '"'$message'"' >> "${XPLR_PIPE_MSG_IN:?}"
]===]
}
}
}
-- Now, when you press "space" in default mode, you will be prompted for your
-- name. Enter your name to receive a nice greeting and to know your location.
```
[1]: #full-list-of-messages
[2]: key-bindings.md
[3]: #lua-function-calls
[4]: #input-pipe
[3]: lua-function-calls.md
[4]: environment-variables-and-pipes.md#input-pipe
[5]: https://www.lua.org/
[6]: http://yaml.org/
[7]: https://www.json.org
[8]: modes.md#mode
[9]: modes.md#builtin
[10]: modes.md#custom
[11]: layouts.md#layout
[11]: layouts.md
[12]: layouts.md#builtin
[13]: layouts.md#custom
[14]: #lua-context
[14]: lua-function-calls.md#lua-context
[15]: filtering.md#filter
[16]: filtering.md
[17]: sorting.md#sorter
[19]: configure-key-bindings.md#tutorial-adding-a-new-mode
[20]: #xplr_pipe_msg_in
[21]: #xplr_pipe_selection_out
[22]: #xplr_pipe_global_help_menu_out
[23]: #xplr_pipe_logs_out
[24]: #xplr_pipe_result_out
[25]: #xplr_pipe_history_out
[26]: #xplr_pipe_directory_nodes_out
[27]: https://www.yaml.org
[28]: layouts.md#table
[29]: #version
[30]: #config
[31]: #pwd
[32]: #focused_node
[33]: #directory_buffer
[34]: #selection
[35]: #mode
[36]: #layout
[37]: #input_buffer
[38]: #pid
[39]: #session_path
[40]: #explorer_config
[41]: #history
[42]: #last_modes
[43]: configuration.md#config
[44]: #node
[45]: #parent
[46]: #relative_path
[47]: #absolute_path
[48]: #extension
[49]: #is_symlink
[50]: #is_broken
[51]: #is_dir
[52]: #is_file
[53]: #is_readonly
[54]: #mime_essence
[55]: #size
[56]: #human_size
[57]: #permissions
[58]: #canonical
[59]: #symlink
[60]: column-renderer.md#permission
[61]: column-renderer.md#resolved-node-metadata
[62]: #directory-buffer
[63]: #nodes
[64]: #total
[65]: #focus
[66]: https://docs.rs/xplr/latest/xplr/app/struct.ExplorerConfig.html
[67]: #history
[68]: #loc
[69]: #paths
[70]: #history-1
[71]: #inputoperation

@ -0,0 +1,58 @@
# Mode
A mode contains the following information:
- [name][5]
- [help][6]
- [extra_help][7]
- [key_bindings][9]
- [layout][10]
### name
Type: string
This is the name of the mode visible in the help menu.
### help
Type: nullable string
If specified, the help menu will display this instead of the auto generated
mappings.
### extra_help
Type: nullable string
If specified, the help menu will display this along-side the auto generated
help menu.
### key_bindings
Type: [Key Bindings][8]
The key bindings available in that mode.
### layout
Type: nullable [Layout][11]
If specified, this layout will be used to render the UI.
## Also See:
- [xplr.config.modes][12]
[1]: #builtin
[2]: #custom
[3]: #mode
[4]: default-key-bindings.md
[5]: #name
[6]: #help
[7]: #extra_help
[8]: configure-key-bindings.md#key-bindings
[9]: #key_bindings
[10]: #layout
[11]: layout.md#layout
[12]: modes.md

@ -1,130 +1,11 @@
# Modes
xplr is a modal file explorer. That means the users switch between different
modes, each containing a different set of key bindings to avoid clashes. Users
can switch between these modes at run-time.
This configuration is exposed via the `xplr.config.modes` API.
The modes can be configured using the `xplr.config.modes` Lua API.
For now, kindly refer to [**init.lua**][1]
It contains the following fields:
> **NEED HELP:** Auto generate rest of the docs from [src/init.lua][1]
> using [docs/script/generate.lua][2].
- [builtin][1]
- [custom][2]
## builtin
Type: mapping of string and [Mode][3]
This is exposed by the `xplr.config.modes.builtin` API.
xplr by default provides the following builtin modes:
- default
- debug_error
- recover
- selection_ops
- create
- create_directory
- create_file
- number
- go_to
- rename
- delete
- duplicate_as
- action
- search
- filter
- relative_path_does_contain
- relative_path_does_not_contain
- sort
- switch_layout
- quit
Visit the [Default Key Bindings][4] to see what each mode
does.
## custom
Type: mapping of string and [Mode][3]
This is exposed by the `xplr.config.modes.custom` API.
It allows the users to define custom modes.
Example:
```lua
xplr.config.modes.custom.example = {
name = "example",
key_bindings = {
on_key = {
enter = {
help = "default mode",
messages = {
"PopMode",
{ SwitchModeBuiltin = "default" }
}
}
}
}
}
xplr.config.general.initial_mode = "example"
-- when you load xplr, you should be in the "example" mode,
-- pressing "enter" should take you to the "default" mode.
```
## Mode
A mode contains the following information:
- [name][5]
- [help][6]
- [extra_help][7]
- [key_bindings][8]
- [layout][10]
### name
Type: string
This is the name of the mode visible in the help menu.
### help
Type: nullable string
If specified, the help menu will display this instead of the auto generated
mappings.
### extra_help
Type: nullable string
If specified, the help menu will display this along-side the auto generated
help menu.
### key_bindings
Type: [Key Bindings][8]
The key bindings available in that mode.
### layout
Type: nullable [Layout][11]
If specified, this layout will be used to render the UI.
[1]: #builtin
[2]: #custom
[3]: #mode
[4]: default-key-bindings.md
[5]: #name
[6]: #help
[7]: #extra_help
[8]: configure-key-bindings.md#key-bindings
[9]: #key-bindings
[10]: #layout
[11]: layouts.md#layout
[1]: https://github.com/sayanarijit/xplr/blob/main/src/init.lua
[2]: https://github.com/sayanarijit/xplr/blob/main/docs/script/generate.lua

@ -0,0 +1,36 @@
# Node Type
A node-type contains the following fields:
- [meta][4]
- [style][5]
### meta
Type: mapping of string and string
A meta field can contain custom metadata about a node. By default, the "icon"
metadata is set for the [directory][1], [file][2], and
[symlink][3] nodes.
Example:
```lua
xplr.config.node_types.file = {
meta = {
icon = "f",
foo = "bar",
}
}
```
## Also See:
- [xplr.config.node_types][6]
[1]: node_types.md#directory
[2]: node_types.md#file
[3]: node_types.md#symlink
[4]: #meta
[5]: style.md
[6]: node_types.md

@ -1,155 +1,11 @@
# Node Types
This configuration defines how to deal with different kinds of nodes (files,
directories, symlinks etc.) in a directory.
This configuration is exposed via the `xplr.config.node_types` API.
This can be configured using the `xplr.config.node_types` Lua API.
For now, kindly refer to [**init.lua**][1]
It contains the following fields:
> **NEED HELP:** Auto generate rest of the docs from [src/init.lua][1]
> using [docs/script/generate.lua][2].
- [directory][1]
- [file][2]
- [symlink][3]
- [mime_essence][4]
- [extension][5]
- [special][6]
One node can fall into multiple categories. For example, a node can have the
extension `md`, and be a `file`. In that case, the properties from the more
specific category i.e. extension will be used.
The priority is:
**special** > **extension** > **mime_essence** > **symlink** > **file** > **directory**
### directory
Type: [NodeType Config][7]
Properties related to directories are defined here.
Contains the following fields:
Example:
```lua
xplr.config.node_types.directory.meta.icon = ""
xplr.config.node_types.directory.style.add_modifiers = { "Bold" }
```
### file
Type: [NodeType Config][7]
Properties related to regular files are defined here.
Contains the following fields:
Example:
```lua
xplr.config.node_types.file.meta.icon = ""
xplr.config.node_types.file.style.fg = "White"
```
### symlink
Type: [NodeType Config][7]
Properties related to symlink are defined here.
Example:
```lua
xplr.config.node_types.symlink.meta.icon = ""
xplr.config.node_types.symlink.style.add_modifiers = { "Italic" }
```
### mime_essence
Type: mapping of mime-type and mapping of mime-subtype and [NodeType Config][7]
Properties related to files with specific mime types are defined here.
It is possible to use the wildcard `*` to match all mime subtypes. It will be
overwritten by the more specific sub types that are defined.
Example:
```lua
xplr.config.node_types.mime_essence = {
application = {
-- application/*
["*"] = { meta = { icon = "a" } }
-- application/pdf
pdf = { meta = { icon = "" } },
-- application/zip
zip = { meta = { icon = ""} },
},
}
```
### extension
Type: mapping of extension and [NodeType Config][7]
Properties related to files with specific extension are defined here.
Example:
```lua
xplr.config.node_types.extension.md = { meta = { icon = "" } }
xplr.config.node_types.extension.rs = { meta = { icon = "🦀" } }
```
### special
Type: mapping of name and [NodeType Config][7]
Properties related to files and directories with special names are defined
here.
Example:
```lua
xplr.config.node_types.special["Cargo.toml"] = { meta = { icon = "" } }
xplr.config.node_types.special["Downloads"] = { meta = { icon = "" } }
```
## NodeType Config
A node-type config contains the following fields:
- [meta][8]
- [style][9]
### meta
Type: mapping of string and string
A meta field can contain custom metadata about a node. By default, the "icon"
metadata is set for the [directory][1], [file][2], and
[symlink][3] nodes.
Example:
```lua
xplr.config.node_types.file = {
meta = {
icon = "f",
foo = "bar",
}
}
```
[1]: #directory
[2]: #file
[3]: #symlink
[4]: #mime_essence
[5]: #extension
[6]: #special
[7]: #nodetype-config
[8]: #meta
[9]: style.md
[1]: https://github.com/sayanarijit/xplr/blob/main/src/init.lua
[2]: https://github.com/sayanarijit/xplr/blob/main/docs/script/generate.lua

@ -74,11 +74,11 @@ Visit [Awesome Plugins][5] for xplr plugin examples.
[4]: https://github.com/sayanarijit/xplr/discussions/categories/show-and-tell
[5]: awesome-plugins.md
[6]: configure-key-bindings.md#tutorial-adding-a-new-mode
[7]: message.md#example-using-environment-variables-and-pipes
[8]: message.md#example-using-lua-function-calls
[9]: layouts.md#example-defining-custom-layout
[7]: environment-variables-and-pipes.md#example-using-environment-variables-and-pipes
[8]: lua-function-calls.md#example-using-lua-function-calls
[9]: layout.md#example-defining-custom-layout
[10]: column-renderer.md#example-customizing-table-renderer
[11]: layouts.md#example-render-a-custom-dynamic-table
[11]: layout.md#example-render-a-custom-dynamic-table
[12]: https://github.com/sayanarijit/xplr/discussions/274
[13]: https://github.com/sayanarijit/xplr/discussions/273
[14]: https://github.com/sayanarijit/xplr/discussions/250

@ -0,0 +1,45 @@
-- Configuration documentation generator
--
-- TODO implement
--
-- This script generates configuration docs by parsing the comments and
-- properties from `src/init.lua`.
--
-- Usage:
--
-- ```
-- lua ./docs/script/generate.lua
-- ```
--
-- Or
--
-- ```
-- xplr -C ./docs/script/generate.lua --on-load Quit
-- ```
-- Generates ./docs/en/src/configuration.md
local function generate_configuration(lines) end
-- Generates ./docs/en/src/general-config.md
local function generate_general_config(lines) end
-- Generates ./docs/en/src/node_types.md
local function generate_node_types(lines) end
-- Generates ./docs/en/src/general-config.md
local function generate_layouts(lines) end
-- Generates ./docs/en/src/general-config.md
local function generate_modes(lines) end
local function main()
local init = io.lines("./src/init.lua")
generate_configuration(init)
generate_general_config(init)
generate_node_types(init)
generate_layouts(init)
generate_modes(init)
end
main()

@ -733,15 +733,15 @@ impl LayoutsConfig {
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Config {
#[serde(default)]
pub layouts: LayoutsConfig,
#[serde(default)]
pub general: GeneralConfig,
#[serde(default)]
pub node_types: NodeTypesConfig,
#[serde(default)]
pub layouts: LayoutsConfig,
#[serde(default)]
pub modes: ModesConfig,
}

@ -1,14 +1,56 @@
--- The configuration is documented at https://xplr.dev/en/configuration.
--- You need to define the script version for compatibility check.
--- See https://xplr.dev/en/upgrade-guide
---
--- version = "0.0.0"
---@diagnostic disable
local xplr = xplr
local xplr = xplr -- The globally exposed configuration to be overridden.
---@diagnostic enable
-- This is the built-in configuration file that gets loaded and sets the
-- default values when xplr loads, before loading any other custom
-- configuration file.
--
-- You can use this file as a reference to create a your custom config file.
--
-- To create a custom configuration file, you need to define the script version
-- for compatibility checks.
--
-- See https://xplr.dev/en/upgrade-guide
--
-- ```lua
-- version = "0.0.0"
-- ```
-- # Configuration ------------------------------------------------------------
--
-- xplr can be configured using [Lua][1] via a special file named `init.lua`,
-- which can be placed in `~/.config/xplr/` (local to user) or `/etc/xplr/`
-- (global) depending on the use case.
--
-- When xplr loads, it first executes the [built-in init.lua][2] to set the
-- default values, which is then overwritten by another config file, if found
-- using the following lookup order:
--
-- 1. `--config /path/to/init.lua`
-- 2. `~/.config/xplr/init.lua`
-- 3. `/etc/xplr/init.lua`
--
-- The first one found will be loaded by xplr and the lookup will stop.
--
-- The loaded config can be further extended using the `-C` or `--extra-config`
-- command-line option.
--
--
-- [1]: https://www.lua.org
-- [2]: https://github.com/sayanarijit/xplr/blob/main/src/init.lua
-- [3]: https://xplr.dev/en/upgrade-guide
-- ## Config ------------------------------------------------------------------
--
-- The xplr configuration, exposed via `xplr.config` Lua API contains the
-- following sections.
-- ### General Configuration --------------------------------------------------
--
-- The general configuration properties are grouped together in
-- `xplr.config.general`.
-- Set it to `true` if you want to ignore the startup errors. You can still see
-- the errors in the logs.
--
@ -384,7 +426,7 @@ xplr.config.general.sort_and_filter_ui.sort_direction_identifiers.reverse.style.
-- The identifiers used to denote applied sorters in the Sort & filter panel.
--
-- Type: nullable map of the following key and value pairs:
-- Type: nullable mapping of the following key-value pairs:
--
-- * key: [Sorter](https://xplr.dev/en/sorting#sorter)
-- * value:
@ -499,7 +541,7 @@ xplr.config.general.sort_and_filter_ui.sorter_identifiers = {
-- The identifiers used to denote applied filters in the Sort & filter panel.
--
-- Type: nullable map of the following key and value pairs:
-- Type: nullable mapping of the following key-value pairs:
--
-- * key: [Filter](https://xplr.dev/en/filtering#filter)
-- * value:
@ -897,38 +939,157 @@ xplr.config.general.initial_layout = "default"
-- Type: nullable string
xplr.config.general.start_fifo = nil
---- TODO: document the rest
-- ### Node Types -------------------------------------------------------------
--
-- This section defines how to deal with different kinds of nodes (files,
-- directories, symlinks etc.) based on their properties.
--
-- One node can fall into multiple categories. For example, a node can have the
-- *extension* `md`, and also be a *file*. In that case, the properties from
-- the more specific category i.e. *extension* will be used.
--
-- This can be configured using the `xplr.config.node_types` Lua API.
xplr.config.node_types.directory.meta.icon = "ð"
-- The style for the directory nodes
--
-- Type: [Style](https://xplr.dev/en/style)
xplr.config.node_types.directory.style.add_modifiers = { "Bold" }
xplr.config.node_types.directory.style.sub_modifiers = nil
xplr.config.node_types.directory.style.bg = nil
xplr.config.node_types.directory.style.fg = "Cyan"
xplr.config.node_types.file.meta.icon = "ƒ"
-- Metadata for the directory nodes
--
-- Type: nullable string
xplr.config.node_types.directory.meta.icon = "ð"
-- The style for the file nodes
--
-- Type: [Style](https://xplr.dev/en/style)
xplr.config.node_types.file.style.add_modifiers = nil
xplr.config.node_types.file.style.sub_modifiers = nil
xplr.config.node_types.file.style.bg = nil
xplr.config.node_types.file.style.fg = nil
xplr.config.node_types.symlink.meta.icon = "§"
-- Metadata for the file nodes
--
-- Type: nullable string
xplr.config.node_types.file.meta.icon = "ƒ"
-- The style for the symlink nodes
--
-- Type: [Style](https://xplr.dev/en/style)
xplr.config.node_types.symlink.style.add_modifiers = { "Italic" }
xplr.config.node_types.symlink.style.sub_modifiers = nil
xplr.config.node_types.symlink.style.bg = nil
xplr.config.node_types.symlink.style.fg = "Magenta"
-- Metadata for the symlink nodes
--
-- Type: nullable string
xplr.config.node_types.symlink.meta.icon = "§"
-- Metadata and style based on mime types.
-- It is possible to use the wildcard `*` to match all mime sub types. It will
-- be overwritten by the more specific sub types that are defined.
--
-- Type: mapping of the following key-value pairs:
--
-- * key: string
-- * value:
-- * key: string
-- * value: [Node Type](https://xplr.dev/en/node_type)
--
-- Example:
--
-- ```lua
-- xplr.config.node_types.mime_essence = {
-- application = {
-- -- application/*
-- ["*"] = { meta = { icon = "a" } }
--
-- -- application/pdf
-- pdf = { meta = { icon = "" }, style = { fg = "Blue" } },
-- -- application/zip
-- zip = { meta = { icon = ""} },
-- },
-- }
-- ```
xplr.config.node_types.mime_essence = {}
-- Metadata and style based on extension.
--
-- Type: mapping of the following key-value pairs:
--
-- * key: string
-- * value: [Node Type](https://xplr.dev/en/node_type)
--
-- Example:
--
-- ```lua
-- xplr.config.node_types.extension.md = { meta = { icon = "" }, style = { fg = "Blue" } }
-- xplr.config.node_types.extension.rs = { meta = { icon = "🦀" } }
-- ```
xplr.config.node_types.extension = {}
-- Metadata and style based on special file names.
--
-- Type: mapping of the following key-value pairs:
--
-- * key: string
-- * value: [Node Type](https://xplr.dev/en/node_type)
--
-- Example:
--
-- ```lua
-- xplr.config.node_types.special["Cargo.toml"] = { meta = { icon = "" } }
-- xplr.config.node_types.special["Downloads"] = { meta = { icon = "" }, style = { fg = "Blue" } }
-- ```
xplr.config.node_types.special = {}
-- ### Layout Configuration ---------------------------------------------------
--
-- xplr layouts define the structure of the UI, i.e. how many panel we see,
-- placement and size of the panels, how they look etc.
--
-- This is configuration exposed via the `xplr.config.layouts` API.
--
-- `xplr.config.layouts.builtin` contain some built-in panels which can be
-- overridden, but you can't add or remove panels in it.
--
-- You can add new panels in `xplr.config.layouts.custom`.
--
-- ##### Example: Defining Custom Layout
--
-- ![demo](https://s6.gifyu.com/images/layout.png)
--
-- ```lua
-- xplr.config.layouts.builtin.default = {
-- Horizontal = {
-- config = {
-- margin = 1,
-- horizontal_margin = 2,
-- vertical_margin = 3,
-- constraints = {
-- { Percentage = 50 },
-- { Percentage = 50 },
-- }
-- },
-- splits = {
-- "Table",
-- "HelpMenu",
-- }
-- }
-- }
-- ```
-- The default layout
--
-- Type: [Layout](https://xplr.dev/en/layout)
xplr.config.layouts.builtin.default = {
Horizontal = {
config = {
margin = nil,
horizontal_margin = 0,
vertical_margin = 0,
constraints = {
{ Percentage = 70 },
{ Percentage = 30 },
@ -938,9 +1099,6 @@ xplr.config.layouts.builtin.default = {
{
Vertical = {
config = {
margin = 0,
horizontal_margin = nil,
vertical_margin = nil,
constraints = {
{ Length = 3 },
{ Min = 1 },
@ -957,9 +1115,6 @@ xplr.config.layouts.builtin.default = {
{
Vertical = {
config = {
margin = 0,
horizontal_margin = nil,
vertical_margin = nil,
constraints = {
{ Percentage = 50 },
{ Percentage = 50 },
@ -975,12 +1130,12 @@ xplr.config.layouts.builtin.default = {
},
}
-- The layout without help menu
--
-- Type: [Layout](https://xplr.dev/en/layout)
xplr.config.layouts.builtin.no_help = {
Horizontal = {
config = {
margin = nil,
horizontal_margin = nil,
vertical_margin = nil,
constraints = {
{ Percentage = 70 },
{ Percentage = 30 },
@ -990,9 +1145,6 @@ xplr.config.layouts.builtin.no_help = {
{
Vertical = {
config = {
margin = nil,
horizontal_margin = nil,
vertical_margin = nil,
constraints = {
{ Length = 3 },
{ Min = 1 },
@ -1011,12 +1163,12 @@ xplr.config.layouts.builtin.no_help = {
},
}
-- The layout without selection panel
--
-- Type: [Layout](https://xplr.dev/en/layout)
xplr.config.layouts.builtin.no_selection = {
Horizontal = {
config = {
margin = nil,
horizontal_margin = nil,
vertical_margin = nil,
constraints = {
{ Percentage = 70 },
{ Percentage = 30 },
@ -1026,9 +1178,6 @@ xplr.config.layouts.builtin.no_selection = {
{
Vertical = {
config = {
margin = nil,
horizontal_margin = nil,
vertical_margin = nil,
constraints = {
{ Length = 3 },
{ Min = 1 },
@ -1047,12 +1196,12 @@ xplr.config.layouts.builtin.no_selection = {
},
}
-- The layout without help menu and selection panel
--
-- Type: [Layout](https://xplr.dev/en/layout)
xplr.config.layouts.builtin.no_help_no_selection = {
Vertical = {
config = {
margin = nil,
horizontal_margin = nil,
vertical_margin = nil,
constraints = {
{ Length = 3 },
{ Min = 1 },
@ -1067,16 +1216,42 @@ xplr.config.layouts.builtin.no_help_no_selection = {
},
}
-- This is where you can define custom layouts
--
-- Type: mapping of the following key-value pairs:
--
-- * key: string
-- * value: [Layout](https://xplr.dev/en/layout)
--
-- Example:
--
-- ```lua
-- xplr.config.layouts.custom.example = "Nothing" -- Show a blank screen
-- xplr.config.general.initial_layout = "example" -- Load the example layout
-- ```
xplr.config.layouts.custom = {}
-- ### Modes ------------------------------------------------------------------
--
-- xplr is a modal file explorer. That means the users switch between different
-- modes, each containing a different set of key bindings to avoid clashes.
-- Users can switch between these modes at run-time.
--
-- The modes can be configured using the `xplr.config.modes` Lua API.
--
-- `xplr.config.modes.builtin` contain some built-in modes which can be
-- overridden, but you can't add or remove modes in it.
-- The builtin default mode.
-- Visit the [Default Key Bindings](https://xplr.dev/en/default-key-bindings)
-- to see what each mode does.
--
-- Type: [Mode](https://xplr.dev/en/mode)
xplr.config.modes.builtin.default = {
name = "default",
help = nil,
extra_help = nil,
key_bindings = {
on_key = {
["#"] = {
help = nil,
messages = {
"PrintAppStateAndQuit",
},
@ -1314,10 +1489,11 @@ xplr.config.modes.builtin.default.key_bindings.on_key["k"] =
xplr.config.modes.builtin.default.key_bindings.on_key["l"] =
xplr.config.modes.builtin.default.key_bindings.on_key.right
-- The builtin debug error mode.
--
-- Type: [Mode](https://xplr.dev/en/mode)
xplr.config.modes.builtin.debug_error = {
name = "debug error",
help = nil,
extra_help = nil,
layout = {
Vertical = {
config = {
@ -1385,12 +1561,14 @@ xplr.config.modes.builtin.debug_error = {
},
},
default = {
help = nil,
messages = {},
},
},
}
-- The builtin recover mode.
--
-- Type: [Mode](https://xplr.dev/en/mode)
xplr.config.modes.builtin.recover = {
name = "recover",
layout = {
@ -1433,10 +1611,11 @@ xplr.config.modes.builtin.recover = {
},
}
-- The builtin selection ops mode.
--
-- Type: [Mode](https://xplr.dev/en/mode)
xplr.config.modes.builtin.selection_ops = {
name = "selection ops",
help = nil,
extra_help = nil,
key_bindings = {
on_key = {
["c"] = {
@ -1518,10 +1697,11 @@ xplr.config.modes.builtin.selection_ops = {
},
}
-- The builtin create mode.
--
-- Type: [Mode](https://xplr.dev/en/mode)
xplr.config.modes.builtin.create = {
name = "create",
help = nil,
extra_help = nil,
key_bindings = {
on_key = {
["ctrl-c"] = {
@ -1556,10 +1736,11 @@ xplr.config.modes.builtin.create = {
},
}
-- The builtin create directory mode.
--
-- Type: [Mode](https://xplr.dev/en/mode)
xplr.config.modes.builtin.create_directory = {
name = "create directory",
help = nil,
extra_help = nil,
key_bindings = {
on_key = {
["ctrl-c"] = {
@ -1602,10 +1783,11 @@ xplr.config.modes.builtin.create_directory = {
},
}
-- The builtin create file mode.
--
-- Type: [Mode](https://xplr.dev/en/mode)
xplr.config.modes.builtin.create_file = {
name = "create file",
help = nil,
extra_help = nil,
key_bindings = {
on_key = {
["ctrl-c"] = {
@ -1639,7 +1821,6 @@ xplr.config.modes.builtin.create_file = {
},
},
},
on_special_character = nil,
default = {
messages = {
"UpdateInputBufferFromKey",
@ -1648,10 +1829,11 @@ xplr.config.modes.builtin.create_file = {
},
}
-- The builtin number mode.
--
-- Type: [Mode](https://xplr.dev/en/mode)
xplr.config.modes.builtin.number = {
name = "number",
help = nil,
extra_help = nil,
key_bindings = {
on_key = {
["ctrl-c"] = {
@ -1707,10 +1889,11 @@ xplr.config.modes.builtin.number.key_bindings.on_key["j"] =
xplr.config.modes.builtin.number.key_bindings.on_key["k"] =
xplr.config.modes.builtin.number.key_bindings.on_key.up
-- The builtin go to mode.
--
-- Type: [Mode](https://xplr.dev/en/mode)
xplr.config.modes.builtin.go_to = {
name = "go to",
help = nil,
extra_help = nil,
key_bindings = {
on_key = {
["ctrl-c"] = {
@ -1765,10 +1948,11 @@ xplr.config.modes.builtin.go_to = {
},
}
-- The builtin rename mode.
--
-- Type: [Mode](https://xplr.dev/en/mode)
xplr.config.modes.builtin.rename = {
name = "rename",
help = nil,
extra_help = nil,
key_bindings = {
on_key = {
["ctrl-c"] = {
@ -1805,7 +1989,6 @@ xplr.config.modes.builtin.rename = {
},
},
default = {
help = nil,
messages = {
"UpdateInputBufferFromKey",
},
@ -1813,10 +1996,11 @@ xplr.config.modes.builtin.rename = {
},
}
-- The builtin duplicate as mode.
--
-- Type: [Mode](https://xplr.dev/en/mode)
xplr.config.modes.builtin.duplicate_as = {
name = "duplicate as",
help = nil,
extra_help = nil,
key_bindings = {
on_key = {
["ctrl-c"] = {
@ -1853,7 +2037,6 @@ xplr.config.modes.builtin.duplicate_as = {
},
},
default = {
help = nil,
messages = {
"UpdateInputBufferFromKey",
},
@ -1861,10 +2044,11 @@ xplr.config.modes.builtin.duplicate_as = {
},
}
-- The builtin delete mode.
--
-- Type: [Mode](https://xplr.dev/en/mode)
xplr.config.modes.builtin.delete = {
name = "delete",
help = nil,
extra_help = nil,
key_bindings = {
on_key = {
["D"] = {
@ -1929,10 +2113,11 @@ xplr.config.modes.builtin.delete = {
},
}
-- The builtin action mode.
--
-- Type: [Mode](https://xplr.dev/en/mode)
xplr.config.modes.builtin.action = {
name = "action to",
help = nil,
extra_help = nil,
key_bindings = {
on_key = {
["!"] = {
@ -2018,10 +2203,11 @@ xplr.config.modes.builtin.action = {
},
}
-- The builtin quit mode.
--
-- Type: [Mode](https://xplr.dev/en/mode)
xplr.config.modes.builtin.quit = {
name = "quit",
help = nil,
extra_help = nil,
key_bindings = {
on_key = {
enter = {
@ -2070,10 +2256,11 @@ xplr.config.modes.builtin.quit = {
},
}
-- The builtin search mode.
--
-- Type: [Mode](https://xplr.dev/en/mode)
xplr.config.modes.builtin.search = {
name = "search",
help = nil,
extra_help = nil,
key_bindings = {
on_key = {
["ctrl-c"] = {
@ -2146,10 +2333,11 @@ xplr.config.modes.builtin.search.key_bindings.on_key["ctrl-n"] =
xplr.config.modes.builtin.search.key_bindings.on_key["ctrl-p"] =
xplr.config.modes.builtin.search.key_bindings.on_key.up
-- The builtin filter mode.
--
-- Type: [Mode](https://xplr.dev/en/mode)
xplr.config.modes.builtin.filter = {
name = "filter",
help = nil,
extra_help = nil,
key_bindings = {
on_key = {
["R"] = {
@ -2203,10 +2391,11 @@ xplr.config.modes.builtin.filter = {
xplr.config.modes.builtin.filter.key_bindings.on_key["esc"] =
xplr.config.modes.builtin.filter.key_bindings.on_key.enter
-- The builtin relative_path_does_contain mode.
--
-- Type: [Mode](https://xplr.dev/en/mode)
xplr.config.modes.builtin.relative_path_does_contain = {
name = "relative path does contain",
help = nil,
extra_help = nil,
key_bindings = {
on_key = {
["ctrl-c"] = {
@ -2231,7 +2420,6 @@ xplr.config.modes.builtin.relative_path_does_contain = {
},
},
default = {
help = nil,
messages = {
{ RemoveNodeFilterFromInput = "IRelativePathDoesContain" },
"UpdateInputBufferFromKey",
@ -2242,10 +2430,11 @@ xplr.config.modes.builtin.relative_path_does_contain = {
},
}
-- The builtin relative_path_does_not_contain mode.
--
-- Type: [Mode](https://xplr.dev/en/mode)
xplr.config.modes.builtin.relative_path_does_not_contain = {
name = "relative path does not contain",
help = nil,
extra_help = nil,
key_bindings = {
on_key = {
["ctrl-c"] = {
@ -2270,7 +2459,6 @@ xplr.config.modes.builtin.relative_path_does_not_contain = {
},
},
default = {
help = nil,
messages = {
{ RemoveNodeFilterFromInput = "IRelativePathDoesNotContain" },
"UpdateInputBufferFromKey",
@ -2281,10 +2469,11 @@ xplr.config.modes.builtin.relative_path_does_not_contain = {
},
}
-- The builtin sort mode.
--
-- Type: [Mode](https://xplr.dev/en/mode)
xplr.config.modes.builtin.sort = {
name = "sort",
help = nil,
extra_help = nil,
key_bindings = {
on_key = {
["!"] = {
@ -2455,10 +2644,11 @@ xplr.config.modes.builtin.sort = {
xplr.config.modes.builtin.sort.key_bindings.on_key["esc"] =
xplr.config.modes.builtin.sort.key_bindings.on_key.enter
-- The builtin switch layout mode.
--
-- Type: [Mode](https://xplr.dev/en/mode)
xplr.config.modes.builtin.switch_layout = {
name = "switch layout",
help = nil,
extra_help = nil,
key_bindings = {
on_key = {
["1"] = {
@ -2505,8 +2695,51 @@ xplr.config.modes.builtin.switch_layout = {
},
}
-- This is where you define custom modes.
--
-- Type: mapping of the following key-value pairs:
--
-- * key: string
-- * value: [Mode](https://xplr.dev/en/mode)
--
-- Example:
--
-- ```lua
-- xplr.config.modes.custom.example = {
-- name = "example",
-- key_bindings = {
-- on_key = {
-- enter = {
-- help = "default mode",
-- messages = {
-- "PopMode",
-- { SwitchModeBuiltin = "default" },
-- },
-- },
-- },
-- },
-- }
--
-- xplr.config.general.initial_mode = "example"
-- ```
xplr.config.modes.custom = {}
-- ## Function ----------------------------------------------------------------
--
-- While `xplr.config` defines all the static parts of the configuration,
-- `xplr.fn` defines all the dynamic parts using functions.
--
-- As always, `xplr.fn.builtin` is where the built-in functions are defined
-- that can be overwritten, and `xplr.fn.custom` is where the custom functions
-- are defined where custom functions can be added or removed.
--
-- There is currently no restriction on what kind of functions can be defined
-- in `xplr.fn.custom`.
--
-- You can also use nested tables such as
-- `xplr.fn.custom.my_plugin.my_function` to define custom functions.
--
xplr.fn.builtin.fmt_general_table_row_cols_0 = function(m)
local r = ""
if m.is_before_focus then

Loading…
Cancel
Save