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 Composer
jmap
Manos Pitsidianakis 2019-11-29 12:15:05 +02:00
parent d4f20b0c0d
commit 0b845a0d16
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
5 changed files with 61 additions and 19 deletions

View File

@ -41,7 +41,7 @@ Newline means LF (0x0A) or CRLF (0x0D 0x0A).
.Pp
Refer to TOML documentation for valid TOML syntax.
Thought not valid TOML syntax,
Thought not part of TOML syntax,
.Nm
can have nested configuration files by using the following include directive, which though starting with
.Em \&#
@ -49,6 +49,9 @@ is not a comment:
.Bd -literal
#include "/path/to/file"
.Ed
The accepted regular expression is
.Li ^\es*include\es*\&\\&\e"(\e\e.|[^\e"])+\e"\es*$
.Sh SECTIONS
The top level sections of the config are accounts, shortcuts, notifications, pager, composing, pgp, terminal.
.Pp

View File

@ -1,6 +1,13 @@
# Look into meli.conf(5) for all valid configuration options, their
# 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
#[accounts.account-name]

View File

@ -134,13 +134,13 @@ impl fmt::Display for Composer {
if self.reply_context.is_some() {
write!(f, "reply: {:8}", self.draft.headers()["Subject"])
} else {
write!(f, "compose")
write!(f, "composing")
}
}
}
impl Composer {
const DESCRIPTION: &'static str = "compose";
const DESCRIPTION: &'static str = "composing";
pub fn new(account_cursor: usize) -> Self {
Composer {
account_cursor,
@ -610,9 +610,8 @@ impl Component for Composer {
}
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) {
// don't pass Reply command to thread view in reply_context
(_, Some(_), UIEvent::Input(Key::Char('R'))) => {}
(ViewMode::Edit, _, _) => {
if self.pager.process_event(event, context) {
return true;
@ -749,7 +748,10 @@ impl Component for Composer {
self.cursor = Cursor::Body;
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.mode = ViewMode::Send(Selector::new(
"send mail?",
@ -862,7 +864,10 @@ impl Component for Composer {
self.set_dirty();
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();
match self.embed.take() {
Some(EmbedStatus::Running(e, f)) | Some(EmbedStatus::Stopped(e, f)) => {
@ -877,7 +882,10 @@ impl Component for Composer {
self.set_dirty();
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 */
let settings = &context.settings;
let editor = if let Some(editor_cmd) = settings.composing.editor_cmd.as_ref() {

View File

@ -515,7 +515,7 @@ impl Component for MailView {
}
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
.dirty_areas
.push_back((upper_left, set_y(bottom_right, y + 3)));

View File

@ -595,8 +595,8 @@ mod pp {
error::{MeliError, Result},
parsec::*,
};
use std::borrow::Cow;
use std::io::Read;
use std::path::{Path, PathBuf};
fn include_directive<'a>() -> impl Parser<'a, Option<&'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 {
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 file = std::fs::File::open(path)?;
@ -668,7 +668,9 @@ mod pp {
if let (_, Some(path)) = include_directive().parse(l).map_err(|l| {
MeliError::new(format!(
"Malformed include directive in line {} of file {}: {}",
i, path, l
i,
path.display(),
l
))
})? {
includes.push(path);
@ -676,17 +678,39 @@ mod pp {
}
if includes.is_empty() {
Ok(Cow::from(contents))
Ok(contents)
} else {
let mut ret = String::with_capacity(contents.len());
for path in includes {
ret.extend(pp_helper(path, level + 1)?.chars());
for sub_path in includes {
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());
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
}
}