Small fixes
- Update documentation on include config syntax - Accept relative paths in include config syntax - Fix one line clearing that shouldn't be redrawn in html view - Fix shortcuts not being honored in Composerjmap
parent
d4f20b0c0d
commit
0b845a0d16
|
@ -41,7 +41,7 @@ Newline means LF (0x0A) or CRLF (0x0D 0x0A).
|
||||||
.Pp
|
.Pp
|
||||||
Refer to TOML documentation for valid TOML syntax.
|
Refer to TOML documentation for valid TOML syntax.
|
||||||
|
|
||||||
Thought not valid TOML syntax,
|
Thought not part of TOML syntax,
|
||||||
.Nm
|
.Nm
|
||||||
can have nested configuration files by using the following include directive, which though starting with
|
can have nested configuration files by using the following include directive, which though starting with
|
||||||
.Em \&#
|
.Em \&#
|
||||||
|
@ -49,6 +49,9 @@ is not a comment:
|
||||||
.Bd -literal
|
.Bd -literal
|
||||||
#include "/path/to/file"
|
#include "/path/to/file"
|
||||||
.Ed
|
.Ed
|
||||||
|
|
||||||
|
The accepted regular expression is
|
||||||
|
.Li ^\es*include\es*\&\\&\e"(\e\e.|[^\e"])+\e"\es*$
|
||||||
.Sh SECTIONS
|
.Sh SECTIONS
|
||||||
The top level sections of the config are accounts, shortcuts, notifications, pager, composing, pgp, terminal.
|
The top level sections of the config are accounts, shortcuts, notifications, pager, composing, pgp, terminal.
|
||||||
.Pp
|
.Pp
|
||||||
|
|
|
@ -1,6 +1,13 @@
|
||||||
# Look into meli.conf(5) for all valid configuration options, their
|
# Look into meli.conf(5) for all valid configuration options, their
|
||||||
# descriptions and default values
|
# descriptions and default values
|
||||||
#
|
#
|
||||||
|
# The syntax for including other configuration files is enclosed in `:
|
||||||
|
#`# include "account_one"`
|
||||||
|
#`# include "./account_two"`
|
||||||
|
#`# include "/home/absolute/path/to/shortcuts/config"`
|
||||||
|
# That is, the # in the beginning is part of the include directive.
|
||||||
|
#
|
||||||
|
#
|
||||||
#
|
#
|
||||||
# Setting up a Maildir account
|
# Setting up a Maildir account
|
||||||
#[accounts.account-name]
|
#[accounts.account-name]
|
||||||
|
|
|
@ -134,13 +134,13 @@ impl fmt::Display for Composer {
|
||||||
if self.reply_context.is_some() {
|
if self.reply_context.is_some() {
|
||||||
write!(f, "reply: {:8}", self.draft.headers()["Subject"])
|
write!(f, "reply: {:8}", self.draft.headers()["Subject"])
|
||||||
} else {
|
} else {
|
||||||
write!(f, "compose")
|
write!(f, "composing")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Composer {
|
impl Composer {
|
||||||
const DESCRIPTION: &'static str = "compose";
|
const DESCRIPTION: &'static str = "composing";
|
||||||
pub fn new(account_cursor: usize) -> Self {
|
pub fn new(account_cursor: usize) -> Self {
|
||||||
Composer {
|
Composer {
|
||||||
account_cursor,
|
account_cursor,
|
||||||
|
@ -610,9 +610,8 @@ impl Component for Composer {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool {
|
fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool {
|
||||||
|
let shortcuts = self.get_shortcuts(context);
|
||||||
match (&mut self.mode, &mut self.reply_context, &event) {
|
match (&mut self.mode, &mut self.reply_context, &event) {
|
||||||
// don't pass Reply command to thread view in reply_context
|
|
||||||
(_, Some(_), UIEvent::Input(Key::Char('R'))) => {}
|
|
||||||
(ViewMode::Edit, _, _) => {
|
(ViewMode::Edit, _, _) => {
|
||||||
if self.pager.process_event(event, context) {
|
if self.pager.process_event(event, context) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -749,7 +748,10 @@ impl Component for Composer {
|
||||||
self.cursor = Cursor::Body;
|
self.cursor = Cursor::Body;
|
||||||
self.dirty = true;
|
self.dirty = true;
|
||||||
}
|
}
|
||||||
UIEvent::Input(Key::Char('s')) if self.mode.is_edit() => {
|
UIEvent::Input(ref key)
|
||||||
|
if shortcut!(key == shortcuts[Self::DESCRIPTION]["send_mail"])
|
||||||
|
&& self.mode.is_edit() =>
|
||||||
|
{
|
||||||
self.update_draft();
|
self.update_draft();
|
||||||
self.mode = ViewMode::Send(Selector::new(
|
self.mode = ViewMode::Send(Selector::new(
|
||||||
"send mail?",
|
"send mail?",
|
||||||
|
@ -862,7 +864,10 @@ impl Component for Composer {
|
||||||
self.set_dirty();
|
self.set_dirty();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
UIEvent::Input(Key::Char('e')) if self.embed.is_some() => {
|
UIEvent::Input(ref key)
|
||||||
|
if self.embed.is_some()
|
||||||
|
&& shortcut!(key == shortcuts[Self::DESCRIPTION]["edit_mail"]) =>
|
||||||
|
{
|
||||||
self.embed.as_ref().unwrap().lock().unwrap().wake_up();
|
self.embed.as_ref().unwrap().lock().unwrap().wake_up();
|
||||||
match self.embed.take() {
|
match self.embed.take() {
|
||||||
Some(EmbedStatus::Running(e, f)) | Some(EmbedStatus::Stopped(e, f)) => {
|
Some(EmbedStatus::Running(e, f)) | Some(EmbedStatus::Stopped(e, f)) => {
|
||||||
|
@ -877,7 +882,10 @@ impl Component for Composer {
|
||||||
self.set_dirty();
|
self.set_dirty();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
UIEvent::Input(Key::Char('e')) if self.mode.is_edit() => {
|
UIEvent::Input(ref key)
|
||||||
|
if self.mode.is_edit()
|
||||||
|
&& shortcut!(key == shortcuts[Self::DESCRIPTION]["edit_mail"]) =>
|
||||||
|
{
|
||||||
/* Edit draft in $EDITOR */
|
/* Edit draft in $EDITOR */
|
||||||
let settings = &context.settings;
|
let settings = &context.settings;
|
||||||
let editor = if let Some(editor_cmd) = settings.composing.editor_cmd.as_ref() {
|
let editor = if let Some(editor_cmd) = settings.composing.editor_cmd.as_ref() {
|
||||||
|
|
|
@ -515,7 +515,7 @@ impl Component for MailView {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.force_draw_headers = false;
|
self.force_draw_headers = false;
|
||||||
clear_area(grid, (set_y(upper_left, y), set_y(bottom_right, y + 1)));
|
clear_area(grid, (set_y(upper_left, y), set_y(bottom_right, y)));
|
||||||
context
|
context
|
||||||
.dirty_areas
|
.dirty_areas
|
||||||
.push_back((upper_left, set_y(bottom_right, y + 3)));
|
.push_back((upper_left, set_y(bottom_right, y + 3)));
|
||||||
|
|
|
@ -595,8 +595,8 @@ mod pp {
|
||||||
error::{MeliError, Result},
|
error::{MeliError, Result},
|
||||||
parsec::*,
|
parsec::*,
|
||||||
};
|
};
|
||||||
use std::borrow::Cow;
|
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
fn include_directive<'a>() -> impl Parser<'a, Option<&'a str>> {
|
fn include_directive<'a>() -> impl Parser<'a, Option<&'a str>> {
|
||||||
move |input: &'a str| {
|
move |input: &'a str| {
|
||||||
|
@ -655,9 +655,9 @@ mod pp {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pp_helper(path: &str, level: u8) -> Result<Cow<'_, str>> {
|
fn pp_helper(path: &Path, level: u8) -> Result<String> {
|
||||||
if level > 7 {
|
if level > 7 {
|
||||||
return Err(MeliError::new(format!("Maximum recursion limit reached while unfolding include directives in {}. Have you included a config file within itself?", path)));
|
return Err(MeliError::new(format!("Maximum recursion limit reached while unfolding include directives in {}. Have you included a config file within itself?", path.display())));
|
||||||
}
|
}
|
||||||
let mut contents = String::new();
|
let mut contents = String::new();
|
||||||
let mut file = std::fs::File::open(path)?;
|
let mut file = std::fs::File::open(path)?;
|
||||||
|
@ -668,7 +668,9 @@ mod pp {
|
||||||
if let (_, Some(path)) = include_directive().parse(l).map_err(|l| {
|
if let (_, Some(path)) = include_directive().parse(l).map_err(|l| {
|
||||||
MeliError::new(format!(
|
MeliError::new(format!(
|
||||||
"Malformed include directive in line {} of file {}: {}",
|
"Malformed include directive in line {} of file {}: {}",
|
||||||
i, path, l
|
i,
|
||||||
|
path.display(),
|
||||||
|
l
|
||||||
))
|
))
|
||||||
})? {
|
})? {
|
||||||
includes.push(path);
|
includes.push(path);
|
||||||
|
@ -676,17 +678,39 @@ mod pp {
|
||||||
}
|
}
|
||||||
|
|
||||||
if includes.is_empty() {
|
if includes.is_empty() {
|
||||||
Ok(Cow::from(contents))
|
Ok(contents)
|
||||||
} else {
|
} else {
|
||||||
let mut ret = String::with_capacity(contents.len());
|
let mut ret = String::with_capacity(contents.len());
|
||||||
for path in includes {
|
for sub_path in includes {
|
||||||
ret.extend(pp_helper(path, level + 1)?.chars());
|
let p = &Path::new(sub_path);
|
||||||
|
debug!(p);
|
||||||
|
let p_buf = if p.is_relative() {
|
||||||
|
/* We checked that path is ok above so we can do unwrap here */
|
||||||
|
debug!(path);
|
||||||
|
let prefix = path.parent().unwrap();
|
||||||
|
debug!(prefix);
|
||||||
|
prefix.join(p)
|
||||||
|
} else {
|
||||||
|
p.to_path_buf()
|
||||||
|
};
|
||||||
|
|
||||||
|
ret.extend(pp_helper(&p_buf, level + 1)?.chars());
|
||||||
}
|
}
|
||||||
ret.extend(contents.chars());
|
ret.extend(contents.chars());
|
||||||
Ok(Cow::from(ret))
|
Ok(ret)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn pp(path: &str) -> Result<Cow<'_, str>> {
|
|
||||||
pp_helper(path, 0)
|
pub fn pp(path: &str) -> Result<String> {
|
||||||
|
let p = &Path::new(path);
|
||||||
|
let p_buf: PathBuf = if p.is_relative() {
|
||||||
|
p.canonicalize()?
|
||||||
|
} else {
|
||||||
|
p.to_path_buf()
|
||||||
|
};
|
||||||
|
|
||||||
|
let ret = pp_helper(&p_buf, 0);
|
||||||
|
drop(p_buf);
|
||||||
|
ret
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue