Honor the odd startup setting from org-mode files.
This commit is contained in:
parent
a74ea730f4
commit
1a704dd312
@ -4,3 +4,4 @@
|
|||||||
* Baz
|
* Baz
|
||||||
*** Lorem
|
*** Lorem
|
||||||
* Ipsum
|
* Ipsum
|
||||||
|
**** Dolar
|
||||||
|
@ -490,11 +490,11 @@ fn compare_heading<'s>(
|
|||||||
let level = get_property(emacs, ":level")?
|
let level = get_property(emacs, ":level")?
|
||||||
.ok_or("Level should not be nil")?
|
.ok_or("Level should not be nil")?
|
||||||
.as_atom()?;
|
.as_atom()?;
|
||||||
if rust.stars.to_string() != level {
|
if rust.level.to_string() != level {
|
||||||
this_status = DiffStatus::Bad;
|
this_status = DiffStatus::Bad;
|
||||||
message = Some(format!(
|
message = Some(format!(
|
||||||
"Headline level do not match (emacs != rust): {} != {}",
|
"Headline level do not match (emacs != rust): {} != {}",
|
||||||
level, rust.stars
|
level, rust.level
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use nom::branch::alt;
|
use nom::branch::alt;
|
||||||
|
use nom::bytes::complete::is_a;
|
||||||
use nom::bytes::complete::tag;
|
use nom::bytes::complete::tag;
|
||||||
use nom::character::complete::anychar;
|
use nom::character::complete::anychar;
|
||||||
use nom::character::complete::space0;
|
use nom::character::complete::space0;
|
||||||
@ -11,7 +12,6 @@ use nom::combinator::recognize;
|
|||||||
use nom::combinator::verify;
|
use nom::combinator::verify;
|
||||||
use nom::multi::many0;
|
use nom::multi::many0;
|
||||||
use nom::multi::many1;
|
use nom::multi::many1;
|
||||||
use nom::multi::many1_count;
|
|
||||||
use nom::multi::separated_list1;
|
use nom::multi::separated_list1;
|
||||||
use nom::sequence::tuple;
|
use nom::sequence::tuple;
|
||||||
|
|
||||||
@ -39,27 +39,27 @@ use crate::types::PriorityCookie;
|
|||||||
use crate::types::TodoKeywordType;
|
use crate::types::TodoKeywordType;
|
||||||
|
|
||||||
pub(crate) const fn heading(
|
pub(crate) const fn heading(
|
||||||
parent_stars: usize,
|
parent_level: usize,
|
||||||
) -> impl for<'b, 'g, 'r, 's> Fn(
|
) -> impl for<'b, 'g, 'r, 's> Fn(
|
||||||
RefContext<'b, 'g, 'r, 's>,
|
RefContext<'b, 'g, 'r, 's>,
|
||||||
OrgSource<'s>,
|
OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, Heading<'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"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn _heading<'b, 'g, 'r, 's>(
|
fn _heading<'b, 'g, 'r, 's>(
|
||||||
context: RefContext<'b, 'g, 'r, 's>,
|
context: RefContext<'b, 'g, 'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
parent_stars: usize,
|
parent_level: usize,
|
||||||
) -> Res<OrgSource<'s>, Heading<'s>> {
|
) -> Res<OrgSource<'s>, Heading<'s>> {
|
||||||
not(|i| context.check_exit_matcher(i))(input)?;
|
not(|i| context.check_exit_matcher(i))(input)?;
|
||||||
let (
|
let (
|
||||||
remaining,
|
remaining,
|
||||||
(star_count, maybe_todo_keyword, maybe_priority, maybe_comment, title, heading_tags),
|
(headline_level, maybe_todo_keyword, maybe_priority, maybe_comment, title, heading_tags),
|
||||||
) = headline(context, input, parent_stars)?;
|
) = headline(context, input, parent_level)?;
|
||||||
let section_matcher = parser_with_context!(section)(context);
|
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) =
|
let (remaining, maybe_section) =
|
||||||
opt(map(section_matcher, DocumentElement::Section))(remaining)?;
|
opt(map(section_matcher, DocumentElement::Section))(remaining)?;
|
||||||
let (remaining, _ws) = opt(tuple((start_of_line, many0(blank_line))))(remaining)?;
|
let (remaining, _ws) = opt(tuple((start_of_line, many0(blank_line))))(remaining)?;
|
||||||
@ -82,7 +82,7 @@ fn _heading<'b, 'g, 'r, 's>(
|
|||||||
remaining,
|
remaining,
|
||||||
Heading {
|
Heading {
|
||||||
source: source.into(),
|
source: source.into(),
|
||||||
stars: star_count,
|
level: headline_level,
|
||||||
todo_keyword: maybe_todo_keyword.map(|(todo_keyword_type, todo_keyword)| {
|
todo_keyword: maybe_todo_keyword.map(|(todo_keyword_type, todo_keyword)| {
|
||||||
(todo_keyword_type, Into::<&str>::into(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>(
|
fn headline<'b, 'g, 'r, 's>(
|
||||||
context: RefContext<'b, 'g, 'r, 's>,
|
context: RefContext<'b, 'g, 'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
parent_stars: usize,
|
parent_level: usize,
|
||||||
) -> Res<
|
) -> Res<
|
||||||
OrgSource<'s>,
|
OrgSource<'s>,
|
||||||
(
|
(
|
||||||
@ -124,11 +124,12 @@ fn headline<'b, 'g, 'r, 's>(
|
|||||||
});
|
});
|
||||||
let parser_context = context.with_additional_node(&parser_context);
|
let parser_context = context.with_additional_node(&parser_context);
|
||||||
|
|
||||||
let (remaining, (_, star_count, _)) = tuple((
|
let (remaining, (_, (star_count, _), _)) = tuple((
|
||||||
start_of_line,
|
start_of_line,
|
||||||
verify(many1_count(tag("*")), |star_count| {
|
verify(
|
||||||
*star_count > parent_stars
|
parser_with_context!(headline_level)(&parser_context),
|
||||||
}),
|
|(level, _)| *level > parent_level,
|
||||||
|
),
|
||||||
peek(org_space),
|
peek(org_space),
|
||||||
))(input)?;
|
))(input)?;
|
||||||
|
|
||||||
@ -255,3 +256,23 @@ fn priority_cookie<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, PriorityCooki
|
|||||||
})?;
|
})?;
|
||||||
Ok((remaining, cookie))
|
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)))
|
||||||
|
}
|
||||||
|
@ -81,6 +81,9 @@ pub(crate) fn apply_in_buffer_settings<'g, 's, 'sf>(
|
|||||||
if settings.contains(&"odd") {
|
if settings.contains(&"odd") {
|
||||||
new_settings.odd_levels_only = HeadlineLevelFilter::Odd;
|
new_settings.odd_levels_only = HeadlineLevelFilter::Odd;
|
||||||
}
|
}
|
||||||
|
if settings.contains(&"oddeven") {
|
||||||
|
new_settings.odd_levels_only = HeadlineLevelFilter::OddEven;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(new_settings)
|
Ok(new_settings)
|
||||||
|
@ -14,7 +14,7 @@ pub struct Document<'s> {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Heading<'s> {
|
pub struct Heading<'s> {
|
||||||
pub source: &'s str,
|
pub source: &'s str,
|
||||||
pub stars: usize,
|
pub level: usize,
|
||||||
pub todo_keyword: Option<(TodoKeywordType, &'s str)>,
|
pub todo_keyword: Option<(TodoKeywordType, &'s str)>,
|
||||||
pub priority_cookie: Option<PriorityCookie>,
|
pub priority_cookie: Option<PriorityCookie>,
|
||||||
pub title: Vec<Object<'s>>,
|
pub title: Vec<Object<'s>>,
|
||||||
|
Loading…
Reference in New Issue
Block a user