---@diagnostic disable
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
--
version = "0.20.2"

-- # 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.
--
-- See:
--
-- * [xplr.config.general](https://xplr.dev/en/general-config)
-- * [xplr.config.node_types](https://xplr.dev/en/node_types)
-- * [xplr.config.layouts](https://xplr.dev/en/layouts)
-- * [xplr.config.modes](https://xplr.dev/en/modes)

-- ### 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.
--
-- Type: boolean
xplr.config.general.disable_debug_error_mode = false

-- Set it to `true` if you want to enable mouse scrolling.
--
-- Type: boolean
xplr.config.general.enable_mouse = false

-- Set it to `true` to show hidden files by default.
--
-- Type: boolean
xplr.config.general.show_hidden = true

-- Set it to `true` to use only a subset of selected operations that forbids
-- executing commands or performing write operations on the file-system.
--
-- Type: boolean
xplr.config.general.read_only = false

-- Set it to `true` if you want to enable a safety feature that will save you
-- from yourself when you type recklessly.
--
-- Type: boolean
xplr.config.general.enable_recover_mode = false

-- Set it to `true` if you want to hide all remaps in the help menu.
--
-- Type: boolean
xplr.config.general.hide_remaps_in_help_menu = false

-- Set it to `true` if you want the cursor to stay in the same position when
-- the focus is on the first path and you navigate to the previous path
-- (by pressing `up`/`k`), or when the focus is on the last path and you
-- navigate to the next path (by pressing `down`/`j`).
-- The default behavior is to rotate from the last/first path.
--
-- Type: boolean
xplr.config.general.enforce_bounded_index_navigation = false

-- This is the shape of the prompt for the input buffer.
--
-- Type: nullable string
xplr.config.general.prompt.format = "❯ "

-- This is the style of the prompt for the input buffer.
--
-- Type: [Style](https://xplr.dev/en/style)
xplr.config.general.prompt.style = {}

-- The string to indicate an information in logs.
--
-- Type: nullable string
xplr.config.general.logs.info.format = "INFO"

-- The style for the information logs.
--
-- Type: [Style](https://xplr.dev/en/style)
xplr.config.general.logs.info.style = { fg = "LightBlue" }

-- The string to indicate an success in logs.
--
-- Type: nullable string
xplr.config.general.logs.success.format = "SUCCESS"

-- The style for the success logs.
--
-- Type: [Style](https://xplr.dev/en/style)
xplr.config.general.logs.success.style = { fg = "Green" }

-- The string to indicate an warnings in logs.
--
-- Type: nullable string
xplr.config.general.logs.warning.format = "WARNING"

-- The style for the warnings logs.
--
-- Type: [Style](https://xplr.dev/en/style)
xplr.config.general.logs.warning.style = { fg = "Yellow" }

-- The string to indicate an error in logs.
--
-- Type: nullable string
xplr.config.general.logs.error.format = "ERROR"

-- The style for the error logs.
--
-- Type: [Style](https://xplr.dev/en/style)
xplr.config.general.logs.error.style = { fg = "Red" }

-- Columns to display in the table header.
--
-- Type: nullable list of tables with the following fields:
--
-- * format: nullable string
-- * style: [Style](https://xplr.dev/en/style)
xplr.config.general.table.header.cols = {
	{ format = " index", style = {} },
	{ format = "╭─── path", style = {} },
	{ format = "permissions", style = {} },
	{ format = "size", style = {} },
	{ format = "modified", style = {} },
}

-- Style of the table header.
--
-- Type: [Style](https://xplr.dev/en/style)
xplr.config.general.table.header.style = {}

-- Height of the table header.
--
-- Type: nullable integer
xplr.config.general.table.header.height = 1

-- Columns to display in each row in the table.
--
-- Type: nullable list of tables with the following fields:
--
-- * format: nullable string
-- * style: [Style](https://xplr.dev/en/style)
xplr.config.general.table.row.cols = {
	{
		format = "builtin.fmt_general_table_row_cols_0",
		style = {},
	},
	{
		format = "builtin.fmt_general_table_row_cols_1",
		style = {},
	},
	{
		format = "builtin.fmt_general_table_row_cols_2",
		style = {},
	},
	{
		format = "builtin.fmt_general_table_row_cols_3",
		style = {},
	},
	{
		format = "builtin.fmt_general_table_row_cols_4",
		style = {},
	},
}

-- Default style of the table.
--
-- Type: [Style](https://xplr.dev/en/style)
xplr.config.general.table.row.style = {}

-- Height of the table rows.
--
-- Type: nullable integer
xplr.config.general.table.row.height = 0

-- Default style of the table.
--
-- Type: [Style](https://xplr.dev/en/style)
xplr.config.general.table.style = {}

-- Tree to display in the table.
--
-- Type: nullable list of tables with the following fields:
--
-- * format: nullable string
-- * style: [Style](https://xplr.dev/en/style)
xplr.config.general.table.tree = {
	{ format = "├", style = {} },
	{ format = "├", style = {} },
	{ format = "╰", style = {} },
}

-- Spacing between the columns in the table.
--
-- Type: nullable integer
xplr.config.general.table.col_spacing = 1

-- Constraint for the column widths.
--
-- Type: nullable list of [Constraint](https://xplr.dev/en/layouts#constraint)
xplr.config.general.table.col_widths = {
	{ Percentage = 10 },
	{ Percentage = 50 },
	{ Percentage = 10 },
	{ Percentage = 10 },
	{ Percentage = 20 },
}

-- The content that is placed before the item name for each row by default.
--
-- Type: nullable string
xplr.config.general.default_ui.prefix = "  "

-- The content which is appended to each item name for each row by default.
--
-- Type: nullable string
xplr.config.general.default_ui.suffix = ""

-- The default style of each item for each row.
--
-- Type: [Style](https://xplr.dev/en/style)
xplr.config.general.default_ui.style = {}

-- The string placed before the item name for a focused row.
--
-- Type: nullable string
xplr.config.general.focus_ui.prefix = "▸["

-- The string placed after the item name for a focused row.
--
-- Type: nullable string
xplr.config.general.focus_ui.suffix = "]"

-- Style for focused item.
-- Type: [Style](https://xplr.dev/en/style)
xplr.config.general.focus_ui.style = { add_modifiers = { "Bold" } }

-- The string placed before the item name for a selected row.
--
-- Type: nullable string
xplr.config.general.selection_ui.prefix = " {"

-- The string placed after the item name for a selected row.
--
-- Type: nullable string
xplr.config.general.selection_ui.suffix = "}"

-- Style for selected rows.
--
-- Type: [Style](https://xplr.dev/en/style)
xplr.config.general.selection_ui.style = {
	fg = "DarkGray",
	add_modifiers = { "CrossedOut" },
}

-- The string placed before item name for a selected row that gets the focus.
--
-- Type: nullable string
xplr.config.general.focus_selection_ui.prefix = "▸["

-- The string placed after the item name for a selected row that gets the focus.
--
-- Type: nullable string
xplr.config.general.focus_selection_ui.suffix = "]"

-- Style for a selected row that gets the focus.
--
-- Type: [Style](https://xplr.dev/en/style)
xplr.config.general.focus_selection_ui.style = {
	add_modifiers = { "Bold", "CrossedOut" },
}

-- The shape of the separator for the Sort & filter panel.
--
-- Type: nullable string
xplr.config.general.sort_and_filter_ui.separator.format = " › "

-- The style of the separator for the Sort & filter panel.
--
-- Type: [Style](https://xplr.dev/en/style)
xplr.config.general.sort_and_filter_ui.separator.style = {
	add_modifiers = { "Dim" },
}

-- The content of the default identifier in Sort & filter panel.
--
-- Type: nullable string
xplr.config.general.sort_and_filter_ui.default_identifier.format = nil

-- Style for the default identifier in Sort & filter panel.
--
-- Type: [Style](https://xplr.dev/en/style)
xplr.config.general.sort_and_filter_ui.default_identifier.style = {}

-- The shape of the forward direction indicator for sort identifiers in Sort & filter panel.
--
-- Type: nullable string
xplr.config.general.sort_and_filter_ui.sort_direction_identifiers.forward.format = "↓"

-- Style of forward direction indicator in Sort & filter panel.
--
-- Type: [Style](https://xplr.dev/en/style)
xplr.config.general.sort_and_filter_ui.sort_direction_identifiers.forward.style = nil

-- The shape of the reverse direction indicator for sort identifiers in Sort & filter panel.
--
-- Type: nullable string
xplr.config.general.sort_and_filter_ui.sort_direction_identifiers.reverse.format = "↑"

-- Style of reverse direction indicator in Sort & filter panel.
--
-- Type: [Style](https://xplr.dev/en/style)
xplr.config.general.sort_and_filter_ui.sort_direction_identifiers.reverse.style = nil

-- The identifiers used to denote applied sorters in the Sort & filter panel.
--
-- Type: nullable mapping of the following key-value pairs:
--
-- * key: [Sorter](https://xplr.dev/en/sorting#sorter)
-- * value:
--   * format: nullable string
--   * style: [Style](https://xplr.dev/en/style)
xplr.config.general.sort_and_filter_ui.sorter_identifiers = {
	ByExtension = { format = "ext", style = {} },
	ByICanonicalAbsolutePath = { format = "[ci]abs", style = {} },
	ByIRelativePath = { format = "[i]rel", style = {} },
	ByISymlinkAbsolutePath = { format = "[si]abs", style = {} },
	ByIsBroken = { format = "⨯", style = {} },
	ByIsDir = { format = "dir", style = {} },
	ByIsFile = { format = "file", style = {} },
	ByIsReadonly = { format = "ro", style = {} },
	ByIsSymlink = { format = "sym", style = {} },
	ByMimeEssence = { format = "mime", style = {} },
	ByRelativePath = { format = "rel", style = {} },
	BySize = { format = "size", style = {} },
	ByCreated = { format = "created", style = {} },
	ByLastModified = { format = "modified", style = {} },
	ByCanonicalAbsolutePath = { format = "[c]abs", style = {} },
	ByCanonicalExtension = { format = "[c]ext", style = {} },
	ByCanonicalIsDir = { format = "[c]dir", style = {} },
	ByCanonicalIsFile = { format = "[c]file", style = {} },
	ByCanonicalIsReadonly = { format = "[c]ro", style = {} },
	ByCanonicalMimeEssence = { format = "[c]mime", style = {} },
	ByCanonicalSize = { format = "[c]size", style = {} },
	ByCanonicalCreated = { format = "[c]created", style = {} },
	ByCanonicalLastModified = { format = "[c]modified", style = {} },
	BySymlinkAbsolutePath = { format = "[s]abs", style = {} },
	BySymlinkExtension = { format = "[s]ext", style = {} },
	BySymlinkIsDir = { format = "[s]dir", style = {} },
	BySymlinkIsFile = { format = "[s]file", style = {} },
	BySymlinkIsReadonly = { format = "[s]ro", style = {} },
	BySymlinkMimeEssence = { format = "[s]mime", style = {} },
	BySymlinkSize = { format = "[s]size", style = {} },
	BySymlinkCreated = { format = "[s]created", style = {} },
	BySymlinkLastModified = { format = "[s]modified", style = {} },
}

-- The identifiers used to denote applied filters in the Sort & filter panel.
--
-- Type: nullable mapping of the following key-value pairs:
--
-- * key: [Filter](https://xplr.dev/en/filtering#filter)
-- * value:
--   * format: nullable string
--   * style: [Style](https://xplr.dev/en/style)
xplr.config.general.sort_and_filter_ui.filter_identifiers = {
	RelativePathDoesContain = { format = "rel=~", style = {} },
	RelativePathDoesEndWith = { format = "rel=$", style = {} },
	RelativePathDoesNotContain = { format = "rel!~", style = {} },
	RelativePathDoesNotEndWith = { format = "rel!$", style = {} },
	RelativePathDoesNotStartWith = { format = "rel!^", style = {} },
	RelativePathDoesStartWith = { format = "rel=^", style = {} },
	RelativePathIs = { format = "rel==", style = {} },
	RelativePathIsNot = { format = "rel!=", style = {} },
	RelativePathDoesMatchRegex = { format = "rel=/", style = {} },
	RelativePathDoesNotMatchRegex = { format = "rel!/", style = {} },
	IRelativePathDoesContain = { format = "[i]rel=~", style = {} },
	IRelativePathDoesEndWith = { format = "[i]rel=$", style = {} },
	IRelativePathDoesNotContain = { format = "[i]rel!~", style = {} },
	IRelativePathDoesNotEndWith = { format = "[i]rel!$", style = {} },
	IRelativePathDoesNotStartWith = { format = "[i]rel!^", style = {} },
	IRelativePathDoesStartWith = { format = "[i]rel=^", style = {} },
	IRelativePathIs = { format = "[i]rel==", style = {} },
	IRelativePathIsNot = { format = "[i]rel!=", style = {} },
	IRelativePathDoesMatchRegex = { format = "[i]rel=/", style = {} },
	IRelativePathDoesNotMatchRegex = { format = "[i]rel!/", style = {} },
	AbsolutePathDoesContain = { format = "abs=~", style = {} },
	AbsolutePathDoesEndWith = { format = "abs=$", style = {} },
	AbsolutePathDoesNotContain = { format = "abs!~", style = {} },
	AbsolutePathDoesNotEndWith = { format = "abs!$", style = {} },
	AbsolutePathDoesNotStartWith = { format = "abs!^", style = {} },
	AbsolutePathDoesStartWith = { format = "abs=^", style = {} },
	AbsolutePathIs = { format = "abs==", style = {} },
	AbsolutePathIsNot = { format = "abs!=", style = {} },
	AbsolutePathDoesMatchRegex = { format = "abs=/", style = {} },
	AbsolutePathDoesNotMatchRegex = { format = "abs!/", style = {} },
	IAbsolutePathDoesContain = { format = "[i]abs=~", style = {} },
	IAbsolutePathDoesEndWith = { format = "[i]abs=$", style = {} },
	IAbsolutePathDoesNotContain = { format = "[i]abs!~", style = {} },
	IAbsolutePathDoesNotEndWith = { format = "[i]abs!$", style = {} },
	IAbsolutePathDoesNotStartWith = { format = "[i]abs!^", style = {} },
	IAbsolutePathDoesStartWith = { format = "[i]abs=^", style = {} },
	IAbsolutePathIs = { format = "[i]abs==", style = {} },
	IAbsolutePathIsNot = { format = "[i]abs!=", style = {} },
	IAbsolutePathDoesMatchRegex = { format = "[i]abs=/", style = {} },
	IAbsolutePathDoesNotMatchRegex = { format = "[i]abs!/", style = {} },
}

-- The identifiers used to denote applied search input.
--
-- Type: { format = nullable string, style = [Style](https://xplr.dev/en/style) }
xplr.config.general.sort_and_filter_ui.search_identifier = {
	format = "search:",
	style = {},
}

-- The content for panel title by default.
--
-- Type: nullable string
xplr.config.general.panel_ui.default.title.format = nil

-- The style for panel title by default.
--
-- Type: [Style](https://xplr.dev/en/style)
xplr.config.general.panel_ui.default.title.style = {
	fg = "Reset",
	add_modifiers = { "Bold" },
}

-- Style of the panels by default.
--
-- Type: [Style](https://xplr.dev/en/style)
xplr.config.general.panel_ui.default.style = {}

-- Defines where to show borders for the panels by default.
--
-- Type: nullable list of [Border](https://xplr.dev/en/borders#border)
xplr.config.general.panel_ui.default.borders = {
	"Top",
	"Right",
	"Bottom",
	"Left",
}

-- Type of the borders by default.
--
-- Type: nullable [Border Type](https://xplr.dev/en/borders#border-type)
xplr.config.general.panel_ui.default.border_type = "Rounded"

-- Style of the panel borders by default.
--
-- Type: [Style](https://xplr.dev/en/style)
xplr.config.general.panel_ui.default.border_style = { fg = "DarkGray" }

-- The content for the table panel title.
--
-- Type: nullable string
xplr.config.general.panel_ui.table.title.format = nil

-- Style of the table panel title.
--
-- Type: [Style](https://xplr.dev/en/style)
xplr.config.general.panel_ui.table.title.style = {}

-- Style of the table panel.
--
-- Type: [Style](https://xplr.dev/en/style)
xplr.config.general.panel_ui.table.style = {}

-- Defines where to show borders for the table panel.
--
-- Type: nullable list of [Border](https://xplr.dev/en/borders#border)
xplr.config.general.panel_ui.table.borders = nil

-- Type of the borders for table panel.
--
-- Type: nullable [Border Type](https://xplr.dev/en/borders#border-type)
xplr.config.general.panel_ui.table.border_type = nil

-- Style of the table panel borders.
--
-- Type: [Style](https://xplr.dev/en/style)
xplr.config.general.panel_ui.table.border_style = {}

-- The content for the help menu panel title.
--
-- Type: nullable string
xplr.config.general.panel_ui.help_menu.title.format = nil

-- Style of the help menu panel title.
--
-- Type: [Style](https://xplr.dev/en/style)
xplr.config.general.panel_ui.help_menu.title.style = {}

-- Style of the help menu panel.
--
-- Type: [Style](https://xplr.dev/en/style)
xplr.config.general.panel_ui.help_menu.style = {}

-- Defines where to show borders for the help menu panel.
--
-- Type: nullable list of [Border](https://xplr.dev/en/borders#border)
xplr.config.general.panel_ui.help_menu.borders = nil

-- Type of the borders for help menu panel.
--
-- Type: nullable [Border Type](https://xplr.dev/en/borders#border-type)
xplr.config.general.panel_ui.help_menu.border_type = nil

-- Style of the help menu panel borders.
--
-- Type: [Style](https://xplr.dev/en/style)
xplr.config.general.panel_ui.help_menu.border_style = {}

-- The content for the input & logs panel title.
--
-- Type: nullable string
xplr.config.general.panel_ui.input_and_logs.title.format = nil

-- Style of the input & logs panel title.
--
-- Type: [Style](https://xplr.dev/en/style)
xplr.config.general.panel_ui.input_and_logs.title.style = {}

-- Style of the input & logs panel.
--
-- Type: [Style](https://xplr.dev/en/style)
xplr.config.general.panel_ui.input_and_logs.style = {}
-- Defines where to show borders for the input & logs panel.
--
-- Type: nullable list of [Border](https://xplr.dev/en/borders#border)
xplr.config.general.panel_ui.input_and_logs.borders = nil

-- Type of the borders for input & logs panel.
--
-- Type: nullable [Border Type](https://xplr.dev/en/borders#border-type)
xplr.config.general.panel_ui.input_and_logs.border_type = nil

-- Style of the input & logs panel borders.
--
-- Type: [Style](https://xplr.dev/en/style)
xplr.config.general.panel_ui.input_and_logs.border_style = {}

-- The content for the selection panel title.
--
-- Type: nullable string
xplr.config.general.panel_ui.selection.title.format = nil

-- Style of the selection panel title.
--
-- Type: [Style](https://xplr.dev/en/style)
xplr.config.general.panel_ui.selection.title.style = {}

-- Style of the selection panel.
--
-- Type: [Style](https://xplr.dev/en/style)
xplr.config.general.panel_ui.selection.style = {}
-- Defines where to show borders for the selection panel.
--
-- Type: nullable list of [Border](https://xplr.dev/en/borders#border)
xplr.config.general.panel_ui.selection.borders = nil

-- Type of the borders for selection panel.
--
-- Type: nullable [Border Type](https://xplr.dev/en/borders#border-type)
xplr.config.general.panel_ui.selection.border_type = nil

-- Style of the selection panel borders.
--
-- Type: [Style](https://xplr.dev/en/style)
xplr.config.general.panel_ui.selection.border_style = {}

-- The content for the sort & filter panel title.
--
-- Type: nullable string
xplr.config.general.panel_ui.sort_and_filter.title.format = nil

-- Style of the sort & filter panel title.
--
-- Type: [Style](https://xplr.dev/en/style)
xplr.config.general.panel_ui.sort_and_filter.title.style = {}

-- Style of the sort & filter panel.
--
-- Type: [Style](https://xplr.dev/en/style)
xplr.config.general.panel_ui.sort_and_filter.style = {}

-- Defines where to show borders for the sort & filter panel.
--
-- Type: nullable list of [Border](https://xplr.dev/en/borders#border)
xplr.config.general.panel_ui.sort_and_filter.borders = nil

-- Type of the borders for sort & filter panel.
--
-- Type: nullable [Border Type](https://xplr.dev/en/borders#border-type)
xplr.config.general.panel_ui.sort_and_filter.border_type = nil

-- Style of the sort & filter panel borders.
--
-- Type: [Style](https://xplr.dev/en/style)
xplr.config.general.panel_ui.sort_and_filter.border_style = {}

-- Initial group if sorters applied to the nodes list in the table.
--
-- Type: nullable list of [Node Sorter](https://xplr.dev/en/sorting#node-sorter-applicable)
xplr.config.general.initial_sorting = {
	{ sorter = "ByCanonicalIsDir", reverse = true },
	{ sorter = "ByIRelativePath", reverse = false },
}

-- The name of one of the modes to use when xplr loads.
--
-- Type: nullable string
xplr.config.general.initial_mode = "default"

-- The name of one of the layouts to use when xplr loads.
--
-- Type: nullable string
xplr.config.general.initial_layout = "default"

-- Set it to a file path to start fifo when xplr loads.
-- Generally it is used to integrate with external tools like previewers.
--
-- Type: nullable string
xplr.config.general.start_fifo = nil

-- Use it to define a set of key bindings that are available by default in
-- every [mode](https://xplr.dev/en/mode). They can be overwritten.
--
-- Type: [Key Bindings](https://xplr.dev/en/configure-key-bindings#key-bindings)
xplr.config.general.global_key_bindings = {
	on_key = {
		["esc"] = {
			messages = {
				"PopMode",
			},
		},
		["ctrl-c"] = {
			messages = {
				"Terminate",
			},
		},
	},
}

-- ### 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.

-- The style for the directory nodes
--
-- Type: [Style](https://xplr.dev/en/style)
xplr.config.node_types.directory.style = {
	fg = "Blue",
}

-- Metadata for the directory nodes.
-- You can set as many metadata as you want.
--
-- Type: nullable string
--
-- Example:
--
-- ```lua
-- xplr.config.node_types.directory.meta.foo = "foo"
-- xplr.config.node_types.directory.meta.bar = "bar"
-- ```
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 = {}

-- Metadata for the file nodes.
-- You can set as many metadata as you want.
--
-- Type: nullable string
--
-- Example:
--
-- ```lua
-- xplr.config.node_types.file.meta.foo = "foo"
-- xplr.config.node_types.file.meta.bar = "bar"
-- ```
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 = {
	fg = "Cyan",
	add_modifiers = { "Italic" },
}

-- Metadata for the symlink nodes.
-- You can set as many metadata as you want.
--
-- Type: nullable string
--
-- Example:
--
-- ```lua
-- xplr.config.node_types.symlink.meta.foo = "foo"
-- xplr.config.node_types.symlink.meta.bar = "bar"
-- ```
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 = {
	audio = {
		["*"] = { meta = { icon = "" } },
	},
	image = {
		["*"] = { meta = { icons = "" } },
	},
	video = {
		["*"] = { meta = { icons = "" } },
	},
	text = {
		["*"] = { meta = { icons = "" } },
	},
}

-- 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 = {
	-- file extensions (vim-devicons)
	ai = { meta = { icon = "" } },
	awk = { meta = { icon = "" } },
	bash = { meta = { icon = "" } },
	bat = { meta = { icon = "" } },
	bmp = { meta = { icon = "" } },
	c = { meta = { icon = "" } },
	cc = { meta = { icon = "" } },
	clj = { meta = { icon = "" } },
	cljc = { meta = { icon = "" } },
	cljs = { meta = { icon = "" } },
	coffee = { meta = { icon = "" } },
	conf = { meta = { icon = "" } },
	cp = { meta = { icon = "" } },
	cpp = { meta = { icon = "" } },
	cs = { meta = { icon = "" } },
	csh = { meta = { icon = "" } },
	css = { meta = { icon = "" } },
	cxx = { meta = { icon = "" } },
	["c++"] = { meta = { icon = "" } },
	d = { meta = { icon = "" } },
	dart = { meta = { icon = "" } },
	db = { meta = { icon = "" } },
	diff = { meta = { icon = "" } },
	dump = { meta = { icon = "" } },
	edn = { meta = { icon = "" } },
	eex = { meta = { icon = "" } },
	ejs = { meta = { icon = "" } },
	elm = { meta = { icon = "" } },
	erl = { meta = { icon = "" } },
	ex = { meta = { icon = "" } },
	exs = { meta = { icon = "" } },
	fish = { meta = { icon = "" } },
	fs = { meta = { icon = "" } },
	fsi = { meta = { icon = "" } },
	fsscript = { meta = { icon = "" } },
	fsx = { meta = { icon = "" } },
	["f#"] = { meta = { icon = "" } },
	gemspec = { meta = { icon = "" } },
	gif = { meta = { icon = "" } },
	go = { meta = { icon = "" } },
	h = { meta = { icon = "" } },
	haml = { meta = { icon = "" } },
	hbs = { meta = { icon = "" } },
	heex = { meta = { icon = "" } },
	hh = { meta = { icon = "" } },
	hpp = { meta = { icon = "" } },
	hrl = { meta = { icon = "" } },
	hs = { meta = { icon = "" } },
	htm = { meta = { icon = "" } },
	html = { meta = { icon = "" } },
	hxx = { meta = { icon = "" } },
	ico = { meta = { icon = "" } },
	ini = { meta = { icon = "" } },
	java = { meta = { icon = "" } },
	jl = { meta = { icon = "" } },
	jpeg = { meta = { icon = "" } },
	jpg = { meta = { icon = "" } },
	js = { meta = { icon = "" } },
	json = { meta = { icon = "" } },
	jsx = { meta = { icon = "" } },
	ksh = { meta = { icon = "" } },
	leex = { meta = { icon = "" } },
	less = { meta = { icon = "" } },
	lhs = { meta = { icon = "" } },
	lua = { meta = { icon = "" } },
	markdown = { meta = { icon = "" } },
	md = { meta = { icon = "" } },
	mdx = { meta = { icon = "" } },
	mjs = { meta = { icon = "" } },
	mk = { meta = { icon = "" } },
	ml = { meta = { icon = "λ" } },
	mli = { meta = { icon = "λ" } },
	mustache = { meta = { icon = "" } },
	nix = { meta = { icon = "" } },
	pem = { meta = { icon = "" } },
	php = { meta = { icon = "" } },
	pl = { meta = { icon = "" } },
	pm = { meta = { icon = "" } },
	png = { meta = { icon = "" } },
	pp = { meta = { icon = "" } },
	ps1 = { meta = { icon = "" } },
	psb = { meta = { icon = "" } },
	psd = { meta = { icon = "" } },
	py = { meta = { icon = "" } },
	pyc = { meta = { icon = "" } },
	pyd = { meta = { icon = "" } },
	pyo = { meta = { icon = "" } },
	r = { meta = { icon = "ﳒ" } },
	rake = { meta = { icon = "" } },
	rb = { meta = { icon = "" } },
	rlib = { meta = { icon = "" } },
	rmd = { meta = { icon = "" } },
	rproj = { meta = { icon = "鉶" } },
	rs = { meta = { icon = "" } },
	rss = { meta = { icon = "" } },
	sass = { meta = { icon = "" } },
	scala = { meta = { icon = "" } },
	scss = { meta = { icon = "" } },
	sh = { meta = { icon = "" } },
	slim = { meta = { icon = "" } },
	sln = { meta = { icon = "" } },
	sol = { meta = { icon = "ﲹ" } },
	sql = { meta = { icon = "" } },
	styl = { meta = { icon = "" } },
	suo = { meta = { icon = "" } },
	swift = { meta = { icon = "" } },
	t = { meta = { icon = "" } },
	tex = { meta = { icon = "ﭨ" } },
	toml = { meta = { icon = "" } },
	ts = { meta = { icon = "" } },
	tsx = { meta = { icon = "" } },
	twig = { meta = { icon = "" } },
	vim = { meta = { icon = "" } },
	vue = { meta = { icon = "﵂" } },
	webmanifest = { meta = { icon = "" } },
	webp = { meta = { icon = "" } },
	xcplayground = { meta = { icon = "" } },
	xul = { meta = { icon = "" } },
	yaml = { meta = { icon = "" } },
	yml = { meta = { icon = "" } },
	zsh = { meta = { icon = "" } },
	-- archives or compressed (extensions from dircolors defaults)
	["7z"] = { meta = { icon = "" } },
	ace = { meta = { icon = "" } },
	alz = { meta = { icon = "" } },
	arc = { meta = { icon = "" } },
	arj = { meta = { icon = "" } },
	bz = { meta = { icon = "" } },
	bz2 = { meta = { icon = "" } },
	cab = { meta = { icon = "" } },
	cpio = { meta = { icon = "" } },
	deb = { meta = { icon = "" } },
	dwm = { meta = { icon = "" } },
	dz = { meta = { icon = "" } },
	ear = { meta = { icon = "" } },
	esd = { meta = { icon = "" } },
	gz = { meta = { icon = "" } },
	jar = { meta = { icon = "" } },
	lha = { meta = { icon = "" } },
	lrz = { meta = { icon = "" } },
	lz = { meta = { icon = "" } },
	lz4 = { meta = { icon = "" } },
	lzh = { meta = { icon = "" } },
	lzma = { meta = { icon = "" } },
	lzo = { meta = { icon = "" } },
	rar = { meta = { icon = "" } },
	rpm = { meta = { icon = "" } },
	rz = { meta = { icon = "" } },
	sar = { meta = { icon = "" } },
	swm = { meta = { icon = "" } },
	t7z = { meta = { icon = "" } },
	tar = { meta = { icon = "" } },
	taz = { meta = { icon = "" } },
	tbz = { meta = { icon = "" } },
	tbz2 = { meta = { icon = "" } },
	tgz = { meta = { icon = "" } },
	tlz = { meta = { icon = "" } },
	txz = { meta = { icon = "" } },
	tz = { meta = { icon = "" } },
	tzo = { meta = { icon = "" } },
	tzst = { meta = { icon = "" } },
	war = { meta = { icon = "" } },
	wim = { meta = { icon = "" } },
	xz = { meta = { icon = "" } },
	z = { meta = { icon = "" } },
	zip = { meta = { icon = "" } },
	zoo = { meta = { icon = "" } },
	zst = { meta = { icon = "" } },
	-- image formats (extensions from dircolors defaults)
	jpg = { meta = { icon = "" } },
	jpeg = { meta = { icon = "" } },
	mjpg = { meta = { icon = "" } },
	mjpeg = { meta = { icon = "" } },
	bmp = { meta = { icon = "" } },
	pbm = { meta = { icon = "" } },
	pgm = { meta = { icon = "" } },
	ppm = { meta = { icon = "" } },
	tga = { meta = { icon = "" } },
	xbm = { meta = { icon = "" } },
	xpm = { meta = { icon = "" } },
	tif = { meta = { icon = "" } },
	tiff = { meta = { icon = "" } },
	png = { meta = { icon = "" } },
	svg = { meta = { icon = "" } },
	svgz = { meta = { icon = "" } },
	pcx = { meta = { icon = "" } },
	m2v = { meta = { icon = "" } },
	ogm = { meta = { icon = "" } },
	nuv = { meta = { icon = "" } },
	rm = { meta = { icon = "" } },
	rmvb = { meta = { icon = "" } },
	flc = { meta = { icon = "" } },
	fli = { meta = { icon = "" } },
	gl = { meta = { icon = "" } },
	dl = { meta = { icon = "" } },
	xcf = { meta = { icon = "" } },
	xwd = { meta = { icon = "" } },
	cgm = { meta = { icon = "" } },
	emf = { meta = { icon = "" } },
	ogx = { meta = { icon = "" } },
	-- video formats
	mkv = { meta = { icon = "" } },
	asf = { meta = { icon = "" } },
	yuv = { meta = { icon = "" } },
	avi = { meta = { icon = "" } },
	gif = { meta = { icon = "" } },
	mpg = { meta = { icon = "" } },
	mpeg = { meta = { icon = "" } },
	qt = { meta = { icon = "" } },
	mng = { meta = { icon = "" } },
	ogv = { meta = { icon = "" } },
	webm = { meta = { icon = "" } },
	vob = { meta = { icon = "" } },
	flv = { meta = { icon = "" } },
	mov = { meta = { icon = "" } },
	wmv = { meta = { icon = "" } },
	mp4 = { meta = { icon = "" } },
	m4v = { meta = { icon = "" } },
	mp4v = { meta = { icon = "" } },
	-- audio formats (extensions from dircolors defaults)
	aac = { meta = { icon = "" } },
	au = { meta = { icon = "" } },
	flac = { meta = { icon = "" } },
	m4a = { meta = { icon = "" } },
	mid = { meta = { icon = "" } },
	midi = { meta = { icon = "" } },
	mka = { meta = { icon = "" } },
	mp3 = { meta = { icon = "" } },
	mpc = { meta = { icon = "" } },
	ogg = { meta = { icon = "" } },
	ra = { meta = { icon = "" } },
	wav = { meta = { icon = "" } },
	oga = { meta = { icon = "" } },
	opus = { meta = { icon = "" } },
	spx = { meta = { icon = "" } },
	xspf = { meta = { icon = "" } },
	-- other formats
	pdf = { meta = { icon = "" } },
}

-- 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 = {
	-- file names (vim-devicons)
	[".DS_Store"] = { meta = { icon = "" } },
	[".bashprofile"] = { meta = { icon = "" } },
	[".bashrc"] = { meta = { icon = "" } },
	[".ds_store"] = { meta = { icon = "" } },
	[".gitattributes"] = { meta = { icon = "" } },
	[".gitconfig"] = { meta = { icon = "" } },
	[".gitignore"] = { meta = { icon = "" } },
	[".gitlab-ci.yml"] = { meta = { icon = "" } },
	[".gvimrc"] = { meta = { icon = "" } },
	[".vimrc"] = { meta = { icon = "" } },
	[".zprofile"] = { meta = { icon = "" } },
	[".zshenv"] = { meta = { icon = "" } },
	[".zshrc"] = { meta = { icon = "" } },
	["CMakeLists.txt"] = { meta = { icon = "" } },
	["Docker-compose.yml"] = { meta = { icon = "" } },
	["Dockerfile"] = { meta = { icon = "" } },
	["Dropbox"] = { meta = { icon = "" } },
	["Gemfile"] = { meta = { icon = "" } },
	["Gruntfile.coffee"] = { meta = { icon = "" } },
	["Gruntfile.js"] = { meta = { icon = "" } },
	["Gruntfile.ls"] = { meta = { icon = "" } },
	["Gulpfile.coffee"] = { meta = { icon = "" } },
	["Gulpfile.js"] = { meta = { icon = "" } },
	["Gulpfile.ls"] = { meta = { icon = "" } },
	["LICENSE"] = { meta = { icon = "" } },
	["Makefile"] = { meta = { icon = "" } },
	["Procfile"] = { meta = { icon = "" } },
	["Rakefile"] = { meta = { icon = "" } },
	["React.jsx"] = { meta = { icon = "" } },
	["_gvimrc"] = { meta = { icon = "" } },
	["_vimrc"] = { meta = { icon = "" } },
	["backbone.min.js"] = { meta = { icon = "" } },
	["cmakelists.txt"] = { meta = { icon = "" } },
	["config.ru"] = { meta = { icon = "" } },
	["docker-compose.yml"] = { meta = { icon = "" } },
	["dockerfile"] = { meta = { icon = "" } },
	["dropbox"] = { meta = { icon = "" } },
	["favicon.ico"] = { meta = { icon = "" } },
	["gemfile"] = { meta = { icon = "" } },
	["gruntfile.coffee"] = { meta = { icon = "" } },
	["gruntfile.js"] = { meta = { icon = "" } },
	["gruntfile.ls"] = { meta = { icon = "" } },
	["gulpfile.coffee"] = { meta = { icon = "" } },
	["gulpfile.js"] = { meta = { icon = "" } },
	["gulpfile.ls"] = { meta = { icon = "" } },
	["license"] = { meta = { icon = "" } },
	["makefile"] = { meta = { icon = "" } },
	["mix.lock"] = { meta = { icon = "" } },
	["node_modules"] = { meta = { icon = "" } },
	["procfile"] = { meta = { icon = "" } },
	["rakefile"] = { meta = { icon = "" } },
	["react.jsx"] = { meta = { icon = "" } },
	["robots.txt"] = { meta = { icon = "ﮧ" } },
	-- file patterns (file name adaptations)
	["Vagrantfile "] = { meta = { icon = "" } },
	["angular.min.js"] = { meta = { icon = "" } },
	["jquery.min.js"] = { meta = { icon = "" } },
	["materialize.min.css"] = { meta = { icon = "" } },
	["materialize.min.js"] = { meta = { icon = "" } },
	["mootools.min.js"] = { meta = { icon = "" } },
	["require.min.js"] = { meta = { icon = "" } },
	["vimrc"] = { meta = { icon = "" } },
}

-- ### Layouts ----------------------------------------------------------------
--
-- 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 = {
			constraints = {
				{ Percentage = 70 },
				{ Percentage = 30 },
			},
		},
		splits = {
			{
				Vertical = {
					config = {
						constraints = {
							{ Length = 3 },
							{ Min = 1 },
							{ Length = 3 },
						},
					},
					splits = {
						"SortAndFilter",
						"Table",
						"InputAndLogs",
					},
				},
			},
			{
				Vertical = {
					config = {
						constraints = {
							{ Percentage = 30 },
							{ Percentage = 70 },
						},
					},
					splits = {
						"Selection",
						"HelpMenu",
					},
				},
			},
		},
	},
}

-- The layout without help menu
--
-- Type: [Layout](https://xplr.dev/en/layout)
xplr.config.layouts.builtin.no_help = {
	Horizontal = {
		config = {
			constraints = {
				{ Percentage = 70 },
				{ Percentage = 30 },
			},
		},
		splits = {
			{
				Vertical = {
					config = {
						constraints = {
							{ Length = 3 },
							{ Min = 1 },
							{ Length = 3 },
						},
					},
					splits = {
						"SortAndFilter",
						"Table",
						"InputAndLogs",
					},
				},
			},
			"Selection",
		},
	},
}

-- The layout without selection panel
--
-- Type: [Layout](https://xplr.dev/en/layout)
xplr.config.layouts.builtin.no_selection = {
	Horizontal = {
		config = {
			constraints = {
				{ Percentage = 70 },
				{ Percentage = 30 },
			},
		},
		splits = {
			{
				Vertical = {
					config = {
						constraints = {
							{ Length = 3 },
							{ Min = 1 },
							{ Length = 3 },
						},
					},
					splits = {
						"SortAndFilter",
						"Table",
						"InputAndLogs",
					},
				},
			},
			"HelpMenu",
		},
	},
}

-- 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 = {
			constraints = {
				{ Length = 3 },
				{ Min = 1 },
				{ Length = 3 },
			},
		},
		splits = {
			"SortAndFilter",
			"Table",
			"InputAndLogs",
		},
	},
}

-- 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",
	key_bindings = {
		on_key = {
			["#"] = {
				messages = {
					"PrintAppStateAndQuit",
				},
			},
			["."] = {
				help = "show hidden",
				messages = {
					{
						ToggleNodeFilter = { filter = "RelativePathDoesNotStartWith", input = "." },
					},
					"ExplorePwdAsync",
				},
			},
			[":"] = {
				help = "action",
				messages = {
					"PopMode",
					{ SwitchModeBuiltin = "action" },
				},
			},
			["?"] = {
				help = "global help menu",
				messages = {
					{
						BashExec = [===[
              [ -z "$PAGER" ] && PAGER="less -+F"
              cat -- "${XPLR_PIPE_GLOBAL_HELP_MENU_OUT}" | ${PAGER:?}
            ]===],
					},
				},
			},
			["G"] = {
				help = "go to bottom",
				messages = {
					"PopMode",
					"FocusLast",
				},
			},
			["ctrl-a"] = {
				help = "select/unselect all",
				messages = {
					"ToggleSelectAll",
				},
			},
			["ctrl-f"] = {
				help = "search",
				messages = {
					"PopMode",
					{ SwitchModeBuiltin = "search" },
					{ SetInputBuffer = "" },
				},
			},
			["ctrl-i"] = {
				help = "next visited path",
				messages = {
					"NextVisitedPath",
				},
			},
			["ctrl-o"] = {
				help = "last visited path",
				messages = {
					"LastVisitedPath",
				},
			},
			["ctrl-r"] = {
				help = "refresh screen",
				messages = {
					"ClearScreen",
				},
			},
			["ctrl-u"] = {
				help = "clear selection",
				messages = {
					"ClearSelection",
				},
			},
			["ctrl-w"] = {
				help = "switch layout",
				messages = {
					{ SwitchModeBuiltin = "switch_layout" },
				},
			},
			["d"] = {
				help = "delete",
				messages = {
					"PopMode",
					{ SwitchModeBuiltin = "delete" },
				},
			},
			["down"] = {
				help = "down",
				messages = {
					"FocusNext",
				},
			},
			["enter"] = {
				help = "quit with result",
				messages = {
					"PrintResultAndQuit",
				},
			},
			["f"] = {
				help = "filter",
				messages = {
					"PopMode",
					{ SwitchModeBuiltin = "filter" },
				},
			},
			["g"] = {
				help = "go to",
				messages = {
					"PopMode",
					{ SwitchModeBuiltin = "go_to" },
				},
			},
			["left"] = {
				help = "back",
				messages = {
					"Back",
				},
			},
			["q"] = {
				help = "quit",
				messages = {
					"Quit",
				},
			},
			["r"] = {
				help = "rename",
				messages = {
					"PopMode",
					{ SwitchModeBuiltin = "rename" },
					{
						BashExecSilently0 = [===[
              NAME=$(basename "${XPLR_FOCUS_PATH:?}")
              "$XPLR" -m 'SetInputBuffer: %q' "${NAME:?}"
            ]===],
					},
				},
			},
			["ctrl-d"] = {
				help = "duplicate as",
				messages = {
					"PopMode",
					{ SwitchModeBuiltin = "duplicate_as" },
					{
						BashExecSilently0 = [===[
              NAME=$(basename "${XPLR_FOCUS_PATH:?}")
              "$XPLR" -m 'SetInputBuffer: %q' "${NAME:?}"
            ]===],
					},
				},
			},
			["right"] = {
				help = "enter",
				messages = {
					"Enter",
				},
			},
			["s"] = {
				help = "sort",
				messages = {
					"PopMode",
					{ SwitchModeBuiltin = "sort" },
				},
			},
			["space"] = {
				help = "toggle selection",
				messages = {
					"ToggleSelection",
					"FocusNext",
				},
			},
			["up"] = {
				help = "up",
				messages = {
					"FocusPrevious",
				},
			},
			["~"] = {
				help = "go home",
				messages = {
					{
						BashExecSilently0 = [===[
              "$XPLR" -m 'ChangeDirectory: %q' "${HOME:?}"
            ]===],
					},
				},
			},
			["page-up"] = {
				help = "scroll up",
				messages = {
					"ScrollUp",
				},
			},
			["page-down"] = {
				help = "scroll down",
				messages = {
					"ScrollDown",
				},
			},
			["{"] = {
				help = "scroll up half",
				messages = {
					"ScrollUpHalf",
				},
			},
			["}"] = {
				help = "scroll down half",
				messages = {
					"ScrollDownHalf",
				},
			},
		},
		on_number = {
			help = "input",
			messages = {
				"PopMode",
				{ SwitchModeBuiltin = "number" },
				"BufferInputFromKey",
			},
		},
	},
}

xplr.config.modes.builtin.default.key_bindings.on_key["tab"] =
	xplr.config.modes.builtin.default.key_bindings.on_key["ctrl-i"]
xplr.config.modes.builtin.default.key_bindings.on_key["v"] =
	xplr.config.modes.builtin.default.key_bindings.on_key["space"]
xplr.config.modes.builtin.default.key_bindings.on_key["V"] =
	xplr.config.modes.builtin.default.key_bindings.on_key["ctrl-a"]
xplr.config.modes.builtin.default.key_bindings.on_key["/"] =
	xplr.config.modes.builtin.default.key_bindings.on_key["ctrl-f"]
xplr.config.modes.builtin.default.key_bindings.on_key["h"] =
	xplr.config.modes.builtin.default.key_bindings.on_key["left"]
xplr.config.modes.builtin.default.key_bindings.on_key["j"] =
	xplr.config.modes.builtin.default.key_bindings.on_key["down"]
xplr.config.modes.builtin.default.key_bindings.on_key["k"] = xplr.config.modes.builtin.default.key_bindings.on_key["up"]
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",
	layout = {
		Vertical = {
			config = {
				constraints = {
					{ Min = 14 },
					{ MinLessThanScreenHeight = 14 },
				},
			},
			splits = {
				{
					CustomContent = {
						title = "debug error",
						body = {
							StaticParagraph = {
								render = [[

  Some errors occurred during startup.
  If you think this is a bug, please report it at:

  https://github.com/sayanarijit/xplr/issues/new

  Press `enter` to open the logs in your $EDITOR.
  Press `escape` to ignore the errors and continue with the default config.

  To disable this mode, set `xplr.config.general.disable_debug_error_mode`
  to `true` in your config file.
                ]],
							},
						},
					},
				},
				"InputAndLogs",
			},
		},
	},
	key_bindings = {
		on_key = {
			["enter"] = {
				help = "open logs in editor",
				messages = {
					{
						BashExec = [===[
              cat "${XPLR_PIPE_LOGS_OUT:?}" | ${EDITOR:-vi} -
            ]===],
					},
				},
			},
			["q"] = {
				help = "quit",
				messages = {
					"Quit",
				},
			},
		},
		default = {
			messages = {},
		},
	},
}

-- The builtin recover mode.
--
-- Type: [Mode](https://xplr.dev/en/mode)
xplr.config.modes.builtin.recover = {
	name = "recover",
	layout = {
		CustomContent = {
			title = " recover ",
			body = {
				StaticParagraph = {
					render = [[

  You pressed an invalid key and went into "recover" mode.
  This mode saves you from performing unwanted actions.

  Let's calm down, press `escape`, and try again.

  To disable this mode, set `xplr.config.general.enable_recover_mode`
  to `false` in your config file.
          ]],
				},
			},
		},
	},
	key_bindings = {
		default = {
			messages = {},
		},
	},
}

-- The builtin go to path mode.
--
-- Type: [Mode](https://xplr.dev/en/mode)
xplr.config.modes.builtin.go_to_path = {
	name = "go to path",
	key_bindings = {
		on_key = {
			["enter"] = {
				help = "submit",
				messages = {
					{
						BashExecSilently0 = [===[
              PTH=${XPLR_INPUT_BUFFER}
              PTH_ESC=$(printf %q "$PTH")
              if [ -d "$PTH" ]; then
                "$XPLR" -m 'ChangeDirectory: %q' "$PTH"
              elif [ -e "$PTH" ]; then
                "$XPLR" -m 'FocusPath: %q' "$PTH"
              else
                "$XPLR" -m 'LogError: %q' "could not find $PTH_ESC"
              fi
            ]===],
					},
					"PopMode",
				},
			},
			["tab"] = {
				help = "try complete",
				messages = {
					{ CallLuaSilently = "builtin.try_complete_path" },
				},
			},
		},
		default = {
			messages = {
				"UpdateInputBufferFromKey",
			},
		},
	},
}

-- The builtin selection ops mode.
--
-- Type: [Mode](https://xplr.dev/en/mode)
xplr.config.modes.builtin.selection_ops = {
	name = "selection ops",
	layout = "HelpMenu",
	key_bindings = {
		on_key = {
			["c"] = {
				help = "copy here",
				messages = {
					{
						BashExec0 = [===[
              (while IFS= read -r -d '' PTH; do
                PTH_ESC=$(printf %q "$PTH")
                if cp -vr -- "${PTH:?}" ./; then
                  "$XPLR" -m 'LogSuccess: %q' "$PTH_ESC copied to ."
                else
                  "$XPLR" -m 'LogError: %q' "Failed to copy $PTH_ESC to ."
                fi
              done < "${XPLR_PIPE_SELECTION_OUT:?}")
              "$XPLR" -m ExplorePwdAsync
              "$XPLR" -m ClearSelection
              read -p "[enter to continue]"
            ]===],
					},
					"PopMode",
				},
			},
			["m"] = {
				help = "move here",
				messages = {
					{
						BashExec0 = [===[
              (while IFS= read -r -d '' PTH; do
                PTH_ESC=$(printf %q "$PTH")
                if mv -v -- "${PTH:?}" ./; then
                  "$XPLR" -m 'LogSuccess: %q' "$PTH_ESC moved to ."
                else
                  "$XPLR" -m 'LogError: %q' "Failed to move $PTH_ESC to ."
                fi
              done < "${XPLR_PIPE_SELECTION_OUT:?}")
              "$XPLR" -m ExplorePwdAsync
              read -p "[enter to continue]"
            ]===],
					},
					"PopMode",
				},
			},
			["u"] = {
				help = "clear selection",
				messages = {
					"ClearSelection",
					"PopMode",
				},
			},
		},
	},
}

-- The builtin create mode.
--
-- Type: [Mode](https://xplr.dev/en/mode)
xplr.config.modes.builtin.create = {
	name = "create",
	layout = "HelpMenu",
	key_bindings = {
		on_key = {
			["d"] = {
				help = "create directory",
				messages = {
					"PopMode",
					{ SwitchModeBuiltin = "create_directory" },
					{ SetInputBuffer = "" },
				},
			},
			["f"] = {
				help = "create file",
				messages = {
					"PopMode",
					{ SwitchModeBuiltin = "create_file" },
					{ SetInputBuffer = "" },
				},
			},
		},
	},
}

-- The builtin create directory mode.
--
-- Type: [Mode](https://xplr.dev/en/mode)
xplr.config.modes.builtin.create_directory = {
	name = "create directory",
	prompt = "ð ❯ ",
	key_bindings = {
		on_key = {
			["tab"] = {
				help = "try complete",
				messages = {
					{ CallLuaSilently = "builtin.try_complete_path" },
				},
			},
			["enter"] = {
				help = "submit",
				messages = {
					{
						BashExecSilently0 = [===[
              PTH="$XPLR_INPUT_BUFFER"
              PTH_ESC=$(printf %q "$PTH")
              if [ "$PTH" ]; then
                mkdir -p -- "$PTH" \
                && "$XPLR" -m 'SetInputBuffer: ""' \
                && "$XPLR" -m ExplorePwd \
                && "$XPLR" -m 'LogSuccess: %q' "$PTH_ESC created" \
                && "$XPLR" -m 'FocusPath: %q' "$PTH"
              else
                "$XPLR" -m PopMode
              fi
            ]===],
					},
				},
			},
		},
		default = {
			messages = {
				"UpdateInputBufferFromKey",
			},
		},
	},
}

-- The builtin create file mode.
--
-- Type: [Mode](https://xplr.dev/en/mode)
xplr.config.modes.builtin.create_file = {
	name = "create file",
	prompt = "ƒ ❯ ",
	key_bindings = {
		on_key = {
			["tab"] = {
				help = "try complete",
				messages = {
					{ CallLuaSilently = "builtin.try_complete_path" },
				},
			},
			["enter"] = {
				help = "submit",
				messages = {
					{
						BashExecSilently0 = [===[
              PTH="$XPLR_INPUT_BUFFER"
              PTH_ESC=$(printf %q "$PTH")
              if [ "$PTH" ]; then
                mkdir -p -- "$(dirname $(realpath -m $PTH))" \
                && touch -- "$PTH" \
                && "$XPLR" -m 'SetInputBuffer: ""' \
                && "$XPLR" -m 'LogSuccess: %q' "$PTH_ESC created" \
                && "$XPLR" -m 'ExplorePwd' \
                && "$XPLR" -m 'FocusPath: %q' "$PTH"
              else
                "$XPLR" -m PopMode
              fi
            ]===],
					},
				},
			},
		},
		default = {
			messages = {
				"UpdateInputBufferFromKey",
			},
		},
	},
}

-- The builtin number mode.
--
-- Type: [Mode](https://xplr.dev/en/mode)
xplr.config.modes.builtin.number = {
	name = "number",
	prompt = ":",
	key_bindings = {
		on_key = {
			["down"] = {
				help = "to down",
				messages = {
					"FocusNextByRelativeIndexFromInput",
					"PopMode",
				},
			},
			["enter"] = {
				help = "to index",
				messages = {
					"FocusByIndexFromInput",
					"PopMode",
				},
			},
			["up"] = {
				help = "to up",
				messages = {
					"FocusPreviousByRelativeIndexFromInput",
					"PopMode",
				},
			},
		},
		on_navigation = {
			messages = {
				"UpdateInputBufferFromKey",
			},
		},
		on_number = {
			help = "input",
			messages = {
				"UpdateInputBufferFromKey",
			},
		},
	},
}

xplr.config.modes.builtin.number.key_bindings.on_key["j"] = xplr.config.modes.builtin.number.key_bindings.on_key["down"]
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",
	layout = "HelpMenu",
	key_bindings = {
		on_key = {
			["f"] = {
				help = "follow symlink",
				messages = {
					"FollowSymlink",
					"PopMode",
				},
			},
			["g"] = {
				help = "top",
				messages = {
					"FocusFirst",
					"PopMode",
				},
			},
			["p"] = {
				help = "path",
				messages = {
					"PopMode",
					{ SwitchModeBuiltin = "go_to_path" },
					{ SetInputBuffer = "" },
				},
			},
			["i"] = {
				help = "initial $PWD",
				messages = {
					"PopMode",
					{
						BashExecSilently0 = [===[
              "$XPLR" -m 'ChangeDirectory: %q' "${XPLR_INITIAL_PWD:?}"
            ]===],
					},
				},
			},
			["x"] = {
				help = "open in gui",
				messages = {
					{
						BashExecSilently0 = [===[
              if [ -z "$OPENER" ]; then
                if command -v xdg-open; then
                  OPENER=xdg-open
                elif command -v open; then
                  OPENER=open
                else
                  "$XPLR" -m 'LogError: "$OPENER not found"'
                  exit 1
                fi
              fi
              (while IFS= read -r -d '' PTH; do
                $OPENER "${PTH:?}" > /dev/null 2>&1
              done < "${XPLR_PIPE_RESULT_OUT:?}")
            ]===],
					},
					"ClearScreen",
					"PopMode",
				},
			},
		},
	},
}

-- The builtin rename mode.
--
-- Type: [Mode](https://xplr.dev/en/mode)
xplr.config.modes.builtin.rename = {
	name = "rename",
	key_bindings = {
		on_key = {
			["tab"] = {
				help = "try complete",
				messages = {
					{ CallLuaSilently = "builtin.try_complete_path" },
				},
			},
			["enter"] = {
				help = "submit",
				messages = {
					{
						BashExecSilently0 = [===[
              SRC="${XPLR_FOCUS_PATH:?}"
              SRC_ESC=$(printf %q "$SRC")
              TARGET="${XPLR_INPUT_BUFFER:?}"
              TARGET_ESC=$(printf %q "$TARGET")
              if [ -e "${TARGET:?}" ]; then
                "$XPLR" -m 'LogError: %q' "$TARGET_ESC already exists"
              else
                mv -- "${SRC:?}" "${TARGET:?}" \
                  && "$XPLR" -m ExplorePwd \
                  && "$XPLR" -m 'FocusPath: %q' "$TARGET" \
                  && "$XPLR" -m 'LogSuccess: %q' "$SRC_ESC renamed to $TARGET_ESC"
              fi
            ]===],
					},
					"PopMode",
				},
			},
		},
		default = {
			messages = {
				"UpdateInputBufferFromKey",
			},
		},
	},
}

-- The builtin duplicate as mode.
--
-- Type: [Mode](https://xplr.dev/en/mode)
xplr.config.modes.builtin.duplicate_as = {
	name = "duplicate as",
	key_bindings = {
		on_key = {
			["tab"] = {
				help = "try complete",
				messages = {
					{ CallLuaSilently = "builtin.try_complete_path" },
				},
			},
			["enter"] = {
				help = "submit",
				messages = {
					{
						BashExecSilently0 = [===[
              SRC="${XPLR_FOCUS_PATH:?}"
              SRC_ESC=$(printf %q "$SRC")
              TARGET="${XPLR_INPUT_BUFFER:?}"
              TARGET_ESC=$(printf %q "$TARGET")
              if [ -e "${TARGET:?}" ]; then
                "$XPLR" -m 'LogError: %q' "$TARGET_ESC already exists"
              else
                cp -r -- "${SRC:?}" "${TARGET:?}" \
                  && "$XPLR" -m ExplorePwd \
                  && "$XPLR" -m 'FocusPath: %q' "$TARGET_ESC" \
                  && "$XPLR" -m 'LogSuccess: %q' "$SRC_ESC duplicated as $TARGET_ESC"
              fi
            ]===],
					},
					"PopMode",
				},
			},
		},
		default = {
			messages = {
				"UpdateInputBufferFromKey",
			},
		},
	},
}

-- The builtin delete mode.
--
-- Type: [Mode](https://xplr.dev/en/mode)
xplr.config.modes.builtin.delete = {
	name = "delete",
	layout = "HelpMenu",
	key_bindings = {
		on_key = {
			["D"] = {
				help = "force delete",
				messages = {
					{
						BashExec0 = [===[
              (while IFS= read -r -d '' PTH; do
                PTH_ESC=$(printf %q "$PTH")
                if rm -rfv -- "${PTH:?}"; then
                  "$XPLR" -m 'LogSuccess: %q' "$PTH_ESC deleted"
                else
                  "$XPLR" -m 'LogError: %q' "Failed to delete $PTH_ESC"
                fi
              done < "${XPLR_PIPE_RESULT_OUT:?}")
              "$XPLR" -m ExplorePwdAsync
              read -p "[enter to continue]"
            ]===],
					},
					"PopMode",
				},
			},
			["d"] = {
				help = "delete",
				messages = {
					{
						BashExec0 = [===[
              (while IFS= read -r -d '' PTH; do
                PTH_ESC=$(printf %q "$PTH")
                if [ -d "$PTH" ] && [ ! -L "$PTH" ]; then
                  if rmdir -v -- "${PTH:?}"; then
                    "$XPLR" -m 'LogSuccess: %q' "$PTH_ESC deleted"
                  else
                    "$XPLR" -m 'LogError: %q' "Failed to delete $PTH_ESC"
                  fi
                else
                  if rm -v -- "${PTH:?}"; then
                    "$XPLR" -m 'LogSuccess: %q' "$PTH_ESC deleted"
                  else
                    "$XPLR" -m 'LogError: %q' "Failed to delete $PTH_ESC"
                  fi
                fi
              done < "${XPLR_PIPE_RESULT_OUT:?}")
              "$XPLR" -m ExplorePwdAsync
              read -p "[enter to continue]"
            ]===],
					},
					"PopMode",
				},
			},
		},
	},
}

-- The builtin action mode.
--
-- Type: [Mode](https://xplr.dev/en/mode)
xplr.config.modes.builtin.action = {
	name = "action to",
	layout = "HelpMenu",
	key_bindings = {
		on_key = {
			["!"] = {
				help = "shell",
				messages = {
					"PopMode",
					{ Call0 = { command = os.getenv("SHELL") or "bash", args = { "-i" } } },
					"ExplorePwdAsync",
				},
			},
			["c"] = {
				help = "create",
				messages = {
					"PopMode",
					{ SwitchModeBuiltin = "create" },
				},
			},
			["e"] = {
				help = "open in editor",
				messages = {
					{
						BashExec0 = [===[
              ${EDITOR:-vi} "${XPLR_FOCUS_PATH:?}"
            ]===],
					},
					"PopMode",
				},
			},
			["l"] = {
				help = "logs",
				messages = {
					{
						BashExec = [===[
              [ -z "$PAGER" ] && PAGER="less -+F"
              cat -- "${XPLR_PIPE_LOGS_OUT}" | ${PAGER:?}
            ]===],
					},
					"PopMode",
				},
			},
			["s"] = {
				help = "selection operations",
				messages = {
					"PopMode",
					{ SwitchModeBuiltin = "selection_ops" },
				},
			},
			["m"] = {
				help = "toggle mouse",
				messages = {
					"PopMode",
					"ToggleMouse",
				},
			},
			["v"] = {
				help = "vroot",
				messages = {
					"PopMode",
					{ SwitchModeBuiltin = "vroot" },
				},
			},
			["q"] = {
				help = "quit options",
				messages = {
					"PopMode",
					{ SwitchModeBuiltin = "quit" },
				},
			},
		},
		on_number = {
			help = "go to index",
			messages = {
				"PopMode",
				{ SwitchModeBuiltin = "number" },
				"BufferInputFromKey",
			},
		},
	},
}

-- The builtin quit mode.
--
-- Type: [Mode](https://xplr.dev/en/mode)
xplr.config.modes.builtin.quit = {
	name = "quit",
	layout = "HelpMenu",
	key_bindings = {
		on_key = {
			["enter"] = {
				help = "just quit",
				messages = {
					"Quit",
				},
			},
			["p"] = {
				help = "quit printing pwd",
				messages = {
					"PrintPwdAndQuit",
				},
			},
			["f"] = {
				help = "quit printing focus",
				messages = {
					"PrintFocusPathAndQuit",
				},
			},
			["s"] = {
				help = "quit printing selection",
				messages = {
					"PrintSelectionAndQuit",
				},
			},
			["r"] = {
				help = "quit printing result",
				messages = {
					"PrintResultAndQuit",
				},
			},
		},
	},
}

-- The builtin search mode.
--
-- Type: [Mode](https://xplr.dev/en/mode)
xplr.config.modes.builtin.search = {
	name = "search",
	prompt = "/",
	key_bindings = {
		on_key = {
			["up"] = {
				help = "up",
				messages = {
					"FocusPrevious",
				},
			},
			["down"] = {
				help = "down",
				messages = {
					"FocusNext",
				},
			},
			["right"] = {
				help = "enter",
				messages = {
					"Enter",
					{ SetInputBuffer = "" },
				},
			},
			["left"] = {
				help = "back",
				messages = {
					"Back",
					{ SetInputBuffer = "" },
				},
			},
			["tab"] = {
				help = "toggle selection",
				messages = {
					"ToggleSelection",
					"FocusNext",
				},
			},
			["enter"] = {
				help = "submit",
				messages = {
					"AcceptSearch",
					"PopMode",
				},
			},
			["esc"] = {
				help = "cancel",
				messages = {
					"CancelSearch",
					"PopMode",
				},
			},
		},
		default = {
			messages = {
				"UpdateInputBufferFromKey",
				"SearchFuzzyFromInput",
				"ExplorePwdAsync",
			},
		},
	},
}

xplr.config.modes.builtin.search.key_bindings.on_key["ctrl-n"] =
	xplr.config.modes.builtin.search.key_bindings.on_key["down"]
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",
	key_bindings = {
		on_key = {
			["r"] = {
				help = "relative path does match regex",
				messages = {
					{ SwitchModeBuiltin = "relative_path_does_match_regex" },
					{ SetInputBuffer = "" },
					{ AddNodeFilterFromInput = "RelativePathDoesMatchRegex" },
					"ExplorePwdAsync",
				},
			},
			["R"] = {
				help = "relative path does not match regex",
				messages = {
					{ SwitchModeBuiltin = "relative_path_does_not_match_regex" },
					{ SetInputBuffer = "" },
					{ AddNodeFilterFromInput = "RelativePathDoesNotMatchRegex" },
					"ExplorePwdAsync",
				},
			},
			["backspace"] = {
				help = "remove last filter",
				messages = {
					"RemoveLastNodeFilter",
					"ExplorePwdAsync",
				},
			},
			["ctrl-r"] = {
				help = "reset filters",
				messages = {
					"ResetNodeFilters",
					"ExplorePwdAsync",
				},
			},
			["ctrl-u"] = {
				help = "clear filters",
				messages = {
					"ClearNodeFilters",
					"ExplorePwdAsync",
				},
			},
		},
	},
}

-- The builtin relative_path_does_match_regex mode.
--
-- Type: [Mode](https://xplr.dev/en/mode)
xplr.config.modes.builtin.relative_path_does_match_regex = {
	name = "relative path does match regex",
	prompt = xplr.config.general.sort_and_filter_ui.filter_identifiers.RelativePathDoesMatchRegex.format,
	key_bindings = {
		on_key = {
			["enter"] = {
				help = "submit",
				messages = {
					"PopMode",
				},
			},
			["esc"] = {
				messages = {
					{ RemoveNodeFilterFromInput = "RelativePathDoesMatchRegex" },
					"PopMode",
					"ExplorePwdAsync",
				},
			},
		},
		default = {
			messages = {
				{ RemoveNodeFilterFromInput = "RelativePathDoesMatchRegex" },
				"UpdateInputBufferFromKey",
				{ AddNodeFilterFromInput = "RelativePathDoesMatchRegex" },
				"ExplorePwdAsync",
			},
		},
	},
}

-- The builtin relative_path_does_not_match_regex mode.
--
-- Type: [Mode](https://xplr.dev/en/mode)
xplr.config.modes.builtin.relative_path_does_not_match_regex = {
	name = "relative path does not match regex",
	prompt = xplr.config.general.sort_and_filter_ui.filter_identifiers.RelativePathDoesNotMatchRegex.format,
	key_bindings = {
		on_key = {
			["enter"] = {
				help = "submit",
				messages = {
					"PopMode",
				},
			},
			["esc"] = {
				messages = {
					{ RemoveNodeFilterFromInput = "RelativePathDoesNotMatchRegex" },
					"PopMode",
					"ExplorePwdAsync",
				},
			},
		},
		default = {
			messages = {
				{ RemoveNodeFilterFromInput = "RelativePathDoesNotMatchRegex" },
				"UpdateInputBufferFromKey",
				{ AddNodeFilterFromInput = "RelativePathDoesNotMatchRegex" },
				"ExplorePwdAsync",
			},
		},
	},
}

-- The builtin sort mode.
--
-- Type: [Mode](https://xplr.dev/en/mode)
xplr.config.modes.builtin.sort = {
	name = "sort",
	key_bindings = {
		on_key = {
			["!"] = {
				help = "reverse sorters",
				messages = {
					"ReverseNodeSorters",
					"ExplorePwdAsync",
				},
			},
			["E"] = {
				help = "by canonical extension reverse",
				messages = {
					{ AddNodeSorter = { sorter = "ByCanonicalExtension", reverse = true } },
					"ExplorePwdAsync",
				},
			},
			["M"] = {
				help = "by canonical mime essence reverse",
				messages = {
					{ AddNodeSorter = { sorter = "ByCanonicalMimeEssence", reverse = true } },
					"ExplorePwdAsync",
				},
			},
			["N"] = {
				help = "by node type reverse",
				messages = {
					{ AddNodeSorter = { sorter = "ByCanonicalIsDir", reverse = true } },
					{ AddNodeSorter = { sorter = "ByCanonicalIsFile", reverse = true } },
					{ AddNodeSorter = { sorter = "ByIsSymlink", reverse = true } },
					"ExplorePwdAsync",
				},
			},
			["R"] = {
				help = "by relative path reverse",
				messages = {
					{ AddNodeSorter = { sorter = "ByIRelativePath", reverse = true } },
					"ExplorePwdAsync",
				},
			},
			["S"] = {
				help = "by size reverse",
				messages = {
					{ AddNodeSorter = { sorter = "BySize", reverse = true } },
					"ExplorePwdAsync",
				},
			},
			["backspace"] = {
				help = "remove last sorter",
				messages = {
					"RemoveLastNodeSorter",
					"ExplorePwdAsync",
				},
			},
			["ctrl-r"] = {
				help = "reset sorters",
				messages = {
					"ResetNodeSorters",
					"ExplorePwdAsync",
				},
			},
			["ctrl-u"] = {
				help = "clear sorters",
				messages = {
					"ClearNodeSorters",
					"ExplorePwdAsync",
				},
			},
			["e"] = {
				help = "by canonical extension",
				messages = {
					{ AddNodeSorter = { sorter = "ByCanonicalExtension", reverse = false } },
					"ExplorePwdAsync",
				},
			},
			["enter"] = {
				help = "submit",
				messages = {
					"PopMode",
				},
			},
			["m"] = {
				help = "by canonical mime essence",
				messages = {
					{ AddNodeSorter = { sorter = "ByCanonicalMimeEssence", reverse = false } },
					"ExplorePwdAsync",
				},
			},
			["n"] = {
				help = "by node type",
				messages = {
					{ AddNodeSorter = { sorter = "ByCanonicalIsDir", reverse = false } },
					{ AddNodeSorter = { sorter = "ByCanonicalIsFile", reverse = false } },
					{ AddNodeSorter = { sorter = "ByIsSymlink", reverse = false } },
					"ExplorePwdAsync",
				},
			},
			["r"] = {
				help = "by relative path",
				messages = {
					{ AddNodeSorter = { sorter = "ByIRelativePath", reverse = false } },
					"ExplorePwdAsync",
				},
			},
			["s"] = {
				help = "by size",
				messages = {
					{ AddNodeSorter = { sorter = "BySize", reverse = false } },
					"ExplorePwdAsync",
				},
			},
			["c"] = {
				help = "by created",
				messages = {
					{ AddNodeSorter = { sorter = "ByCreated", reverse = false } },
					"ExplorePwdAsync",
				},
			},
			["C"] = {
				help = "by created reverse",
				messages = {
					{ AddNodeSorter = { sorter = "ByCreated", reverse = true } },
					"ExplorePwdAsync",
				},
			},
			["l"] = {
				help = "by last modified",
				messages = {
					{ AddNodeSorter = { sorter = "ByLastModified", reverse = false } },
					"ExplorePwdAsync",
				},
			},
			["L"] = {
				help = "by last modified reverse",
				messages = {
					{ AddNodeSorter = { sorter = "ByLastModified", reverse = true } },
					"ExplorePwdAsync",
				},
			},
		},
	},
}

-- The builtin switch layout mode.
--
-- Type: [Mode](https://xplr.dev/en/mode)
xplr.config.modes.builtin.switch_layout = {
	name = "switch layout",
	layout = "HelpMenu",
	key_bindings = {
		on_key = {
			["1"] = {
				help = "default",
				messages = {
					{ SwitchLayoutBuiltin = "default" },
					"PopMode",
				},
			},
			["2"] = {
				help = "no help menu",
				messages = {
					{ SwitchLayoutBuiltin = "no_help" },
					"PopMode",
				},
			},
			["3"] = {
				help = "no selection panel",
				messages = {
					{ SwitchLayoutBuiltin = "no_selection" },
					"PopMode",
				},
			},
			["4"] = {
				help = "no help or selection",
				messages = {
					{ SwitchLayoutBuiltin = "no_help_no_selection" },
					"PopMode",
				},
			},
		},
	},
}

-- The builtin vroot mode.
--
-- Type: [Mode](https://xplr.dev/en/mode)
xplr.config.modes.builtin.vroot = {
	name = "vroot",
	layout = "HelpMenu",
	key_bindings = {
		on_key = {
			["v"] = {
				help = "toggle vroot",
				messages = {
					"PopMode",
					"ToggleVroot",
				},
			},
			["."] = {
				help = "vroot $PWD",
				messages = {
					"PopMode",
					{
						BashExecSilently0 = [===[
              "$XPLR" -m 'SetVroot: %q' "${PWD:?}"
            ]===],
					},
				},
			},
			["/"] = {
				help = "vroot /",
				messages = {
					"PopMode",
					{ SetVroot = "/" },
				},
			},
			["~"] = {
				help = "vroot $HOME",
				messages = {
					"PopMode",
					{
						BashExecSilently0 = [===[
              "$XPLR" -m 'SetVroot: %q' "${HOME:?}"
            ]===],
					},
				},
			},
			["ctrl-r"] = {
				help = "reset vroot",
				messages = {
					"PopMode",
					"ResetVroot",
				},
			},
			["ctrl-u"] = {
				help = "unset vroot",
				messages = {
					"PopMode",
					"UnsetVroot",
				},
			},
		},
	},
}

-- 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.
--
-- See: [Lua Function Calls](https://xplr.dev/en/lua-function-calls)
--
-- As always, `xplr.fn.builtin` is where the built-in functions are defined
-- that can be overwritten.

-- Tries to auto complete the path in the input buffer
xplr.fn.builtin.try_complete_path = function(m)
	if not m.input_buffer then
		return
	end

	local function matches_all(str, paths)
		for _, path in ipairs(paths) do
			if string.sub(path, 1, #str) ~= str then
				return false
			end
		end
		return true
	end

	local path = m.input_buffer
	local explorer_config = {
		filters = {
			{ filter = "RelativePathDoesStartWith", input = xplr.util.basename(path) },
		},
	}
	local parent = xplr.util.dirname(path)
	if not parent or parent == "" then
		parent = "./"
	elseif parent ~= "/" then
		parent = parent .. "/"
	end

	local nodes = xplr.util.explore(parent, explorer_config)
	local found = {}
	for _, node in ipairs(nodes) do
		table.insert(found, parent .. node.relative_path)
	end
	local count = #found

	if count == 0 then
		return
	elseif count == 1 then
		return {
			{ SetInputBuffer = found[1] },
		}
	else
		local first = found[1]
		while #first > #path and matches_all(path, found) do
			path = string.sub(first, 1, #path + 1)
		end

		if matches_all(path, found) then
			return {
				{ SetInputBuffer = path },
			}
		end

		return {
			{ SetInputBuffer = string.sub(path, 1, #path - 1) },
		}
	end
end

-- Renders the first column in the table
xplr.fn.builtin.fmt_general_table_row_cols_0 = function(m)
	local r = ""
	if m.is_before_focus then
		r = r .. " -"
	else
		r = r .. "  "
	end

	r = r .. m.relative_index .. "│" .. m.index

	return r
end

-- Renders the second column in the table
xplr.fn.builtin.fmt_general_table_row_cols_1 = function(m)
	local r = m.tree .. m.prefix

	local function path_escape(path)
		return string.gsub(string.gsub(path, "\\", "\\\\"), "\n", "\\n")
	end

	if m.meta.icon == nil then
		r = r .. ""
	else
		r = r .. m.meta.icon .. " "
	end

	r = r .. path_escape(m.relative_path)

	if m.is_dir then
		r = r .. "/"
	end

	r = r .. m.suffix .. " "

	if m.is_symlink then
		r = r .. "-> "

		if m.is_broken then
			r = r .. "×"
		else
			r = r .. path_escape(m.symlink.absolute_path)

			if m.symlink.is_dir then
				r = r .. "/"
			end
		end
	end

	return r
end

-- Renders the third column in the table
xplr.fn.builtin.fmt_general_table_row_cols_2 = function(m)
	local no_color = os.getenv("NO_COLOR")

	local function green(x)
		if no_color == nil then
			return "\x1b[32m" .. x .. "\x1b[0m"
		else
			return x
		end
	end

	local function yellow(x)
		if no_color == nil then
			return "\x1b[33m" .. x .. "\x1b[0m"
		else
			return x
		end
	end

	local function red(x)
		if no_color == nil then
			return "\x1b[31m" .. x .. "\x1b[0m"
		else
			return x
		end
	end

	local function bit(x, color, cond)
		if cond then
			return color(x)
		else
			return color("-")
		end
	end

	local p = m.permissions

	local r = ""

	r = r .. bit("r", green, p.user_read)
	r = r .. bit("w", yellow, p.user_write)

	if p.user_execute == false and p.setuid == false then
		r = r .. bit("-", red, p.user_execute)
	elseif p.user_execute == true and p.setuid == false then
		r = r .. bit("x", red, p.user_execute)
	elseif p.user_execute == false and p.setuid == true then
		r = r .. bit("S", red, p.user_execute)
	else
		r = r .. bit("s", red, p.user_execute)
	end

	r = r .. bit("r", green, p.group_read)
	r = r .. bit("w", yellow, p.group_write)

	if p.group_execute == false and p.setuid == false then
		r = r .. bit("-", red, p.group_execute)
	elseif p.group_execute == true and p.setuid == false then
		r = r .. bit("x", red, p.group_execute)
	elseif p.group_execute == false and p.setuid == true then
		r = r .. bit("S", red, p.group_execute)
	else
		r = r .. bit("s", red, p.group_execute)
	end

	r = r .. bit("r", green, p.other_read)
	r = r .. bit("w", yellow, p.other_write)

	if p.other_execute == false and p.setuid == false then
		r = r .. bit("-", red, p.other_execute)
	elseif p.other_execute == true and p.setuid == false then
		r = r .. bit("x", red, p.other_execute)
	elseif p.other_execute == false and p.setuid == true then
		r = r .. bit("T", red, p.other_execute)
	else
		r = r .. bit("t", red, p.other_execute)
	end

	return r
end

-- Renders the fourth column in the table
xplr.fn.builtin.fmt_general_table_row_cols_3 = function(m)
	if not m.is_dir then
		return m.human_size
	else
		return ""
	end
end

-- Renders the fifth column in the table
xplr.fn.builtin.fmt_general_table_row_cols_4 = function(m)
	return tostring(os.date("%a %b %d %H:%M:%S %Y", m.last_modified / 1000000000))
end

-- This is where the custom functions can be added.
--
-- 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.custom = {}

-- ## Hooks -------------------------------------------------------------------
--
-- This section of the configuration cannot be overwritten by another config
-- file or plugin, since this is an optional lua return statement specific to
-- each config file. It can be used to define things that should be explicit
-- for reasons like performance concerns, such as hooks.
--
-- Plugins should expose the hooks, and require users to subscribe to them
-- explicitly.
--
-- Example:
--
-- ```lua
-- return {
--   -- Add messages to send when the xplr loads.
--   -- This is similar to the `--on-load` command-line option.
--   --
--   -- Type: list of [Message](https://xplr.dev/en/message#message)s
--   on_load = {
--     { LogSuccess = "Configuration successfully loaded!" },
--     { CallLuaSilently = "custom.some_plugin_with_hooks.on_load" },
--   },
--
--   -- Add messages to send when the directory changes.
--   --
--   -- Type: list of [Message](https://xplr.dev/en/message#message)s
--   on_directory_change = {
--     { LogSuccess = "Changed directory" },
--     { CallLuaSilently = "custom.some_plugin_with_hooks.on_directory_change" },
--   },
--
--   -- Add messages to send when the focus changes.
--   --
--   -- Type: list of [Message](https://xplr.dev/en/message#message)s
--   on_focus_change = {
--     { LogSuccess = "Changed focus" },
--     { CallLuaSilently = "custom.some_plugin_with_hooks.on_focus_change" },
--   }
--
--   -- Add messages to send when the mode is switched.
--   --
--   -- Type: list of [Message](https://xplr.dev/en/message#message)s
--   on_mode_switch = {
--     { LogSuccess = "Switched mode" },
--     { CallLuaSilently = "custom.some_plugin_with_hooks.on_mode_switch" },
--   }
--
--   -- Add messages to send when the layout is switched
--   --
--   -- Type: list of [Message](https://xplr.dev/en/message#message)s
--   on_layout_switch = {
--     { LogSuccess = "Switched layout" },
--     { CallLuaSilently = "custom.some_plugin_with_hooks.on_layout_switch" },
--   }
-- }
-- ```

local home = os.getenv("HOME")
local xpm_path = home .. "/.local/share/xplr/dtomvan/xpm.xplr"
local xpm_url = "https://github.com/dtomvan/xpm.xplr"

package.path = package.path .. ";" .. xpm_path .. "/?.lua;" .. xpm_path .. "/?/init.lua"

os.execute(string.format("[ -e '%s' ] || git clone '%s' '%s'", xpm_path, xpm_url, xpm_path))

require("xpm").setup({
	plugins = {
		"dtomvan/xpm.xplr",
		"Junker/nuke.xplr",
	},
	auto_install = true,
	auto_cleanup = true,
})

xplr.config.modes.builtin.default.key_bindings.on_key.x = {
	help = "xpm",
	messages = {
		"PopMode",
		{ SwitchModeCustom = "xpm" },
	},
}

require("nuke").setup({
	pager = "less -R", -- default: less -R
	open = {
		run_executables = false, -- default: false
		custom = {
			{ mime = "image/*", command = "nsxiv -aio {}" },
			{ mime = "video/*", command = "mpv {} -quiet" },
			{ mime = "audio/*", command = "mpv --audio-display=no {}" },
		},
	},
	view = {
		show_line_numbers = true, -- default: false
	},
	smart_view = {
		custom = {
			{ extension = "so", command = "ldd -r {} | less" },
		},
	},
})

return {
	on_load = {},
	on_directory_change = {},
	on_focus_change = {},
	on_mode_switch = {},
	on_layout_switch = {},
}
