A simple CPU rendered GUI IDE experience.
ranges
| -rw-r--r-- | src/com.rs | 2 | ||||
| -rw-r--r-- | src/sni.rs | 45 | ||||
| -rw-r--r-- | src/text.rs | 2 |
3 files changed, 38 insertions, 11 deletions
@@ -62,7 +62,7 @@ fn score<'a>( nucleo::pattern::CaseMatching::Smart, nucleo::pattern::Normalization::Smart, ); - let mut v = x + let mut v = x.filter .map(move |y| { let mut utf32 = vec![]; @@ -1,8 +1,33 @@ +use std::ops::Range; + use helix_core::snippets::parser::SnippetElement; #[derive(Debug)] pub struct Snippet { - stops: Vec<(Stop, usize)>, + stops: Vec<(Stop, StopP)>, +} + +#[derive(Debug, Clone, PartialEq, Eq)] +enum StopP { + Just(usize), + Range(Range<usize>), +} +impl StopP { + pub fn r(self) -> Range<usize> { + match self { + Self::Just(x) => x..x, + Self::Range(range) => range, + } + } + pub fn manipulate(&mut self, mut f: impl FnMut(usize) -> usize) { + match self { + Self::Just(x) => *x = f(*x), + Self::Range(range) => { + range.start = f(range.start); + range.end = f(range.end); + } + } + } } impl Snippet { @@ -17,35 +42,37 @@ impl Snippet { Self::apply(value, &mut stops, &mut cursor, &mut o); } stops.sort_by_key(|x| x.0); - stops.iter_mut().for_each(|x| x.1 += at); + stops.iter_mut().for_each(|x| x.1.manipulate(|x| x + at)); Some((Snippet { stops }, o)) } - pub fn manipulate(&mut self, mut f: impl FnMut(usize) -> usize) { - self.stops.iter_mut().for_each(|x| x.1 = f(x.1)); + pub fn manipulate(&mut self, f: impl FnMut(usize) -> usize + Clone) { + self.stops.iter_mut().for_each(|x| x.1.manipulate(f.clone())); } - pub fn next(&mut self) -> usize { + pub fn next(&mut self) -> StopP { self.stops.pop().unwrap().1 } pub fn apply( x: SnippetElement, - stops: &mut Vec<(Stop, usize)>, + stops: &mut Vec<(Stop, StopP)>, cursor: &mut usize, text: &mut String, ) { match x { SnippetElement::Tabstop { tabstop, transform: None } => - stops.push((tabstop, *cursor)), + stops.push((tabstop, StopP::Just(*cursor))), SnippetElement::Placeholder { tabstop, value } => { + let start = *cursor; for value in value { Self::apply(value, stops, cursor, text) } - stops.push((tabstop, *cursor)) + stops.push((tabstop, StopP::Range(start..*cursor))) } SnippetElement::Choice { tabstop, choices } => { + let start = *cursor; text.push_str(&choices[0]); *cursor += choices[0].chars().count(); - stops.push((tabstop, *cursor)) + stops.push((tabstop, StopP::Range(start..*cursor))) } SnippetElement::Text(x) => { text.push_str(&x); diff --git a/src/text.rs b/src/text.rs index 2a06da0..1f503bc 100644 --- a/src/text.rs +++ b/src/text.rs @@ -324,7 +324,7 @@ impl TextArea { crate::sni::Snippet::parse(&x.new_text, begin) .ok_or(anyhow!("failed to parse snippet"))?; self.rope.try_insert(begin, &tex)?; - self.cursor = sni.next(); + self.cursor = sni.next().r().end; Ok(()) } pub fn cursor(&self) -> (usize, usize) { |