|
|
|
@ -15,14 +15,12 @@ use std::env;
|
|
|
|
|
use std::ops::BitXor;
|
|
|
|
|
use tui::backend::Backend;
|
|
|
|
|
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::text::{Span, Spans, Text};
|
|
|
|
|
use tui::widgets::{
|
|
|
|
|
Block, BorderType as TuiBorderType, Borders as TuiBorders, Cell, List,
|
|
|
|
|
ListItem, Paragraph, Row, Table,
|
|
|
|
|
Block, BorderType as TuiBorderType, Borders as TuiBorders, Cell, List, ListItem,
|
|
|
|
|
Paragraph, Row, Table,
|
|
|
|
|
};
|
|
|
|
|
use tui::Frame;
|
|
|
|
|
|
|
|
|
@ -43,8 +41,7 @@ fn string_to_text<'a>(string: String) -> Text<'a> {
|
|
|
|
|
if *NO_COLOR {
|
|
|
|
|
Text::raw(string)
|
|
|
|
|
} else {
|
|
|
|
|
ansi_to_text(string.bytes())
|
|
|
|
|
.unwrap_or_else(|e| Text::raw(format!("{:?}", e)))
|
|
|
|
|
ansi_to_text(string.bytes()).unwrap_or_else(|e| Text::raw(format!("{:?}", e)))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -67,8 +64,7 @@ pub struct LayoutOptions {
|
|
|
|
|
impl LayoutOptions {
|
|
|
|
|
pub fn extend(mut self, other: &Self) -> Self {
|
|
|
|
|
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.constraints = other.constraints.to_owned().or(self.constraints);
|
|
|
|
|
self
|
|
|
|
@ -265,10 +261,8 @@ 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_modifiers =
|
|
|
|
|
other.add_modifiers.to_owned().or(self.add_modifiers);
|
|
|
|
|
self.sub_modifiers =
|
|
|
|
|
other.sub_modifiers.to_owned().or(self.sub_modifiers);
|
|
|
|
|
self.add_modifiers = other.add_modifiers.to_owned().or(self.add_modifiers);
|
|
|
|
|
self.sub_modifiers = other.sub_modifiers.to_owned().or(self.sub_modifiers);
|
|
|
|
|
self
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -288,12 +282,8 @@ impl Into<TuiStyle> for Style {
|
|
|
|
|
TuiStyle {
|
|
|
|
|
fg: self.fg,
|
|
|
|
|
bg: self.bg,
|
|
|
|
|
add_modifier: TuiModifier::from_bits_truncate(xor(
|
|
|
|
|
self.add_modifiers
|
|
|
|
|
)),
|
|
|
|
|
sub_modifier: TuiModifier::from_bits_truncate(xor(
|
|
|
|
|
self.sub_modifiers
|
|
|
|
|
)),
|
|
|
|
|
add_modifier: TuiModifier::from_bits_truncate(xor(self.add_modifiers)),
|
|
|
|
|
sub_modifier: TuiModifier::from_bits_truncate(xor(self.sub_modifiers)),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -322,11 +312,7 @@ pub enum Constraint {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Constraint {
|
|
|
|
|
pub fn to_tui(
|
|
|
|
|
self,
|
|
|
|
|
screen_size: TuiRect,
|
|
|
|
|
layout_size: TuiRect,
|
|
|
|
|
) -> TuiConstraint {
|
|
|
|
|
pub fn to_tui(self, screen_size: TuiRect, layout_size: TuiRect) -> TuiConstraint {
|
|
|
|
|
match self {
|
|
|
|
|
Self::Percentage(n) => TuiConstraint::Percentage(n),
|
|
|
|
|
Self::Ratio(x, y) => TuiConstraint::Ratio(x, y),
|
|
|
|
@ -518,9 +504,8 @@ fn draw_table<B: Backend>(
|
|
|
|
|
let config = panel_config.default.to_owned().extend(&panel_config.table);
|
|
|
|
|
let app_config = app.config.to_owned();
|
|
|
|
|
let header_height = app_config.general.table.header.height.unwrap_or(1);
|
|
|
|
|
let height: usize = (layout_size.height.max(header_height + 2)
|
|
|
|
|
- (header_height + 2))
|
|
|
|
|
.into();
|
|
|
|
|
let height: usize =
|
|
|
|
|
(layout_size.height.max(header_height + 2) - (header_height + 2)).into();
|
|
|
|
|
|
|
|
|
|
let rows = app
|
|
|
|
|
.directory_buffer
|
|
|
|
@ -595,25 +580,18 @@ fn draw_table<B: Backend>(
|
|
|
|
|
|
|
|
|
|
let (relative_index, is_before_focus, is_after_focus) =
|
|
|
|
|
match dir.focus.cmp(&index) {
|
|
|
|
|
Ordering::Greater => {
|
|
|
|
|
(dir.focus - index, true, false)
|
|
|
|
|
}
|
|
|
|
|
Ordering::Greater => (dir.focus - index, true, false),
|
|
|
|
|
Ordering::Less => (index - dir.focus, false, true),
|
|
|
|
|
Ordering::Equal => (0, false, false),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let (mut prefix, mut suffix, mut style) = {
|
|
|
|
|
let ui = app_config.general.default_ui.to_owned();
|
|
|
|
|
(
|
|
|
|
|
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 {
|
|
|
|
|
let ui =
|
|
|
|
|
app_config.general.focus_selection_ui.to_owned();
|
|
|
|
|
let ui = app_config.general.focus_selection_ui.to_owned();
|
|
|
|
|
prefix = ui.prefix.to_owned().or(prefix);
|
|
|
|
|
suffix = ui.suffix.to_owned().or(suffix);
|
|
|
|
|
style = style.extend(&ui.style);
|
|
|
|
@ -688,9 +666,7 @@ fn draw_table<B: Backend>(
|
|
|
|
|
.widths(&table_constraints)
|
|
|
|
|
.style(app_config.general.table.style.to_owned().into())
|
|
|
|
|
.highlight_style(app_config.general.focus_ui.style.to_owned().into())
|
|
|
|
|
.column_spacing(
|
|
|
|
|
app_config.general.table.col_spacing.unwrap_or_default(),
|
|
|
|
|
)
|
|
|
|
|
.column_spacing(app_config.general.table.col_spacing.unwrap_or_default())
|
|
|
|
|
.block(block(
|
|
|
|
|
config,
|
|
|
|
|
format!(
|
|
|
|
@ -777,8 +753,7 @@ fn draw_help_menu<B: Backend>(
|
|
|
|
|
if app.config.general.hide_remaps_in_help_menu {
|
|
|
|
|
[Cell::from(k), Cell::from(h)].to_vec()
|
|
|
|
|
} 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()
|
|
|
|
|
}
|
|
|
|
|
}),
|
|
|
|
|
})
|
|
|
|
@ -857,9 +832,7 @@ fn draw_input_buffer<B: Backend>(
|
|
|
|
|
f.render_widget(input_buf, layout_size);
|
|
|
|
|
f.set_cursor(
|
|
|
|
|
// Put cursor past the end of the input text
|
|
|
|
|
layout_size.x
|
|
|
|
|
+ (input.cursor() as u16).min(width)
|
|
|
|
|
+ cursor_offset_left,
|
|
|
|
|
layout_size.x + (input.cursor() as u16).min(width) + cursor_offset_left,
|
|
|
|
|
// Move one line down, from the border to the input line
|
|
|
|
|
layout_size.y + 1,
|
|
|
|
|
);
|
|
|
|
@ -879,8 +852,7 @@ fn draw_sort_n_filter<B: Backend>(
|
|
|
|
|
.to_owned()
|
|
|
|
|
.extend(&panel_config.sort_and_filter);
|
|
|
|
|
let ui = app.config.general.sort_and_filter_ui.to_owned();
|
|
|
|
|
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 defaultui = &ui.default_identifier;
|
|
|
|
|
let forwardui = defaultui
|
|
|
|
@ -977,11 +949,7 @@ fn draw_logs<B: Backend>(
|
|
|
|
|
app::LogLevel::Warning => ListItem::new(format!(
|
|
|
|
|
"{} | {} | {}",
|
|
|
|
|
&time,
|
|
|
|
|
&logs_config
|
|
|
|
|
.warning
|
|
|
|
|
.format
|
|
|
|
|
.to_owned()
|
|
|
|
|
.unwrap_or_default(),
|
|
|
|
|
&logs_config.warning.format.to_owned().unwrap_or_default(),
|
|
|
|
|
l.message
|
|
|
|
|
))
|
|
|
|
|
.style(logs_config.warning.style.to_owned().into()),
|
|
|
|
@ -989,11 +957,7 @@ fn draw_logs<B: Backend>(
|
|
|
|
|
app::LogLevel::Success => ListItem::new(format!(
|
|
|
|
|
"{} | {} | {}",
|
|
|
|
|
&time,
|
|
|
|
|
&logs_config
|
|
|
|
|
.success
|
|
|
|
|
.format
|
|
|
|
|
.to_owned()
|
|
|
|
|
.unwrap_or_default(),
|
|
|
|
|
&logs_config.success.format.to_owned().unwrap_or_default(),
|
|
|
|
|
l.message
|
|
|
|
|
))
|
|
|
|
|
.style(logs_config.success.style.to_owned().into()),
|
|
|
|
@ -1001,11 +965,7 @@ fn draw_logs<B: Backend>(
|
|
|
|
|
app::LogLevel::Error => ListItem::new(format!(
|
|
|
|
|
"{} | {} | {}",
|
|
|
|
|
&time,
|
|
|
|
|
&logs_config
|
|
|
|
|
.error
|
|
|
|
|
.format
|
|
|
|
|
.to_owned()
|
|
|
|
|
.unwrap_or_default(),
|
|
|
|
|
&logs_config.error.format.to_owned().unwrap_or_default(),
|
|
|
|
|
l.message
|
|
|
|
|
))
|
|
|
|
|
.style(logs_config.error.style.to_owned().into()),
|
|
|
|
@ -1070,8 +1030,7 @@ pub fn draw_custom_content<B: Backend>(
|
|
|
|
|
|
|
|
|
|
let render = lua::serialize(lua, &ctx)
|
|
|
|
|
.map(|arg| {
|
|
|
|
|
lua::call(lua, &render, arg)
|
|
|
|
|
.unwrap_or_else(|e| format!("{:?}", e))
|
|
|
|
|
lua::call(lua, &render, arg).unwrap_or_else(|e| format!("{:?}", e))
|
|
|
|
|
})
|
|
|
|
|
.unwrap_or_else(|e| e.to_string());
|
|
|
|
|
|
|
|
|
@ -1243,12 +1202,8 @@ pub fn draw_layout<B: Backend>(
|
|
|
|
|
Layout::SortAndFilter => {
|
|
|
|
|
draw_sort_n_filter(f, screen_size, layout_size, app, lua)
|
|
|
|
|
}
|
|
|
|
|
Layout::HelpMenu => {
|
|
|
|
|
draw_help_menu(f, screen_size, layout_size, app, lua)
|
|
|
|
|
}
|
|
|
|
|
Layout::Selection => {
|
|
|
|
|
draw_selection(f, screen_size, layout_size, app, lua)
|
|
|
|
|
}
|
|
|
|
|
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 => {
|
|
|
|
|
if app.input.buffer.is_some() {
|
|
|
|
|
draw_input_buffer(f, screen_size, layout_size, app, lua);
|
|
|
|
@ -1256,15 +1211,9 @@ pub fn draw_layout<B: Backend>(
|
|
|
|
|
draw_logs(f, screen_size, layout_size, app, lua);
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
Layout::CustomContent { title, body } => draw_custom_content(
|
|
|
|
|
f,
|
|
|
|
|
screen_size,
|
|
|
|
|
layout_size,
|
|
|
|
|
app,
|
|
|
|
|
title,
|
|
|
|
|
body,
|
|
|
|
|
lua,
|
|
|
|
|
),
|
|
|
|
|
Layout::CustomContent { title, body } => {
|
|
|
|
|
draw_custom_content(f, screen_size, layout_size, app, title, body, lua)
|
|
|
|
|
}
|
|
|
|
|
Layout::Horizontal { config, splits } => {
|
|
|
|
|
let chunks = TuiLayout::default()
|
|
|
|
|
.direction(Direction::Horizontal)
|
|
|
|
@ -1284,18 +1233,16 @@ pub fn draw_layout<B: Backend>(
|
|
|
|
|
.unwrap_or_default(),
|
|
|
|
|
)
|
|
|
|
|
.vertical_margin(
|
|
|
|
|
config
|
|
|
|
|
.vertical_margin
|
|
|
|
|
.or(config.margin)
|
|
|
|
|
.unwrap_or_default(),
|
|
|
|
|
config.vertical_margin.or(config.margin).unwrap_or_default(),
|
|
|
|
|
)
|
|
|
|
|
.split(layout_size);
|
|
|
|
|
|
|
|
|
|
splits.into_iter().zip(chunks.into_iter()).for_each(
|
|
|
|
|
|(split, chunk)| {
|
|
|
|
|
splits
|
|
|
|
|
.into_iter()
|
|
|
|
|
.zip(chunks.into_iter())
|
|
|
|
|
.for_each(|(split, chunk)| {
|
|
|
|
|
draw_layout(split, f, screen_size, chunk, app, lua)
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Layout::Vertical { config, splits } => {
|
|
|
|
@ -1317,18 +1264,16 @@ pub fn draw_layout<B: Backend>(
|
|
|
|
|
.unwrap_or_default(),
|
|
|
|
|
)
|
|
|
|
|
.vertical_margin(
|
|
|
|
|
config
|
|
|
|
|
.vertical_margin
|
|
|
|
|
.or(config.margin)
|
|
|
|
|
.unwrap_or_default(),
|
|
|
|
|
config.vertical_margin.or(config.margin).unwrap_or_default(),
|
|
|
|
|
)
|
|
|
|
|
.split(layout_size);
|
|
|
|
|
|
|
|
|
|
splits.into_iter().zip(chunks.into_iter()).for_each(
|
|
|
|
|
|(split, chunk)| {
|
|
|
|
|
splits
|
|
|
|
|
.into_iter()
|
|
|
|
|
.zip(chunks.into_iter())
|
|
|
|
|
.for_each(|(split, chunk)| {
|
|
|
|
|
draw_layout(split, f, screen_size, chunk, app, lua)
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|