Honor the odd startup setting from org-mode files.
rust-test Build rust-test has succeeded Details
rust-build Build rust-build has succeeded Details
rust-foreign-document-test Build rust-foreign-document-test has failed Details

This commit is contained in:
Tom Alexander 2023-09-15 22:44:39 -04:00
parent a74ea730f4
commit 1a704dd312
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
5 changed files with 41 additions and 16 deletions

View File

@ -4,3 +4,4 @@
* Baz
*** Lorem
* Ipsum
**** Dolar

View File

@ -490,11 +490,11 @@ fn compare_heading<'s>(
let level = get_property(emacs, ":level")?
.ok_or("Level should not be nil")?
.as_atom()?;
if rust.stars.to_string() != level {
if rust.level.to_string() != level {
this_status = DiffStatus::Bad;
message = Some(format!(
"Headline level do not match (emacs != rust): {} != {}",
level, rust.stars
level, rust.level
))
}

View File

@ -1,4 +1,5 @@
use nom::branch::alt;
use nom::bytes::complete::is_a;
use nom::bytes::complete::tag;
use nom::character::complete::anychar;
use nom::character::complete::space0;
@ -11,7 +12,6 @@ use nom::combinator::recognize;
use nom::combinator::verify;
use nom::multi::many0;
use nom::multi::many1;
use nom::multi::many1_count;
use nom::multi::separated_list1;
use nom::sequence::tuple;
@ -39,27 +39,27 @@ use crate::types::PriorityCookie;
use crate::types::TodoKeywordType;
pub(crate) const fn heading(
parent_stars: usize,
parent_level: usize,
) -> impl for<'b, 'g, 'r, 's> Fn(
RefContext<'b, 'g, 'r, 's>,
OrgSource<'s>,
) -> Res<OrgSource<'s>, Heading<'s>> {
move |context, input: OrgSource<'_>| _heading(context, input, parent_stars)
move |context, input: OrgSource<'_>| _heading(context, input, parent_level)
}
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
fn _heading<'b, 'g, 'r, 's>(
context: RefContext<'b, 'g, 'r, 's>,
input: OrgSource<'s>,
parent_stars: usize,
parent_level: usize,
) -> Res<OrgSource<'s>, Heading<'s>> {
not(|i| context.check_exit_matcher(i))(input)?;
let (
remaining,
(star_count, maybe_todo_keyword, maybe_priority, maybe_comment, title, heading_tags),
) = headline(context, input, parent_stars)?;
(headline_level, maybe_todo_keyword, maybe_priority, maybe_comment, title, heading_tags),
) = headline(context, input, parent_level)?;
let section_matcher = parser_with_context!(section)(context);
let heading_matcher = parser_with_context!(heading(star_count))(context);
let heading_matcher = parser_with_context!(heading(headline_level))(context);
let (remaining, maybe_section) =
opt(map(section_matcher, DocumentElement::Section))(remaining)?;
let (remaining, _ws) = opt(tuple((start_of_line, many0(blank_line))))(remaining)?;
@ -82,7 +82,7 @@ fn _heading<'b, 'g, 'r, 's>(
remaining,
Heading {
source: source.into(),
stars: star_count,
level: headline_level,
todo_keyword: maybe_todo_keyword.map(|(todo_keyword_type, todo_keyword)| {
(todo_keyword_type, Into::<&str>::into(todo_keyword))
}),
@ -106,7 +106,7 @@ pub(crate) fn detect_headline<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, ()
fn headline<'b, 'g, 'r, 's>(
context: RefContext<'b, 'g, 'r, 's>,
input: OrgSource<'s>,
parent_stars: usize,
parent_level: usize,
) -> Res<
OrgSource<'s>,
(
@ -124,11 +124,12 @@ fn headline<'b, 'g, 'r, 's>(
});
let parser_context = context.with_additional_node(&parser_context);
let (remaining, (_, star_count, _)) = tuple((
let (remaining, (_, (star_count, _), _)) = tuple((
start_of_line,
verify(many1_count(tag("*")), |star_count| {
*star_count > parent_stars
}),
verify(
parser_with_context!(headline_level)(&parser_context),
|(level, _)| *level > parent_level,
),
peek(org_space),
))(input)?;
@ -255,3 +256,23 @@ fn priority_cookie<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, PriorityCooki
})?;
Ok((remaining, cookie))
}
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
fn headline_level<'b, 'g, 'r, 's>(
context: RefContext<'b, 'g, 'r, 's>,
input: OrgSource<'s>,
) -> Res<OrgSource<'s>, (usize, OrgSource<'s>)> {
let (remaining, stars) = is_a("*")(input)?;
let count = stars.len();
let level = match context.get_global_settings().odd_levels_only {
crate::context::HeadlineLevelFilter::Odd => {
if count % 2 == 0 {
(count + 2) / 2
} else {
(count + 1) / 2
}
}
crate::context::HeadlineLevelFilter::OddEven => count,
};
Ok((remaining, (level, stars)))
}

View File

@ -81,6 +81,9 @@ pub(crate) fn apply_in_buffer_settings<'g, 's, 'sf>(
if settings.contains(&"odd") {
new_settings.odd_levels_only = HeadlineLevelFilter::Odd;
}
if settings.contains(&"oddeven") {
new_settings.odd_levels_only = HeadlineLevelFilter::OddEven;
}
}
Ok(new_settings)

View File

@ -14,7 +14,7 @@ pub struct Document<'s> {
#[derive(Debug)]
pub struct Heading<'s> {
pub source: &'s str,
pub stars: usize,
pub level: usize,
pub todo_keyword: Option<(TodoKeywordType, &'s str)>,
pub priority_cookie: Option<PriorityCookie>,
pub title: Vec<Object<'s>>,