A simple CPU rendered GUI IDE experience.
Diffstat (limited to 'src/sni.rs')
-rw-r--r--src/sni.rs58
1 files changed, 58 insertions, 0 deletions
diff --git a/src/sni.rs b/src/sni.rs
new file mode 100644
index 0000000..bcd0d4e
--- /dev/null
+++ b/src/sni.rs
@@ -0,0 +1,58 @@
+use helix_core::snippets::parser::SnippetElement;
+
+#[derive(Debug)]
+pub struct Snippet {
+ stops: Vec<(Stop, usize)>,
+}
+
+impl Snippet {
+ pub fn parse(x: &str, at: usize) -> Option<(Self, String)> {
+ let value = helix_core::snippets::parser::parse(x).ok()?;
+
+ let mut stops = vec![];
+ let mut cursor = 0;
+ let mut o = String::default();
+ // snippets may request multiple cursors; i dont support multiple cursors yet
+ for value in value.into_iter() {
+ 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);
+ 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 next(&mut self) -> usize {
+ self.stops.pop().unwrap().1
+ }
+
+ pub fn apply(
+ x: SnippetElement,
+ stops: &mut Vec<(Stop, usize)>,
+ cursor: &mut usize,
+ text: &mut String,
+ ) {
+ match x {
+ SnippetElement::Tabstop { tabstop, transform: None } =>
+ stops.push((tabstop, *cursor)),
+ SnippetElement::Placeholder { tabstop, value } => {
+ for value in value {
+ Self::apply(value, stops, cursor, text)
+ }
+ stops.push((tabstop, *cursor))
+ }
+ SnippetElement::Choice { tabstop, choices } => {
+ text.push_str(&choices[0]);
+ *cursor += choices[0].chars().count();
+ stops.push((tabstop, *cursor))
+ }
+ SnippetElement::Text(x) => {
+ text.push_str(&x);
+ *cursor += x.chars().count();
+ }
+ _ => unimplemented!(),
+ }
+ }
+}
+type Stop = usize;