aboutsummaryrefslogtreecommitdiff
path: root/helix-parsec
diff options
context:
space:
mode:
authorUrgau2023-02-07 19:15:39 +0000
committerBlaž Hrastnik2023-03-08 01:48:35 +0000
commite973b71c83dcefbdb3a748f28ce3bfd51e9cd842 (patch)
tree9071c629cb395524ec97265ca898f37615468907 /helix-parsec
parent9c12e0fb765f065b43788da670ffb98159d64a5f (diff)
Optimize LSP snippet parsing
Diffstat (limited to 'helix-parsec')
-rw-r--r--helix-parsec/src/lib.rs29
1 files changed, 29 insertions, 0 deletions
diff --git a/helix-parsec/src/lib.rs b/helix-parsec/src/lib.rs
index c86a1a05..bfa981e5 100644
--- a/helix-parsec/src/lib.rs
+++ b/helix-parsec/src/lib.rs
@@ -157,6 +157,35 @@ where
}
}
+/// A parser which matches all values until the specified pattern no longer match.
+///
+/// This parser only ever fails if the input has a length of zero.
+///
+/// # Examples
+///
+/// ```
+/// use helix_parsec::{take_while, Parser};
+/// let parser = take_while(|c| c == '1');
+/// assert_eq!(Ok(("2", "11")), parser.parse("112"));
+/// assert_eq!(Err("22"), parser.parse("22"));
+/// ```
+pub fn take_while<'a, F>(pattern: F) -> impl Parser<'a, Output = &'a str>
+where
+ F: Fn(char) -> bool,
+{
+ move |input: &'a str| match input
+ .char_indices()
+ .take_while(|(_p, c)| pattern(*c))
+ .last()
+ {
+ Some((index, c)) => {
+ let index = index + c.len_utf8();
+ Ok((&input[index..], &input[0..index]))
+ }
+ _ => Err(input),
+ }
+}
+
// Variadic parser combinators
/// A parser combinator which matches a sequence of parsers in an all-or-nothing fashion.