@@ -395,7 +395,7 @@ class ClangdLSPServer::MessageHandler : public Transport::MessageHandler {
395395 Context handlerContext () const {
396396 return Context::current ().derive (
397397 kCurrentOffsetEncoding ,
398- Server.NegotiatedOffsetEncoding .getValueOr (OffsetEncoding::UTF16));
398+ Server.Opts . Encoding .getValueOr (OffsetEncoding::UTF16));
399399 }
400400
401401 // We run cancelable requests in a context that does two things:
@@ -465,43 +465,42 @@ static std::vector<llvm::StringRef> semanticTokenTypes() {
465465void ClangdLSPServer::onInitialize (const InitializeParams &Params,
466466 Callback<llvm::json::Value> Reply) {
467467 // Determine character encoding first as it affects constructed ClangdServer.
468- if (Params.capabilities .offsetEncoding && !NegotiatedOffsetEncoding ) {
469- NegotiatedOffsetEncoding = OffsetEncoding::UTF16; // fallback
468+ if (Params.capabilities .offsetEncoding && !Opts. Encoding ) {
469+ Opts. Encoding = OffsetEncoding::UTF16; // fallback
470470 for (OffsetEncoding Supported : *Params.capabilities .offsetEncoding )
471471 if (Supported != OffsetEncoding::UnsupportedEncoding) {
472- NegotiatedOffsetEncoding = Supported;
472+ Opts. Encoding = Supported;
473473 break ;
474474 }
475475 }
476476
477- ClangdServerOpts .TheiaSemanticHighlighting =
477+ Opts .TheiaSemanticHighlighting =
478478 Params.capabilities .TheiaSemanticHighlighting ;
479479 if (Params.capabilities .TheiaSemanticHighlighting &&
480480 Params.capabilities .SemanticTokens ) {
481481 log (" Client supports legacy semanticHighlights notification and standard "
482482 " semanticTokens request, choosing the latter (no notifications)." );
483- ClangdServerOpts .TheiaSemanticHighlighting = false ;
483+ Opts .TheiaSemanticHighlighting = false ;
484484 }
485485
486486 if (Params.rootUri && *Params.rootUri )
487- ClangdServerOpts .WorkspaceRoot = std::string (Params.rootUri ->file ());
487+ Opts .WorkspaceRoot = std::string (Params.rootUri ->file ());
488488 else if (Params.rootPath && !Params.rootPath ->empty ())
489- ClangdServerOpts .WorkspaceRoot = *Params.rootPath ;
489+ Opts .WorkspaceRoot = *Params.rootPath ;
490490 if (Server)
491491 return Reply (llvm::make_error<LSPError>(" server already initialized" ,
492492 ErrorCode::InvalidRequest));
493493 if (const auto &Dir = Params.initializationOptions .compilationDatabasePath )
494- CompileCommandsDir = Dir;
495- if (UseDirBasedCDB) {
494+ Opts. CompileCommandsDir = Dir;
495+ if (Opts. UseDirBasedCDB ) {
496496 BaseCDB = std::make_unique<DirectoryBasedGlobalCompilationDatabase>(
497- CompileCommandsDir);
498- BaseCDB = getQueryDriverDatabase (
499- llvm::makeArrayRef (ClangdServerOpts.QueryDriverGlobs ),
500- std::move (BaseCDB));
497+ Opts.CompileCommandsDir );
498+ BaseCDB = getQueryDriverDatabase (llvm::makeArrayRef (Opts.QueryDriverGlobs ),
499+ std::move (BaseCDB));
501500 }
502501 auto Mangler = CommandMangler::detect ();
503- if (ClangdServerOpts .ResourceDir )
504- Mangler.ResourceDir = *ClangdServerOpts .ResourceDir ;
502+ if (Opts .ResourceDir )
503+ Mangler.ResourceDir = *Opts .ResourceDir ;
505504 CDB.emplace (BaseCDB.get (), Params.initializationOptions .fallbackFlags ,
506505 tooling::ArgumentsAdjuster (std::move (Mangler)));
507506 {
@@ -510,19 +509,18 @@ void ClangdLSPServer::onInitialize(const InitializeParams &Params,
510509 // Server, CDB, etc.
511510 WithContext MainContext (BackgroundContext.clone ());
512511 llvm::Optional<WithContextValue> WithOffsetEncoding;
513- if (NegotiatedOffsetEncoding)
514- WithOffsetEncoding.emplace (kCurrentOffsetEncoding ,
515- *NegotiatedOffsetEncoding);
516- Server.emplace (*CDB, TFS, ClangdServerOpts,
512+ if (Opts.Encoding )
513+ WithOffsetEncoding.emplace (kCurrentOffsetEncoding , *Opts.Encoding );
514+ Server.emplace (*CDB, TFS, Opts,
517515 static_cast <ClangdServer::Callbacks *>(this ));
518516 }
519517 applyConfiguration (Params.initializationOptions .ConfigSettings );
520518
521- CCOpts .EnableSnippets = Params.capabilities .CompletionSnippets ;
522- CCOpts .IncludeFixIts = Params.capabilities .CompletionFixes ;
523- if (!CCOpts .BundleOverloads .hasValue ())
524- CCOpts .BundleOverloads = Params.capabilities .HasSignatureHelp ;
525- CCOpts .DocumentationFormat =
519+ Opts. CodeComplete .EnableSnippets = Params.capabilities .CompletionSnippets ;
520+ Opts. CodeComplete .IncludeFixIts = Params.capabilities .CompletionFixes ;
521+ if (!Opts. CodeComplete .BundleOverloads .hasValue ())
522+ Opts. CodeComplete .BundleOverloads = Params.capabilities .HasSignatureHelp ;
523+ Opts. CodeComplete .DocumentationFormat =
526524 Params.capabilities .CompletionDocumentationFormat ;
527525 DiagOpts.EmbedFixesInDiagnostics = Params.capabilities .DiagnosticFixes ;
528526 DiagOpts.SendDiagnosticCategory = Params.capabilities .DiagnosticCategory ;
@@ -622,14 +620,14 @@ void ClangdLSPServer::onInitialize(const InitializeParams &Params,
622620 }},
623621 {" typeHierarchyProvider" , true },
624622 }}}};
625- if (NegotiatedOffsetEncoding )
626- Result[" offsetEncoding" ] = *NegotiatedOffsetEncoding ;
627- if (ClangdServerOpts .TheiaSemanticHighlighting )
623+ if (Opts. Encoding )
624+ Result[" offsetEncoding" ] = *Opts. Encoding ;
625+ if (Opts .TheiaSemanticHighlighting )
628626 Result.getObject (" capabilities" )
629627 ->insert (
630628 {" semanticHighlighting" ,
631629 llvm::json::Object{{" scopes" , buildHighlightScopeLookupTable ()}}});
632- if (ClangdServerOpts .FoldingRanges )
630+ if (Opts .FoldingRanges )
633631 Result.getObject (" capabilities" )->insert ({" foldingRangeProvider" , true });
634632 Reply (std::move (Result));
635633}
@@ -788,7 +786,7 @@ void ClangdLSPServer::onWorkspaceSymbol(
788786 const WorkspaceSymbolParams &Params,
789787 Callback<std::vector<SymbolInformation>> Reply) {
790788 Server->workspaceSymbols (
791- Params.query , CCOpts .Limit ,
789+ Params.query , Opts. CodeComplete .Limit ,
792790 [Reply = std::move (Reply),
793791 this ](llvm::Expected<std::vector<SymbolInformation>> Items) mutable {
794792 if (!Items)
@@ -803,7 +801,7 @@ void ClangdLSPServer::onWorkspaceSymbol(
803801void ClangdLSPServer::onPrepareRename (const TextDocumentPositionParams &Params,
804802 Callback<llvm::Optional<Range>> Reply) {
805803 Server->prepareRename (Params.textDocument .uri .file (), Params.position ,
806- RenameOpts , std::move (Reply));
804+ Opts. Rename , std::move (Reply));
807805}
808806
809807void ClangdLSPServer::onRename (const RenameParams &Params,
@@ -813,7 +811,7 @@ void ClangdLSPServer::onRename(const RenameParams &Params,
813811 return Reply (llvm::make_error<LSPError>(
814812 " onRename called for non-added file" , ErrorCode::InvalidParams));
815813 Server->rename (
816- File, Params.position , Params.newName , RenameOpts ,
814+ File, Params.position , Params.newName , Opts. Rename ,
817815 [File, Params, Reply = std::move (Reply),
818816 this ](llvm::Expected<FileEdits> Edits) mutable {
819817 if (!Edits)
@@ -1009,6 +1007,20 @@ void ClangdLSPServer::onCodeAction(const CodeActionParams &Params,
10091007 for (const auto &T : *Tweaks)
10101008 Actions.push_back (toCodeAction (T, File, Selection));
10111009
1010+ // If there's exactly one quick-fix, call it "preferred".
1011+ // We never consider refactorings etc as preferred.
1012+ CodeAction *OnlyFix = nullptr ;
1013+ for (auto &Action : Actions) {
1014+ if (Action.kind && *Action.kind == CodeAction::QUICKFIX_KIND) {
1015+ if (OnlyFix) {
1016+ OnlyFix->isPreferred = false ;
1017+ break ;
1018+ }
1019+ Action.isPreferred = true ;
1020+ OnlyFix = &Action;
1021+ }
1022+ }
1023+
10121024 if (SupportsCodeAction)
10131025 return Reply (llvm::json::Array (Actions));
10141026 std::vector<Command> Commands;
@@ -1030,15 +1042,16 @@ void ClangdLSPServer::onCompletion(const CompletionParams &Params,
10301042 vlog (" ignored auto-triggered completion, preceding char did not match" );
10311043 return Reply (CompletionList ());
10321044 }
1033- Server->codeComplete (Params.textDocument .uri .file (), Params.position , CCOpts,
1045+ Server->codeComplete (Params.textDocument .uri .file (), Params.position ,
1046+ Opts.CodeComplete ,
10341047 [Reply = std::move (Reply),
10351048 this ](llvm::Expected<CodeCompleteResult> List) mutable {
10361049 if (!List)
10371050 return Reply (List.takeError ());
10381051 CompletionList LSPList;
10391052 LSPList.isIncomplete = List->HasMore ;
10401053 for (const auto &R : List->Completions ) {
1041- CompletionItem C = R.render (CCOpts );
1054+ CompletionItem C = R.render (Opts. CodeComplete );
10421055 C.kind = adjustKindToCapability (
10431056 C.kind , SupportedCompletionItemKinds);
10441057 LSPList.items .push_back (std::move (C));
@@ -1224,7 +1237,7 @@ void ClangdLSPServer::onChangeConfiguration(
12241237void ClangdLSPServer::onReference (const ReferenceParams &Params,
12251238 Callback<std::vector<Location>> Reply) {
12261239 Server->findReferences (Params.textDocument .uri .file (), Params.position ,
1227- CCOpts .Limit ,
1240+ Opts. CodeComplete .Limit ,
12281241 [Reply = std::move (Reply)](
12291242 llvm::Expected<ReferencesResult> Refs) mutable {
12301243 if (!Refs)
@@ -1340,20 +1353,13 @@ void ClangdLSPServer::onSemanticTokensDelta(
13401353 });
13411354}
13421355
1343- ClangdLSPServer::ClangdLSPServer (
1344- class Transport &Transp, const ThreadsafeFS &TFS,
1345- const clangd::CodeCompleteOptions &CCOpts,
1346- const clangd::RenameOptions &RenameOpts,
1347- llvm::Optional<Path> CompileCommandsDir, bool UseDirBasedCDB,
1348- llvm::Optional<OffsetEncoding> ForcedOffsetEncoding,
1349- const ClangdServer::Options &Opts)
1356+ ClangdLSPServer::ClangdLSPServer (class Transport &Transp,
1357+ const ThreadsafeFS &TFS,
1358+ const ClangdLSPServer::Options &Opts)
13501359 : BackgroundContext(Context::current().clone()), Transp(Transp),
1351- MsgHandler (new MessageHandler(*this )), TFS(TFS), CCOpts(CCOpts),
1352- RenameOpts(RenameOpts), SupportedSymbolKinds(defaultSymbolKinds()),
1353- SupportedCompletionItemKinds(defaultCompletionItemKinds()),
1354- UseDirBasedCDB(UseDirBasedCDB),
1355- CompileCommandsDir(std::move(CompileCommandsDir)), ClangdServerOpts(Opts),
1356- NegotiatedOffsetEncoding(ForcedOffsetEncoding) {
1360+ MsgHandler (new MessageHandler(*this )), TFS(TFS),
1361+ SupportedSymbolKinds(defaultSymbolKinds()),
1362+ SupportedCompletionItemKinds(defaultCompletionItemKinds()), Opts(Opts) {
13571363 // clang-format off
13581364 MsgHandler->bind (" initialize" , &ClangdLSPServer::onInitialize);
13591365 MsgHandler->bind (" initialized" , &ClangdLSPServer::onInitialized);
0 commit comments