From ddb09a18051a3878e0d84371c6fb491f764900f9 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 7 Oct 2023 03:00:40 -0400 Subject: [PATCH] Add support for application in plain links. --- src/compare/diff.rs | 4 ++-- src/parser/plain_link.rs | 25 +++++++++++++++++++++++-- src/types/object.rs | 1 + 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/compare/diff.rs b/src/compare/diff.rs index 16902dd..6141b29 100644 --- a/src/compare/diff.rs +++ b/src/compare/diff.rs @@ -2973,8 +2973,8 @@ fn compare_plain_link<'b, 's>( ), ( EmacsField::Required(":application"), - compare_identity, - compare_property_always_nil + |r| r.application, + compare_property_quoted_string ), ( EmacsField::Required(":search-option"), diff --git a/src/parser/plain_link.rs b/src/parser/plain_link.rs index ae90402..2d2c82b 100644 --- a/src/parser/plain_link.rs +++ b/src/parser/plain_link.rs @@ -8,10 +8,12 @@ use nom::character::complete::one_of; use nom::combinator::consumed; use nom::combinator::eof; use nom::combinator::map; +use nom::combinator::map_parser; use nom::combinator::not; use nom::combinator::opt; use nom::combinator::peek; use nom::combinator::recognize; +use nom::combinator::rest; use nom::combinator::verify; use nom::multi::many0; use nom::multi::many1; @@ -56,6 +58,7 @@ pub(crate) fn plain_link<'b, 'g, 'r, 's>( path: path_plain.path, raw_link: path_plain.raw_link, search_option: path_plain.search_option, + application: path_plain.application, }, )) } @@ -66,6 +69,7 @@ struct PathPlain<'s> { path: &'s str, raw_link: &'s str, search_option: Option<&'s str>, + application: Option<&'s str>, } #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] @@ -107,6 +111,17 @@ fn parse_path_plain<'b, 'g, 'r, 's>( ))(input) } +fn parse_file_and_application<'s>( + input: OrgSource<'s>, +) -> Res, Option>> { + let (remaining, _) = tag("file")(input)?; + let (remaining, application) = + opt(map(tuple((tag("+"), rest)), |(_, application)| application))(remaining)?; + // Assert we consumed the entire protocol. + not(anychar)(remaining)?; + Ok((remaining, application)) +} + fn file_path_plain<'b, 'g, 'r, 's>( context: RefContext<'b, 'g, 'r, 's>, input: OrgSource<'s>, @@ -117,8 +132,12 @@ fn file_path_plain<'b, 'g, 'r, 's>( exit_matcher: &path_plain_end, }); let parser_context = context.with_additional_node(&parser_context); - let (remaining, (raw_link, (_, path, search_option))) = consumed(tuple(( - tag("file:"), + let (remaining, (raw_link, (application, _, path, search_option))) = consumed(tuple(( + map_parser( + parser_with_context!(protocol)(&parser_context), + parse_file_and_application, + ), + tag(":"), parser_with_context!(path_plain)(&parser_context), opt(map( tuple((tag("::"), is_not(" \t\r\n"))), @@ -132,6 +151,7 @@ fn file_path_plain<'b, 'g, 'r, 's>( path: path.into(), raw_link: raw_link.into(), search_option: search_option.map(Into::<&str>::into), + application: application.map(Into::<&str>::into), }, )) } @@ -158,6 +178,7 @@ fn protocol_path_plain<'b, 'g, 'r, 's>( path: path.into(), raw_link: raw_link.into(), search_option: None, + application: None, }, )) } diff --git a/src/types/object.rs b/src/types/object.rs index ac8620e..a8d2edb 100644 --- a/src/types/object.rs +++ b/src/types/object.rs @@ -108,6 +108,7 @@ pub struct PlainLink<'s> { pub path: &'s str, pub raw_link: &'s str, pub search_option: Option<&'s str>, + pub application: Option<&'s str>, } #[derive(Debug, PartialEq)]