From 8d82a60f767544070e7dfcd50a9739065e6fac1f Mon Sep 17 00:00:00 2001 From: takeokunn Date: Sat, 14 Feb 2026 17:37:09 +0900 Subject: [PATCH] feat(code-action): mark remove extra with as preferred quickfix - Add DK_ExtraWith to preferred code actions in CodeAction.cpp - Add tests for remove extra with on basic and multiline expressions - Ensure action is not offered when with is actually needed --- nixd/lib/Controller/CodeAction.cpp | 1 + .../nixd/test/code-action/extra-with/basic.md | 78 +++++++++++++++++++ .../test/code-action/extra-with/multiline.md | 77 ++++++++++++++++++ .../code-action/extra-with/needed-with.md | 69 ++++++++++++++++ 4 files changed, 225 insertions(+) create mode 100644 nixd/tools/nixd/test/code-action/extra-with/basic.md create mode 100644 nixd/tools/nixd/test/code-action/extra-with/multiline.md create mode 100644 nixd/tools/nixd/test/code-action/extra-with/needed-with.md diff --git a/nixd/lib/Controller/CodeAction.cpp b/nixd/lib/Controller/CodeAction.cpp index 6e737116f..292b68610 100644 --- a/nixd/lib/Controller/CodeAction.cpp +++ b/nixd/lib/Controller/CodeAction.cpp @@ -51,6 +51,7 @@ void Controller::onCodeAction(const lspserver::CodeActionParams &Params, bool IsPreferred = false; switch (D.kind()) { case nixf::Diagnostic::DK_UnusedDefLet: + case nixf::Diagnostic::DK_ExtraWith: IsPreferred = true; break; default: diff --git a/nixd/tools/nixd/test/code-action/extra-with/basic.md b/nixd/tools/nixd/test/code-action/extra-with/basic.md new file mode 100644 index 000000000..744544801 --- /dev/null +++ b/nixd/tools/nixd/test/code-action/extra-with/basic.md @@ -0,0 +1,78 @@ +# RUN: nixd --lit-test < %s | FileCheck %s + +Test basic `remove extra with` action for unused with expression. + +<-- initialize(0) + +```json +{ + "jsonrpc":"2.0", + "id":0, + "method":"initialize", + "params":{ + "processId":123, + "rootPath":"", + "capabilities":{ + }, + "trace":"off" + } +} +``` + + +<-- textDocument/didOpen + +```nix file:///extra-with.nix +with {}; 1 +``` + +<-- textDocument/codeAction(2) + + +```json +{ + "jsonrpc":"2.0", + "id":2, + "method":"textDocument/codeAction", + "params":{ + "textDocument":{ + "uri":"file:///extra-with.nix" + }, + "range":{ + "start":{ + "line": 0, + "character":0 + }, + "end":{ + "line":0, + "character":4 + } + }, + "context":{ + "diagnostics":[], + "triggerKind":2 + } + } +} +``` + +The action should remove `with {};` leaving just `1`. + +``` + CHECK: "id": 2, + CHECK: "newText": "", + CHECK: "range": + CHECK: "end": + CHECK: "character": 4, + CHECK: "line": 0 + CHECK: "start": + CHECK: "character": 0, + CHECK: "line": 0 + CHECK: "isPreferred": true, + CHECK: "kind": "quickfix", + CHECK: "title": "remove `with` expression" +``` + +```json +{"jsonrpc":"2.0","method":"exit"} +``` diff --git a/nixd/tools/nixd/test/code-action/extra-with/multiline.md b/nixd/tools/nixd/test/code-action/extra-with/multiline.md new file mode 100644 index 000000000..70c08a5be --- /dev/null +++ b/nixd/tools/nixd/test/code-action/extra-with/multiline.md @@ -0,0 +1,77 @@ +# RUN: nixd --lit-test < %s | FileCheck %s + +Test `remove extra with` action with multiline expression. + +<-- initialize(0) + +```json +{ + "jsonrpc":"2.0", + "id":0, + "method":"initialize", + "params":{ + "processId":123, + "rootPath":"", + "capabilities":{ + }, + "trace":"off" + } +} +``` + + +<-- textDocument/didOpen + +```nix file:///multiline-with.nix +with lib; +1 + 2 +``` + +<-- textDocument/codeAction(2) + + +```json +{ + "jsonrpc":"2.0", + "id":2, + "method":"textDocument/codeAction", + "params":{ + "textDocument":{ + "uri":"file:///multiline-with.nix" + }, + "range":{ + "start":{ + "line": 0, + "character":0 + }, + "end":{ + "line":0, + "character":4 + } + }, + "context":{ + "diagnostics":[], + "triggerKind":2 + } + } +} +``` + +The action should remove the `with lib;` part. + +``` + CHECK: "id": 2, + CHECK: "newText": "", + CHECK: "range": + CHECK: "end": + CHECK: "line": 0 + CHECK: "start": + CHECK: "line": 0 + CHECK: "isPreferred": true, + CHECK: "kind": "quickfix", + CHECK: "title": "remove `with` expression" +``` + +```json +{"jsonrpc":"2.0","method":"exit"} +``` diff --git a/nixd/tools/nixd/test/code-action/extra-with/needed-with.md b/nixd/tools/nixd/test/code-action/extra-with/needed-with.md new file mode 100644 index 000000000..cda9b9152 --- /dev/null +++ b/nixd/tools/nixd/test/code-action/extra-with/needed-with.md @@ -0,0 +1,69 @@ +# RUN: nixd --lit-test < %s | FileCheck %s + +Test that `remove extra with` action is NOT offered when with is actually used. + +<-- initialize(0) + +```json +{ + "jsonrpc":"2.0", + "id":0, + "method":"initialize", + "params":{ + "processId":123, + "rootPath":"", + "capabilities":{ + }, + "trace":"off" + } +} +``` + + +<-- textDocument/didOpen + +```nix file:///needed-with.nix +with lib; foo +``` + +<-- textDocument/codeAction(2) + + +```json +{ + "jsonrpc":"2.0", + "id":2, + "method":"textDocument/codeAction", + "params":{ + "textDocument":{ + "uri":"file:///needed-with.nix" + }, + "range":{ + "start":{ + "line": 0, + "character":0 + }, + "end":{ + "line":0, + "character":4 + } + }, + "context":{ + "diagnostics":[], + "triggerKind":2 + } + } +} +``` + +No "remove `with` expression" action should be offered because `foo` is +resolved through the `with lib` scope. + +``` + CHECK: "id": 2, + CHECK-NOT: "remove `with` expression" +``` + +```json +{"jsonrpc":"2.0","method":"exit"} +```