summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManos Pitsidianakis <el13635@mail.ntua.gr>2019-10-06 10:58:47 +0300
committerManos Pitsidianakis <el13635@mail.ntua.gr>2019-10-06 11:31:53 +0300
commitb25f10f92a299309a8319c22c3ca0c7da8b6689f (patch)
tree5dd77a5193ee1ed47a22c9b7f52628648b545881
parenta0602274f8417bfeb22784c8e31a889bf50caa93 (diff)
conf: add a light theme option
-rw-r--r--meli.16
-rw-r--r--meli.conf.511
-rw-r--r--sample-config3
-rw-r--r--ui/src/components/mail/listing/compact.rs46
-rw-r--r--ui/src/components/mail/listing/conversations.rs33
-rw-r--r--ui/src/components/mail/listing/plain.rs64
-rw-r--r--ui/src/components/mail/view.rs26
-rw-r--r--ui/src/conf.rs6
-rw-r--r--ui/src/conf/terminal.rs36
9 files changed, 186 insertions, 45 deletions
diff --git a/meli.1 b/meli.1
index d9c22865..12bed547 100644
--- a/meli.1
+++ b/meli.1
@@ -62,6 +62,12 @@ The main visual navigation tool is the left-side sidebar. The menu's visibility
).
.Pp
The view into each folder has 4 modes: plain, threaded, conversations and compact. Plain views each mail indvidually, threaded shows their thread relationship visually, and conversations includes one entry per thread of emails (compact is one row per thread).
+.Pp
+If you're using a light color palette in your terminal, you can set
+.Em theme = "light"
+in the
+.Em terminal
+section of your configuration.
.Bd -literal
^^ .-=-=-=-. ^^
^^ (`-=-=-=-=-`) ^^
diff --git a/meli.conf.5 b/meli.conf.5
index 1cc82cce..0c24bd5e 100644
--- a/meli.conf.5
+++ b/meli.conf.5
@@ -41,7 +41,7 @@ Newline means LF (0x0A) or CRLF (0x0D 0x0A).
.Pp
Refer to TOML documentation for valid TOML syntax.
.Sh SECTIONS
-The top level sections of the config are accounts, shortcuts, notifications, pager, composing, pgp.
+The top level sections of the config are accounts, shortcuts, notifications, pager, composing, pgp, terminal.
.Pp
.Sy example configuration
.Bd -literal
@@ -85,6 +85,9 @@ scroll_up = 'k'
scroll_down = 'j'
page_up = PageUp
page_down = PageDown
+
+[terminal]
+theme = "light"
.Ed
.Pp
available options are listed below.
@@ -308,6 +311,12 @@ auto verify signed e-mail according to RFC3156
.\" default value
.Pq Em "gpg2"
.El
+.Sh TERMINAL
+.Bl -tag -width "danger_accept_invalid_certs boolean" -offset -indent
+.It Cm theme Ar String
+(optional) select between these themes: light / dark
+.\" default value
+.Pq Em dark
.Sh SEE ALSO
.Xr meli 1
.Sh CONFORMING TO
diff --git a/sample-config b/sample-config
index 29aa62ef..0bb8ad9e 100644
--- a/sample-config
+++ b/sample-config
@@ -84,3 +84,6 @@
#auto_sign = false # always sign sent messages
#auto_verify_signatures = true # always verify signatures when reading signed e-mails
#gpg_binary = "/usr/bin/gpg2" #optional
+#
+#[terminal]
+#theme = "dark" # or "light"
diff --git a/ui/src/components/mail/listing/compact.rs b/ui/src/components/mail/listing/compact.rs
index 7afd9db9..e486009d 100644
--- a/ui/src/components/mail/listing/compact.rs
+++ b/ui/src/components/mail/listing/compact.rs
@@ -93,14 +93,26 @@ impl ListingTrait for CompactListing {
let thread_node = &threads.thread_nodes[&i];
let fg_color = self.data_columns.columns[0][(0, idx)].fg();
- let bg_color = if self.cursor_pos.2 == idx {
- Color::Byte(246)
- } else if self.selection[&i] {
- Color::Byte(210)
- } else if thread_node.has_unseen() {
- Color::Byte(251)
+ let bg_color = if context.settings.terminal.theme == "light" {
+ if self.cursor_pos.2 == idx {
+ Color::Byte(244)
+ } else if self.selection[&i] {
+ Color::Byte(210)
+ } else if thread_node.has_unseen() {
+ Color::Byte(251)
+ } else {
+ self.data_columns.columns[0][(0, idx)].bg()
+ }
} else {
- self.data_columns.columns[0][(0, idx)].bg()
+ if self.cursor_pos.2 == idx {
+ Color::Byte(246)
+ } else if self.selection[&i] {
+ Color::Byte(210)
+ } else if thread_node.has_unseen() {
+ Color::Byte(251)
+ } else {
+ self.data_columns.columns[0][(0, idx)].bg()
+ }
};
let (upper_left, bottom_right) = area;
@@ -639,12 +651,22 @@ impl CompactListing {
} else {
Color::Default
};
- let bg_color = if thread_node.has_unseen() {
- Color::Byte(251)
- } else if idx % 2 == 0 {
- Color::Byte(236)
+ let bg_color = if context.settings.terminal.theme == "light" {
+ if thread_node.has_unseen() {
+ Color::Byte(251)
+ } else if idx % 2 == 0 {
+ Color::Byte(252)
+ } else {
+ Color::Default
+ }
} else {
- Color::Default
+ if thread_node.has_unseen() {
+ Color::Byte(253)
+ } else if idx % 2 == 0 {
+ Color::Byte(236)
+ } else {
+ Color::Default
+ }
};
let (x, _) = write_string_to_grid(
&idx.to_string(),
diff --git a/ui/src/components/mail/listing/conversations.rs b/ui/src/components/mail/listing/conversations.rs
index 2fc8dd66..7289f081 100644
--- a/ui/src/components/mail/listing/conversations.rs
+++ b/ui/src/components/mail/listing/conversations.rs
@@ -146,6 +146,12 @@ impl ListingTrait for ConversationsListing {
((0, 3 * idx), pos_dec(self.content.size(), (1, 1))),
);
+ let padding_fg = if context.settings.terminal.theme == "light" {
+ Color::Byte(254)
+ } else {
+ Color::Byte(235)
+ };
+
let (upper_left, bottom_right) = area;
let width = self.content.size().0;
let (x, y) = upper_left;
@@ -157,7 +163,7 @@ impl ListingTrait for ConversationsListing {
grid[(x, y + 1)].set_fg(fg_color);
grid[(x, y + 1)].set_bg(bg_color);
- grid[(x, y + 2)].set_fg(Color::Byte(235));
+ grid[(x, y + 2)].set_fg(padding_fg);
grid[(x, y + 2)].set_bg(bg_color);
}
} else if width < width!(area) {
@@ -169,7 +175,7 @@ impl ListingTrait for ConversationsListing {
grid[(x, y + 1)].set_fg(fg_color);
grid[(x, y + 1)].set_bg(bg_color);
- grid[(x, y + 2)].set_fg(Color::Byte(235));
+ grid[(x, y + 2)].set_fg(padding_fg);
grid[(x, y + 2)].set_bg(bg_color);
}
}
@@ -362,6 +368,12 @@ impl ListingTrait for ConversationsListing {
/* fill any remaining columns, if our view is wider than self.content */
let width = self.content.size().0;
+ let padding_fg = if context.settings.terminal.theme == "light" {
+ Color::Byte(254)
+ } else {
+ Color::Byte(235)
+ };
+
if width < width!(area) {
let y_offset = get_y(upper_left);
for y in 0..rows {
@@ -372,7 +384,7 @@ impl ListingTrait for ConversationsListing {
grid[(x, y_offset + 3 * y + 2)].set_fg(Color::Default);
grid[(x, y_offset + 3 * y + 1)].set_bg(bg_color);
grid[(x, y_offset + 3 * y + 2)].set_ch('▓');
- grid[(x, y_offset + 3 * y + 2)].set_fg(Color::Byte(235));
+ grid[(x, y_offset + 3 * y + 2)].set_fg(padding_fg);
grid[(x, y_offset + 3 * y + 2)].set_bg(bg_color);
}
}
@@ -643,6 +655,12 @@ impl ConversationsListing {
let width = std::cmp::min(MAX_COLS, max_entry_columns);
self.content = CellBuffer::new(width, 4 * rows.len(), Cell::with_char(' '));
+ let padding_fg = if context.settings.terminal.theme == "light" {
+ Color::Byte(254)
+ } else {
+ Color::Byte(235)
+ };
+
for ((idx, root_idx), strings) in threads.root_iter().enumerate().zip(rows) {
let thread_node = &threads.thread_nodes()[&root_idx];
let i = if let Some(i) = thread_node.message() {
@@ -724,7 +742,7 @@ impl ConversationsListing {
}
for x in 0..width {
self.content[(x, 3 * idx + 2)].set_ch('▓');
- self.content[(x, 3 * idx + 2)].set_fg(Color::Byte(235));
+ self.content[(x, 3 * idx + 2)].set_fg(padding_fg);
self.content[(x, 3 * idx + 2)].set_bg(bg_color);
}
}
@@ -1074,10 +1092,15 @@ impl Component for ConversationsListing {
fg_color,
bg_color,
);
+ let padding_fg = if context.settings.terminal.theme == "light" {
+ Color::Byte(254)
+ } else {
+ Color::Byte(235)
+ };
change_colors(
&mut self.content,
((0, 3 * row + 2), (width - 1, 3 * row + 2)),
- Color::Byte(235),
+ padding_fg,
bg_color,
);
let rows = (get_y(bottom_right) - get_y(upper_left) + 1) / 3;
diff --git a/ui/src/components/mail/listing/plain.rs b/ui/src/components/mail/listing/plain.rs
index 5667774c..be31814e 100644
--- a/ui/src/components/mail/listing/plain.rs
+++ b/ui/src/components/mail/listing/plain.rs
@@ -102,14 +102,26 @@ impl ListingTrait for PlainListing {
} else {
Color::Default
};
- let bg_color = if self.cursor_pos.2 == idx {
- Color::Byte(246)
- } else if !envelope.is_seen() {
- Color::Byte(251)
- } else if idx % 2 == 0 {
- Color::Byte(236)
+ let bg_color = if context.settings.terminal.theme == "light" {
+ if self.cursor_pos.2 == idx {
+ Color::Byte(246)
+ } else if !envelope.is_seen() {
+ Color::Byte(251)
+ } else if idx % 2 == 0 {
+ Color::Byte(252)
+ } else {
+ Color::Default
+ }
} else {
- Color::Default
+ if self.cursor_pos.2 == idx {
+ Color::Byte(246)
+ } else if !envelope.is_seen() {
+ Color::Byte(251)
+ } else if idx % 2 == 0 {
+ Color::Byte(236)
+ } else {
+ Color::Default
+ }
};
change_colors(grid, area, fg_color, bg_color);
}
@@ -369,12 +381,22 @@ impl PlainListing {
} else {
Color::Default
};
- let bg_color = if !envelope.is_seen() {
- Color::Byte(251)
- } else if idx % 2 == 0 {
- Color::Byte(236)
+ let bg_color = if context.settings.terminal.theme == "light" {
+ if !envelope.is_seen() {
+ Color::Byte(251)
+ } else if idx % 2 == 0 {
+ Color::Byte(252)
+ } else {
+ Color::Default
+ }
} else {
- Color::Default
+ if !envelope.is_seen() {
+ Color::Byte(251)
+ } else if idx % 2 == 0 {
+ Color::Byte(236)
+ } else {
+ Color::Default
+ }
};
let (x, _) = write_string_to_grid(
&rows[idx].0,
@@ -432,12 +454,20 @@ impl PlainListing {
}
}
- fn unhighlight_line(&mut self, idx: usize) {
+ fn unhighlight_line(&mut self, idx: usize, context: &Context) {
let fg_color = Color::Default;
- let bg_color = if idx % 2 == 0 {
- Color::Byte(236)
+ let bg_color = if context.settings.terminal.theme == "light" {
+ if idx % 2 == 0 {
+ Color::Byte(252)
+ } else {
+ Color::Default
+ }
} else {
- Color::Default
+ if idx % 2 == 0 {
+ Color::Byte(236)
+ } else {
+ Color::Default
+ }
};
change_colors(
&mut self.content,
@@ -503,7 +533,7 @@ impl Component for PlainListing {
}
};
if must_unhighlight {
- self.unhighlight_line(idx);
+ self.unhighlight_line(idx, context);
}
let mid = get_y(upper_left) + total_rows - bottom_entity_rows;
self.draw_list(
diff --git a/ui/src/components/mail/view.rs b/ui/src/components/mail/view.rs
index 92a11cb9..6845e28a 100644
--- a/ui/src/components/mail/view.rs
+++ b/ui/src/components/mail/view.rs
@@ -334,6 +334,12 @@ impl Component for MailView {
}
let envelope: &Envelope = &account.get_env(&self.coordinates.2);
+ let header_fg = if context.settings.terminal.theme == "light" {
+ Color::Black
+ } else {
+ Color::Byte(33)
+ };
+
if self.mode == ViewMode::Raw {
clear_area(grid, area);
context.dirty_areas.push_back(area);
@@ -342,7 +348,7 @@ impl Component for MailView {
let (x, y) = write_string_to_grid(
&format!("Date: {}", envelope.date_as_str()),
grid,
- Color::Byte(33),
+ header_fg,
Color::Default,
Attr::Default,
area,
@@ -356,7 +362,7 @@ impl Component for MailView {
let (x, y) = write_string_to_grid(
&format!("From: {}", envelope.field_from_to_string()),
grid,
- Color::Byte(33),
+ header_fg,
Color::Default,
Attr::Default,
(set_y(upper_left, y + 1), bottom_right),
@@ -370,7 +376,7 @@ impl Component for MailView {
let (x, y) = write_string_to_grid(
&format!("To: {}", envelope.field_to_to_string()),
grid,
- Color::Byte(33),
+ header_fg,
Color::Default,
Attr::Default,
(set_y(upper_left, y + 1), bottom_right),
@@ -384,7 +390,7 @@ impl Component for MailView {
let (x, y) = write_string_to_grid(
&format!("Subject: {}", envelope.subject()),
grid,
- Color::Byte(33),
+ header_fg,
Color::Default,
Attr::Default,
(set_y(upper_left, y + 1), bottom_right),
@@ -398,7 +404,7 @@ impl Component for MailView {
let (x, mut y) = write_string_to_grid(
&format!("Message-ID: <{}>", envelope.message_id_raw()),
grid,
- Color::Byte(33),
+ header_fg,
Color::Default,
Attr::Default,
(set_y(upper_left, y + 1), bottom_right),
@@ -413,7 +419,7 @@ impl Component for MailView {
let (x, _y) = write_string_to_grid(
&format!("In-Reply-To: {}", envelope.in_reply_to_display().unwrap()),
grid,
- Color::Byte(33),
+ header_fg,
Color::Default,
Attr::Default,
(set_y(upper_left, y + 1), bottom_right),
@@ -435,7 +441,7 @@ impl Component for MailView {
.join(", ")
),
grid,
- Color::Byte(33),
+ header_fg,
Color::Default,
Attr::Default,
(set_y(upper_left, _y + 1), bottom_right),
@@ -461,7 +467,7 @@ impl Component for MailView {
let (_x, _) = write_string_to_grid(
"List-ID: ",
grid,
- Color::Byte(33),
+ header_fg,
Color::Default,
Attr::Default,
(set_y(upper_left, y), bottom_right),
@@ -482,7 +488,7 @@ impl Component for MailView {
let (_x, _) = write_string_to_grid(
" Available actions: [ ",
grid,
- Color::Byte(33),
+ header_fg,
Color::Default,
Attr::Default,
((x, y), bottom_right),
@@ -528,7 +534,7 @@ impl Component for MailView {
}
if archive.is_some() || post.is_some() || unsubscribe.is_some() {
grid[(x - 2, y)].set_ch(' ');
- grid[(x - 1, y)].set_fg(Color::Byte(33));
+ grid[(x - 1, y)].set_fg(header_fg);
grid[(x - 1, y)].set_bg(Color::Default);
grid[(x - 1, y)].set_ch(']');
}
diff --git a/ui/src/conf.rs b/ui/src/conf.rs
index 46e9d09c..f4e2498e 100644
--- a/ui/src/conf.rs
+++ b/ui/src/conf.rs
@@ -29,6 +29,7 @@ pub mod notifications;
pub mod pager;
pub mod pgp;
pub mod shortcuts;
+pub mod terminal;
pub mod accounts;
pub use self::accounts::Account;
@@ -38,6 +39,7 @@ pub use self::shortcuts::*;
use self::default_vals::*;
use self::notifications::NotificationsSettings;
+use self::terminal::TerminalSettings;
use crate::pager::PagerSettings;
use melib::backends::SpecialUseMailbox;
use melib::conf::AccountSettings;
@@ -277,6 +279,8 @@ struct FileSettings {
composing: ComposingSettings,
#[serde(default)]
pgp: PGPSettings,
+ #[serde(default)]
+ terminal: TerminalSettings,
}
#[derive(Debug, Clone, Default)]
@@ -306,6 +310,7 @@ pub struct Settings {
pub shortcuts: Shortcuts,
pub composing: ComposingSettings,
pub pgp: PGPSettings,
+ pub terminal: TerminalSettings,
}
impl FileSettings {
@@ -394,6 +399,7 @@ impl Settings {
shortcuts: fs.shortcuts,
composing: fs.composing,
pgp: fs.pgp,
+ terminal: fs.terminal,
}
}
}
diff --git a/ui/src/conf/terminal.rs b/ui/src/conf/terminal.rs
new file mode 100644
index 00000000..2861cb50
--- /dev/null
+++ b/ui/src/conf/terminal.rs
@@ -0,0 +1,36 @@
+/*
+ * meli - configuration module.
+ *
+ * Copyright 2019 Manos Pitsidianakis
+ *
+ * This file is part of meli.
+ *
+ * meli is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * meli is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with meli. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/// Settings for terminal display
+#[derive(Debug, Deserialize, Clone, Serialize)]
+pub struct TerminalSettings {
+ #[serde(default)]
+ /// light, dark
+ pub theme: String,
+}
+
+impl Default for TerminalSettings {
+ fn default() -> Self {
+ TerminalSettings {
+ theme: "dark".to_string(),
+ }
+ }
+}