Don't add space when joining line to opening quote

This commit is contained in:
Aleksey Kladov 2021-03-02 16:48:54 +03:00
parent 8eee9149e8
commit e2fc9411f1

View file

@ -7,6 +7,7 @@ use syntax::{
SyntaxKind::{self, USE_TREE, WHITESPACE}, SyntaxKind::{self, USE_TREE, WHITESPACE},
SyntaxNode, SyntaxToken, TextRange, TextSize, T, SyntaxNode, SyntaxToken, TextRange, TextSize, T,
}; };
use test_utils::mark;
use text_edit::{TextEdit, TextEditBuilder}; use text_edit::{TextEdit, TextEditBuilder};
// Feature: Join Lines // Feature: Join Lines
@ -44,9 +45,9 @@ pub(crate) fn join_lines(file: &SourceFile, range: TextRange) -> TextEdit {
let text = token.text(); let text = token.text();
for (pos, _) in text[range].bytes().enumerate().filter(|&(_, b)| b == b'\n') { for (pos, _) in text[range].bytes().enumerate().filter(|&(_, b)| b == b'\n') {
let pos: TextSize = (pos as u32).into(); let pos: TextSize = (pos as u32).into();
let off = token.text_range().start() + range.start() + pos; let offset = token.text_range().start() + range.start() + pos;
if !edit.invalidates_offset(off) { if !edit.invalidates_offset(offset) {
remove_newline(&mut edit, &token, off); 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) { fn remove_newline(edit: &mut TextEditBuilder, token: &SyntaxToken, offset: TextSize) {
if token.kind() != WHITESPACE || token.text().bytes().filter(|&b| b == b'\n').count() != 1 { 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 mut string_open_quote = false;
let suff = &token.text()[TextRange::new( if let Some(string) = ast::String::cast(token.clone()) {
offset - token.text_range().start() + TextSize::of('\n'), if let Some(range) = string.open_quote_text_range() {
TextSize::of(token.text()), mark::hit!(join_string_literal);
)]; string_open_quote = range.end() == offset;
let spaces = suff.bytes().take_while(|&b| b == b' ').count(); }
}
edit.replace(TextRange::at(offset, ((spaces + 1) as u32).into()), " ".to_string()); 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; return;
} }
@ -194,7 +206,7 @@ fn compute_ws(left: SyntaxKind, right: SyntaxKind) -> &'static str {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use syntax::SourceFile; 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::*; 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
";
}
"#,
);
}
} }