From 9070cd9e17bbf24fa709b861d028fe41da6ba74e Mon Sep 17 00:00:00 2001 From: Arijit Basu Date: Tue, 20 Jul 2021 22:10:51 +0530 Subject: [PATCH] Add more docs --- README.md | 1 + docs/en/src/SUMMARY.md | 4 +- docs/en/src/awesome-plugins.md | 6 +- docs/en/src/column-renderer.md | 313 +++++++++++++++++++++++++++++++++ docs/en/src/general-config.md | 48 ++--- docs/en/src/message.md | 222 +++++++++++++++++++++-- src/app.rs | 49 +----- src/ui.rs | 6 +- 8 files changed, 544 insertions(+), 105 deletions(-) create mode 100644 docs/en/src/column-renderer.md diff --git a/README.md b/README.md index 59e9059..fa756ed 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,7 @@ Table of content - [Style](https://arijitbasu.in/xplr/en/style.html) - [Sorting](https://arijitbasu.in/xplr/en/sorting.html) - [Filtering](https://arijitbasu.in/xplr/en/filtering.html) + - [Column Renderer](https://arijitbasu.in/xplr/en/column-renderer.html) - [Default Key Bindings](https://arijitbasu.in/xplr/en/default-key-bindings.html) - [Plugin](https://arijitbasu.in/xplr/en/plugin.html) - [Installing Plugins](https://arijitbasu.in/xplr/en/installing-plugins.html) diff --git a/docs/en/src/SUMMARY.md b/docs/en/src/SUMMARY.md index 12fd853..5d467a1 100644 --- a/docs/en/src/SUMMARY.md +++ b/docs/en/src/SUMMARY.md @@ -14,6 +14,7 @@ A hackable, minimal, fast TUI file explorer - [Style][11] - [Sorting][12] - [Filtering][13] + - [Column Renderer][26] - [Default Key Bindings][14] - [Plugin][15] - [Installing Plugins][16] @@ -52,4 +53,5 @@ A hackable, minimal, fast TUI file explorer [22]:alternatives.md [23]:upgrade-guide.md [24]:community.md -[25]:contribute.md \ No newline at end of file +[25]:contribute.md +[26]:column-renderer.md diff --git a/docs/en/src/awesome-plugins.md b/docs/en/src/awesome-plugins.md index e3551c8..e08b9d3 100644 --- a/docs/en/src/awesome-plugins.md +++ b/docs/en/src/awesome-plugins.md @@ -40,10 +40,8 @@ Integration Theme ----- -- [material-landscape.xplr][19] - Material Landscape -- [material-landscape2.xplr][20] - Material Landscape 2 +- [**material-landscape.xplr**][19] Material Landscape +- [**material-landscape2.xplr**][20] Material Landscape 2 [1]:./writing-plugins.md diff --git a/docs/en/src/column-renderer.md b/docs/en/src/column-renderer.md new file mode 100644 index 0000000..6948e3a --- /dev/null +++ b/docs/en/src/column-renderer.md @@ -0,0 +1,313 @@ +Column Renderer +============== + +A column renderer is a Lua function that receives a [special argument][1] and +returns a string that will be displayed in each specific field of the +[files table][2]. + +xplr by default provides the following column renderers: + +- `xplr.fn.builtin.fmt_general_table_row_cols_0` +- `xplr.fn.builtin.fmt_general_table_row_cols_1` +- `xplr.fn.builtin.fmt_general_table_row_cols_2` +- `xplr.fn.builtin.fmt_general_table_row_cols_3` +- `xplr.fn.builtin.fmt_general_table_row_cols_4` + +You can either overwrite these functions, or create new functions in +`xplr.fn.custom` and point to them. + +Terminal colors are supported. + + +Table Renderer Argument +----------------------- + +The special argument contains the following fields + +- [parent][3] +- [relative_path][4] +- [absolute_path][5] +- [extension][6] +- [is_symlink][7] +- [is_broken][8] +- [is_dir][9] +- [is_file][10] +- [is_readonly][11] +- [mime_essence][12] +- [size][13] +- [human_size][14] +- [permissions][15] +- [canonical][16] +- [symlink][17] +- [index][18] +- [relative_index][19] +- [is_before_focus][20] +- [is_after_focus][21] +- [tree][22] +- [prefix][23] +- [suffix][24] +- [is_selected][25] +- [is_focused][26] +- [total][27] +- [meta][28] + +### parent + +Type: string + +The parent path of the node. + +### relative_path + +Type: string + +The path relative to the parent, i.e. the file/directory name with extension. + +### absolute_path + +Type: string + +The absolute path (without resolving symlinks) of the node. + +### extension + +Type: string + +The extension of the node. + + +### is_symlink + +Type: boolean + +`true` if the node is a symlink. + + +### is_broken + +Type: boolean + +`true` if the node is a broken symlink. + + +### is_dir + +Type: boolean + +`true` if the node is a directory. + +### is_file + +Type: boolean + +`true` if the node is a file. + +### is_readonly + +Type: boolean + +`true` if the node is real-only. + + +### mime_essence + +Type: string + +The mime type of the node. For e.g. `text/csv`, `image/jpeg` etc. + +### size + +Type: integer + +The size of the exact node. The size of a directory won't be calculated +recursively. + +### human_size + +Type: string + +Like [size][29] but in human readable format. + +### permissions + +Type: [Permission][30] + +The [permissions][30] applied to the node. + +### canonical + +Type: nullable [Resolved Node Metadata][31] + +If the node is a symlink, it will hold information about the symlink resolved +node. Else, it will hold information the actual node. It the symlink is broken, +it will be null. + +### symlink + +Type: nullable [Resolved Node Metadata][31] + +If the node is a symlink and is not broken, it will hold information about the +symlink resolved node. However, it will never hold information about the actual +node. It will instead be null. + +### index + +Type: integer + +Index (starting from 0) of the node. + +### relative_index + +Type: integer + +Relative index from the focused node (i.e. 0th node). + +### is_before_focus + +Type: boolean + +`true` if the node is before the focused node. + +### is_after_focus + +Type: boolean + +`true` if the node is after the focused node. + +### tree + +Type: string + +The [tree component][32] based on the node's index. + +### prefix + +Type: string + +The prefix applicable for the node. + +### suffix + +Type: string + +The suffix applicable for the node. + +### is_selected + +Type: boolean + +`true` if the node is selected. + +### is_focused + +Type: boolean + +`true` if the node is under focus. + +### total + +Type: integer + +The total number of the nodes. + +### meta + +Type: mapping of string and string + +The applicable [meta object][33] for the node. + + +Permission +---------- + +Permission contains the following fields: + +- user_read +- user_write +- user_execute +- group_read +- group_write +- group_execute +- other_read +- other_write +- other_execute +- sticky +- setgid +- setuid + +Each field holds a boolean value. + + +Resolved Node Metadata +---------------------- + +It contains the following fields. + +- [absolute_path][5] +- [extension][6] +- [is_dir][9] +- [is_file][10] +- [is_readonly][11] +- [mime_essence][12] +- [size][13] +- [human_size][14] + + +Example +------- + +```lua +xplr.fn.custom.fmt_simple_column = function(m) + return m.prefix .. m.relative_path .. m.suffix +end + +xplr.config.general.table.header.cols = { + { format = " path" } +} + +xplr.config.general.table.row.cols = { + { format = "custom.fmt_simple_column" } +} + +xplr.config.general.table.col_widths = { + { Percentage = 100 } +} + +-- With this config, you should only see a single column displaying the +-- relative paths. +``` + + +[1]:#table-renderer-argument +[2]:layouts.md#table +[3]:#parent +[4]:#relative_path +[5]:#absolute_path +[6]:#extension +[7]:#is_symlink +[8]:#is_broken +[9]:#is_dir +[10]:#is_file +[11]:#is_readonly +[12]:#mime_essence +[13]:#size +[14]:#human_size +[15]:#permissions +[16]:#canonical +[17]:#symlink +[18]:#index +[19]:#relative_index +[20]:#is_before_focus +[21]:#is_after_focus +[22]:#tree +[23]:#prefix +[24]:#suffix +[25]:#is_selected +[26]:#is_focused +[27]:#total +[28]:meta +[29]:#size +[30]:#permission +[31]:#resolved-node-metadata +[32]:general-config.md#tabletree +[33]:node_types.md#meta diff --git a/docs/en/src/general-config.md b/docs/en/src/general-config.md index 0c9968b..e158cb8 100644 --- a/docs/en/src/general-config.md +++ b/docs/en/src/general-config.md @@ -153,51 +153,31 @@ Each column config contains `format` field (string) and `style` field ([Style][1]). However, unlike [table.header.cols][6], the `format` field here -points to a Lua function that receives a -[special argument][7] -as input and returns a string that will be displayed in the column. +points to a [column renderer function][7]. -TODO: Document the argument fields here. -xplr by default provides the following functions: +table.tree +----------------- -- `xplr.fn.builtin.fmt_general_table_row_cols_0` -- `xplr.fn.builtin.fmt_general_table_row_cols_1` -- `xplr.fn.builtin.fmt_general_table_row_cols_2` -- `xplr.fn.builtin.fmt_general_table_row_cols_3` -- `xplr.fn.builtin.fmt_general_table_row_cols_4` +Type: List of tree configuration -You can either overwrite these functions, or create new functions in -`xplr.fn.custom` and point to them. +It expects a list of three items. The first component of the tree, then the +middle components, and finally the last component of the tree. -Terminal colors are supported. +Each item requires the `format` field which is a string, and the `style` field, +which is the [Style][1] object. Example: ```lua -xplr.fn.custom.fmt_simple_column = function(m) - return m.prefix .. m.relative_path .. m.suffix -end - -xplr.config.general.table.header.cols = { - { format = " path" } +xplr.config.general.table.tree = { + { format = "├─", style = { add_modifiers = { "Bold" }, bg = nil, fg = "Blue", sub_modifiers = nil } }, + { format = "├─", style = { add_modifiers = { "Bold" }, bg = nil, fg = "Blue", sub_modifiers = nil } }, + { format = "╰─", style = { add_modifiers = { "Bold" }, bg = nil, fg = "Blue", sub_modifiers = nil } }, } - -xplr.config.general.table.row.cols = { - { format = "custom.fmt_simple_column" } -} - -xplr.config.general.table.col_widths = { - { Percentage = 100 } -} - --- With this config, you should only see a single column displaying the --- relative paths. ``` ------------- - -TODO: Continue documentation +TODO: Continue documentation. [1]:style.md @@ -206,4 +186,4 @@ TODO: Continue documentation [4]:sorting.md#node-sorter-applicable [5]:layouts.md#constraint [6]:#tableheadercols -[7]:https://docs.rs/xplr/latest/xplr/ui/struct.NodeUiMetadata.html \ No newline at end of file +[7]:column-renderer.md diff --git a/docs/en/src/message.md b/docs/en/src/message.md index 2b3d75f..9818932 100644 --- a/docs/en/src/message.md +++ b/docs/en/src/message.md @@ -767,23 +767,176 @@ This is a special argument passed to the lua functions when called using the It contains the following information: -- version -- config -- pwd -- focused_node -- directory_buffer -- selection -- mode -- layout -- input_buffer -- pid -- session_path -- explorer_config -- history -- last_modes - -TODO: Document each. For now, refer to the -[rust doc][18]. +- [version][29] +- [config][30] +- [pwd][31] +- [focused_node][32] +- [directory_buffer][33] +- [selection][34] +- [mode][35] +- [layout][36] +- [input_buffer][37] +- [pid][38] +- [session_path][39] +- [explorer_config][40] +- [history][41] +- [last_modes][42] + + +### version + +Type: string + +xplr version. Can be used to test compatibility. + +### config + +Type: [Config][43] + + +### pwd + +Type: string + +The present working directory/ + +### focused_node + +Type: nullable [Node][44] + +The node under focus. + +- [directory_buffer][33] +- [selection][34] +- [mode][35] +- [layout][36] +- [input_buffer][37] +- [pid][38] +- [session_path][39] +- [explorer_config][40] +- [history][41] +- [last_modes][42] + + +### Node + +A node contains the following fields: + +- [parent][45] +- [relative_path][46] +- [absolute_path][47] +- [extension][48] +- [is_symlink][49] +- [is_broken][50] +- [is_dir][51] +- [is_file][52] +- [is_readonly][53] +- [mime_essence][54] +- [size][55] +- [human_size][56] +- [permissions][57] +- [canonical][58] +- [symlink][59] + +### parent + +Type: string + +The parent path of the node. + +### relative_path + +Type: string + +The path relative to the parent, i.e. the file/directory name with extension. + +### absolute_path + +Type: string + +The absolute path (without resolving symlinks) of the node. + +### extension + +Type: string + +The extension of the node. + + +### is_symlink + +Type: boolean + +`true` if the node is a symlink. + + +### is_broken + +Type: boolean + +`true` if the node is a broken symlink. + + +### is_dir + +Type: boolean + +`true` if the node is a directory. + +### is_file + +Type: boolean + +`true` if the node is a file. + +### is_readonly + +Type: boolean + +`true` if the node is real-only. + + +### mime_essence + +Type: string + +The mime type of the node. For e.g. `text/csv`, `image/jpeg` etc. + +### size + +Type: integer + +The size of the exact node. The size of a directory won't be calculated +recursively. + +### human_size + +Type: string + +Like size but in human readable format. + +### permissions + +Type: [Permission][60] + +The [permissions][60] applied to the node. + +### canonical + +Type: nullable [Resolved Node Metadata][61] + +If the node is a symlink, it will hold information about the symlink resolved +node. Else, it will hold information the actual node. It the symlink is broken, +it will be null. + +### symlink + +Type: nullable [Resolved Node Metadata][61] + +If the node is a symlink and is not broken, it will hold information about the +symlink resolved node. However, it will never hold information about the actual +node. It will instead be null. + ### Example: @@ -963,4 +1116,37 @@ xplr.config.modes.builtin.default.key_bindings.on_key.space = { [25]:#xplr_pipe_history_out [26]:#xplr_pipe_directory_nodes_out [27]:https://www.yaml.org -[28]:layouts.md#table \ No newline at end of file +[28]:layouts.md#table +[29]:#version +[30]:#config +[31]:#pwd +[32]:#focused_node +[33]:#directory_buffer +[34]:#selection +[35]:#mode +[36]:#layout +[37]:#input_buffer +[38]:#pid +[39]:#session_path +[40]:#explorer_config +[41]:#history +[42]:#last_modes +[43]:configuration.md#config +[44]:#node +[45]:#parent +[46]:#relative_path +[47]:#absolute_path +[48]:#extension +[49]:#is_symlink +[50]:#is_broken +[51]:#is_dir +[52]:#is_file +[53]:#is_readonly +[54]:#mime_essence +[55]:#size +[56]:#human_size +[57]:#permissions +[58]:#canonical +[59]:#symlink +[60]:column-renderer.md#permission +[61]:column-renderer.md#resolved-node-metadata diff --git a/src/app.rs b/src/app.rs index 9755bb3..f0bd439 100644 --- a/src/app.rs +++ b/src/app.rs @@ -2784,70 +2784,27 @@ impl App { } pub fn write_pipes(&self) -> Result<()> { - // TODO optimize and test - fs::create_dir_all(self.pipe().path())?; - fs::write(&self.pipe().msg_in, "")?; let selection_str = self.selection_str(); - // if last_app - // .map(|a| a.selection_str() != selection_str) - // .unwrap_or(true) - // { fs::write(&self.pipe().selection_out, selection_str)?; - // }; let history_str = self.history_str(); - // if last_app - // .map(|a| a.history_str() != history_str) - // .unwrap_or(true) - // { fs::write(&self.pipe().history_out, history_str)?; - // }; let directory_nodes_str = self.directory_nodes_str(); - // if last_app - // .map(|a| a.directory_nodes_str() != directory_nodes_str) - // .unwrap_or(true) - // { fs::write(&self.pipe().directory_nodes_out, directory_nodes_str)?; - // }; - - // if last_app - // .map(|a| a.logs().len() != self.logs().len()) - // .unwrap_or(true) - // { - // let new_logs = self - // .logs() - // .iter() - // .skip(last_app.map(|a| a.logs().len()).unwrap_or(0)) - // .map(|l| format!("{}\n", l)) - // .collect::>() - // .join(""); - - // let mut file = fs::OpenOptions::new() - // .append(true) - // .open(&self.pipe().logs_out)?; - // file.write_all(new_logs.as_bytes())?; - // }; + let logs_str = self.logs_str(); fs::write(&self.pipe().logs_out, logs_str)?; let result_str = self.result_str(); - // if last_app - // .map(|a| a.result_str() != result_str) - // .unwrap_or(true) - // { fs::write(&self.pipe().result_out, result_str)?; - // }; + let global_help_menu_str = self.global_help_menu_str(); - // if last_app - // .map(|a| a.global_help_menu_str() != global_help_menu_str) - // .unwrap_or(true) - // { fs::write(&self.pipe().global_help_menu_out, global_help_menu_str)?; - // }; + Ok(()) } diff --git a/src/ui.rs b/src/ui.rs index 5eefba2..33578bc 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -453,8 +453,10 @@ fn draw_table( .map(|(index, node)| { let is_focused = dir.focus() == index; - // TODO : Optimize - let is_selected = app.selection().contains(node); + let is_selected = app + .selection() + .iter() + .any(|s| s.absolute_path == node.absolute_path); let is_first = index == 0; let is_last = index == dir.total().max(1) - 1;