@@ -50,14 +50,11 @@ pub struct Snippet<'a> {
50 elements: Vec<SnippetElement<'a>>,
50 elements: Vec<SnippetElement<'a>>,
53−pub fn parse<'a>(s: &'a str) -> Result<Snippet<'a>> {
53+pub fn parse(s: &str) -> Result<Snippet<'_>> {
54 parser::parse(s).map_err(|rest| anyhow!("Failed to parse snippet. Remaining input: {}", rest))
54 parser::parse(s).map_err(|rest| anyhow!("Failed to parse snippet. Remaining input: {}", rest))
57mod parser {
57mod parser {
58− use helix_core::regex;
59− use once_cell::sync::Lazy;
61 use helix_parsec::*;
58 use helix_parsec::*;
63 use super::{CaseChange, FormatItem, Regex, Snippet, SnippetElement};
60 use super::{CaseChange, FormatItem, Regex, Snippet, SnippetElement};
@@ -86,17 +83,34 @@ mod parser {
86 else ::= text
83 else ::= text
89− static DIGIT: Lazy<regex::Regex> = Lazy::new(|| regex::Regex::new(r"^[0-9]+").unwrap());
90− static VARIABLE: Lazy<regex::Regex> =
91− Lazy::new(|| regex::Regex::new(r"^[_a-zA-Z][_a-zA-Z0-9]*").unwrap());
92− static TEXT: Lazy<regex::Regex> = Lazy::new(|| regex::Regex::new(r"^[^\$]+").unwrap());
94 fn var<'a>() -> impl Parser<'a, Output = &'a str> {
86 fn var<'a>() -> impl Parser<'a, Output = &'a str> {
95− pattern(&VARIABLE)
87+ // var = [_a-zA-Z][_a-zA-Z0-9]*
88+ move |input: &'a str| match input
90+ .take_while(|(p, c)| {
93+ c.is_ascii_alphabetic()
95+ c.is_ascii_alphanumeric()
100+ Some((index, c)) if index >= 1 => {
101+ let index = index + c.len_utf8();
102+ Ok((&input[index..], &input[0..index]))
108+ fn text<'a>() -> impl Parser<'a, Output = &'a str> {
109+ take_while(|c| c != '$')
98 fn digit<'a>() -> impl Parser<'a, Output = usize> {
112 fn digit<'a>() -> impl Parser<'a, Output = usize> {
99− filter_map(pattern(&DIGIT), |s| s.parse().ok())
113+ filter_map(take_while(|c| c.is_ascii_digit()), |s| s.parse().ok())
102 fn case_change<'a>() -> impl Parser<'a, Output = CaseChange> {
116 fn case_change<'a>() -> impl Parser<'a, Output = CaseChange> {
@@ -152,7 +166,7 @@ mod parser {
152 |seq| { Conditional(seq.1, None, Some(seq.4)) }
166 |seq| { Conditional(seq.1, None, Some(seq.4)) }
154 // Any text
168 // Any text
155− map(pattern(&TEXT), Text),
169+ map(text(), Text),
@@ -245,12 +259,9 @@ mod parser {
248− fn text<'a>() -> impl Parser<'a, Output = SnippetElement<'a>> {
249− map(pattern(&TEXT), SnippetElement::Text)
252 fn anything<'a>() -> impl Parser<'a, Output = SnippetElement<'a>> {
262 fn anything<'a>() -> impl Parser<'a, Output = SnippetElement<'a>> {
263+ let text = map(text(), SnippetElement::Text);
253− choice!(tabstop(), placeholder(), choice(), variable(), text())
264+ choice!(tabstop(), placeholder(), choice(), variable(), text)
256 fn snippet<'a>() -> impl Parser<'a, Output = Snippet<'a>> {
267 fn snippet<'a>() -> impl Parser<'a, Output = Snippet<'a>> {