[PATCH] D88489: [clangd] Mark code action as "preferred" if it's the sole quickfix action
This revision was landed with ongoing or failed builds. This revision was automatically updated to reflect the committed changes. Closed by commit rG8392685c2b9f: [clangd] Mark code action as preferred if its the sole quickfix action (authored by sammccall). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D88489/new/ https://reviews.llvm.org/D88489 Files: clang-tools-extra/clangd/ClangdLSPServer.cpp clang-tools-extra/clangd/Diagnostics.cpp clang-tools-extra/clangd/Protocol.cpp clang-tools-extra/clangd/Protocol.h clang-tools-extra/clangd/test/fixits-embed-in-diagnostic.test Index: clang-tools-extra/clangd/test/fixits-embed-in-diagnostic.test === --- clang-tools-extra/clangd/test/fixits-embed-in-diagnostic.test +++ clang-tools-extra/clangd/test/fixits-embed-in-diagnostic.test @@ -28,6 +28,7 @@ # CHECK-NEXT:] # CHECK-NEXT: } # CHECK-NEXT:}, +# CHECK-NEXT:"isPreferred": true, # CHECK-NEXT:"kind": "quickfix", # CHECK-NEXT:"title": "change 'union' to 'struct'" # CHECK-NEXT: } Index: clang-tools-extra/clangd/Protocol.h === --- clang-tools-extra/clangd/Protocol.h +++ clang-tools-extra/clangd/Protocol.h @@ -952,6 +952,13 @@ /// The diagnostics that this code action resolves. llvm::Optional> diagnostics; + /// Marks this as a preferred action. Preferred actions are used by the + /// `auto fix` command and can be targeted by keybindings. + /// A quick fix should be marked preferred if it properly addresses the + /// underlying error. A refactoring should be marked preferred if it is the + /// most reasonable choice of actions to take. + bool isPreferred = false; + /// The workspace edit this code action performs. llvm::Optional edit; Index: clang-tools-extra/clangd/Protocol.cpp === --- clang-tools-extra/clangd/Protocol.cpp +++ clang-tools-extra/clangd/Protocol.cpp @@ -740,6 +740,8 @@ CodeAction["kind"] = *CA.kind; if (CA.diagnostics) CodeAction["diagnostics"] = llvm::json::Array(*CA.diagnostics); + if (CA.isPreferred) +CodeAction["isPreferred"] = true; if (CA.edit) CodeAction["edit"] = *CA.edit; if (CA.command) Index: clang-tools-extra/clangd/Diagnostics.cpp === --- clang-tools-extra/clangd/Diagnostics.cpp +++ clang-tools-extra/clangd/Diagnostics.cpp @@ -411,6 +411,8 @@ Main.codeActions.emplace(); for (const auto : D.Fixes) Main.codeActions->push_back(toCodeAction(Fix, File)); +if (Main.codeActions->size() == 1) + Main.codeActions->front().isPreferred = true; } if (Opts.SendDiagnosticCategory && !D.Category.empty()) Main.category = D.Category; Index: clang-tools-extra/clangd/ClangdLSPServer.cpp === --- clang-tools-extra/clangd/ClangdLSPServer.cpp +++ clang-tools-extra/clangd/ClangdLSPServer.cpp @@ -1007,6 +1007,20 @@ for (const auto : *Tweaks) Actions.push_back(toCodeAction(T, File, Selection)); +// If there's exactly one quick-fix, call it "preferred". +// We never consider refactorings etc as preferred. +CodeAction *OnlyFix = nullptr; +for (auto : Actions) { + if (Action.kind && *Action.kind == CodeAction::QUICKFIX_KIND) { +if (OnlyFix) { + OnlyFix->isPreferred = false; + break; +} +Action.isPreferred = true; +OnlyFix = + } +} + if (SupportsCodeAction) return Reply(llvm::json::Array(Actions)); std::vector Commands; Index: clang-tools-extra/clangd/test/fixits-embed-in-diagnostic.test === --- clang-tools-extra/clangd/test/fixits-embed-in-diagnostic.test +++ clang-tools-extra/clangd/test/fixits-embed-in-diagnostic.test @@ -28,6 +28,7 @@ # CHECK-NEXT:] # CHECK-NEXT: } # CHECK-NEXT:}, +# CHECK-NEXT:"isPreferred": true, # CHECK-NEXT:"kind": "quickfix", # CHECK-NEXT:"title": "change 'union' to 'struct'" # CHECK-NEXT: } Index: clang-tools-extra/clangd/Protocol.h === --- clang-tools-extra/clangd/Protocol.h +++ clang-tools-extra/clangd/Protocol.h @@ -952,6 +952,13 @@ /// The diagnostics that this code action resolves. llvm::Optional> diagnostics; + /// Marks this as a preferred action. Preferred actions are used by the + /// `auto fix` command and can be targeted by keybindings. + /// A quick fix should be marked preferred if it properly addresses the + ///
[PATCH] D88489: [clangd] Mark code action as "preferred" if it's the sole quickfix action
sammccall created this revision. sammccall added a reviewer: usaxena95. Herald added subscribers: cfe-commits, kadircet, arphaman. Herald added a project: clang. sammccall requested review of this revision. Herald added subscribers: MaskRay, ilya-biryukov. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D88489 Files: clang-tools-extra/clangd/ClangdLSPServer.cpp clang-tools-extra/clangd/Diagnostics.cpp clang-tools-extra/clangd/Protocol.cpp clang-tools-extra/clangd/Protocol.h clang-tools-extra/clangd/test/fixits-embed-in-diagnostic.test Index: clang-tools-extra/clangd/test/fixits-embed-in-diagnostic.test === --- clang-tools-extra/clangd/test/fixits-embed-in-diagnostic.test +++ clang-tools-extra/clangd/test/fixits-embed-in-diagnostic.test @@ -28,6 +28,7 @@ # CHECK-NEXT:] # CHECK-NEXT: } # CHECK-NEXT:}, +# CHECK-NEXT:"isPreferred": true, # CHECK-NEXT:"kind": "quickfix", # CHECK-NEXT:"title": "change 'union' to 'struct'" # CHECK-NEXT: } Index: clang-tools-extra/clangd/Protocol.h === --- clang-tools-extra/clangd/Protocol.h +++ clang-tools-extra/clangd/Protocol.h @@ -952,6 +952,13 @@ /// The diagnostics that this code action resolves. llvm::Optional> diagnostics; + /// Marks this as a preferred action. Preferred actions are used by the + /// `auto fix` command and can be targeted by keybindings. + /// A quick fix should be marked preferred if it properly addresses the + /// underlying error. A refactoring should be marked preferred if it is the + /// most reasonable choice of actions to take. + bool isPreferred = false; + /// The workspace edit this code action performs. llvm::Optional edit; Index: clang-tools-extra/clangd/Protocol.cpp === --- clang-tools-extra/clangd/Protocol.cpp +++ clang-tools-extra/clangd/Protocol.cpp @@ -740,6 +740,8 @@ CodeAction["kind"] = *CA.kind; if (CA.diagnostics) CodeAction["diagnostics"] = llvm::json::Array(*CA.diagnostics); + if (CA.isPreferred) +CodeAction["isPreferred"] = true; if (CA.edit) CodeAction["edit"] = *CA.edit; if (CA.command) Index: clang-tools-extra/clangd/Diagnostics.cpp === --- clang-tools-extra/clangd/Diagnostics.cpp +++ clang-tools-extra/clangd/Diagnostics.cpp @@ -411,6 +411,8 @@ Main.codeActions.emplace(); for (const auto : D.Fixes) Main.codeActions->push_back(toCodeAction(Fix, File)); +if (Main.codeActions->size() == 1) + Main.codeActions->front().isPreferred = true; } if (Opts.SendDiagnosticCategory && !D.Category.empty()) Main.category = D.Category; Index: clang-tools-extra/clangd/ClangdLSPServer.cpp === --- clang-tools-extra/clangd/ClangdLSPServer.cpp +++ clang-tools-extra/clangd/ClangdLSPServer.cpp @@ -1009,6 +1009,20 @@ for (const auto : *Tweaks) Actions.push_back(toCodeAction(T, File, Selection)); +// If there's exactly one quick-fix, call it "preferred". +// We never consider refactorings etc as preferred. +CodeAction *OnlyFix = nullptr; +for (auto : Actions) { + if (Action.kind && *Action.kind == CodeAction::QUICKFIX_KIND) { +if (OnlyFix) { + OnlyFix->isPreferred = false; + break; +} +Action.isPreferred = true; +OnlyFix = + } +} + if (SupportsCodeAction) return Reply(llvm::json::Array(Actions)); std::vector Commands; Index: clang-tools-extra/clangd/test/fixits-embed-in-diagnostic.test === --- clang-tools-extra/clangd/test/fixits-embed-in-diagnostic.test +++ clang-tools-extra/clangd/test/fixits-embed-in-diagnostic.test @@ -28,6 +28,7 @@ # CHECK-NEXT:] # CHECK-NEXT: } # CHECK-NEXT:}, +# CHECK-NEXT:"isPreferred": true, # CHECK-NEXT:"kind": "quickfix", # CHECK-NEXT:"title": "change 'union' to 'struct'" # CHECK-NEXT: } Index: clang-tools-extra/clangd/Protocol.h === --- clang-tools-extra/clangd/Protocol.h +++ clang-tools-extra/clangd/Protocol.h @@ -952,6 +952,13 @@ /// The diagnostics that this code action resolves. llvm::Optional> diagnostics; + /// Marks this as a preferred action. Preferred actions are used by the + /// `auto fix` command and can be targeted by keybindings. + /// A quick fix should be marked preferred if it properly addresses the + /// underlying error. A refactoring should be marked preferred if it is the +