diff --git a/docs/en/src/configuration.md b/docs/en/src/configuration.md index ef84ab0..a5a8b00 100644 --- a/docs/en/src/configuration.md +++ b/docs/en/src/configuration.md @@ -47,6 +47,20 @@ that can be overwritten. Tries to auto complete the path in the input buffer +#### xplr.fn.builtin.fmt_general_selection_item + +Formats each node in the selection + +#### xplr.fn.builtin.fmt_general_preview_renderer + +Renders the focused node in preview pane + +See: [xplr.util.preview](https://xplr.dev/en/xplr.util#xplrutilpreview) + +The focused node is passed as the node value, and layout_hight is passed +dynamically. +When there is no item under focus, the node value will be nil. + #### xplr.fn.builtin.fmt_general_table_row_cols_0 Renders the first column in the table diff --git a/docs/en/src/general-config.md b/docs/en/src/general-config.md index 75fa861..da387df 100644 --- a/docs/en/src/general-config.md +++ b/docs/en/src/general-config.md @@ -193,6 +193,18 @@ Style for each item in the selection list. Type: [Style](https://xplr.dev/en/style) +#### xplr.config.general.preview.renderer.format + +Preview renderer for the path under focus. + +Type: nullable string + +#### xplr.config.general.preview.renderer.style + +Style for preview panel. + +Type: [Style](https://xplr.dev/en/style) + #### xplr.config.general.search.algorithm The default search algorithm @@ -542,6 +554,41 @@ Style of the selection panel borders. Type: [Style](https://xplr.dev/en/style) +#### xplr.config.general.panel_ui.preview.title.format + +The content for the preview panel title. + +Type: nullable string + +#### xplr.config.general.panel_ui.preview.title.style + +Style of the preview panel title. + +Type: [Style](https://xplr.dev/en/style) + +#### xplr.config.general.panel_ui.preview.borders + +#### xplr.config.general.panel_ui.preview.style + +Style of the preview panel. + +Type: [Style](https://xplr.dev/en/style) +Defines where to show borders for the preview panel. + +Type: nullable list of [Border](https://xplr.dev/en/borders#border) + +#### xplr.config.general.panel_ui.preview.border_type + +Type of the borders for preview panel. + +Type: nullable [Border Type](https://xplr.dev/en/borders#border-type) + +#### xplr.config.general.panel_ui.preview.border_style + +Style of the preview panel borders. + +Type: [Style](https://xplr.dev/en/style) + #### xplr.config.general.panel_ui.sort_and_filter.title.format The content for the sort & filter panel title. diff --git a/docs/en/src/xplr.util.md b/docs/en/src/xplr.util.md index 5c1684f..7c9ec8a 100644 --- a/docs/en/src/xplr.util.md +++ b/docs/en/src/xplr.util.md @@ -110,12 +110,12 @@ xplr.util.path_split(".././foo") ### xplr.util.node -Get [Node][5] information of a given path. +Get [Node][2] information of a given path. Doesn't check if the path exists. Returns nil if the path is "/". Errors out if absolute path can't be obtained. -Type: function( path:string ) -> [Node][5]|nil +Type: function( path:string ) -> [Node][2]|nil Example: @@ -129,9 +129,9 @@ xplr.util.node("/") ### xplr.util.node_type -Get the configured [Node Type][6] of a given [Node][5]. +Get the configured [Node Type][6] of a given [Node][2]. -Type: function( [Node][5], [xplr.config.node_types][7]|nil ) -> [Node Type][6] +Type: function( [Node][2], [xplr.config.node_types][7]|nil ) -> [Node Type][6] If the second argument is missing, global config `xplr.config.node_types` will be used. @@ -501,11 +501,33 @@ xplr.util.permissions_octal(app.focused_node.permission) -- { 0, 7, 5, 4 } ``` +### xplr.util.preview + +Renders a preview of the given node as string. + +You probably want to use it inside the function mentioned in +[xplr.config.general.preview.renderer.format][9], or inside a +[custom dynamic layout][10]. + +Type: function( { node:[Node][2]|nil, layout_size:[Size][5] } ) -> string + +Example: + +```lua +xplr.util.preview({ + node = xplr.util.node("/foo"), + layout_size = { x = 0, y = 0, height = 10, width = 10 }, +}) +-- "Preview of /foo" +``` + [1]: https://xplr.dev/en/lua-function-calls#explorer-config [2]: https://xplr.dev/en/lua-function-calls#node [3]: https://xplr.dev/en/style [4]: https://xplr.dev/en/layout -[5]: https://xplr.dev/en/lua-function-calls#node +[5]: https://xplr.dev/en/layout#size [6]: https://xplr.dev/en/node-type [7]: https://xplr.dev/en/node_types [8]: https://xplr.dev/en/column-renderer#permission +[9]: https://xplr.dev/en/general-config#xplrconfiggeneralpreviewrendererformat +[10]: https://xplr.dev/en/layout#dynamic diff --git a/src/config.rs b/src/config.rs index db08f86..1c0557f 100644 --- a/src/config.rs +++ b/src/config.rs @@ -189,6 +189,13 @@ pub struct SelectionConfig { pub item: UiElement, } +#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct PreviewConfig { + #[serde(default)] + pub renderer: UiElement, +} + #[derive(Debug, Clone, Default, Serialize, Deserialize)] #[serde(deny_unknown_fields)] pub struct SearchConfig { @@ -275,6 +282,9 @@ pub struct PanelUi { #[serde(default)] pub selection: PanelUiConfig, + #[serde(default)] + pub preview: PanelUiConfig, + #[serde(default)] pub input_and_logs: PanelUiConfig, @@ -318,6 +328,9 @@ pub struct GeneralConfig { #[serde(default)] pub selection: SelectionConfig, + #[serde(default)] + pub preview: PreviewConfig, + #[serde(default)] pub search: SearchConfig, diff --git a/src/init.lua b/src/init.lua index 89d29aa..197111e 100644 --- a/src/init.lua +++ b/src/init.lua @@ -256,6 +256,16 @@ xplr.config.general.selection.item.format = "builtin.fmt_general_selection_item" -- Type: [Style](https://xplr.dev/en/style) xplr.config.general.selection.item.style = {} +-- Preview renderer for the path under focus. +-- +-- Type: nullable string +xplr.config.general.preview.renderer.format = "builtin.fmt_general_preview_renderer" + +-- Style for preview panel. +-- +-- Type: [Style](https://xplr.dev/en/style) +xplr.config.general.preview.renderer.style = {} + -- The default search algorithm -- -- Type: [Search Algorithm](https://xplr.dev/en/searching#algorithm) @@ -634,12 +644,43 @@ 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 +xplr.config.general.panel_ui.selection.border_type = "Double" -- Style of the selection panel borders. -- -- Type: [Style](https://xplr.dev/en/style) -xplr.config.general.panel_ui.selection.border_style = {} +xplr.config.general.panel_ui.selection.border_style = { + fg = "Red", +} + +-- The content for the preview panel title. +-- +-- Type: nullable string +xplr.config.general.panel_ui.preview.title.format = nil + +-- Style of the preview panel title. +-- +-- Type: [Style](https://xplr.dev/en/style) +xplr.config.general.panel_ui.preview.title.style = {} + +-- Style of the preview panel. +-- +-- Type: [Style](https://xplr.dev/en/style) +xplr.config.general.panel_ui.preview.style = {} +-- Defines where to show borders for the preview panel. +-- +-- Type: nullable list of [Border](https://xplr.dev/en/borders#border) +xplr.config.general.panel_ui.preview.borders = nil + +-- Type of the borders for preview panel. +-- +-- Type: nullable [Border Type](https://xplr.dev/en/borders#border-type) +xplr.config.general.panel_ui.preview.border_type = nil + +-- Style of the preview panel borders. +-- +-- Type: [Style](https://xplr.dev/en/style) +xplr.config.general.panel_ui.preview.border_style = {} -- The content for the sort & filter panel title. -- @@ -2948,6 +2989,7 @@ xplr.fn.builtin.try_complete_path = function(m) end end +-- Formats each node in the selection xplr.fn.builtin.fmt_general_selection_item = function(n) local nl = xplr.util.paint("\\n", { add_modifiers = { "Italic", "Dim" } }) local sh_config = { with_prefix_dots = true, without_suffix_dots = true } @@ -2961,6 +3003,15 @@ xplr.fn.builtin.fmt_general_selection_item = function(n) return xplr.util.paint(shortened:gsub("\n", nl), style) end +-- Renders the focused node in preview pane +-- +-- See: [xplr.util.preview](https://xplr.dev/en/xplr.util#xplrutilpreview) +-- +-- The focused node is passed as the node value, and layout_hight is passed +-- dynamically. +-- When there is no item under focus, the node value will be nil. +xplr.fn.builtin.fmt_general_preview_renderer = xplr.util.preview + -- Renders the first column in the table xplr.fn.builtin.fmt_general_table_row_cols_0 = function(m) local r = "" diff --git a/src/lua/util.rs b/src/lua/util.rs index 21d8ce7..30e6861 100644 --- a/src/lua/util.rs +++ b/src/lua/util.rs @@ -10,6 +10,7 @@ use crate::permissions::Octal; use crate::permissions::Permissions; use crate::ui; use crate::ui::Layout; +use crate::ui::PreviewRendererArgs; use crate::ui::Style; use crate::ui::WrapOptions; use anyhow::Result; @@ -25,8 +26,11 @@ use serde::{Deserialize, Serialize}; use serde_json as json; use serde_yaml as yaml; use std::borrow::Cow; +use std::io::BufRead; +use std::iter; use std::path::PathBuf; use std::process::Command; +use std::{fs, io}; /// Get the xplr version details. /// @@ -195,12 +199,12 @@ pub fn path_split<'a>(util: Table<'a>, lua: &Lua) -> Result