Skip to content

Commit

Permalink
Add replace_let_attrset assist
Browse files Browse the repository at this point in the history
  • Loading branch information
MoritzBoehme committed Mar 4, 2023
1 parent 3487ed4 commit 3098c5c
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 0 deletions.
2 changes: 2 additions & 0 deletions crates/ide/src/ide/assists/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ mod convert_to_inherit;
mod flatten_attrset;
mod pack_bindings;
mod remove_empty_inherit;
mod replace_let_attrset;

use crate::{DefDatabase, FileRange, TextEdit, WorkspaceEdit};
use syntax::ast::{self, AstNode};
Expand Down Expand Up @@ -45,6 +46,7 @@ pub(crate) fn assists(db: &dyn DefDatabase, frange: FileRange) -> Vec<Assist> {
flatten_attrset::flatten_attrset,
pack_bindings::pack_bindings,
remove_empty_inherit::remove_empty_inherit,
replace_let_attrset::replace_let_attrset,
];

let mut ctx = AssistsCtx::new(db, frange);
Expand Down
74 changes: 74 additions & 0 deletions crates/ide/src/ide/assists/replace_let_attrset.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
//! Replace `let {...}` with `let ... in ...`.
//!
//! ```nix
//! let { foo = "bar"; body = foo; }
//! ```
//! =>
//! ```nix
//! let foo = "bar" in foo
//! ```
use super::{AssistKind, AssistsCtx};
use crate::TextEdit;
use syntax::ast::{self, AstNode};

pub(super) fn replace_let_attrset(ctx: &mut AssistsCtx<'_>) -> Option<()> {
let node = ctx.covering_node::<ast::AttrSet>()?;

if node.let_token().is_none() {
return None;
}

let is_body_node = |child: &syntax::SyntaxNode| {
if let Some(tok) = child.first_token() {
tok.text() == "body"
} else {
false
}
};

let body_binding = node.syntax().children().find(is_body_node)?.last_child()?;

let bindings: String = node
.syntax()
.children()
.filter(|child| !is_body_node(child))
.map(|b| b.text().to_string())
.collect::<Vec<String>>()
.join(" ");

ctx.add(
"replace_let_attrset",
"Replace `let {...}` with `let ... in ...`",
AssistKind::QuickFix,
vec![TextEdit {
delete: node.syntax().text_range(),
insert: format!("let {bindings} in {body_binding}").into(),
}],
);

Some(())
}

#[cfg(test)]
mod tests {
use expect_test::expect;

define_check_assist!(super::replace_let_attrset);

#[test]
fn simple() {
check(
r#"let { $0foo = "bar"; body = foo; }"#,
expect![r#"let foo = "bar"; in foo"#],
);
check_no(r#"{ $0foo = "bar"; }"#);
}

#[test]
fn multiple_bindings() {
check(
r#"let { $0foo = "foo"; bar = "bar"; body = foo + bar; }"#,
expect![r#"let foo = "foo"; bar = "bar"; in foo + bar"#],
)
}
}

0 comments on commit 3098c5c

Please sign in to comment.