Skip to content

Commit 70dbff2

Browse files
committed
fix: ide-assists, gen from impl for enum indent
1 parent 2bafe9d commit 70dbff2

File tree

2 files changed

+85
-3
lines changed

2 files changed

+85
-3
lines changed

crates/ide-assists/src/handlers/generate_from_impl_for_enum.rs

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
use ide_db::{RootDatabase, famous_defs::FamousDefs};
2-
use syntax::ast::{self, AstNode, HasName};
2+
use syntax::ast::{self, AstNode, HasName, edit::AstNodeEdit};
33

4-
use crate::{AssistContext, AssistId, Assists, utils::generate_trait_impl_text_intransitive};
4+
use crate::{
5+
AssistContext, AssistId, Assists,
6+
utils::{generate_trait_impl_text_intransitive, indent_string},
7+
};
58

69
// Assist: generate_from_impl_for_enum
710
//
@@ -71,7 +74,7 @@ pub(crate) fn generate_from_impl_for_enum(
7174
)
7275
};
7376
let from_impl = generate_trait_impl_text_intransitive(&enum_, &from_trait, &impl_code);
74-
edit.insert(start_offset, from_impl);
77+
edit.insert(start_offset, indent_string(&from_impl, enum_.indent_level()));
7578
},
7679
)
7780
}
@@ -295,6 +298,54 @@ impl<'a> From<&'a i32> for Generic<'a> {
295298
Self::One(v)
296299
}
297300
}
301+
"#,
302+
);
303+
}
304+
305+
#[test]
306+
fn test_non_zero_indent() {
307+
check_assist(
308+
generate_from_impl_for_enum,
309+
r#"
310+
//- minicore: from
311+
mod foo {
312+
enum Generic<'a> { $0One(&'a i32) }
313+
}
314+
"#,
315+
r#"
316+
mod foo {
317+
enum Generic<'a> { One(&'a i32) }
318+
319+
impl<'a> From<&'a i32> for Generic<'a> {
320+
fn from(v: &'a i32) -> Self {
321+
Self::One(v)
322+
}
323+
}
324+
}
325+
"#,
326+
);
327+
check_assist(
328+
generate_from_impl_for_enum,
329+
r#"
330+
//- minicore: from
331+
mod foo {
332+
mod bar {
333+
enum Generic<'a> { $0One(&'a i32) }
334+
}
335+
}
336+
"#,
337+
r#"
338+
mod foo {
339+
mod bar {
340+
enum Generic<'a> { One(&'a i32) }
341+
342+
impl<'a> From<&'a i32> for Generic<'a> {
343+
fn from(v: &'a i32) -> Self {
344+
Self::One(v)
345+
}
346+
}
347+
}
348+
}
298349
"#,
299350
);
300351
}

crates/ide-assists/src/utils.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
//! Assorted functions shared by several assists.
22
3+
use std::borrow::Cow;
4+
35
pub(crate) use gen_trait_fn_body::gen_trait_fn_body;
46
use hir::{
57
DisplayTarget, HasAttrs as HirHasAttrs, HirDisplay, InFile, ModuleDef, PathResolution,
@@ -250,6 +252,35 @@ pub fn add_trait_assoc_items_to_impl(
250252
first_item.unwrap()
251253
}
252254

255+
pub(crate) fn indent_string(mut s: &str, indent_level: IndentLevel) -> Cow<'_, str> {
256+
if indent_level.is_zero() || s.is_empty() {
257+
return s.into();
258+
}
259+
let level = indent_level.0 as usize;
260+
261+
let indent = indent_level.to_string();
262+
let mut buf = String::with_capacity(s.len() + level * 3 * 4);
263+
264+
if !s.starts_with('\n') {
265+
buf.push_str(&indent);
266+
}
267+
268+
while let Some((line, rest)) = s.split_once('\n') {
269+
buf.push_str(line);
270+
buf.push('\n');
271+
272+
if !rest.split_once('\n').map_or(rest, |s| s.0).is_empty() {
273+
buf.push_str(&indent);
274+
}
275+
276+
s = rest;
277+
}
278+
279+
buf.push_str(s);
280+
281+
buf.into()
282+
}
283+
253284
pub(crate) fn vis_offset(node: &SyntaxNode) -> TextSize {
254285
node.children_with_tokens()
255286
.find(|it| !matches!(it.kind(), WHITESPACE | COMMENT | ATTR))

0 commit comments

Comments
 (0)