@ -18,7 +18,7 @@ use std::ops::BitXor;
use time ::macros ::format_description ;
use time ::macros ::format_description ;
use tui ::layout ::Rect as TuiRect ;
use tui ::layout ::Rect as TuiRect ;
use tui ::layout ::{ Constraint as TuiConstraint , Direction , Layout as TuiLayout } ;
use tui ::layout ::{ Constraint as TuiConstraint , Direction , Layout as TuiLayout } ;
use tui ::style ::{ Color , Modifier as TuiModifier , Style as TuiStyle } ;
use tui ::style ::{ Color as TuiColor , Modifier as TuiModifier , Style as TuiStyle } ;
use tui ::text ::{ Line , Span , Text } ;
use tui ::text ::{ Line , Span , Text } ;
use tui ::widgets ::{
use tui ::widgets ::{
Block , BorderType as TuiBorderType , Borders as TuiBorders , Cell , List , ListItem ,
Block , BorderType as TuiBorderType , Borders as TuiBorders , Cell , List , ListItem ,
@ -26,9 +26,10 @@ use tui::widgets::{
} ;
} ;
use tui ::Frame ;
use tui ::Frame ;
const DEFAULT_STYLE : TuiStyle = TuiStyle ::new ( ) ;
lazy_static ! {
lazy_static ! {
pub static ref NO_COLOR : bool = env ::var ( "NO_COLOR" ) . is_ok ( ) ;
pub static ref NO_COLOR : bool = env ::var ( "NO_COLOR" ) . is_ok ( ) ;
pub static ref DEFAULT_STYLE : TuiStyle = TuiStyle ::default ( ) ;
}
}
fn read_only_indicator ( app : & app ::App ) -> & str {
fn read_only_indicator ( app : & app ::App ) -> & str {
@ -59,6 +60,33 @@ pub fn string_to_text<'a>(string: String) -> Text<'a> {
}
}
}
}
#[ derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize) ]
pub struct Rect {
x : u16 ,
y : u16 ,
height : u16 ,
width : u16 ,
}
impl From < TuiRect > for Rect {
fn from ( tui : TuiRect ) -> Self {
Self {
x : tui . x ,
y : tui . y ,
height : tui . height ,
width : tui . width ,
}
}
}
#[ derive(Debug, Clone, Serialize) ]
pub struct ContentRendererArg {
pub app : app ::LuaContextLight ,
pub screen_size : Rect ,
pub layout_size : Rect ,
pub scrolltop : u16 ,
}
#[ derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq) ]
#[ derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq) ]
#[ serde(deny_unknown_fields) ]
#[ serde(deny_unknown_fields) ]
pub struct LayoutOptions {
pub struct LayoutOptions {
@ -80,7 +108,7 @@ impl LayoutOptions {
self . margin = other . margin . or ( self . margin ) ;
self . margin = other . margin . or ( self . margin ) ;
self . horizontal_margin = other . horizontal_margin . or ( self . horizontal_margin ) ;
self . horizontal_margin = other . horizontal_margin . or ( self . horizontal_margin ) ;
self . vertical_margin = other . vertical_margin . or ( self . vertical_margin ) ;
self . vertical_margin = other . vertical_margin . or ( self . vertical_margin ) ;
self . constraints = other . constraints . to_owned ( ) . or ( self . constraints ) ;
self . constraints = other . constraints . clone ( ) . or ( self . constraints ) ;
self
self
}
}
}
}
@ -128,7 +156,7 @@ pub enum Layout {
splits : Vec < Layout > ,
splits : Vec < Layout > ,
} ,
} ,
/// For compatibility only. A better choice is Static or Dy ma nic layout.
/// For compatibility only. A better choice is Static or Dy nam ic layout.
CustomContent ( Box < CustomContent > ) ,
CustomContent ( Box < CustomContent > ) ,
}
}
@ -153,7 +181,7 @@ impl Layout {
} ,
} ,
) = > Self ::Horizontal {
) = > Self ::Horizontal {
config : sconfig . extend ( oconfig ) ,
config : sconfig . extend ( oconfig ) ,
splits : osplits . to_owned ( ) ,
splits : osplits . clone ( ) ,
} ,
} ,
(
(
@ -167,9 +195,9 @@ impl Layout {
} ,
} ,
) = > Self ::Vertical {
) = > Self ::Vertical {
config : sconfig . extend ( oconfig ) ,
config : sconfig . extend ( oconfig ) ,
splits : osplits . to_owned ( ) ,
splits : osplits . clone ( ) ,
} ,
} ,
( _ , other ) = > other . to_owned ( ) ,
( _ , other ) = > other . clone ( ) ,
}
}
}
}
@ -191,7 +219,7 @@ impl Layout {
} ,
} ,
other = > {
other = > {
if other = = * target {
if other = = * target {
replacement . to_owned ( )
replacement . clone ( )
} else {
} else {
other
other
}
}
@ -297,6 +325,59 @@ fn extend_optional_modifiers(
}
}
}
}
// raratui doesn't support directly serializing `Color::Rgb` and
// `Color::Indexed` anymore.
// See https://github.com/ratatui-org/ratatui/pull/934
#[ derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, Serialize, Deserialize) ]
pub enum Color {
#[ default ]
Reset ,
Black ,
Red ,
Green ,
Yellow ,
Blue ,
Magenta ,
Cyan ,
Gray ,
DarkGray ,
LightRed ,
LightGreen ,
LightYellow ,
LightBlue ,
LightMagenta ,
LightCyan ,
White ,
Rgb ( u8 , u8 , u8 ) ,
Indexed ( u8 ) ,
}
impl From < Color > for TuiColor {
fn from ( value : Color ) -> Self {
match value {
Color ::Reset = > TuiColor ::Reset ,
Color ::Black = > TuiColor ::Black ,
Color ::Red = > TuiColor ::Red ,
Color ::Green = > TuiColor ::Green ,
Color ::Yellow = > TuiColor ::Yellow ,
Color ::Blue = > TuiColor ::Blue ,
Color ::Magenta = > TuiColor ::Magenta ,
Color ::Cyan = > TuiColor ::Cyan ,
Color ::Gray = > TuiColor ::Gray ,
Color ::DarkGray = > TuiColor ::DarkGray ,
Color ::LightRed = > TuiColor ::LightRed ,
Color ::LightGreen = > TuiColor ::LightGreen ,
Color ::LightYellow = > TuiColor ::LightYellow ,
Color ::LightBlue = > TuiColor ::LightBlue ,
Color ::LightMagenta = > TuiColor ::LightMagenta ,
Color ::LightCyan = > TuiColor ::LightCyan ,
Color ::White = > TuiColor ::White ,
Color ::Rgb ( r , g , b ) = > TuiColor ::Rgb ( r , g , b ) ,
Color ::Indexed ( index ) = > TuiColor ::Indexed ( index ) ,
}
}
}
#[ derive(Debug, PartialEq, Eq, Clone, Default, Serialize, Deserialize) ]
#[ derive(Debug, PartialEq, Eq, Clone, Default, Serialize, Deserialize) ]
#[ serde(deny_unknown_fields) ]
#[ serde(deny_unknown_fields) ]
pub struct Style {
pub struct Style {
@ -310,20 +391,16 @@ impl Style {
pub fn extend ( mut self , other : & Self ) -> Self {
pub fn extend ( mut self , other : & Self ) -> Self {
self . fg = other . fg . or ( self . fg ) ;
self . fg = other . fg . or ( self . fg ) ;
self . bg = other . bg . or ( self . bg ) ;
self . bg = other . bg . or ( self . bg ) ;
self . add_modifiers = extend_optional_modifiers (
self . add_modifiers =
self . add_modifiers ,
extend_optional_modifiers ( self . add_modifiers , other . add_modifiers . clone ( ) ) ;
other . add_modifiers . to_owned ( ) ,
self . sub_modifiers =
) ;
extend_optional_modifiers ( self . sub_modifiers , other . sub_modifiers . clone ( ) ) ;
self . sub_modifiers = extend_optional_modifiers (
self . sub_modifiers ,
other . sub_modifiers . to_owned ( ) ,
) ;
self
self
}
}
}
}
impl Into< Tui Style> for Style {
impl From< Style> for Tui Style {
fn into( self ) -> TuiStyle {
fn from( val : Style ) -> Self {
fn xor ( modifiers : Option < IndexSet < Modifier > > ) -> u16 {
fn xor ( modifiers : Option < IndexSet < Modifier > > ) -> u16 {
modifiers
modifiers
. unwrap_or_default ( )
. unwrap_or_default ( )
@ -332,14 +409,13 @@ impl Into<TuiStyle> for Style {
. fold ( 0 , BitXor ::bitxor )
. fold ( 0 , BitXor ::bitxor )
}
}
if * NO_COLOR {
if * NO_COLOR {
* DEFAULT_STYLE
DEFAULT_STYLE
} else {
} else {
TuiStyle {
TuiStyle {
fg : self . fg ,
fg : val . fg . map ( Into ::into ) ,
bg : self . bg ,
bg : val . bg . map ( Into ::into ) ,
underline_color : None ,
add_modifier : TuiModifier ::from_bits_truncate ( xor ( val . add_modifiers ) ) ,
add_modifier : TuiModifier ::from_bits_truncate ( xor ( self . add_modifiers ) ) ,
sub_modifier : TuiModifier ::from_bits_truncate ( xor ( val . sub_modifiers ) ) ,
sub_modifier : TuiModifier ::from_bits_truncate ( xor ( self . sub_modifiers ) ) ,
}
}
}
}
}
}
@ -378,8 +454,8 @@ impl From<&LsColorsStyle> for Style {
}
}
}
}
impl Into< nu_ansi_term :: Style > for Style {
impl From< Style > for nu_ansi_term ::Style {
fn into( self ) -> nu_ansi_term ::Style {
fn from( val : Style ) -> Self {
fn convert_color ( color : Color ) -> Option < nu_ansi_term ::Color > {
fn convert_color ( color : Color ) -> Option < nu_ansi_term ::Color > {
match color {
match color {
Color ::Black = > Some ( nu_ansi_term ::Color ::Black ) ,
Color ::Black = > Some ( nu_ansi_term ::Color ::Black ) ,
@ -411,20 +487,20 @@ impl Into<nu_ansi_term::Style> for Style {
}
}
let mut style = nu_ansi_term ::Style ::new ( ) ;
let mut style = nu_ansi_term ::Style ::new ( ) ;
style . foreground = self . fg . and_then ( convert_color ) ;
style . foreground = val . fg . and_then ( convert_color ) ;
style . background = self . bg . and_then ( convert_color ) ;
style . background = val . bg . and_then ( convert_color ) ;
style . is_bold = match_modifiers ( & self , | m | m . contains ( & Modifier ::Bold ) ) ;
style . is_bold = match_modifiers ( & val , | m | m . contains ( & Modifier ::Bold ) ) ;
style . is_dimmed = match_modifiers ( & self , | m | m . contains ( & Modifier ::Dim ) ) ;
style . is_dimmed = match_modifiers ( & val , | m | m . contains ( & Modifier ::Dim ) ) ;
style . is_italic = match_modifiers ( & self , | m | m . contains ( & Modifier ::Italic ) ) ;
style . is_italic = match_modifiers ( & val , | m | m . contains ( & Modifier ::Italic ) ) ;
style . is_underline =
style . is_underline =
match_modifiers ( & self , | m | m . contains ( & Modifier ::Underlined ) ) ;
match_modifiers ( & val , | m | m . contains ( & Modifier ::Underlined ) ) ;
style . is_blink = match_modifiers ( & self , | m | {
style . is_blink = match_modifiers ( & val , | m | {
m . contains ( & Modifier ::SlowBlink ) | | m . contains ( & Modifier ::RapidBlink )
m . contains ( & Modifier ::SlowBlink ) | | m . contains ( & Modifier ::RapidBlink )
} ) ;
} ) ;
style . is_reverse = match_modifiers ( & self , | m | m . contains ( & Modifier ::Reversed ) ) ;
style . is_reverse = match_modifiers ( & val , | m | m . contains ( & Modifier ::Reversed ) ) ;
style . is_hidden = match_modifiers ( & self , | m | m . contains ( & Modifier ::Hidden ) ) ;
style . is_hidden = match_modifiers ( & val , | m | m . contains ( & Modifier ::Hidden ) ) ;
style . is_strikethrough =
style . is_strikethrough =
match_modifiers ( & self , | m | m . contains ( & Modifier ::CrossedOut ) ) ;
match_modifiers ( & val , | m | m . contains ( & Modifier ::CrossedOut ) ) ;
style
style
}
}
}
}
@ -541,12 +617,12 @@ pub struct ResolvedNodeUiMetadata {
impl From < ResolvedNode > for ResolvedNodeUiMetadata {
impl From < ResolvedNode > for ResolvedNodeUiMetadata {
fn from ( node : ResolvedNode ) -> Self {
fn from ( node : ResolvedNode ) -> Self {
Self {
Self {
absolute_path : node . absolute_path . to_owned ( ) ,
absolute_path : node . absolute_path . clone ( ) ,
extension : node . extension . to_owned ( ) ,
extension : node . extension . clone ( ) ,
is_dir : node . is_dir ,
is_dir : node . is_dir ,
is_file : node . is_file ,
is_file : node . is_file ,
is_readonly : node . is_readonly ,
is_readonly : node . is_readonly ,
mime_essence : node . mime_essence . to_owned ( ) ,
mime_essence : node . mime_essence . clone ( ) ,
size : node . size ,
size : node . size ,
human_size : node . human_size ,
human_size : node . human_size ,
created : node . created ,
created : node . created ,
@ -610,21 +686,21 @@ impl NodeUiMetadata {
style : Style ,
style : Style ,
) -> Self {
) -> Self {
Self {
Self {
parent : node . parent . to_owned ( ) ,
parent : node . parent . clone ( ) ,
relative_path : node . relative_path . to_owned ( ) ,
relative_path : node . relative_path . clone ( ) ,
absolute_path : node . absolute_path . to_owned ( ) ,
absolute_path : node . absolute_path . clone ( ) ,
extension : node . extension . to_owned ( ) ,
extension : node . extension . clone ( ) ,
is_symlink : node . is_symlink ,
is_symlink : node . is_symlink ,
is_broken : node . is_broken ,
is_broken : node . is_broken ,
is_dir : node . is_dir ,
is_dir : node . is_dir ,
is_file : node . is_file ,
is_file : node . is_file ,
is_readonly : node . is_readonly ,
is_readonly : node . is_readonly ,
mime_essence : node . mime_essence . to_owned ( ) ,
mime_essence : node . mime_essence . clone ( ) ,
size : node . size ,
size : node . size ,
human_size : node . human_size . to_owned ( ) ,
human_size : node . human_size . clone ( ) ,
permissions : node . permissions .to_owned ( ) ,
permissions : node . permissions ,
canonical : node . canonical . to_owned ( ) . map ( ResolvedNode ::into ) ,
canonical : node . canonical . clone ( ) . map ( ResolvedNode ::into ) ,
symlink : node . symlink . to_owned ( ) . map ( ResolvedNode ::into ) ,
symlink : node . symlink . clone ( ) . map ( ResolvedNode ::into ) ,
created : node . created ,
created : node . created ,
last_modified : node . last_modified ,
last_modified : node . last_modified ,
uid : node . uid ,
uid : node . uid ,
@ -650,7 +726,7 @@ pub fn block<'a>(config: PanelUiConfig, default_title: String) -> Block<'a> {
. borders ( TuiBorders ::from_bits_truncate (
. borders ( TuiBorders ::from_bits_truncate (
config
config
. borders
. borders
. to_owned ( )
. clone ( )
. unwrap_or_default ( )
. unwrap_or_default ( )
. iter ( )
. iter ( )
. map ( | b | b . bits ( ) )
. map ( | b | b . bits ( ) )
@ -658,36 +734,71 @@ pub fn block<'a>(config: PanelUiConfig, default_title: String) -> Block<'a> {
) )
) )
. title ( Span ::styled (
. title ( Span ::styled (
config . title . format . unwrap_or ( default_title ) ,
config . title . format . unwrap_or ( default_title ) ,
config . title . style .into ( ) ,
config . title . style ,
) )
) )
. style ( config . style .into ( ) )
. style ( config . style )
. border_type ( config . border_type . unwrap_or_default ( ) . into ( ) )
. border_type ( config . border_type . unwrap_or_default ( ) . into ( ) )
. border_style ( config . border_style .into ( ) )
. border_style ( config . border_style )
}
}
fn draw_table (
pub struct UI < ' lua > {
f : & mut Frame ,
pub lua : & ' lua Lua ,
screen_size : TuiRect ,
pub screen_size : TuiRect ,
layout_size : TuiRect ,
pub scrolltop : usize ,
app : & app ::App ,
}
lua : & Lua ,
) {
impl < ' lua > UI < ' lua > {
pub fn new ( lua : & ' lua Lua ) -> Self {
let screen_size = Default ::default ( ) ;
let scrolltop = 0 ;
Self {
lua ,
scrolltop ,
screen_size ,
}
}
}
impl UI < ' _ > {
fn draw_table ( & mut self , f : & mut Frame , layout_size : TuiRect , app : & app ::App ) {
let panel_config = & app . config . general . panel_ui ;
let panel_config = & app . config . general . panel_ui ;
let config = panel_config . default . to_owned ( ) . extend ( & panel_config . table ) ;
let config = panel_config . default . clone ( ) . extend ( & panel_config . table ) ;
let app_config = app . config . to_owned ( ) ;
let app_config = app . config . clone ( ) ;
let header_height = app_config . general . table . header . height . unwrap_or ( 1 ) ;
let header_height = app_config . general . table . header . height . unwrap_or ( 1 ) ;
let height : usize =
let height : usize = layout_size . height . saturating_sub ( header_height + 2 ) . into ( ) ;
( layout_size . height . max ( header_height + 2 ) - ( header_height + 2 ) ) . into ( ) ;
let row_style = app_config . general . table . row . style . clone ( ) ;
let row_style = app_config . general . table . row . style . to_owned ( ) ;
let rows = app
let rows = app
. directory_buffer
. directory_buffer
. as_ref ( )
. as_ref ( )
. map ( | dir | {
. map ( | dir | {
// Scroll
if app . config . general . paginated_scrolling {
// Paginated scrolling
self . scrolltop = height * ( dir . focus / height . max ( 1 ) )
} else {
// Vim-like-scrolling
let padding = app
. config
. general
. scroll_padding
. min ( height / 2 )
. saturating_sub ( 1 ) ;
if dir . focus > = ( self . scrolltop + height ) . saturating_sub ( padding ) {
// Scrolling down
self . scrolltop = ( dir . focus + padding + 1 )
. saturating_sub ( height )
. min ( dir . total . saturating_sub ( height ) ) ;
} else if dir . focus < self . scrolltop + padding {
// Scrolling up
self . scrolltop = dir . focus . saturating_sub ( padding ) ;
}
} ;
dir . nodes
dir . nodes
. iter ( )
. iter ( )
. enumerate ( )
. enumerate ( )
. skip ( height * ( dir . focus / height . max ( 1 ) ) )
. skip ( self . scrolltop )
. take ( height )
. take ( height )
. map ( | ( index , node ) | {
. map ( | ( index , node ) | {
let is_focused = dir . focus = = index ;
let is_focused = dir . focus = = index ;
@ -704,7 +815,7 @@ fn draw_table(
. general
. general
. table
. table
. tree
. tree
. to_owned ( )
. clone ( )
. map ( | t | {
. map ( | t | {
if is_last {
if is_last {
t . 2. format
t . 2. format
@ -726,24 +837,24 @@ fn draw_table(
} ;
} ;
let ( mut prefix , mut suffix , mut style ) = {
let ( mut prefix , mut suffix , mut style ) = {
let ui = app_config . general . default_ui . to_owned ( ) ;
let ui = app_config . general . default_ui . clone ( ) ;
( ui . prefix , ui . suffix , ui . style . extend ( & node_type . style ) )
( ui . prefix , ui . suffix , ui . style . extend ( & node_type . style ) )
} ;
} ;
if is_focused & & is_selected {
if is_focused & & is_selected {
let ui = app_config . general . focus_selection_ui . to_owned ( ) ;
let ui = app_config . general . focus_selection_ui . clone ( ) ;
prefix = ui . prefix . to_owned ( ) . or ( prefix ) ;
prefix = ui . prefix . clone ( ) . or ( prefix ) ;
suffix = ui . suffix . to_owned ( ) . or ( suffix ) ;
suffix = ui . suffix . clone ( ) . or ( suffix ) ;
style = style . extend ( & ui . style ) ;
style = style . extend ( & ui . style ) ;
} else if is_selected {
} else if is_selected {
let ui = app_config . general . selection_ui . to_owned ( ) ;
let ui = app_config . general . selection_ui . clone ( ) ;
prefix = ui . prefix . to_owned ( ) . or ( prefix ) ;
prefix = ui . prefix . clone ( ) . or ( prefix ) ;
suffix = ui . suffix . to_owned ( ) . or ( suffix ) ;
suffix = ui . suffix . clone ( ) . or ( suffix ) ;
style = style . extend ( & ui . style ) ;
style = style . extend ( & ui . style ) ;
} else if is_focused {
} else if is_focused {
let ui = app_config . general . focus_ui . to_owned ( ) ;
let ui = app_config . general . focus_ui . clone ( ) ;
prefix = ui . prefix . to_owned ( ) . or ( prefix ) ;
prefix = ui . prefix . clone ( ) . or ( prefix ) ;
suffix = ui . suffix . to_owned ( ) . or ( suffix ) ;
suffix = ui . suffix . clone ( ) . or ( suffix ) ;
style = style . extend ( & ui . style ) ;
style = style . extend ( & ui . style ) ;
} ;
} ;
@ -763,31 +874,31 @@ fn draw_table(
style ,
style ,
) ;
) ;
let cols = lua ::serialize ::< NodeUiMetadata > ( lua , & meta )
let cols = lua ::serialize ::< NodeUiMetadata > ( self . lua , & meta )
. map ( | v | {
. map ( | v | {
app_config
app_config
. general
. general
. table
. table
. row
. row
. cols
. cols
. to_owned ( )
. clone ( )
. unwrap_or_default ( )
. unwrap_or_default ( )
. iter ( )
. iter ( )
. filter_map ( | c | {
. filter_map ( | c | {
c . format . as_ref ( ) . map ( | f | {
c . format . as_ref ( ) . map ( | f | {
let out = lua ::call ( lua , f , v . clone ( ) )
let out = lua ::call ( self . lua , f , v . clone ( ) )
. unwrap_or_else ( | e | format! ( "{e:?}" ) ) ;
. unwrap_or_else ( | e | format! ( "{e:?}" ) ) ;
( string_to_text ( out ) , c . style . to_owned ( ) )
( string_to_text ( out ) , c . style . clone ( ) )
} )
} )
} )
} )
. collect ::< Vec < ( Text , Style ) > > ( )
. collect ::< Vec < ( Text , Style ) > > ( )
} )
} )
. unwrap_or_default ( )
. unwrap_or_default ( )
. into_iter ( )
. into_iter ( )
. map ( | ( text , style ) | Cell ::from ( text ) . style ( style . into ( ) ) )
. map ( | ( text , style ) | Cell ::from ( text ) . style ( style ) )
. collect ::< Vec < Cell > > ( ) ;
. collect ::< Vec < Cell > > ( ) ;
Row ::new ( cols ) . style ( row_style . to_owned( ) . into ( ) )
Row ::new ( cols ) . style ( row_style . clone ( ) )
} )
} )
. collect ::< Vec < Row > > ( )
. collect ::< Vec < Row > > ( )
} )
} )
@ -797,10 +908,10 @@ fn draw_table(
. general
. general
. table
. table
. col_widths
. col_widths
. to_owned ( )
. clone ( )
. unwrap_or_default ( )
. unwrap_or_default ( )
. into_iter ( )
. into_iter ( )
. map ( | c | c . to_tui ( screen_size , layout_size ) )
. map ( | c | c . to_tui ( self . screen_size , layout_size ) )
. collect ( ) ;
. collect ( ) ;
let pwd = if let Some ( vroot ) = app . vroot . as_ref ( ) {
let pwd = if let Some ( vroot ) = app . vroot . as_ref ( ) {
@ -822,49 +933,40 @@ fn draw_table(
} ;
} ;
let table = Table ::new ( rows , table_constraints )
let table = Table ::new ( rows , table_constraints )
. style ( app_config . general . table . style . to_owned( ) . into ( ) )
. style ( app_config . general . table . style . clone ( ) )
. highlight_style ( app_config . general . focus_ui . style . to_owned( ) . into ( ) )
. highlight_style ( app_config . general . focus_ui . style . clone ( ) )
. column_spacing ( app_config . general . table . col_spacing . unwrap_or_default ( ) )
. column_spacing ( app_config . general . table . col_spacing . unwrap_or_default ( ) )
. block ( block (
. block ( block (
config ,
config ,
format! ( " {vroot_indicator}/{pwd} {node_count}" ) ,
format! ( " {vroot_indicator}/{pwd} {node_count}" ) ,
) ) ;
) ) ;
let table = table . to_owned ( ) . header (
let table = table . clone ( ) . header (
Row ::new (
Row ::new (
app_config
app_config
. general
. general
. table
. table
. header
. header
. cols
. cols
. to_owned ( )
. clone ( )
. unwrap_or_default ( )
. unwrap_or_default ( )
. iter ( )
. iter ( )
. map ( | c | {
. map ( | c | {
Cell ::from ( c . format . to_owned ( ) . unwrap_or_default ( ) )
Cell ::from ( c . format . clone ( ) . unwrap_or_default ( ) )
. style ( c . style . to_owned( ) . into ( ) )
. style ( c . style . clone ( ) )
} )
} )
. collect ::< Vec < Cell > > ( ) ,
. collect ::< Vec < Cell > > ( ) ,
)
)
. height ( header_height )
. height ( header_height )
. style ( app_config . general . table . header . style . to_owned( ) . into ( ) ) ,
. style ( app_config . general . table . header . style . clone ( ) ) ,
) ;
) ;
f . render_widget ( table , layout_size ) ;
f . render_widget ( table , layout_size ) ;
}
}
fn draw_selection (
fn draw_selection ( & mut self , f : & mut Frame , layout_size : TuiRect , app : & app ::App ) {
f : & mut Frame ,
_screen_size : TuiRect ,
layout_size : TuiRect ,
app : & app ::App ,
lua : & Lua ,
) {
let panel_config = & app . config . general . panel_ui ;
let panel_config = & app . config . general . panel_ui ;
let config = panel_config
let config = panel_config . default . clone ( ) . extend ( & panel_config . selection ) ;
. default
. to_owned ( )
. extend ( & panel_config . selection ) ;
let selection_count = app . selection . len ( ) ;
let selection_count = app . selection . len ( ) ;
@ -883,16 +985,15 @@ fn draw_selection(
. format
. format
. as_ref ( )
. as_ref ( )
. map ( | f | {
. map ( | f | {
lua ::serialize ::< Node > ( lua , n )
lua ::serialize ::< Node > ( self . lua , n )
. and_then ( | n | lua ::call ( lua , f , n ) )
. and_then ( | n | lua ::call ( self . lua , f , n ) )
. unwrap_or_else ( | e | format! ( "{e:?}" ) )
. unwrap_or_else ( | e | format! ( "{e:?}" ) )
} )
} )
. unwrap_or_else ( | | n . absolute_path . clone ( ) ) ;
. unwrap_or_else ( | | n . absolute_path . clone ( ) ) ;
string_to_text ( out )
string_to_text ( out )
} )
} )
. map ( | i | {
. map ( | i | {
ListItem ::new ( i )
ListItem ::new ( i ) . style ( app . config . general . selection . item . style . clone ( ) )
. style ( app . config . general . selection . item . style . to_owned ( ) . into ( ) )
} )
} )
. collect ( ) ;
. collect ( ) ;
@ -909,19 +1010,10 @@ fn draw_selection(
f . render_widget ( selection_list , layout_size ) ;
f . render_widget ( selection_list , layout_size ) ;
}
}
fn draw_help_menu (
fn draw_help_menu ( & mut self , f : & mut Frame , layout_size : TuiRect , app : & app ::App ) {
f : & mut Frame ,
_screen_size : TuiRect ,
layout_size : TuiRect ,
app : & app ::App ,
_ : & Lua ,
) {
let panel_config = & app . config . general . panel_ui ;
let panel_config = & app . config . general . panel_ui ;
let config = panel_config
let config = panel_config . default . clone ( ) . extend ( & panel_config . help_menu ) ;
. default
. to_owned ( )
. extend ( & panel_config . help_menu ) ;
let help_menu_rows = app
let help_menu_rows = app
. mode
. mode
@ -933,7 +1025,8 @@ fn draw_help_menu(
if app . config . general . hide_remaps_in_help_menu {
if app . config . general . hide_remaps_in_help_menu {
[ Cell ::from ( k ) , Cell ::from ( h ) ] . to_vec ( )
[ Cell ::from ( k ) , Cell ::from ( h ) ] . to_vec ( )
} else {
} else {
[ Cell ::from ( k ) , Cell ::from ( remaps . join ( "|" ) ) , Cell ::from ( h ) ] . to_vec ( )
[ Cell ::from ( k ) , Cell ::from ( remaps . join ( "|" ) ) , Cell ::from ( h ) ]
. to_vec ( )
}
}
} ) ,
} ) ,
} )
} )
@ -956,17 +1049,16 @@ fn draw_help_menu(
}
}
fn draw_input_buffer (
fn draw_input_buffer (
& mut self ,
f : & mut Frame ,
f : & mut Frame ,
_screen_size : TuiRect ,
layout_size : TuiRect ,
layout_size : TuiRect ,
app : & app ::App ,
app : & app ::App ,
_ : & Lua ,
) {
) {
if let Some ( input ) = app . input . buffer . as_ref ( ) {
if let Some ( input ) = app . input . buffer . as_ref ( ) {
let panel_config = & app . config . general . panel_ui ;
let panel_config = & app . config . general . panel_ui ;
let config = panel_config
let config = panel_config
. default
. default
. to_owned ( )
. clone ( )
. extend ( & panel_config . input_and_logs ) ;
. extend ( & panel_config . input_and_logs ) ;
let cursor_offset_left = config
let cursor_offset_left = config
@ -989,8 +1081,8 @@ fn draw_input_buffer(
let input_buf = Paragraph ::new ( Line ::from ( vec! [
let input_buf = Paragraph ::new ( Line ::from ( vec! [
Span ::styled (
Span ::styled (
app . input . prompt . to_owned ( ) ,
app . input . prompt . clone ( ) ,
app . config . general . prompt . style . to_owned( ) . into ( ) ,
app . config . general . prompt . style . clone ( ) ,
) ,
) ,
Span ::raw ( input . value ( ) ) ,
Span ::raw ( input . value ( ) ) ,
] ) )
] ) )
@ -1018,35 +1110,34 @@ fn draw_input_buffer(
}
}
fn draw_sort_n_filter (
fn draw_sort_n_filter (
& mut self ,
f : & mut Frame ,
f : & mut Frame ,
_screen_size : TuiRect ,
layout_size : TuiRect ,
layout_size : TuiRect ,
app : & app ::App ,
app : & app ::App ,
_ : & Lua ,
) {
) {
let panel_config = & app . config . general . panel_ui ;
let panel_config = & app . config . general . panel_ui ;
let config = panel_config
let config = panel_config
. default
. default
. to_owned ( )
. clone ( )
. extend ( & panel_config . sort_and_filter ) ;
. extend ( & panel_config . sort_and_filter ) ;
let ui = app . config . general . sort_and_filter_ui . to_owned ( ) ;
let ui = app . config . general . sort_and_filter_ui . clone ( ) ;
let filter_by : & IndexSet < NodeFilterApplicable > = & app . explorer_config . filters ;
let filter_by : & IndexSet < NodeFilterApplicable > = & app . explorer_config . filters ;
let sort_by : & IndexSet < NodeSorterApplicable > = & app . explorer_config . sorters ;
let sort_by : & IndexSet < NodeSorterApplicable > = & app . explorer_config . sorters ;
let search = app . explorer_config . searcher . as_ref ( ) ;
let search = app . explorer_config . searcher . as_ref ( ) ;
let defaultui = & ui . default_identifier ;
let defaultui = & ui . default_identifier ;
let forwardui = defaultui
let forwardui = defaultui
. to_owned ( )
. clone ( )
. extend ( & ui . sort_direction_identifiers . forward ) ;
. extend ( & ui . sort_direction_identifiers . forward ) ;
let reverseui = defaultui
let reverseui = defaultui
. to_owned ( )
. clone ( )
. extend ( & ui . sort_direction_identifiers . reverse ) ;
. extend ( & ui . sort_direction_identifiers . reverse ) ;
let orderedui = defaultui
let orderedui = defaultui
. to_owned ( )
. clone ( )
. extend ( & ui . search_direction_identifiers . ordered ) ;
. extend ( & ui . search_direction_identifiers . ordered ) ;
let unorderedui = defaultui
let unorderedui = defaultui
. to_owned ( )
. clone ( )
. extend ( & ui . search_direction_identifiers . unordered ) ;
. extend ( & ui . search_direction_identifiers . unordered ) ;
let is_ordered_search = search . as_ref ( ) . map ( | s | ! s . unordered ) . unwrap_or ( false ) ;
let is_ordered_search = search . as_ref ( ) . map ( | s | ! s . unordered ) . unwrap_or ( false ) ;
@ -1057,13 +1148,13 @@ fn draw_sort_n_filter(
ui . filter_identifiers
ui . filter_identifiers
. get ( & f . filter )
. get ( & f . filter )
. map ( | u | {
. map ( | u | {
let ui = defaultui . to_owned ( ) . extend ( u ) ;
let ui = defaultui . clone ( ) . extend ( u ) ;
(
(
Span ::styled (
Span ::styled (
ui . format . to_owned ( ) . unwrap_or_default ( ) ,
ui . format . clone ( ) . unwrap_or_default ( ) ,
ui . style . to_owned ( ) . into ( ) ,
ui . style . clone ( ) ,
) ,
) ,
Span ::styled ( f . input . to_owned ( ) , ui . style . into ( ) ) ,
Span ::styled ( f . input . clone ( ) , ui . style ) ,
)
)
} )
} )
. unwrap_or ( ( Span ::raw ( "f" ) , Span ::raw ( "" ) ) )
. unwrap_or ( ( Span ::raw ( "f" ) , Span ::raw ( "" ) ) )
@ -1077,17 +1168,17 @@ fn draw_sort_n_filter(
} else {
} else {
& orderedui
& orderedui
} ;
} ;
let ui = defaultui . to_owned ( ) . extend ( u ) ;
let ui = defaultui . clone ( ) . extend ( u ) ;
let f = ui
let f = ui
. format
. format
. as_ref ( )
. as_ref ( )
. map ( | f | format! ( "{f}{p}" , p = & s . pattern ) )
. map ( | f | format! ( "{f}{p}" , p = & s . pattern ) )
. unwrap_or_else ( | | s . pattern . clone ( ) ) ;
. unwrap_or_else ( | | s . pattern . clone ( ) ) ;
(
(
Span ::styled ( f , ui . style . into ( ) ) ,
Span ::styled ( f , ui . style ) ,
Span ::styled (
Span ::styled (
direction . format . to_owned ( ) . unwrap_or_default ( ) ,
direction . format . clone ( ) . unwrap_or_default ( ) ,
direction . style . to_owned( ) . into ( ) ,
direction . style . clone ( ) ,
) ,
) ,
)
)
} )
} )
@ -1101,15 +1192,15 @@ fn draw_sort_n_filter(
ui . sorter_identifiers
ui . sorter_identifiers
. get ( & s . sorter )
. get ( & s . sorter )
. map ( | u | {
. map ( | u | {
let ui = defaultui . to_owned ( ) . extend ( u ) ;
let ui = defaultui . clone ( ) . extend ( u ) ;
(
(
Span ::styled (
Span ::styled (
ui . format . to_owned ( ) . unwrap_or_default ( ) ,
ui . format . clone ( ) . unwrap_or_default ( ) ,
ui . style . into ( ) ,
ui . style ,
) ,
) ,
Span ::styled (
Span ::styled (
direction . format . to_owned ( ) . unwrap_or_default ( ) ,
direction . format . clone ( ) . unwrap_or_default ( ) ,
direction . style . to_owned( ) . into ( ) ,
direction . style . clone ( ) ,
) ,
) ,
)
)
} )
} )
@ -1118,8 +1209,8 @@ fn draw_sort_n_filter(
. take ( if ! is_ordered_search { sort_by . len ( ) } else { 0 } ) ,
. take ( if ! is_ordered_search { sort_by . len ( ) } else { 0 } ) ,
)
)
. zip ( std ::iter ::repeat ( Span ::styled (
. zip ( std ::iter ::repeat ( Span ::styled (
ui . separator . format . to_owned ( ) . unwrap_or_default ( ) ,
ui . separator . format . clone ( ) . unwrap_or_default ( ) ,
ui . separator . style . to_owned( ) . into ( ) ,
ui . separator . style . clone ( ) ,
) ) )
) ) )
. flat_map ( | ( ( a , b ) , c ) | vec! [ a , b , c ] )
. flat_map ( | ( ( a , b ) , c ) | vec! [ a , b , c ] )
. collect ::< Vec < Span > > ( ) ;
. collect ::< Vec < Span > > ( ) ;
@ -1139,19 +1230,13 @@ fn draw_sort_n_filter(
f . render_widget ( p , layout_size ) ;
f . render_widget ( p , layout_size ) ;
}
}
fn draw_logs (
fn draw_logs ( & mut self , f : & mut Frame , layout_size : TuiRect , app : & app ::App ) {
f : & mut Frame ,
_screen_size : TuiRect ,
layout_size : TuiRect ,
app : & app ::App ,
_ : & Lua ,
) {
let panel_config = & app . config . general . panel_ui ;
let panel_config = & app . config . general . panel_ui ;
let config = panel_config
let config = panel_config
. default
. default
. to_owned ( )
. clone ( )
. extend ( & panel_config . input_and_logs ) ;
. extend ( & panel_config . input_and_logs ) ;
let logs_config = app . config . general . logs . to_owned ( ) ;
let logs_config = app . config . general . logs . clone ( ) ;
let logs = if app . logs_hidden {
let logs = if app . logs_hidden {
vec! [ ]
vec! [ ]
} else {
} else {
@ -1161,7 +1246,8 @@ fn draw_logs(
. take ( layout_size . height as usize )
. take ( layout_size . height as usize )
. map ( | log | {
. map ( | log | {
let fd = format_description ! ( "[hour]:[minute]:[second]" ) ;
let fd = format_description ! ( "[hour]:[minute]:[second]" ) ;
let time = log . created_at . format ( fd ) . unwrap_or_else ( | _ | "when?" . into ( ) ) ;
let time =
log . created_at . format ( fd ) . unwrap_or_else ( | _ | "when?" . into ( ) ) ;
let cfg = match log . level {
let cfg = match log . level {
app ::LogLevel ::Info = > & logs_config . info ,
app ::LogLevel ::Info = > & logs_config . info ,
app ::LogLevel ::Warning = > & logs_config . warning ,
app ::LogLevel ::Warning = > & logs_config . warning ,
@ -1170,7 +1256,7 @@ fn draw_logs(
} ;
} ;
let prefix =
let prefix =
format! ( "{time}|{0}" , cfg . format . to_owned ( ) . unwrap_or_default ( ) ) ;
format! ( "{time}|{0}" , cfg . format . clone ( ) . unwrap_or_default ( ) ) ;
let padding = " " . repeat ( prefix . chars ( ) . count ( ) ) ;
let padding = " " . repeat ( prefix . chars ( ) . count ( ) ) ;
@ -1189,7 +1275,7 @@ fn draw_logs(
. collect ::< Vec < _ > > ( )
. collect ::< Vec < _ > > ( )
. join ( "\n" ) ;
. join ( "\n" ) ;
ListItem ::new ( txt ) . style ( cfg . style . to_owned( ) . into ( ) )
ListItem ::new ( txt ) . style ( cfg . style . clone ( ) )
} )
} )
. collect ::< Vec < ListItem > > ( )
. collect ::< Vec < ListItem > > ( )
} ;
} ;
@ -1215,50 +1301,43 @@ fn draw_logs(
f . render_widget ( logs_list , layout_size ) ;
f . render_widget ( logs_list , layout_size ) ;
}
}
pub fn draw_nothing (
fn draw_nothing ( & mut self , f : & mut Frame , layout_size : TuiRect , app : & app ::App ) {
f : & mut Frame ,
_screen_size : TuiRect ,
layout_size : TuiRect ,
app : & app ::App ,
_lua : & Lua ,
) {
let panel_config = & app . config . general . panel_ui ;
let panel_config = & app . config . general . panel_ui ;
let config = panel_config . default . to_owned ( ) ;
let config = panel_config . default . clone ( ) ;
let nothing = Paragraph ::new ( "" ) . block ( block ( config , "" . into ( ) ) ) ;
let nothing = Paragraph ::new ( "" ) . block ( block ( config , "" . into ( ) ) ) ;
f . render_widget ( nothing , layout_size ) ;
f . render_widget ( nothing , layout_size ) ;
}
}
pub fn draw_dynamic (
fn draw_dynamic (
& mut self ,
f : & mut Frame ,
f : & mut Frame ,
screen_size : TuiRect ,
layout_size : TuiRect ,
layout_size : TuiRect ,
app : & app ::App ,
app : & app ::App ,
func : & str ,
func : & str ,
lua : & Lua ,
) {
) {
let ctx = ContentRendererArg {
let ctx = ContentRendererArg {
app : app . to_lua_ctx_light ( ) ,
app : app . to_lua_ctx_light ( ) ,
layout_size : layout_size . into ( ) ,
layout_size : layout_size . into ( ) ,
screen_size : screen_size . into ( ) ,
screen_size : self . screen_size . into ( ) ,
scrolltop : self . scrolltop as u16 ,
} ;
} ;
let panel : CustomPanel = lua ::serialize ( lua , & ctx )
let panel : CustomPanel = lua ::serialize ( self . lua , & ctx )
. and_then ( | arg | lua ::call ( lua , func , arg ) )
. and_then ( | arg | lua ::call ( self . lua , func , arg ) )
. unwrap_or_else ( | e | CustomPanel ::CustomParagraph {
. unwrap_or_else ( | e | CustomPanel ::CustomParagraph {
ui : app . config . general . panel_ui . default . clone ( ) ,
ui : app . config . general . panel_ui . default . clone ( ) ,
body : format ! ( "{e:?}" ) ,
body : format ! ( "{e:?}" ) ,
} ) ;
} ) ;
draw_static ( f , screen_size, layout_size, app , panel , lua ) ;
self . draw_static ( f , layout_size, app , panel ) ;
}
}
pub fn draw_static (
fn draw_static (
& mut self ,
f : & mut Frame ,
f : & mut Frame ,
screen_size : TuiRect ,
layout_size : TuiRect ,
layout_size : TuiRect ,
app : & app ::App ,
app : & app ::App ,
panel : CustomPanel ,
panel : CustomPanel ,
_lua : & Lua ,
) {
) {
let defaultui = app . config . general . panel_ui . default . clone ( ) ;
let defaultui = app . config . general . panel_ui . default . clone ( ) ;
match panel {
match panel {
@ -1303,7 +1382,7 @@ pub fn draw_static(
let widths = widths
let widths = widths
. into_iter ( )
. into_iter ( )
. map ( | w | w . to_tui ( screen_size , layout_size ) )
. map ( | w | w . to_tui ( self . screen_size , layout_size ) )
. collect ::< Vec < TuiConstraint > > ( ) ;
. collect ::< Vec < TuiConstraint > > ( ) ;
let content = Table ::new ( rows , widths )
let content = Table ::new ( rows , widths )
@ -1314,68 +1393,35 @@ pub fn draw_static(
}
}
CustomPanel ::CustomLayout ( layout ) = > {
CustomPanel ::CustomLayout ( layout ) = > {
draw_layout ( layout , f , screen_size , layout_size , app , _lua ) ;
self . draw_layout ( layout , f , layout_size , app ) ;
}
}
}
}
}
#[ derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize) ]
pub struct Rect {
x : u16 ,
y : u16 ,
height : u16 ,
width : u16 ,
}
}
impl From < TuiRect > for Rect {
fn draw_layout (
fn from ( tui : TuiRect ) -> Self {
& mut self ,
Self {
x : tui . x ,
y : tui . y ,
height : tui . height ,
width : tui . width ,
}
}
}
#[ derive(Debug, Clone, Serialize) ]
pub struct ContentRendererArg {
pub app : app ::LuaContextLight ,
pub screen_size : Rect ,
pub layout_size : Rect ,
}
pub fn draw_layout (
layout : Layout ,
layout : Layout ,
f : & mut Frame ,
f : & mut Frame ,
screen_size : TuiRect ,
layout_size : TuiRect ,
layout_size : TuiRect ,
app : & app ::App ,
app : & app ::App ,
lua : & Lua ,
) {
) {
match layout {
match layout {
Layout ::Nothing = > draw_nothing ( f , screen_size , layout_size , app , lua ) ,
Layout ::Nothing = > self . draw_nothing ( f , layout_size , app ) ,
Layout ::Table = > draw_table ( f , screen_size , layout_size , app , lua ) ,
Layout ::Table = > self . draw_table ( f , layout_size , app ) ,
Layout ::SortAndFilter = > {
Layout ::SortAndFilter = > self . draw_sort_n_filter ( f , layout_size , app ) ,
draw_sort_n_filter ( f , screen_size , layout_size , app , lua )
Layout ::HelpMenu = > self . draw_help_menu ( f , layout_size , app ) ,
}
Layout ::Selection = > self . draw_selection ( f , layout_size , app ) ,
Layout ::HelpMenu = > draw_help_menu ( f , screen_size , layout_size , app , lua ) ,
Layout ::Selection = > draw_selection ( f , screen_size , layout_size , app , lua ) ,
Layout ::InputAndLogs = > {
Layout ::InputAndLogs = > {
if app . input . buffer . is_some ( ) {
if app . input . buffer . is_some ( ) {
draw_input_buffer ( f , screen_size, layout_size, app , lua ) ;
self . draw_input_buffer ( f , layout_size , app ) ;
} else {
} else {
draw_logs ( f , screen_size, layout_size, app , lua ) ;
self . draw_logs ( f , layout_size , app ) ;
} ;
} ;
}
}
Layout ::Static ( panel ) = > {
Layout ::Static ( panel ) = > self . draw_static ( f , layout_size , app , * panel ) ,
draw_static ( f , screen_size , layout_size , app , * panel , lua )
Layout ::Dynamic ( ref func ) = > self . draw_dynamic ( f , layout_size , app , func ) ,
}
Layout ::Dynamic ( ref func ) = > {
draw_dynamic ( f , screen_size , layout_size , app , func , lua )
}
Layout ::CustomContent ( content ) = > {
Layout ::CustomContent ( content ) = > {
draw_custom_content ( f , screen_size , layout_size , app , * content , lua )
draw_custom_content ( self , f , layout_size , app , * content )
}
}
Layout ::Horizontal { config , splits } = > {
Layout ::Horizontal { config , splits } = > {
let chunks = TuiLayout ::default ( )
let chunks = TuiLayout ::default ( )
@ -1383,10 +1429,10 @@ pub fn draw_layout(
. constraints (
. constraints (
config
config
. constraints
. constraints
. to_owned ( )
. clone ( )
. unwrap_or_default ( )
. unwrap_or_default ( )
. iter ( )
. iter ( )
. map ( | c | c . to_tui ( screen_size , layout_size ) )
. map ( | c | c . to_tui ( self . screen_size , layout_size ) )
. collect ::< Vec < TuiConstraint > > ( ) ,
. collect ::< Vec < TuiConstraint > > ( ) ,
)
)
. horizontal_margin (
. horizontal_margin (
@ -1403,9 +1449,7 @@ pub fn draw_layout(
splits
splits
. into_iter ( )
. into_iter ( )
. zip ( chunks . iter ( ) )
. zip ( chunks . iter ( ) )
. for_each ( | ( split , chunk ) | {
. for_each ( | ( split , chunk ) | self . draw_layout ( split , f , * chunk , app ) ) ;
draw_layout ( split , f , screen_size , * chunk , app , lua )
} ) ;
}
}
Layout ::Vertical { config , splits } = > {
Layout ::Vertical { config , splits } = > {
@ -1414,10 +1458,10 @@ pub fn draw_layout(
. constraints (
. constraints (
config
config
. constraints
. constraints
. to_owned ( )
. clone ( )
. unwrap_or_default ( )
. unwrap_or_default ( )
. iter ( )
. iter ( )
. map ( | c | c . to_tui ( screen_size , layout_size ) )
. map ( | c | c . to_tui ( self . screen_size , layout_size ) )
. collect ::< Vec < TuiConstraint > > ( ) ,
. collect ::< Vec < TuiConstraint > > ( ) ,
)
)
. horizontal_margin (
. horizontal_margin (
@ -1434,24 +1478,21 @@ pub fn draw_layout(
splits
splits
. into_iter ( )
. into_iter ( )
. zip ( chunks . iter ( ) )
. zip ( chunks . iter ( ) )
. for_each ( | ( split , chunk ) | {
. for_each ( | ( split , chunk ) | self . draw_layout ( split , f , * chunk , app ) ) ;
draw_layout ( split , f , screen_size , * chunk , app , lua )
} ) ;
}
}
}
}
}
}
pub fn draw ( f : & mut Frame , app : & app ::App , lua : & Lua ) {
pub fn draw ( & mut self , f : & mut Frame , app : & app ::App ) {
let screen_size = f . size ( ) ;
self . screen_size = f . size ( ) ;
let layout = app . mode . layout . as_ref ( ) . unwrap_or ( & app . layout ) . to_owned ( ) ;
let layout = app . mode . layout . as_ref ( ) . unwrap_or ( & app . layout ) . clone ( ) ;
self . draw_layout ( layout , f , self . screen_size , app ) ;
draw_layout ( layout , f , screen_size , screen_size , app , lua ) ;
}
}
}
#[ cfg(test) ]
#[ cfg(test) ]
mod tests {
mod tests {
use super ::* ;
use super ::* ;
use tui ::style ::Color ;
fn modifier ( m : Modifier ) -> Option < IndexSet < Modifier > > {
fn modifier ( m : Modifier ) -> Option < IndexSet < Modifier > > {
let mut x = IndexSet ::new ( ) ;
let mut x = IndexSet ::new ( ) ;
@ -1483,7 +1524,7 @@ mod tests {
} ;
} ;
assert_eq! (
assert_eq! (
a . to_owned ( ) . extend ( & b ) ,
a . clone ( ) . extend ( & b ) ,
Style {
Style {
fg : Some ( Color ::Red ) ,
fg : Some ( Color ::Red ) ,
bg : Some ( Color ::Blue ) ,
bg : Some ( Color ::Blue ) ,
@ -1503,7 +1544,7 @@ mod tests {
) ;
) ;
assert_eq! (
assert_eq! (
a . to_owned ( ) . extend ( & c ) ,
a . clone ( ) . extend ( & c ) ,
Style {
Style {
fg : Some ( Color ::Cyan ) ,
fg : Some ( Color ::Cyan ) ,
bg : Some ( Color ::Magenta ) ,
bg : Some ( Color ::Magenta ) ,