mirror of
https://github.com/sayanarijit/xplr
synced 2024-11-10 07:10:45 +00:00
Add support for NO_COLOR
Also, add `general.logs` to the config. Ref: https://no-color.org/
This commit is contained in:
parent
af1cda5762
commit
d0342260fe
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -1362,7 +1362,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "xplr"
|
||||
version = "0.4.3"
|
||||
version = "0.4.4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"chrono",
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "xplr"
|
||||
version = "0.4.3" # Update config.yml, config.rs and default.nix
|
||||
version = "0.4.4" # Update config.yml, config.rs and default.nix
|
||||
authors = ["Arijit Basu <sayanarijit@gmail.com>"]
|
||||
edition = "2018"
|
||||
description = "A hackable, minimal, fast TUI file explorer, stealing ideas from nnn and fzf"
|
||||
|
@ -1,54 +1,12 @@
|
||||
use crate::app::ExternalMsg;
|
||||
use crate::app::HelpMenuLine;
|
||||
use crate::default_config;
|
||||
use crate::ui::Style;
|
||||
use anyhow::Result;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::BTreeMap;
|
||||
use std::collections::HashMap;
|
||||
use tui::layout::Constraint as TuiConstraint;
|
||||
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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)]
|
||||
@ -252,6 +210,28 @@ impl TableConfig {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct LogsConfig {
|
||||
#[serde(default)]
|
||||
pub info: UiElement,
|
||||
|
||||
#[serde(default)]
|
||||
pub success: UiElement,
|
||||
|
||||
#[serde(default)]
|
||||
pub error: UiElement,
|
||||
}
|
||||
|
||||
impl LogsConfig {
|
||||
pub fn extend(mut self, other: Self) -> Self {
|
||||
self.info = other.info.extend(self.info);
|
||||
self.success = other.success.extend(self.success);
|
||||
self.error = other.error.extend(self.error);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct GeneralConfig {
|
||||
@ -264,6 +244,9 @@ pub struct GeneralConfig {
|
||||
#[serde(default)]
|
||||
pub prompt: UiElement,
|
||||
|
||||
#[serde(default)]
|
||||
pub logs: LogsConfig,
|
||||
|
||||
#[serde(default)]
|
||||
pub table: TableConfig,
|
||||
|
||||
@ -282,6 +265,7 @@ impl GeneralConfig {
|
||||
self.show_hidden = other.show_hidden.or(self.show_hidden);
|
||||
self.cursor = other.cursor.extend(self.cursor);
|
||||
self.prompt = other.prompt.extend(self.prompt);
|
||||
self.logs = other.logs.extend(self.logs);
|
||||
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);
|
||||
@ -559,6 +543,7 @@ impl Config {
|
||||
|
||||
pub fn is_compatible(&self) -> Result<bool> {
|
||||
let result = match self.parsed_version()? {
|
||||
(0, 4, 4) => true,
|
||||
(0, 4, 3) => true,
|
||||
(0, 4, 2) => true,
|
||||
(0, 4, 1) => true,
|
||||
@ -571,7 +556,7 @@ impl Config {
|
||||
|
||||
pub fn upgrade_notification(&self) -> Result<Option<&str>> {
|
||||
let result = match self.parsed_version()? {
|
||||
(0, 4, 3) => None,
|
||||
(0, 4, 4) => None,
|
||||
(_, _, _) => Some("App version updated"),
|
||||
};
|
||||
|
||||
|
@ -1,10 +1,23 @@
|
||||
version: v0.4.3
|
||||
version: v0.4.4
|
||||
general:
|
||||
show_hidden: false
|
||||
prompt:
|
||||
format: "> "
|
||||
cursor:
|
||||
format: █
|
||||
logs:
|
||||
info:
|
||||
format: "INFO"
|
||||
style:
|
||||
fg: LightBlue
|
||||
success:
|
||||
format: "SUCCESS"
|
||||
style:
|
||||
fg: Green
|
||||
error:
|
||||
format: "ERROR"
|
||||
style:
|
||||
fg: Red
|
||||
table:
|
||||
header:
|
||||
cols:
|
||||
|
88
src/ui.rs
88
src/ui.rs
@ -2,17 +2,69 @@ use crate::app;
|
||||
use crate::app::HelpMenuLine;
|
||||
use crate::app::{Node, SymlinkNode};
|
||||
use handlebars::Handlebars;
|
||||
use lazy_static::lazy_static;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::cmp::Ordering;
|
||||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
use tui::backend::Backend;
|
||||
use tui::layout::Rect;
|
||||
use tui::layout::{Constraint as TuiConstraint, Direction, Layout};
|
||||
use tui::style::{Color, Style};
|
||||
use tui::style::{Color, Modifier, Style as TuiStyle};
|
||||
use tui::text::{Span, Spans};
|
||||
use tui::widgets::{Block, Borders, Cell, List, ListItem, Paragraph, Row, Table};
|
||||
use tui::Frame;
|
||||
|
||||
lazy_static! {
|
||||
pub static ref NO_COLOR: bool = env::var("NO_COLOR").ok().map(|_| true).unwrap_or(false);
|
||||
pub static ref DEFAULT_STYLE: TuiStyle = TuiStyle::default();
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Default, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct Style {
|
||||
pub fg: Option<Color>,
|
||||
pub bg: Option<Color>,
|
||||
pub add_modifier: Option<Modifier>,
|
||||
pub 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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<TuiStyle> for Style {
|
||||
fn into(self) -> TuiStyle {
|
||||
if *NO_COLOR {
|
||||
*DEFAULT_STYLE
|
||||
} else {
|
||||
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, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct SymlinkNodeUiMetadata {
|
||||
@ -356,6 +408,7 @@ fn draw_input_buffer<B: Backend>(f: &mut Frame<B>, rect: Rect, app: &app::App, _
|
||||
}
|
||||
|
||||
fn draw_logs<B: Backend>(f: &mut Frame<B>, rect: Rect, app: &app::App, _: &Handlebars) {
|
||||
let config = app.config().general.logs.clone();
|
||||
let logs = app
|
||||
.logs()
|
||||
.iter()
|
||||
@ -364,18 +417,37 @@ fn draw_logs<B: Backend>(f: &mut Frame<B>, rect: Rect, app: &app::App, _: &Handl
|
||||
.rev()
|
||||
.map(|l| {
|
||||
let time = l.created_at.format("%r");
|
||||
let log = format!("{} | {}", &time, l.message);
|
||||
match &l.level {
|
||||
app::LogLevel::Info => ListItem::new(log).style(Style::default().fg(Color::Gray)),
|
||||
app::LogLevel::Success => {
|
||||
ListItem::new(log).style(Style::default().fg(Color::Green))
|
||||
}
|
||||
app::LogLevel::Error => ListItem::new(log).style(Style::default().fg(Color::Red)),
|
||||
app::LogLevel::Info => ListItem::new(format!(
|
||||
"{} | {} | {}",
|
||||
&time,
|
||||
&config.info.format.to_owned().unwrap_or_default(),
|
||||
&l.message
|
||||
))
|
||||
.style(config.info.style.into()),
|
||||
app::LogLevel::Success => ListItem::new(format!(
|
||||
"{} | {} | {}",
|
||||
&time,
|
||||
&config.success.format.to_owned().unwrap_or_default(),
|
||||
&l.message
|
||||
))
|
||||
.style(config.success.style.into()),
|
||||
app::LogLevel::Error => ListItem::new(format!(
|
||||
"{} | {} | {}",
|
||||
&time,
|
||||
&config.error.format.to_owned().unwrap_or_default(),
|
||||
&l.message
|
||||
))
|
||||
.style(config.error.style.into()),
|
||||
}
|
||||
})
|
||||
.collect::<Vec<ListItem>>();
|
||||
|
||||
let logs_list = List::new(logs).block(Block::default().borders(Borders::ALL).title(" Logs "));
|
||||
let logs_list = List::new(logs).block(
|
||||
Block::default()
|
||||
.borders(Borders::ALL)
|
||||
.title(format!(" Logs ({}) ", app.logs().len())),
|
||||
);
|
||||
|
||||
f.render_widget(logs_list, rect);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user