summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManos Pitsidianakis <el13635@mail.ntua.gr>2022-12-30 17:02:10 +0200
committerManos Pitsidianakis <el13635@mail.ntua.gr>2022-12-30 17:02:10 +0200
commit660bacb9262dac7457bd8c421cc70343a0db3cd5 (patch)
tree53fbdd7bc77e2d684dab217b62ecee8d183bc4ee
parentde2f46fe611726a445c1e06cbc35343e716aa335 (diff)
downloadmeli-master.zip
Add `mailto` command to open composer with initial values from mailto templatemaster
-rw-r--r--docs/meli.14
-rw-r--r--melib/src/email/mailto.rs10
-rw-r--r--melib/src/email/parser.rs8
-rw-r--r--src/command.rs15
-rw-r--r--src/command/actions.rs1
-rw-r--r--src/components/mail/listing.rs9
6 files changed, 44 insertions, 3 deletions
diff --git a/docs/meli.1 b/docs/meli.1
index e248538a..8a721d7e 100644
--- a/docs/meli.1
+++ b/docs/meli.1
@@ -472,6 +472,10 @@ open list archive with
.El
.Ss composing mail commands
.Bl -tag -width 36n
+.It Cm mailto Ar MAILTO_ADDRESS
+Opens a composer tab with initial values parsed from the
+.Li mailto:
+address.
.It Cm add-attachment Ar PATH
in composer, add
.Ar PATH
diff --git a/melib/src/email/mailto.rs b/melib/src/email/mailto.rs
index a5ecaa15..efec1bb7 100644
--- a/melib/src/email/mailto.rs
+++ b/melib/src/email/mailto.rs
@@ -23,7 +23,7 @@
use super::*;
use std::convert::TryFrom;
-#[derive(Debug)]
+#[derive(Debug, Clone)]
pub struct Mailto {
pub address: Address,
pub subject: Option<String>,
@@ -47,7 +47,13 @@ impl From<Mailto> for Draft {
ret.set_header("Bcc", bcc.unwrap_or_default());
ret.set_body(body.unwrap_or_default());
ret.set_header("To", address.to_string());
- debug!(ret)
+ ret
+ }
+}
+
+impl From<&Mailto> for Draft {
+ fn from(val: &Mailto) -> Self {
+ Draft::from(val.clone())
}
}
diff --git a/melib/src/email/parser.rs b/melib/src/email/parser.rs
index 72f64885..efb66fa8 100644
--- a/melib/src/email/parser.rs
+++ b/melib/src/email/parser.rs
@@ -184,6 +184,12 @@ impl From<nom::Err<nom::error::Error<&[u8]>>> for Error {
}
}
+impl<'i> From<ParsingError<&'i [u8]>> for nom::error::Error<&'i [u8]> {
+ fn from(val: ParsingError<&'i [u8]>) -> nom::error::Error<&'i [u8]> {
+ nom::error::Error::new(val.input, ErrorKind::Satisfy)
+ }
+}
+
macro_rules! is_ctl_or_space {
($var:ident) => {
/* <any ASCII control character and DEL> */
@@ -952,7 +958,7 @@ pub mod generic {
let value = String::from_utf8_lossy(&input[..value_end]).to_string();
match tag {
b"subject" if subject.is_none() => {
- subject = Some(value);
+ subject = Some(value.replace("%20", " "));
}
b"cc" if cc.is_none() => {
cc = Some(value);
diff --git a/src/command.rs b/src/command.rs
index c83008bf..562b1a5d 100644
--- a/src/command.rs
+++ b/src/command.rs
@@ -500,6 +500,20 @@ define_commands!([
}
)
},
+ { tags: ["mailto "],
+ desc: "mailto MAILTO_ADDRESS",
+ tokens: &[One(Literal("mailto")), One(QuotedStringValue)],
+ parser:(
+ fn mailto(input: &[u8]) -> IResult<&[u8], Action> {
+ let (input, _) = tag("mailto")(input.ltrim())?;
+ let (input, _) = is_a(" ")(input)?;
+ let (input, val) = map_res(not_line_ending, std::str::from_utf8)(input.trim())?;
+ let (_empty, _) = eof(input)?;
+ let (input, val) = melib::email::parser::generic::mailto(val.as_bytes()).map_err(|err| err.map(Into::into))?;
+ Ok((input, Compose(Mailto(val))))
+ }
+ )
+ },
/* Pipe pager contents to binary */
{ tags: ["pipe "],
desc: "pipe EXECUTABLE ARGS",
@@ -931,6 +945,7 @@ fn listing_action(input: &[u8]) -> IResult<&[u8], Action> {
fn compose_action(input: &[u8]) -> IResult<&[u8], Action> {
alt((
add_attachment,
+ mailto,
remove_attachment,
toggle_sign,
toggle_encrypt,
diff --git a/src/command/actions.rs b/src/command/actions.rs
index 8cc89aea..7152471e 100644
--- a/src/command/actions.rs
+++ b/src/command/actions.rs
@@ -89,6 +89,7 @@ pub enum ComposeAction {
SaveDraft,
ToggleSign,
ToggleEncrypt,
+ Mailto(melib::Mailto),
}
#[derive(Debug)]
diff --git a/src/components/mail/listing.rs b/src/components/mail/listing.rs
index 849d2370..5a0e9d06 100644
--- a/src/components/mail/listing.rs
+++ b/src/components/mail/listing.rs
@@ -1889,6 +1889,15 @@ impl Component for Listing {
.push_back(UIEvent::Action(Tab(New(Some(Box::new(mgr))))));
return true;
}
+ UIEvent::Action(Action::Compose(ComposeAction::Mailto(ref mailto))) => {
+ let account_hash = context.accounts[self.cursor_pos.0].hash();
+ let mut composer = Composer::with_account(account_hash, context);
+ composer.set_draft(mailto.into());
+ context
+ .replies
+ .push_back(UIEvent::Action(Tab(New(Some(Box::new(composer))))));
+ return true;
+ }
UIEvent::StartupCheck(_)
| UIEvent::MailboxUpdate(_)
| UIEvent::EnvelopeUpdate(_)