diff --git a/clang-tools-extra/clangd/SemanticHighlighting.cpp b/clang-tools-extra/clangd/SemanticHighlighting.cpp --- a/clang-tools-extra/clangd/SemanticHighlighting.cpp +++ b/clang-tools-extra/clangd/SemanticHighlighting.cpp @@ -545,7 +545,7 @@ case HighlightingKind::Macro: return "entity.name.function.preprocessor.cpp"; case HighlightingKind::InactiveCode: - return "meta.disabled"; + return "clangd.preprocessor.inactive"; } llvm_unreachable("unhandled HighlightingKind"); } diff --git a/clang-tools-extra/clangd/clients/clangd-vscode/src/semantic-highlighting.ts b/clang-tools-extra/clangd/clients/clangd-vscode/src/semantic-highlighting.ts --- a/clang-tools-extra/clangd/clients/clangd-vscode/src/semantic-highlighting.ts +++ b/clang-tools-extra/clangd/clients/clangd-vscode/src/semantic-highlighting.ts @@ -23,6 +23,8 @@ // with its start position, length and the "lookup table" index of of the // semantic highlighting Text Mate scopes. tokens?: string; + // Whether the line is part of an inactive preprocessor branch. + isInactive?: boolean; } // A SemanticHighlightingToken decoded from the base64 data sent by clangd. @@ -40,6 +42,8 @@ line: number; // All SemanticHighlightingTokens on the line. tokens: SemanticHighlightingToken[]; + // Whether the line is part of an inactive preprocessor branch. + isInactive: boolean; } // Language server push notification providing the semantic highlighting @@ -122,7 +126,10 @@ handleNotification(params: SemanticHighlightingParams) { const lines: SemanticHighlightingLine[] = params.lines.map( - (line) => ({line : line.line, tokens : decodeTokens(line.tokens)})); + (line) => ({ + line: line.line, tokens: decodeTokens(line.tokens), + isInactive: line.isInactive || false + })); this.highlighter.highlight(vscode.Uri.parse(params.textDocument.uri), lines); } @@ -161,6 +168,7 @@ // SemanticHighlightingToken with scopeIndex i should have the decoration at // index i in this list. private decorationTypes: vscode.TextEditorDecorationType[] = []; + private inactiveDecorationIndex: number; // The clangd TextMate scope lookup table. private scopeLookupTable: string[][]; constructor(scopeLookupTable: string[][]) { @@ -180,7 +188,22 @@ // theme is loaded. public initialize(themeRuleMatcher: ThemeRuleMatcher) { this.decorationTypes.forEach((t) => t.dispose()); - this.decorationTypes = this.scopeLookupTable.map((scopes) => { + this.decorationTypes = this.scopeLookupTable.map((scopes, index) => { + if (scopes[0] == "clangd.preprocessor.inactive") { + this.inactiveDecorationIndex = index; + return vscode.window.createTextEditorDecorationType({ + isWholeLine: true, + // FIXME: Avoid hardcoding these colors. + light: { + color: "rgb(100, 100, 100)", + backgroundColor: "rgba(220, 220, 220, 0.3)" + }, + dark: { + color: "rgb(100, 100, 100)", + backgroundColor: "rgba(18, 18, 18, 0.3)" + } + }); + } const options: vscode.DecorationRenderOptions = { // If there exists no rule for this scope the matcher returns an empty // color. That's ok because vscode does not do anything when applying @@ -262,6 +285,11 @@ new vscode.Position(line.line, token.character), new vscode.Position(line.line, token.character + token.length))); }); + if (line.isInactive) { + decorations[this.inactiveDecorationIndex].push(new vscode.Range( + new vscode.Position(line.line, 0), + new vscode.Position(line.line, 0))); + } }); return decorations; } diff --git a/clang-tools-extra/clangd/clients/clangd-vscode/test/semantic-highlighting.test.ts b/clang-tools-extra/clangd/clients/clangd-vscode/test/semantic-highlighting.test.ts --- a/clang-tools-extra/clangd/clients/clangd-vscode/test/semantic-highlighting.test.ts +++ b/clang-tools-extra/clangd/clients/clangd-vscode/test/semantic-highlighting.test.ts @@ -63,7 +63,8 @@ test('Colorizer groups decorations correctly', async () => { const scopeTable = [ [ 'variable' ], [ 'entity.type.function' ], - [ 'entity.type.function.method' ] + [ 'entity.type.function.method' ], + [ 'clangd.preprocessor.inactive' ] ]; // Create the scope source ranges the highlightings should be highlighted // at. Assumes the scopes used are the ones in the "scopeTable" variable. @@ -80,6 +81,12 @@ new vscode.Position(line.line, token.character + token.length))); }); + if (line.isInactive) { + scopeRanges[scopeRanges.length - 1].push(new vscode.Range( + new vscode.Position(line.line, 0), + new vscode.Position(line.line, 0) + )); + } }); return scopeRanges; }; @@ -121,7 +128,8 @@ tokens : [ {character : 1, length : 2, scopeIndex : 1}, {character : 10, length : 2, scopeIndex : 2}, - ] + ], + isInactive: false }, { line : 2, @@ -129,7 +137,8 @@ {character : 3, length : 2, scopeIndex : 1}, {character : 6, length : 2, scopeIndex : 1}, {character : 8, length : 2, scopeIndex : 2}, - ] + ], + isInactive: true }, ]; @@ -144,7 +153,8 @@ line : 1, tokens : [ {character : 2, length : 1, scopeIndex : 0}, - ] + ], + isInactive: false }; highlighter.highlight(fileUri2, [ highlightingsInLine1 ]); assert.deepEqual( diff --git a/clang-tools-extra/clangd/test/semantic-highlighting.test b/clang-tools-extra/clangd/test/semantic-highlighting.test --- a/clang-tools-extra/clangd/test/semantic-highlighting.test +++ b/clang-tools-extra/clangd/test/semantic-highlighting.test @@ -62,7 +62,7 @@ # CHECK-NEXT: "entity.name.function.preprocessor.cpp" # CHECK-NEXT: ], # CHECK-NEXT: [ -# CHECK-NEXT: "meta.disabled" +# CHECK-NEXT: "clangd.preprocessor.inactive" # CHECK-NEXT: ] # CHECK-NEXT: ] # CHECK-NEXT: },