@ -1,13 +1,56 @@
use crate ::app ::ExternalMsg ;
use crate ::app ::HelpMenuLine ;
use crate ::default_config ::DEFAULT_CONFIG ;
use crate ::default_config ;
use serde ::{ Deserialize , Serialize } ;
use std ::collections ::BTreeMap ;
use std ::collections ::HashMap ;
use tui ::layout ::Constraint as TuiConstraint ;
use tui ::style ::Style ;
use tui ::style ::Style as TuiStyle ;
use tui ::style ::{ Color , Modifier } ;
#[ derive(Debug, Copy, Clone, Default, PartialEq, Serialize, Deserialize) ]
#[ serde(deny_unknown_fields) ]
pub struct Style {
fg : Option < Color > ,
bg : Option < Color > ,
add_modifier : Option < Modifier > ,
sub_modifier : Option < Modifier > ,
}
impl Style {
pub fn extend ( mut self , other : Self ) -> Self {
self . fg = other . fg . or ( self . fg ) ;
self . bg = other . bg . or ( self . bg ) ;
self . add_modifier = other . add_modifier . or ( self . add_modifier ) ;
self . sub_modifier = other . sub_modifier . or ( self . sub_modifier ) ;
self
}
}
impl From < TuiStyle > for Style {
fn from ( s : TuiStyle ) -> Self {
Self {
fg : s . fg ,
bg : s . bg ,
add_modifier : Some ( s . add_modifier ) ,
sub_modifier : Some ( s . sub_modifier ) ,
}
}
}
#[ derive(Debug, Clone, PartialEq, Serialize, Deserialize) ]
impl Into < TuiStyle > for Style {
fn into ( self ) -> TuiStyle {
TuiStyle {
fg : self . fg ,
bg : self . bg ,
add_modifier : self . add_modifier . unwrap_or_else ( Modifier ::empty ) ,
sub_modifier : self . sub_modifier . unwrap_or_else ( Modifier ::empty ) ,
}
}
}
#[ derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize) ]
#[ serde(deny_unknown_fields) ]
pub struct Action {
#[ serde(default) ]
pub help : Option < String > ,
@ -16,68 +59,130 @@ pub struct Action {
pub messages : Vec < ExternalMsg > ,
}
impl Action {
pub fn extend ( mut self , other : Self ) -> Self {
self . help = other . help . or ( self . help ) ;
self . messages = other . messages ;
self
}
}
#[ derive(Debug, Clone, Default, Serialize, Deserialize) ]
pub struct FileTypeConfig {
#[ serde(default) ]
pub icon : String ,
#[ serde(deny_unknown_fields) ]
pub struct NodeTypeConfig {
#[ serde(default) ]
pub style : Style ,
#[ serde(default) ]
pub custom : HashMap < String , String > ,
pub meta : HashMap < String , String > ,
}
#[ derive(Debug, Clone, Serialize, Deserialize) ]
pub struct FileTypesConfig {
impl NodeTypeConfig {
pub fn extend ( mut self , mut other : Self ) -> Self {
self . style = other . style . extend ( self . style ) ;
other . meta . extend ( self . meta ) ;
self . meta = other . meta ;
self
}
}
#[ derive(Debug, Clone, Default, Serialize, Deserialize) ]
#[ serde(deny_unknown_fields) ]
pub struct NodeTypesConfig {
#[ serde(default) ]
pub directory : FileTypeConfig ,
pub directory : NodeTypeConfig ,
#[ serde(default) ]
pub file : FileTypeConfig ,
pub file : NodeTypeConfig ,
#[ serde(default) ]
pub symlink : FileTypeConfig ,
pub symlink : NodeTypeConfig ,
#[ serde(default) ]
pub mime_essence : HashMap < String , FileTypeConfig > ,
pub mime_essence : HashMap < String , NodeTypeConfig > ,
#[ serde(default) ]
pub extension : HashMap < String , FileTypeConfig > ,
pub extension : HashMap < String , NodeTypeConfig > ,
#[ serde(default) ]
pub special : HashMap < String , Fil eTypeConfig> ,
pub special : HashMap < String , Nod eTypeConfig> ,
}
impl Default for FileTypesConfig {
fn default ( ) -> Self {
DEFAULT_CONFIG . filetypes . clone ( )
impl NodeTypesConfig {
fn extend ( mut self , mut other : Self ) -> Self {
self . directory = other . directory . extend ( self . directory ) ;
self . file = other . file . extend ( self . file ) ;
self . symlink = other . symlink . extend ( self . symlink ) ;
other . mime_essence . extend ( self . mime_essence ) ;
self . mime_essence = other . mime_essence ;
other . extension . extend ( self . extension ) ;
self . extension = other . extension ;
other . special . extend ( self . special ) ;
self . special = other . special ;
self
}
}
#[ derive(Debug, Clone, Default, Serialize, Deserialize) ]
#[ serde(deny_unknown_fields) ]
pub struct UiConfig {
#[ serde(default) ]
pub prefix : String ,
pub prefix : Option < String > ,
#[ serde(default) ]
pub suffix : String ,
pub suffix : Option < String > ,
#[ serde(default) ]
pub style : Style ,
}
impl UiConfig {
fn extend ( mut self , other : Self ) -> Self {
self . prefix = other . prefix . or ( self . prefix ) ;
self . suffix = other . suffix . or ( self . suffix ) ;
self . style = other . style . extend ( self . style ) ;
self
}
}
#[ derive(Debug, Clone, Default, Serialize, Deserialize) ]
#[ serde(deny_unknown_fields) ]
pub struct UiElement {
#[ serde(default) ]
pub format : String ,
pub format : Option < String > ,
#[ serde(default) ]
pub style : Style ,
}
#[ derive(Debug, Clone, Default, Serialize, Deserialize) ]
#[ serde(deny_unknown_fields) ]
pub struct TableRowConfig {
#[ serde(default) ]
pub cols : Vec < UiElement > ,
pub cols : Option < Vec < UiElement > > ,
#[ serde(default) ]
pub style : Style ,
#[ serde(default) ]
pub height : u16 ,
pub height : Option < u16 > ,
}
impl TableRowConfig {
fn extend ( mut self , other : Self ) -> Self {
self . cols = other . cols . or ( self . cols ) ;
self . style = other . style . extend ( self . style ) ;
self . height = other . height . or ( self . height ) ;
self
}
}
#[ derive(Debug, Clone, Copy, Serialize, Deserialize) ]
#[ serde(rename_all = " snake_case " ) ]
#[ serde(rename_all = " snake_case " , deny_unknown_fields )]
pub enum Constraint {
Percentage ( u16 ) ,
Ratio ( u32 , u32 ) ,
@ -105,46 +210,71 @@ impl Into<TuiConstraint> for Constraint {
}
#[ derive(Debug, Clone, Default, Serialize, Deserialize) ]
#[ serde(deny_unknown_fields) ]
pub struct TableConfig {
#[ serde(default) ]
pub header : Option < TableRowConfig > ,
pub header : TableRowConfig ,
#[ serde(default) ]
pub row : TableRowConfig ,
#[ serde(default) ]
pub style : Style ,
#[ serde(default) ]
pub tree : Option < ( UiElement , UiElement , UiElement ) > ,
#[ serde(default) ]
pub col_spacing : u16 ,
pub col_spacing : Option < u16 > ,
#[ serde(default) ]
pub col_widths : Vec< Constraint > ,
pub col_widths : Option< Vec< Constraint > > ,
}
#[ derive(Debug, Clone, Serialize, Deserialize) ]
impl TableConfig {
pub fn extend ( mut self , other : Self ) -> Self {
self . header = other . header . extend ( self . header ) ;
self . row = other . row . extend ( self . row ) ;
self . style = other . style . extend ( self . style ) ;
self . tree = other . tree . or ( self . tree ) ;
self . col_spacing = other . col_spacing . or ( self . col_spacing ) ;
self . col_widths = other . col_widths . or ( self . col_widths ) ;
self
}
}
#[ derive(Debug, Clone, Default, Serialize, Deserialize) ]
#[ serde(deny_unknown_fields) ]
pub struct GeneralConfig {
#[ serde(default) ]
pub show_hidden : bool ,
pub show_hidden : Option < bool > ,
#[ serde(default) ]
pub table : TableConfig ,
#[ serde(default) ]
pub normal_ui : UiConfig ,
pub default _ui: UiConfig ,
#[ serde(default) ]
pub focused_ui : UiConfig ,
pub focus _ui: UiConfig ,
#[ serde(default) ]
pub selection_ui : UiConfig ,
}
impl Default for GeneralConfig {
fn default ( ) -> Self {
DEFAULT_CONFIG . general . clone ( )
impl GeneralConfig {
pub fn extend ( mut self , other : Self ) -> Self {
self . show_hidden = other . show_hidden . or ( self . show_hidden ) ;
self . table = other . table . extend ( self . table ) ;
self . default_ui = other . default_ui . extend ( self . default_ui ) ;
self . focus_ui = other . focus_ui . extend ( self . focus_ui ) ;
self . selection_ui = other . selection_ui . extend ( self . selection_ui ) ;
self
}
}
#[ derive(Debug, Clone, Serialize, Deserialize) ]
#[ derive(Debug, Clone, Default, Serialize, Deserialize) ]
#[ serde(deny_unknown_fields) ]
pub struct KeyBindings {
#[ serde(default) ]
pub on_key : BTreeMap < String , Action > ,
@ -162,8 +292,22 @@ pub struct KeyBindings {
pub default : Option < Action > ,
}
#[ derive(Debug, Clone, Serialize, Deserialize) ]
impl KeyBindings {
pub fn extend ( mut self , mut other : Self ) -> Self {
other . on_key . extend ( self . on_key ) ;
self . on_key = other . on_key ;
self . on_alphabet = other . on_alphabet . or ( self . on_alphabet ) ;
self . on_number = other . on_number . or ( self . on_number ) ;
self . on_special_character = other . on_special_character . or ( self . on_special_character ) ;
self . default = other . default . or ( self . default ) ;
self
}
}
#[ derive(Debug, Clone, Default, Serialize, Deserialize) ]
#[ serde(deny_unknown_fields) ]
pub struct Mode {
#[ serde(default) ]
pub name : String ,
#[ serde(default) ]
@ -172,10 +316,18 @@ pub struct Mode {
#[ serde(default) ]
pub extra_help : Option < String > ,
#[ serde(default) ]
pub key_bindings : KeyBindings ,
}
impl Mode {
pub fn extend ( mut self , other : Self ) -> Self {
self . help = other . help . or ( self . help ) ;
self . extra_help = other . extra_help . or ( self . extra_help ) ;
self . key_bindings = other . key_bindings . extend ( self . key_bindings ) ;
self
}
pub fn help_menu ( & self ) -> Vec < HelpMenuLine > {
let extra_help_lines = self . extra_help . clone ( ) . map ( | e | {
e . lines ( )
@ -230,7 +382,104 @@ impl Mode {
}
}
#[ derive(Debug, Clone, Default, Serialize, Deserialize) ]
#[ serde(deny_unknown_fields) ]
pub struct BuiltinModesConfig {
#[ serde(default) ]
pub default : Mode ,
#[ serde(default) ]
pub selection_ops : Mode ,
#[ serde(default) ]
pub create : Mode ,
#[ serde(default) ]
pub create_directory : Mode ,
#[ serde(default) ]
pub create_file : Mode ,
#[ serde(default) ]
pub number : Mode ,
#[ serde(default) ]
pub go_to : Mode ,
#[ serde(default) ]
pub rename : Mode ,
#[ serde(default) ]
pub delete : Mode ,
#[ serde(default) ]
pub action : Mode ,
#[ serde(default) ]
pub search : Mode ,
}
impl BuiltinModesConfig {
pub fn extend ( mut self , other : Self ) -> Self {
self . default = other . default . extend ( self . default ) ;
self . selection_ops = other . selection_ops . extend ( self . selection_ops ) ;
self . go_to = other . go_to . extend ( self . go_to ) ;
self . create = other . create . extend ( self . create ) ;
self . create_file = other . create_file . extend ( self . create_file ) ;
self . create_directory = other . create_directory . extend ( self . create_directory ) ;
self . rename = other . rename . extend ( self . rename ) ;
self . delete = other . delete . extend ( self . delete ) ;
self . number = other . number . extend ( self . number ) ;
self . action = other . action . extend ( self . action ) ;
self . search = other . search . extend ( self . search ) ;
self
}
pub fn get ( & self , name : & str ) -> Option < & Mode > {
match name {
"default" = > Some ( & self . default ) ,
"selection ops" = > Some ( & self . selection_ops ) ,
"selection_ops" = > Some ( & self . selection_ops ) ,
"create" = > Some ( & self . create ) ,
"create file" = > Some ( & self . create_file ) ,
"create_file" = > Some ( & self . create_file ) ,
"create directory" = > Some ( & self . create_directory ) ,
"create_directory" = > Some ( & self . create_directory ) ,
"number" = > Some ( & self . number ) ,
"go to" = > Some ( & self . go_to ) ,
"go_to" = > Some ( & self . go_to ) ,
"rename" = > Some ( & self . rename ) ,
"delete" = > Some ( & self . delete ) ,
"action" = > Some ( & self . action ) ,
"search" = > Some ( & self . search ) ,
_ = > None ,
}
}
}
#[ derive(Debug, Clone, Default, Serialize, Deserialize) ]
#[ serde(deny_unknown_fields) ]
pub struct ModesConfig {
#[ serde(default) ]
pub builtin : BuiltinModesConfig ,
#[ serde(default) ]
pub custom : HashMap < String , Mode > ,
}
impl ModesConfig {
pub fn get ( & self , name : & str ) -> Option < & Mode > {
self . builtin . get ( name ) . or_else ( | | self . custom . get ( name ) )
}
pub fn extend ( mut self , other : Self ) -> Self {
self . builtin = other . builtin . extend ( self . builtin ) ;
self
}
}
#[ derive(Debug, Clone, Serialize, Deserialize) ]
#[ serde(deny_unknown_fields) ]
pub struct Config {
pub version : String ,
@ -238,18 +487,29 @@ pub struct Config {
pub general : GeneralConfig ,
#[ serde(default) ]
pub filetypes: Fil eTypesConfig,
pub node_types: Nod eTypesConfig,
pub modes : HashMap < String , Mode > ,
#[ serde(default) ]
pub modes : ModesConfig ,
}
impl Default for Config {
fn default ( ) -> Self {
Self {
version : DEFAULT_CONFIG. version . clone ( ) ,
general : Default ::default ( ) ,
filetypes: Default ::default ( ) ,
modes : DEFAULT_CONFIG. modes . clone ( ) ,
version : default_config::version ( ) ,
general : default_config ::general ( ) ,
node_types: default_config ::node_types ( ) ,
modes : default_config::modes ( ) ,
}
}
}
impl Config {
pub fn extended ( mut self ) -> Self {
let default = Self ::default ( ) ;
self . general = default . general . extend ( self . general ) ;
self . node_types = default . node_types . extend ( self . node_types ) ;
self . modes = default . modes . extend ( self . modes ) ;
self
}
}