Index: clang-tools-extra/clangd/ClangdLSPServer.h =================================================================== --- clang-tools-extra/clangd/ClangdLSPServer.h +++ clang-tools-extra/clangd/ClangdLSPServer.h @@ -61,6 +61,10 @@ std::function TweakFilter = [](const Tweak &T) { return !T.hidden(); // only enable non-hidden tweaks. }; + /// If set, include files in #include directives are exposed to the clients + /// as documentLinks. If disabled include files can still be opened with the + /// go to definition feature. + bool IncludesAsLinks = true; }; ClangdLSPServer(Transport &Transp, const ThreadsafeFS &TFS, Index: clang-tools-extra/clangd/ClangdLSPServer.cpp =================================================================== --- clang-tools-extra/clangd/ClangdLSPServer.cpp +++ clang-tools-extra/clangd/ClangdLSPServer.cpp @@ -610,10 +610,6 @@ {"definitionProvider", true}, {"implementationProvider", true}, {"documentHighlightProvider", true}, - {"documentLinkProvider", - llvm::json::Object{ - {"resolveProvider", false}, - }}, {"hoverProvider", true}, {"renameProvider", std::move(RenameProvider)}, {"selectionRangeProvider", true}, @@ -640,6 +636,12 @@ llvm::json::Object{{"scopes", buildHighlightScopeLookupTable()}}}); if (Opts.FoldingRanges) Result.getObject("capabilities")->insert({"foldingRangeProvider", true}); + if (Opts.IncludesAsLinks) + // Currently we only provide documentLink for #included headers. + // If that's turned off, let clients avoid sending the request altogether. + Result.getObject("capabilities") + ->insert({"documentLinkProvider", + llvm::json::Object{{"resolveProvider", false}}}); Reply(std::move(Result)); } Index: clang-tools-extra/clangd/test/document-link.test =================================================================== --- clang-tools-extra/clangd/test/document-link.test +++ clang-tools-extra/clangd/test/document-link.test @@ -37,6 +37,26 @@ # CHECK-NEXT: } # CHECK-NEXT: ] # CHECK-NEXT:} +--- +# Go to definition on include (necessary when documentLinks are disabled) +{"jsonrpc":"2.0","id":1,"method":"textDocument/definition","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":0,"character":15}}} +# CHECK: "id": 1, +# CHECK-NEXT: "jsonrpc": "2.0", +# CHECK-NEXT: "result": [ +# CHECK-NEXT: { +# CHECK-NEXT: "range": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": 0, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": 0, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: } +# CHECK-NEXT: }, +# CHECK-NEXT: "uri": "file://{{.*}}/{{([A-Z]:/)?}}stdint.h" +# CHECK-NEXT: } +# CHECK-NEXT: ] --- {"jsonrpc":"2.0","id":3,"method":"shutdown"} Index: clang-tools-extra/clangd/tool/ClangdMain.cpp =================================================================== --- clang-tools-extra/clangd/tool/ClangdMain.cpp +++ clang-tools-extra/clangd/tool/ClangdMain.cpp @@ -339,6 +339,15 @@ Hidden, }; +opt IncludesAsLinks{ + "includes-as-links", + cat(Features), + desc("Provide a document link to the files included with #include " + "directive. If set to false, include files can still be opened with " + "go to definition feature"), + init(true), +}; + opt WorkerThreadsCount{ "j", cat(Misc), @@ -825,6 +834,7 @@ Opts.PreserveRecoveryASTType = RecoveryASTType; Opts.FoldingRanges = FoldingRanges; Opts.MemoryCleanup = getMemoryCleanupFunction(); + Opts.IncludesAsLinks = IncludesAsLinks; Opts.CodeComplete.IncludeIneligibleResults = IncludeIneligibleResults; Opts.CodeComplete.Limit = LimitResults;