Index: clangd/ClangdLSPServer.cpp =================================================================== --- clangd/ClangdLSPServer.cpp +++ clangd/ClangdLSPServer.cpp @@ -149,9 +149,13 @@ if (Params.contentChanges.size() != 1) return replyError(ErrorCode::InvalidParams, "can only apply one change at a time"); + auto WantDiags = WantDiagnostics::Auto; + if (Params.wantDiagnostics.hasValue()) + WantDiags = Params.wantDiagnostics.getValue() ? WantDiagnostics::Yes + : WantDiagnostics::No; // We only support full syncing right now. Server.addDocument(Params.textDocument.uri.file(), - Params.contentChanges[0].text, WantDiagnostics::Auto); + Params.contentChanges[0].text, WantDiags); } void ClangdLSPServer::onFileEvent(DidChangeWatchedFilesParams &Params) { Index: clangd/Protocol.h =================================================================== --- clangd/Protocol.h +++ clangd/Protocol.h @@ -297,6 +297,15 @@ /// The actual content changes. std::vector contentChanges; + + /// If this is not set, diagnostics will be generated for the current version + /// or a subsequent one. + /// If this is set to true, dianostics are guaranteed to be generated for the + /// current version. + /// If this is set to false, dianostics will not be generated for this + /// request. + /// This is a clangd extension. + llvm::Optional wantDiagnostics; }; bool fromJSON(const json::Expr &, DidChangeTextDocumentParams &); Index: clangd/Protocol.cpp =================================================================== --- clangd/Protocol.cpp +++ clangd/Protocol.cpp @@ -221,7 +221,8 @@ bool fromJSON(const json::Expr &Params, DidChangeTextDocumentParams &R) { json::ObjectMapper O(Params); return O && O.map("textDocument", R.textDocument) && - O.map("contentChanges", R.contentChanges); + O.map("contentChanges", R.contentChanges) && + O.map("wantDiagnostics", R.wantDiagnostics); } bool fromJSON(const json::Expr &E, FileChangeType &Out) { Index: test/clangd/want-diagnostics.test =================================================================== --- /dev/null +++ test/clangd/want-diagnostics.test @@ -0,0 +1,19 @@ +# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s +{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}} +--- +{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///main.cpp","languageId":"cpp","version":1,"text":"void main() {}"}}} +# CHECK: "method": "textDocument/publishDiagnostics", +--- +{"jsonrpc":"2.0","method":"textDocument/didChange","params":{"textDocument":{"uri":"test:///main.cpp","version":2},"contentChanges":[{"text":"void main() {}"}]}} +--- +# CHECK: "method": "textDocument/publishDiagnostics", +{"jsonrpc":"2.0","method":"textDocument/didChange","params":{"textDocument":{"uri":"test:///main.cpp","version":3},"contentChanges":[{"text":"void main() {}"}],"wantDiagnostics":true}} +--- +# CHECK: "method": "textDocument/publishDiagnostics", +{"jsonrpc":"2.0","method":"textDocument/didChange","params":{"textDocument":{"uri":"test:///main.cpp","version":4},"contentChanges":[{"text":"void main() {}"}],"wantDiagnostics":false}} +--- +# CHECK-NOT: "method": "textDocument/publishDiagnostics", +{"jsonrpc":"2.0","id":2,"method":"shutdown"} +# CHECK: "method": "textDocument/publishDiagnostics", +--- +{"jsonrpc":"2.0","method":"exit"}