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 a986348..50a91e7 100644 --- a/docs/en/src/general-config.md +++ b/docs/en/src/general-config.md @@ -199,6 +199,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 @@ -548,6 +560,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 fed14d0..76038c1 100644 --- a/docs/en/src/xplr.util.md +++ b/docs/en/src/xplr.util.md @@ -127,12 +127,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: @@ -146,9 +146,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. @@ -518,11 +518,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 05f9998..3dbcc20 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 48a5f54..d0ebf7a 100644 --- a/src/init.lua +++ b/src/init.lua @@ -261,6 +261,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 = { add_modifiers = { "Dim" } } + -- The default search algorithm -- -- Type: [Search Algorithm](https://xplr.dev/en/searching#algorithm) @@ -343,9 +353,7 @@ 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" }, -} +xplr.config.general.sort_and_filter_ui.separator.style = { add_modifiers = { "Dim" } } -- The content of the default identifier in Sort & filter panel. -- @@ -639,12 +647,41 @@ 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. -- @@ -3111,6 +3148,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 } @@ -3124,6 +3162,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 da01f3c..c1aedcf 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; @@ -26,8 +27,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}; lazy_static! { static ref LS_COLORS: LsColors = LsColors::from_env().unwrap_or_default(); @@ -224,12 +228,12 @@ pub fn path_split<'a>(util: Table<'a>, lua: &Lua) -> Result