Optimize scanning for in-buffer settings by scanning forward for possible keywords.

Previously we stepped through the document character by character which involved a lot of extra processing inside OrgSource. By scanning for possible keywords, we can skip many of the intermediate steps.
This commit is contained in:
Tom Alexander
2023-09-24 02:58:32 -04:00
parent f9460b88d7
commit 8cd0e4ec63
2 changed files with 91 additions and 10 deletions

View File

@@ -1,6 +1,7 @@
use std::ops::RangeBounds;
use nom::Compare;
use nom::FindSubstring;
use nom::InputIter;
use nom::InputLength;
use nom::InputTake;
@@ -77,6 +78,55 @@ impl<'s> OrgSource<'s> {
self.slice(..(other.start - self.start))
}
pub(crate) fn get_start_of_line(&self) -> OrgSource<'s> {
let skipped_text = self.text_since_line_break();
let mut bracket_depth = self.bracket_depth;
let mut brace_depth = self.brace_depth;
let mut parenthesis_depth = self.parenthesis_depth;
// Since we're going backwards, this does the opposite.
for byte in skipped_text.bytes() {
match byte {
b'\n' => {
panic!("Should not hit a line break when only going back to the start of the line.");
}
b'[' => {
bracket_depth -= 1;
}
b']' => {
bracket_depth += 1;
}
b'{' => {
brace_depth -= 1;
}
b'}' => {
brace_depth += 1;
}
b'(' => {
parenthesis_depth -= 1;
}
b')' => {
parenthesis_depth += 1;
}
_ => {}
};
}
OrgSource {
full_source: self.full_source,
start: self.start_of_line,
end: self.end,
start_of_line: self.start_of_line,
preceding_character: if self.start_of_line > 0 {
Some('\n')
} else {
None
},
bracket_depth,
brace_depth,
parenthesis_depth,
}
}
pub(crate) fn get_bracket_depth(&self) -> BracketDepth {
self.bracket_depth
}
@@ -310,6 +360,12 @@ impl<'s> InputTakeAtPosition for OrgSource<'s> {
}
}
impl<'n, 's> FindSubstring<&'n str> for OrgSource<'s> {
fn find_substring(&self, substr: &'n str) -> Option<usize> {
Into::<&str>::into(self).find(substr)
}
}
pub(crate) fn convert_error<'a, I: Into<CustomError<&'a str>>>(
err: nom::Err<I>,
) -> nom::Err<CustomError<&'a str>> {