Skip to content

Commit

Permalink
Add add_to_top_level_lambda_param assist
Browse files Browse the repository at this point in the history
  • Loading branch information
figsoda authored and oxalica committed Dec 5, 2022
1 parent cbc6298 commit 101387f
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 0 deletions.
91 changes: 91 additions & 0 deletions crates/ide/src/ide/assists/add_to_top_level_lambda_param.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
//! Add an undefined name to the top-level lambda.
//!
//! ```nix
//! { foo }: foo + bar
//! ```
//! =>
//! ```nix
//! { foo, bar }: foo + bar
//! ```
use super::{AssistKind, AssistsCtx};
use crate::TextEdit;
use syntax::ast::{self, AstNode};
use syntax::{SyntaxNodePtr, TextRange, TextSize};

pub(super) fn add_to_top_level_lambda_param(ctx: &mut AssistsCtx<'_>) -> Option<()> {
let node = ctx.covering_node::<ast::Ref>()?;
let name = node.token()?;
let name = name.text();

// The whole file should be a lambda.
let pat = ast::Lambda::cast(ctx.ast.syntax().first_child()?)?
.param()?
.pat()?;

// Name should be undefined.
let expr = ctx
.db
.source_map(ctx.frange.file_id)
.expr_for_node(SyntaxNodePtr::new(node.syntax()))?;
if ctx
.db
.name_resolution(ctx.frange.file_id)
.get(expr)
.is_some()
{
return None;
};

let (pos, insert) = if let Some(field) = pat.fields().last() {
let field = field.syntax();
let mut pos = field.text_range().end();
// Insert before the space if the field ends with a space.
if matches!(field.last_token(), Some(tok) if tok.text().ends_with(' ')) {
pos -= TextSize::from(1);
}
(pos, format!(", {name}"))
} else if let Some(ellipsis) = pat.ellipsis_token() {
(ellipsis.text_range().start(), format!("{name}, "))
} else if let Some(curly) = pat.r_curly_token() {
(curly.text_range().start(), format!("{name} "))
} else {
(pat.syntax().text_range().start(), name.into())
};

ctx.add(
"add_to_top_level_lambda_param",
format!("Add `{name}` to the top-level lambda parameter"),
AssistKind::QuickFix,
vec![TextEdit {
delete: TextRange::new(pos, pos),
insert: insert.into(),
}],
);

Some(())
}

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

define_check_assist!(super::add_to_top_level_lambda_param);

#[test]
fn simple() {
check("{ }: foo$0", expect!["{ foo }: foo"]);
check("{}: foo$0", expect!["{foo }: foo"]);
check("{ foo }: b$0ar", expect!["{ foo, bar }: bar"]);
check("{foo}: $0bar", expect!["{foo, bar}: bar"]);
check("{ ... }: foo$0", expect!["{ foo, ... }: foo"]);
check("{...}: foo$0", expect!["{foo, ...}: foo"]);
check("{foo, ...}: $0bar", expect!["{foo, bar, ...}: bar"]);
check("{foo,...}: $0bar", expect!["{foo, bar,...}: bar"]);

check_no("{ foo }: fo$0o");
check_no("{ }: foo.$0bar");
check_no("{ }: let foo = bar; in f$0oo");
check_no("{ bar }: { fo$0o = bar; }");
check_no("bar: fo$0o");
}
}
3 changes: 3 additions & 0 deletions crates/ide/src/ide/assists/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ macro_rules! define_check_assist {
};
}

mod add_to_top_level_lambda_param;
mod convert_to_inherit;
mod flatten_attrset;
mod pack_bindings;
Expand All @@ -30,11 +31,13 @@ pub struct Assist {

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum AssistKind {
QuickFix,
RefactorRewrite,
}

pub(crate) fn assists(db: &dyn DefDatabase, frange: FileRange) -> Vec<Assist> {
let handlers = [
add_to_top_level_lambda_param::add_to_top_level_lambda_param,
convert_to_inherit::convert_to_inherit,
flatten_attrset::flatten_attrset,
pack_bindings::pack_bindings,
Expand Down
1 change: 1 addition & 0 deletions crates/nil/src/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,7 @@ pub(crate) fn to_code_action(vfs: &Vfs, assist: Assist) -> CodeActionOrCommand {
CodeActionOrCommand::CodeAction(CodeAction {
title: assist.label,
kind: Some(match assist.kind {
AssistKind::QuickFix => CodeActionKind::QUICKFIX,
AssistKind::RefactorRewrite => CodeActionKind::REFACTOR_REWRITE,
}),
diagnostics: None,
Expand Down

0 comments on commit 101387f

Please sign in to comment.