mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 05:23:24 +00:00
Fix indentation of inserted use statements
This commit is contained in:
parent
4105378dc7
commit
bc65200105
2 changed files with 135 additions and 37 deletions
|
@ -14,6 +14,7 @@ use syntax::{
|
||||||
},
|
},
|
||||||
InsertPosition, SyntaxElement, SyntaxNode,
|
InsertPosition, SyntaxElement, SyntaxNode,
|
||||||
};
|
};
|
||||||
|
use test_utils::mark;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum ImportScope {
|
pub enum ImportScope {
|
||||||
|
@ -109,6 +110,12 @@ pub(crate) fn insert_use(
|
||||||
// so look for the place we have to insert to
|
// so look for the place we have to insert to
|
||||||
let (insert_position, add_blank) = find_insert_position(scope, path);
|
let (insert_position, add_blank) = find_insert_position(scope, path);
|
||||||
|
|
||||||
|
let indent = if let ident_level @ 1..=usize::MAX = scope.indent_level().0 as usize {
|
||||||
|
Some(make::tokens::whitespace(&" ".repeat(4 * ident_level)).into())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
let to_insert: Vec<SyntaxElement> = {
|
let to_insert: Vec<SyntaxElement> = {
|
||||||
let mut buf = Vec::new();
|
let mut buf = Vec::new();
|
||||||
|
|
||||||
|
@ -120,9 +127,13 @@ pub(crate) fn insert_use(
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
if let ident_level @ 1..=usize::MAX = scope.indent_level().0 as usize {
|
if add_blank.has_before() {
|
||||||
buf.push(make::tokens::whitespace(&" ".repeat(4 * ident_level)).into());
|
if let Some(indent) = indent.clone() {
|
||||||
|
mark::hit!(insert_use_indent_before);
|
||||||
|
buf.push(indent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
buf.push(use_item.syntax().clone().into());
|
buf.push(use_item.syntax().clone().into());
|
||||||
|
|
||||||
match add_blank {
|
match add_blank {
|
||||||
|
@ -133,6 +144,16 @@ pub(crate) fn insert_use(
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// only add indentation *after* our stuff if there's another node directly after it
|
||||||
|
if add_blank.has_after() && matches!(insert_position, InsertPosition::Before(_)) {
|
||||||
|
if let Some(indent) = indent {
|
||||||
|
mark::hit!(insert_use_indent_after);
|
||||||
|
buf.push(indent);
|
||||||
|
}
|
||||||
|
} else if add_blank.has_after() && matches!(insert_position, InsertPosition::After(_)) {
|
||||||
|
mark::hit!(insert_use_no_indent_after);
|
||||||
|
}
|
||||||
|
|
||||||
buf
|
buf
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -470,6 +491,15 @@ enum AddBlankLine {
|
||||||
AfterTwice,
|
AfterTwice,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl AddBlankLine {
|
||||||
|
fn has_before(&self) -> bool {
|
||||||
|
matches!(self, AddBlankLine::Before | AddBlankLine::BeforeTwice | AddBlankLine::Around)
|
||||||
|
}
|
||||||
|
fn has_after(&self) -> bool {
|
||||||
|
matches!(self, AddBlankLine::After | AddBlankLine::AfterTwice | AddBlankLine::Around)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn find_insert_position(
|
fn find_insert_position(
|
||||||
scope: &ImportScope,
|
scope: &ImportScope,
|
||||||
insert_path: ast::Path,
|
insert_path: ast::Path,
|
||||||
|
@ -561,6 +591,21 @@ use std::bar::G;",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn insert_start_indent() {
|
||||||
|
mark::check!(insert_use_indent_after);
|
||||||
|
check_none(
|
||||||
|
"std::bar::AA",
|
||||||
|
r"
|
||||||
|
use std::bar::B;
|
||||||
|
use std::bar::D;",
|
||||||
|
r"
|
||||||
|
use std::bar::AA;
|
||||||
|
use std::bar::B;
|
||||||
|
use std::bar::D;",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn insert_middle() {
|
fn insert_middle() {
|
||||||
check_none(
|
check_none(
|
||||||
|
@ -579,6 +624,24 @@ use std::bar::G;",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn insert_middle_indent() {
|
||||||
|
check_none(
|
||||||
|
"std::bar::EE",
|
||||||
|
r"
|
||||||
|
use std::bar::A;
|
||||||
|
use std::bar::D;
|
||||||
|
use std::bar::F;
|
||||||
|
use std::bar::G;",
|
||||||
|
r"
|
||||||
|
use std::bar::A;
|
||||||
|
use std::bar::D;
|
||||||
|
use std::bar::EE;
|
||||||
|
use std::bar::F;
|
||||||
|
use std::bar::G;",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn insert_end() {
|
fn insert_end() {
|
||||||
check_none(
|
check_none(
|
||||||
|
@ -597,6 +660,25 @@ use std::bar::ZZ;",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn insert_end_indent() {
|
||||||
|
mark::check!(insert_use_indent_before);
|
||||||
|
check_none(
|
||||||
|
"std::bar::ZZ",
|
||||||
|
r"
|
||||||
|
use std::bar::A;
|
||||||
|
use std::bar::D;
|
||||||
|
use std::bar::F;
|
||||||
|
use std::bar::G;",
|
||||||
|
r"
|
||||||
|
use std::bar::A;
|
||||||
|
use std::bar::D;
|
||||||
|
use std::bar::F;
|
||||||
|
use std::bar::G;
|
||||||
|
use std::bar::ZZ;",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn insert_middle_nested() {
|
fn insert_middle_nested() {
|
||||||
check_none(
|
check_none(
|
||||||
|
@ -620,18 +702,18 @@ use std::bar::G;",
|
||||||
check_none(
|
check_none(
|
||||||
"foo::bar::GG",
|
"foo::bar::GG",
|
||||||
r"
|
r"
|
||||||
use std::bar::A;
|
use std::bar::A;
|
||||||
use std::bar::D;
|
use std::bar::D;
|
||||||
|
|
||||||
use foo::bar::F;
|
use foo::bar::F;
|
||||||
use foo::bar::H;",
|
use foo::bar::H;",
|
||||||
r"
|
r"
|
||||||
use std::bar::A;
|
use std::bar::A;
|
||||||
use std::bar::D;
|
use std::bar::D;
|
||||||
|
|
||||||
use foo::bar::F;
|
use foo::bar::F;
|
||||||
use foo::bar::GG;
|
use foo::bar::GG;
|
||||||
use foo::bar::H;",
|
use foo::bar::H;",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -640,22 +722,22 @@ use foo::bar::H;",
|
||||||
check_none(
|
check_none(
|
||||||
"foo::bar::GG",
|
"foo::bar::GG",
|
||||||
r"
|
r"
|
||||||
use foo::bar::A;
|
use foo::bar::A;
|
||||||
use foo::bar::D;
|
use foo::bar::D;
|
||||||
|
|
||||||
use std;
|
use std;
|
||||||
|
|
||||||
use foo::bar::F;
|
use foo::bar::F;
|
||||||
use foo::bar::H;",
|
use foo::bar::H;",
|
||||||
r"
|
r"
|
||||||
use foo::bar::A;
|
use foo::bar::A;
|
||||||
use foo::bar::D;
|
use foo::bar::D;
|
||||||
use foo::bar::GG;
|
use foo::bar::GG;
|
||||||
|
|
||||||
use std;
|
use std;
|
||||||
|
|
||||||
use foo::bar::F;
|
use foo::bar::F;
|
||||||
use foo::bar::H;",
|
use foo::bar::H;",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -664,13 +746,13 @@ use foo::bar::H;",
|
||||||
check_none(
|
check_none(
|
||||||
"std::fmt",
|
"std::fmt",
|
||||||
r"
|
r"
|
||||||
use foo::bar::A;
|
use foo::bar::A;
|
||||||
use foo::bar::D;",
|
use foo::bar::D;",
|
||||||
r"
|
r"
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use foo::bar::A;
|
use foo::bar::A;
|
||||||
use foo::bar::D;",
|
use foo::bar::D;",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -713,6 +795,20 @@ fn main() {}",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn insert_empty_module() {
|
||||||
|
mark::check!(insert_use_no_indent_after);
|
||||||
|
check(
|
||||||
|
"foo::bar",
|
||||||
|
"mod x {}",
|
||||||
|
r"{
|
||||||
|
use foo::bar;
|
||||||
|
}",
|
||||||
|
None,
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn insert_after_inner_attr() {
|
fn insert_after_inner_attr() {
|
||||||
check_full(
|
check_full(
|
||||||
|
@ -991,11 +1087,13 @@ use foo::bar::baz::Qux;",
|
||||||
ra_fixture_before: &str,
|
ra_fixture_before: &str,
|
||||||
ra_fixture_after: &str,
|
ra_fixture_after: &str,
|
||||||
mb: Option<MergeBehaviour>,
|
mb: Option<MergeBehaviour>,
|
||||||
|
module: bool,
|
||||||
) {
|
) {
|
||||||
let file = super::ImportScope::from(
|
let mut syntax = ast::SourceFile::parse(ra_fixture_before).tree().syntax().clone();
|
||||||
ast::SourceFile::parse(ra_fixture_before).tree().syntax().clone(),
|
if module {
|
||||||
)
|
syntax = syntax.descendants().find_map(ast::Module::cast).unwrap().syntax().clone();
|
||||||
.unwrap();
|
}
|
||||||
|
let file = super::ImportScope::from(syntax).unwrap();
|
||||||
let path = ast::SourceFile::parse(&format!("use {};", path))
|
let path = ast::SourceFile::parse(&format!("use {};", path))
|
||||||
.tree()
|
.tree()
|
||||||
.syntax()
|
.syntax()
|
||||||
|
@ -1008,15 +1106,15 @@ use foo::bar::baz::Qux;",
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_full(path: &str, ra_fixture_before: &str, ra_fixture_after: &str) {
|
fn check_full(path: &str, ra_fixture_before: &str, ra_fixture_after: &str) {
|
||||||
check(path, ra_fixture_before, ra_fixture_after, Some(MergeBehaviour::Full))
|
check(path, ra_fixture_before, ra_fixture_after, Some(MergeBehaviour::Full), false)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_last(path: &str, ra_fixture_before: &str, ra_fixture_after: &str) {
|
fn check_last(path: &str, ra_fixture_before: &str, ra_fixture_after: &str) {
|
||||||
check(path, ra_fixture_before, ra_fixture_after, Some(MergeBehaviour::Last))
|
check(path, ra_fixture_before, ra_fixture_after, Some(MergeBehaviour::Last), false)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_none(path: &str, ra_fixture_before: &str, ra_fixture_after: &str) {
|
fn check_none(path: &str, ra_fixture_before: &str, ra_fixture_after: &str) {
|
||||||
check(path, ra_fixture_before, ra_fixture_after, None)
|
check(path, ra_fixture_before, ra_fixture_after, None, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_merge_only_fail(ra_fixture0: &str, ra_fixture1: &str, mb: MergeBehaviour) {
|
fn check_merge_only_fail(ra_fixture0: &str, ra_fixture1: &str, mb: MergeBehaviour) {
|
||||||
|
|
|
@ -43,12 +43,12 @@ macro_rules! assert_eq_text {
|
||||||
let right = $right;
|
let right = $right;
|
||||||
if left != right {
|
if left != right {
|
||||||
if left.trim() == right.trim() {
|
if left.trim() == right.trim() {
|
||||||
eprintln!("Left:\n{:?}\n\nRight:\n{:?}\n\nWhitespace difference\n", left, right);
|
std::eprintln!("Left:\n{:?}\n\nRight:\n{:?}\n\nWhitespace difference\n", left, right);
|
||||||
} else {
|
} else {
|
||||||
let changeset = $crate::__Changeset::new(left, right, "\n");
|
let changeset = $crate::__Changeset::new(left, right, "\n");
|
||||||
eprintln!("Left:\n{}\n\nRight:\n{}\n\nDiff:\n{}\n", left, right, changeset);
|
std::eprintln!("Left:\n{}\n\nRight:\n{}\n\nDiff:\n{}\n", left, right, changeset);
|
||||||
}
|
}
|
||||||
eprintln!($($tt)*);
|
std::eprintln!($($tt)*);
|
||||||
panic!("text differs");
|
panic!("text differs");
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
|
|
Loading…
Reference in a new issue