mirror of
https://github.com/kdheepak/taskwarrior-tui.git
synced 2025-08-25 08:47:18 +02:00
Support configuration of indicator from taskrc
This commit is contained in:
parent
6ab87c94d9
commit
92f53291fc
2 changed files with 97 additions and 49 deletions
|
@ -743,14 +743,15 @@ impl TTApp {
|
||||||
let mut style = Style::default();
|
let mut style = Style::default();
|
||||||
|
|
||||||
for tag_name in tag_names_in_precedence {
|
for tag_name in tag_names_in_precedence {
|
||||||
|
|
||||||
if task.tags().unwrap_or(&vec![]).contains(&tag_name.to_string().replace(".", "").to_uppercase()) {
|
if task.tags().unwrap_or(&vec![]).contains(&tag_name.to_string().replace(".", "").to_uppercase()) {
|
||||||
let color_tag_name = format!("color.{}", tag_name);
|
let color_tag_name = format!("color.{}", tag_name);
|
||||||
let c = self.config.color.get(&color_tag_name).cloned().unwrap_or_default();
|
let c = self.config.color.get(&color_tag_name).cloned().unwrap_or_default();
|
||||||
style = style.fg(c.fg).bg(c.bg);
|
style = style.fg(c.fg).bg(c.bg);
|
||||||
|
for modifier in c.modifiers {
|
||||||
|
style = style.add_modifier(modifier);
|
||||||
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
style
|
style
|
||||||
|
@ -824,7 +825,7 @@ impl TTApp {
|
||||||
let t = Table::new(header, rows.into_iter())
|
let t = Table::new(header, rows.into_iter())
|
||||||
.block(Block::default().borders(Borders::ALL).title("Task next"))
|
.block(Block::default().borders(Borders::ALL).title("Task next"))
|
||||||
.highlight_style(highlight_style)
|
.highlight_style(highlight_style)
|
||||||
.highlight_symbol("• ")
|
.highlight_symbol(&self.config.active_indicator)
|
||||||
.widths(&constraints);
|
.widths(&constraints);
|
||||||
|
|
||||||
f.render_stateful_widget(t, rect, &mut self.state);
|
f.render_stateful_widget(t, rect, &mut self.state);
|
||||||
|
@ -1547,6 +1548,7 @@ mod tests {
|
||||||
assert_eq!(app.context_name, "".to_string());
|
assert_eq!(app.context_name, "".to_string());
|
||||||
println!("{:?}", app.tasks.lock().unwrap()[0]);
|
println!("{:?}", app.tasks.lock().unwrap()[0]);
|
||||||
|
|
||||||
|
println!("{:?}", app.style_for_task(&app.task_current().unwrap()));
|
||||||
//println!("{:?}", app.task_report_columns);
|
//println!("{:?}", app.task_report_columns);
|
||||||
//println!("{:?}", app.task_report_labels);
|
//println!("{:?}", app.task_report_labels);
|
||||||
|
|
||||||
|
|
138
src/config.rs
138
src/config.rs
|
@ -1,12 +1,13 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use std::str;
|
use std::str;
|
||||||
use tui::style::Color;
|
use tui::style::{Color, Modifier};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct TColor {
|
pub struct TColor {
|
||||||
pub fg: Color,
|
pub fg: Color,
|
||||||
pub bg: Color,
|
pub bg: Color,
|
||||||
|
pub modifiers: Vec<Modifier>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for TColor {
|
impl Default for TColor {
|
||||||
|
@ -20,6 +21,7 @@ impl TColor {
|
||||||
TColor {
|
TColor {
|
||||||
fg: Color::Black,
|
fg: Color::Black,
|
||||||
bg: Color::White,
|
bg: Color::White,
|
||||||
|
modifiers: vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,6 +33,7 @@ pub struct TConfig {
|
||||||
pub obfuscate: bool,
|
pub obfuscate: bool,
|
||||||
pub print_empty_columns: bool,
|
pub print_empty_columns: bool,
|
||||||
pub rule_precedence_color: Vec<String>,
|
pub rule_precedence_color: Vec<String>,
|
||||||
|
pub active_indicator: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TConfig {
|
impl TConfig {
|
||||||
|
@ -42,6 +45,7 @@ impl TConfig {
|
||||||
print_empty_columns: bool_collection.get("print_empty_columns").cloned().unwrap_or(false),
|
print_empty_columns: bool_collection.get("print_empty_columns").cloned().unwrap_or(false),
|
||||||
color: Self::get_color_collection(),
|
color: Self::get_color_collection(),
|
||||||
rule_precedence_color: Self::get_rule_precedence_color(),
|
rule_precedence_color: Self::get_rule_precedence_color(),
|
||||||
|
active_indicator: Self::get_active_indicator(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,68 +79,94 @@ impl TConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_tcolor(line: &str) -> TColor {
|
fn get_tcolor(line: &str) -> TColor {
|
||||||
if line.contains(" on ") {
|
let (foreground, background) = line.split_at(line.find("on ").unwrap_or(line.len()));
|
||||||
let foreground = line.split(' ').collect::<Vec<&str>>()[0];
|
let background = background.trim_start_matches("on ");
|
||||||
let background = line.split(' ').collect::<Vec<&str>>()[2];
|
let mut modifiers = vec![];
|
||||||
TColor {
|
if foreground.contains("underline") {
|
||||||
fg: Self::get_color(foreground, Color::Black),
|
modifiers.push(Modifier::BOLD);
|
||||||
bg: Self::get_color(background, Color::White),
|
}
|
||||||
}
|
let foreground = foreground.replace("underline ", "");
|
||||||
} else if line.contains("on ") {
|
if foreground.contains("bold") {
|
||||||
let background = line.split(' ').collect::<Vec<&str>>()[1];
|
modifiers.push(Modifier::BOLD);
|
||||||
TColor {
|
}
|
||||||
fg: Color::Black,
|
let foreground = foreground.replace("bold ", "");
|
||||||
bg: Self::get_color(background, Color::White),
|
TColor {
|
||||||
}
|
fg: Self::get_color(foreground.as_str(), Color::Black),
|
||||||
} else {
|
bg: Self::get_color(background, Color::White),
|
||||||
let foreground = line;
|
modifiers,
|
||||||
TColor {
|
|
||||||
fg: Self::get_color(foreground, Color::Black),
|
|
||||||
bg: Color::White,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_color(s: &str, default: Color) -> Color {
|
fn get_color(s: &str, default: Color) -> Color {
|
||||||
if s.starts_with("color") {
|
let s = s.trim_start();
|
||||||
let fg = (s.as_bytes()[5] as char).to_digit(10).unwrap() as u8;
|
let s = s.trim_end();
|
||||||
|
if s.contains("color") {
|
||||||
|
let s = s.trim_start_matches("bright ");
|
||||||
|
let fg = (s.as_bytes()[5] as char).to_digit(10).unwrap_or_default() as u8;
|
||||||
Color::Indexed(fg)
|
Color::Indexed(fg)
|
||||||
} else if s.starts_with("rgb") {
|
} else if s.contains("gray") {
|
||||||
let red = (s.as_bytes()[3] as char).to_digit(10).unwrap() as u8;
|
let s = s.trim_start_matches("bright ");
|
||||||
let green = (s.as_bytes()[4] as char).to_digit(10).unwrap() as u8;
|
let fg = 232 + s.trim_start_matches("gray").parse::<u8>().unwrap_or_default();
|
||||||
let blue = (s.as_bytes()[5] as char).to_digit(10).unwrap() as u8;
|
Color::Indexed(fg)
|
||||||
|
} else if s.contains("rgb") {
|
||||||
|
let s = s.trim_start_matches("bright ");
|
||||||
|
let red = (s.as_bytes()[3] as char).to_digit(10).unwrap_or_default() as u8;
|
||||||
|
let green = (s.as_bytes()[4] as char).to_digit(10).unwrap_or_default() as u8;
|
||||||
|
let blue = (s.as_bytes()[5] as char).to_digit(10).unwrap_or_default() as u8;
|
||||||
Color::Indexed(16 + red * 36 + green * 6 + blue)
|
Color::Indexed(16 + red * 36 + green * 6 + blue)
|
||||||
} else if s == "black" {
|
} else if s == "bright red" {
|
||||||
Color::Black
|
Color::LightRed
|
||||||
} else if s == "red" {
|
} else if s == "bright green" {
|
||||||
Color::Red
|
Color::LightGreen
|
||||||
} else if s == "green" {
|
} else if s == "bright yellow" {
|
||||||
Color::Green
|
Color::LightYellow
|
||||||
} else if s == "yellow" {
|
} else if s == "bright blue" {
|
||||||
Color::Yellow
|
Color::LightBlue
|
||||||
} else if s == "blue" {
|
} else if s == "bright magenta" {
|
||||||
Color::Blue
|
Color::LightMagenta
|
||||||
} else if s == "magenta" {
|
} else if s == "bright cyan" {
|
||||||
Color::Magenta
|
Color::LightCyan
|
||||||
} else if s == "cyan" {
|
} else if s == "bright white" {
|
||||||
Color::Cyan
|
|
||||||
} else if s == "white" {
|
|
||||||
Color::White
|
Color::White
|
||||||
|
} else if s.contains("black") {
|
||||||
|
Color::Black
|
||||||
|
} else if s.contains("red") {
|
||||||
|
Color::Red
|
||||||
|
} else if s.contains("green") {
|
||||||
|
Color::Green
|
||||||
|
} else if s.contains("yellow") {
|
||||||
|
Color::Yellow
|
||||||
|
} else if s.contains("blue") {
|
||||||
|
Color::Blue
|
||||||
|
} else if s.contains("magenta") {
|
||||||
|
Color::Magenta
|
||||||
|
} else if s.contains("cyan") {
|
||||||
|
Color::Cyan
|
||||||
|
} else if s.contains("white") {
|
||||||
|
Color::White
|
||||||
|
} else if s.contains("black") {
|
||||||
|
Color::Black
|
||||||
} else {
|
} else {
|
||||||
default
|
default
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_rule_precedence_color() -> Vec<String> {
|
fn get_config(config: &str) -> String {
|
||||||
|
|
||||||
let output = Command::new("task")
|
let output = Command::new("task")
|
||||||
.arg("rc.color=off")
|
.arg("rc.color=off")
|
||||||
.arg("show")
|
.arg("show")
|
||||||
.arg("rule.precedence.color")
|
.arg(config)
|
||||||
.output()
|
.output()
|
||||||
.expect("Unable to run `task show`");
|
.expect("Unable to run `task show`");
|
||||||
|
|
||||||
let data = String::from_utf8(output.stdout).expect("Unable to convert stdout to string");
|
let data = String::from_utf8(output.stdout).expect("Unable to convert stdout to string");
|
||||||
|
data
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_rule_precedence_color() -> Vec<String> {
|
||||||
|
|
||||||
|
let data = Self::get_config("rule.precedence.color");
|
||||||
|
|
||||||
let mut rule_precedence_color = vec![];
|
let mut rule_precedence_color = vec![];
|
||||||
for line in data.split('\n') {
|
for line in data.split('\n') {
|
||||||
if line.starts_with("rule.precedence.color ") {
|
if line.starts_with("rule.precedence.color ") {
|
||||||
|
@ -152,6 +182,21 @@ impl TConfig {
|
||||||
return rule_precedence_color;
|
return rule_precedence_color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_active_indicator() -> String {
|
||||||
|
|
||||||
|
let data = Self::get_config("active.indicator");
|
||||||
|
|
||||||
|
for line in data.split('\n') {
|
||||||
|
if line.starts_with("active.indicator") {
|
||||||
|
let active_indicator = line
|
||||||
|
.trim_start_matches("active.indicator ");
|
||||||
|
return format!("{} ", active_indicator.trim_end());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "• ".to_string();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -160,6 +205,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_colors() {
|
fn test_colors() {
|
||||||
let tc = TConfig::default();
|
let tc = TConfig::default();
|
||||||
dbg!(tc);
|
dbg!(&tc.color["color.active"]);
|
||||||
|
dbg!(&tc.active_indicator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue