From 0a382a4050ca4e9a5ac94674a5d90a9c1df2cfbf Mon Sep 17 00:00:00 2001 From: Kai Schmidt Date: Fri, 14 Jun 2024 10:54:31 -0700 Subject: [PATCH] fix a bug in lsp spans for multiline strings --- src/ast.rs | 2 +- src/compile/mod.rs | 20 +++++++++++++++++++- src/format.rs | 5 +++-- src/lsp.rs | 18 +++++++++++------- src/parse.rs | 9 ++++----- 5 files changed, 38 insertions(+), 16 deletions(-) diff --git a/src/ast.rs b/src/ast.rs index 4a67e203c..2dcc424c3 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -97,7 +97,7 @@ pub enum Word { Number(String, f64), Char(String), String(String), - MultilineString(String), + MultilineString(Vec>), FormatString(Vec), MultilineFormatString(Vec>>), Label(String), diff --git a/src/compile/mod.rs b/src/compile/mod.rs index afc886ac8..68b54b62d 100644 --- a/src/compile/mod.rs +++ b/src/compile/mod.rs @@ -961,7 +961,25 @@ code: } self.push_instr(instr); } - Word::String(s) | Word::MultilineString(s) => { + Word::String(s) => { + let mut instr = Instr::push(s); + if !call { + instr = Instr::PushFunc(self.make_function( + FunctionId::Anonymous(word.span.clone()), + Signature::new(0, 1), + eco_vec![instr], + )); + } + self.push_instr(instr); + } + Word::MultilineString(lines) => { + let mut s = EcoVec::new(); + for (i, line) in lines.into_iter().enumerate() { + if i > 0 { + s.push('\n'); + } + s.extend(line.value.chars()); + } let mut instr = Instr::push(s); if !call { instr = Instr::PushFunc(self.make_function( diff --git a/src/format.rs b/src/format.rs index 3826726c9..479f5ac96 100644 --- a/src/format.rs +++ b/src/format.rs @@ -793,13 +793,14 @@ impl<'a> Formatter<'a> { Word::Char(_) | Word::String(_) | Word::Label(_) | Word::FormatString(_) => self .output .push_str(&self.inputs.get(&word.span.src)[word.span.byte_range()]), - Word::MultilineString(s) => { + Word::MultilineString(lines) => { let curr_line_pos = if self.output.ends_with('\n') { 0 } else { (self.output.split('\n').last().unwrap_or_default().chars()).count() }; - for (i, mut line) in s.split('\n').enumerate() { + for (i, line) in lines.iter().enumerate() { + let mut line = line.value.as_str(); if line.ends_with('\r') { line = &line[..line.len() - 1]; } diff --git a/src/lsp.rs b/src/lsp.rs index b541f5340..40017cab5 100644 --- a/src/lsp.rs +++ b/src/lsp.rs @@ -308,11 +308,13 @@ impl Spanner { } spans.push(word.span.clone().sp(SpanKind::Number)) } - Word::Char(_) - | Word::String(_) - | Word::MultilineString(_) - | Word::FormatString(_) => spans.push(word.span.clone().sp(SpanKind::String)), + Word::Char(_) | Word::String(_) | Word::FormatString(_) => { + spans.push(word.span.clone().sp(SpanKind::String)) + } Word::Label(_) => spans.push(word.span.clone().sp(SpanKind::Label)), + Word::MultilineString(lines) => { + spans.extend((lines.iter()).map(|line| line.span.clone().sp(SpanKind::String))) + } Word::MultilineFormatString(lines) => { spans.extend((lines.iter()).map(|line| line.span.clone().sp(SpanKind::String))) } @@ -1276,13 +1278,15 @@ mod server { } else { start.character }; - tokens.push(SemanticToken { + let length = span.end.char_pos - span.start.char_pos; + let token = SemanticToken { delta_line: start.line - prev_line, delta_start, - length: (span.end.char_pos - span.start.char_pos), + length, token_type, token_modifiers_bitset: 0, - }); + }; + tokens.push(token); prev_line = start.line; prev_char = start.character; } diff --git a/src/parse.rs b/src/parse.rs index 055f31066..a3b4e96b4 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -877,13 +877,12 @@ impl<'i> Parser<'i> { frags.map(Word::FormatString) } else if let Some(line) = self.next_token_map(Token::as_multiline_string) { let mut span = line.span.clone(); - let mut s = line.value; + let mut lines = vec![line]; while let Some(line) = self.next_token_map(Token::as_multiline_string) { - span = span.merge(line.span); - s.push('\n'); - s.push_str(&line.value); + span = span.merge(line.span.clone()); + lines.push(line); } - span.sp(Word::MultilineString(s)) + span.sp(Word::MultilineString(lines)) } else if let Some(line) = self.next_token_map(Token::as_multiline_format_string) { let start = line.span.clone(); let mut end = start.clone();