Add a config option for org-list-allow-alphabetical.
This fixes an issue where lines in a paragraph were incorrectly getting identified as lists because I had defaulted to assuming alphabetical bullets were allowed.
This commit is contained in:
parent
ac0db64081
commit
33372429dd
@ -12,6 +12,10 @@ pub struct GlobalSettings<'g, 's> {
|
||||
pub file_access: &'g dyn FileAccessInterface,
|
||||
pub in_progress_todo_keywords: BTreeSet<String>,
|
||||
pub complete_todo_keywords: BTreeSet<String>,
|
||||
/// Set to true to allow for plain lists using single letters as the bullet in the same way that numbers are used.
|
||||
///
|
||||
/// Corresponds to the org-list-allow-alphabetical elisp variable.
|
||||
pub org_list_allow_alphabetical: bool,
|
||||
}
|
||||
|
||||
impl<'g, 's> GlobalSettings<'g, 's> {
|
||||
@ -23,6 +27,7 @@ impl<'g, 's> GlobalSettings<'g, 's> {
|
||||
},
|
||||
in_progress_todo_keywords: BTreeSet::new(),
|
||||
complete_todo_keywords: BTreeSet::new(),
|
||||
org_list_allow_alphabetical: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -141,7 +141,7 @@ fn _detect_element<'b, 'g, 'r, 's>(
|
||||
can_be_paragraph: bool,
|
||||
) -> Res<OrgSource<'s>, ()> {
|
||||
if alt((
|
||||
detect_plain_list,
|
||||
parser_with_context!(detect_plain_list)(context),
|
||||
detect_footnote_definition,
|
||||
detect_diary_sexp,
|
||||
detect_comment,
|
||||
|
@ -41,12 +41,15 @@ use crate::types::PlainList;
|
||||
use crate::types::PlainListItem;
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub(crate) fn detect_plain_list<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, ()> {
|
||||
pub(crate) fn detect_plain_list<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, ()> {
|
||||
if verify(
|
||||
tuple((
|
||||
start_of_line,
|
||||
space0,
|
||||
bullet,
|
||||
parser_with_context!(bullet)(context),
|
||||
alt((space1, line_ending, eof)),
|
||||
)),
|
||||
|(_start, indent, bull, _after_whitespace)| {
|
||||
@ -145,12 +148,17 @@ fn plain_list_item<'b, 'g, 'r, 's>(
|
||||
let (remaining, leading_whitespace) = space0(input)?;
|
||||
// It is fine that we get the indent level using the number of bytes rather than the number of characters because nom's space0 only matches space and tab (0x20 and 0x09)
|
||||
let indent_level = leading_whitespace.len();
|
||||
let (remaining, bull) = verify(bullet, |bull: &OrgSource<'_>| {
|
||||
Into::<&str>::into(bull) != "*" || indent_level > 0
|
||||
})(remaining)?;
|
||||
let (remaining, bull) = verify(
|
||||
parser_with_context!(bullet)(context),
|
||||
|bull: &OrgSource<'_>| Into::<&str>::into(bull) != "*" || indent_level > 0,
|
||||
)(remaining)?;
|
||||
|
||||
let (remaining, _maybe_counter_set) =
|
||||
opt(tuple((space1, tag("[@"), counter, tag("]"))))(remaining)?;
|
||||
let (remaining, _maybe_counter_set) = opt(tuple((
|
||||
space1,
|
||||
tag("[@"),
|
||||
parser_with_context!(counter)(context),
|
||||
tag("]"),
|
||||
)))(remaining)?;
|
||||
|
||||
// TODO: parse checkbox
|
||||
|
||||
@ -228,18 +236,36 @@ fn plain_list_item<'b, 'g, 'r, 's>(
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn bullet<'s>(i: OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
fn bullet<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
alt((
|
||||
tag("*"),
|
||||
tag("-"),
|
||||
tag("+"),
|
||||
recognize(tuple((counter, alt((tag("."), tag(")")))))),
|
||||
))(i)
|
||||
recognize(tuple((
|
||||
parser_with_context!(counter)(context),
|
||||
alt((tag("."), tag(")"))),
|
||||
))),
|
||||
))(input)
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn counter<'s>(i: OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
alt((recognize(one_of("abcdefghijklmnopqrstuvwxyz")), digit1))(i)
|
||||
fn counter<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
if context.get_global_settings().org_list_allow_alphabetical {
|
||||
alt((
|
||||
recognize(one_of(
|
||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
|
||||
)),
|
||||
digit1,
|
||||
))(input)
|
||||
} else {
|
||||
digit1(input)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
@ -558,21 +584,30 @@ dolar"#,
|
||||
r#"+
|
||||
"#,
|
||||
);
|
||||
let result = detect_plain_list(input);
|
||||
let global_settings = GlobalSettings::default();
|
||||
let initial_context = ContextElement::document_context();
|
||||
let initial_context = Context::new(&global_settings, List::new(&initial_context));
|
||||
let result = detect_plain_list(&initial_context, input);
|
||||
assert!(result.is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn detect_eof() {
|
||||
let input = OrgSource::new(r#"+"#);
|
||||
let result = detect_plain_list(input);
|
||||
let global_settings = GlobalSettings::default();
|
||||
let initial_context = ContextElement::document_context();
|
||||
let initial_context = Context::new(&global_settings, List::new(&initial_context));
|
||||
let result = detect_plain_list(&initial_context, input);
|
||||
assert!(result.is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn detect_no_gap() {
|
||||
let input = OrgSource::new(r#"+foo"#);
|
||||
let result = detect_plain_list(input);
|
||||
let global_settings = GlobalSettings::default();
|
||||
let initial_context = ContextElement::document_context();
|
||||
let initial_context = Context::new(&global_settings, List::new(&initial_context));
|
||||
let result = detect_plain_list(&initial_context, input);
|
||||
// Since there is no whitespace after the '+' this is a paragraph, not a plain list.
|
||||
assert!(result.is_err());
|
||||
}
|
||||
@ -580,7 +615,10 @@ dolar"#,
|
||||
#[test]
|
||||
fn detect_with_gap() {
|
||||
let input = OrgSource::new(r#"+ foo"#);
|
||||
let result = detect_plain_list(input);
|
||||
let global_settings = GlobalSettings::default();
|
||||
let initial_context = ContextElement::document_context();
|
||||
let initial_context = Context::new(&global_settings, List::new(&initial_context));
|
||||
let result = detect_plain_list(&initial_context, input);
|
||||
assert!(result.is_ok());
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user