From e2fc9411f1869fb0b8dd3893b937c4604887ee39 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 2 Mar 2021 16:48:54 +0300 Subject: Don't add space when joining line to opening quote --- crates/ide/src/join_lines.rs | 74 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 62 insertions(+), 12 deletions(-) diff --git a/crates/ide/src/join_lines.rs b/crates/ide/src/join_lines.rs index 2c077ed1f..7fcae13e0 100644 --- a/crates/ide/src/join_lines.rs +++ b/crates/ide/src/join_lines.rs @@ -7,6 +7,7 @@ use syntax::{ SyntaxKind::{self, USE_TREE, WHITESPACE}, SyntaxNode, SyntaxToken, TextRange, TextSize, T, }; +use test_utils::mark; use text_edit::{TextEdit, TextEditBuilder}; // Feature: Join Lines @@ -44,9 +45,9 @@ pub(crate) fn join_lines(file: &SourceFile, range: TextRange) -> TextEdit { let text = token.text(); for (pos, _) in text[range].bytes().enumerate().filter(|&(_, b)| b == b'\n') { let pos: TextSize = (pos as u32).into(); - let off = token.text_range().start() + range.start() + pos; - if !edit.invalidates_offset(off) { - remove_newline(&mut edit, &token, off); + let offset = token.text_range().start() + range.start() + pos; + if !edit.invalidates_offset(offset) { + remove_newline(&mut edit, &token, offset); } } } @@ -56,14 +57,25 @@ pub(crate) fn join_lines(file: &SourceFile, range: TextRange) -> TextEdit { fn remove_newline(edit: &mut TextEditBuilder, token: &SyntaxToken, offset: TextSize) { if token.kind() != WHITESPACE || token.text().bytes().filter(|&b| b == b'\n').count() != 1 { - // The node is either the first or the last in the file - let suff = &token.text()[TextRange::new( - offset - token.text_range().start() + TextSize::of('\n'), - TextSize::of(token.text()), - )]; - let spaces = suff.bytes().take_while(|&b| b == b' ').count(); - - edit.replace(TextRange::at(offset, ((spaces + 1) as u32).into()), " ".to_string()); + let mut string_open_quote = false; + if let Some(string) = ast::String::cast(token.clone()) { + if let Some(range) = string.open_quote_text_range() { + mark::hit!(join_string_literal); + string_open_quote = range.end() == offset; + } + } + + let n_spaces_after_line_break = { + let suff = &token.text()[TextRange::new( + offset - token.text_range().start() + TextSize::of('\n'), + TextSize::of(token.text()), + )]; + suff.bytes().take_while(|&b| b == b' ').count() + }; + + let range = TextRange::at(offset, ((n_spaces_after_line_break + 1) as u32).into()); + let replace_with = if string_open_quote { "" } else { " " }; + edit.replace(range, replace_with.to_string()); return; } @@ -194,7 +206,7 @@ fn compute_ws(left: SyntaxKind, right: SyntaxKind) -> &'static str { #[cfg(test)] mod tests { use syntax::SourceFile; - use test_utils::{add_cursor, assert_eq_text, extract_offset, extract_range}; + use test_utils::{add_cursor, assert_eq_text, extract_offset, extract_range, mark}; use super::*; @@ -771,4 +783,42 @@ fn foo() { ", ); } + + #[test] + fn join_string_literal() { + mark::check!(join_string_literal); + check_join_lines( + r#" +fn main() { + $0" +hello +"; +} +"#, + r#" +fn main() { + $0"hello +"; +} +"#, + ); + + check_join_lines( + r#" +fn main() { + " +$0hello +world +"; +} +"#, + r#" +fn main() { + " +$0hello world +"; +} +"#, + ); + } } -- cgit v1.2.3