diff --git a/Documentation/LanguageServer/colorization.md b/Documentation/LanguageServer/colorization.md index 58e919a96..1bc95ff2c 100644 --- a/Documentation/LanguageServer/colorization.md +++ b/Documentation/LanguageServer/colorization.md @@ -1,7 +1,7 @@ # VS Code C/C++ Extension - Enhanced Colorization -The VS Code C/C++ extension now supports lexical/syntactic and semantic colorization, when IntelliSense is enabled. Enhanced colorization can be enabled using the enhancedColorization setting: +The VS Code C/C++ extension now supports semantic colorization, when IntelliSense is enabled. Enhanced colorization can be enabled using the enhancedColorization setting: ``` "C_Cpp.enhancedColorization": "Enabled" @@ -20,7 +20,6 @@ Colors are associated with [TextMate scopes](https://macromates.com/manual/en/la | Token | Scope | | ------------- |:-------------:| | Class Template | entity.name.class.template | -| Comment | comment | | Enumerator | variable.other.enummember | | Event (C++/CLI) | variable.other.event | | Function | entity.name.function | @@ -28,33 +27,25 @@ Colors are associated with [TextMate scopes](https://macromates.com/manual/en/la | Generic Type (C++/CLI) | entity.name.class.generic | | Global Variable | variable.other.global | | Identifier | entity.name | -| Keyword | keyword.control | | Label | entity.name.label | | Local Variable | variable.other.local | | Macro | entity.name.function.preprocessor | | Member Field | variable.other.member | | Member Function | entity.name.function.member | | Member Operator | keyword.operator.member | -| Namespace | entity.name.namespace | +| Namespace | entity.name.type.namespace | | New / Delete | keyword.operator.new | -| Number Literal | constant.numeric | -| Operator | keyword.operator | | Operator Function | entity.name.function.operator | | Parameter | variable.parameter | -| Preprocessor Keyword | keyword.control.directive | | Property (C++/CLI) | variable.other.property | | Reference Type (C++/CLI) | entity.name.class.reference | | Static Member Field | variable.other.member.static | | Static Member Function | entity.name.function.member.static | -| String Literal | string.quoted | | Type | entity.name.type | -| User-Defined Literal – Number | entity.name.user-defined-literal.number | +| User-Defined Literal - Number | entity.name.user-defined-literal.number | | User-Defined Literal - Raw | entity.name.user-defined-literal | | User-Defined Literal - String | entity.name.user-defined-literal.string | | Value Type (C++/CLI) | entity.name.class.value | -| Variable | variable | -| Xml Doc Comment | comment.xml.doc | -| Xml Doc Tag | comment.xml.doc.tag | Many of the tokens recognized by IntelliSense do not directly map to existing scopes in the VS Code's default C/C++ TextMate grammar, so are likely not colored by existing VS Code themes. @@ -259,7 +250,7 @@ Use the following to augment the Visual Studio Dark theme to match what Visual S } }, { - "scope": "entity.name.namespace", + "scope": "entity.name.type.namespace", "settings": { "foreground": "#C8C8C8" } @@ -480,7 +471,7 @@ Use the following to augment the Visual Studio Light theme to match what Visual } }, { - "scope": "entity.name.namespace", + "scope": "entity.name.type.namespace", "settings": { "foreground": "#000000" } diff --git a/Extension/CHANGELOG.md b/Extension/CHANGELOG.md index 445384e52..875cc479a 100644 --- a/Extension/CHANGELOG.md +++ b/Extension/CHANGELOG.md @@ -1,8 +1,21 @@ # C/C++ for Visual Studio Code Change Log +## Version 0.24.0-insiders2: June 25, 2019 +### Minor Changes +* Change `C_Cpp.clang_format_path` to `machine` scope. [#3774](https://github.com/microsoft/vscode-cpptools/issues/3774) +* Removed syntactic/lexical colorization from `enhancedColorization`. [PR #3821](https://github.com/microsoft/vscode-cpptools/pull/3821) + +### Bug Fixes +* Fix crash when tag parsing Objective-C code. [#3776](https://github.com/microsoft/vscode-cpptools/issues/3776) +* Fix duplicate slashes getting added to `c_cpp_properties.json`. [PR #3778](https://github.com/microsoft/vscode-cpptools/pull/3778) +* Fix incorrect "file already opened in editor" message on Linux/Mac. [#3786](https://github.com/microsoft/vscode-cpptools/issues/3786) +* Fix colorization for themes with background colors equal to the editor background color. [#3780](https://github.com/microsoft/vscode-cpptools/issues/3780) +* Improve performance of colorization. [#3781](https://github.com/microsoft/vscode-cpptools/issues/3781) +* Fix regression crash on hover. [#3792](https://github.com/microsoft/vscode-cpptools/issues/3792) + ## Version 0.24.0-insiders: June 14, 2019 ### New Features -* Syntactic/lexical and semantic colorization [PR #3651](https://github.com/microsoft/vscode-cpptools/pull/3651) [Documentation](https://github.com/microsoft/vscode-cpptools/blob/master/Documentation/LanguageServer/colorization.md) +* Semantic colorization [Documentation](https://github.com/microsoft/vscode-cpptools/blob/master/Documentation/LanguageServer/colorization.md) [#230](https://github.com/microsoft/vscode-cpptools/issues/230) * Add `Rescan Workspace` command. [microsoft/vscode-cpptools-api#11](https://github.com/microsoft/vscode-cpptools-api/issues/11) ### Minor Changes diff --git a/Extension/package.json b/Extension/package.json index 6f34e3b90..cc3a4c512 100644 --- a/Extension/package.json +++ b/Extension/package.json @@ -146,7 +146,7 @@ "C_Cpp.dimInactiveRegions": { "type": "boolean", "default": true, - "description": "Controls whether inactive preprocessor blocks are colored differently than active code. This setting is ignored by the Tag Parser engine.", + "description": "Controls whether inactive preprocessor blocks are colored differently than active code. This setting has no effect if IntelliSense is disabled or if using the Default High Contrast theme.", "scope": "resource" }, "C_Cpp.inactiveRegionOpacity": { @@ -504,7 +504,7 @@ "Disabled" ], "default": "Disabled", - "description": "If enabled, code is colorized based on IntelliSense. This setting has no effect if IntelliSense is disabled.", + "description": "If enabled, code is colorized based on IntelliSense. This setting has no effect if IntelliSense is disabled or if using the Default High Contrast theme.", "scope": "resource" } } diff --git a/Extension/src/LanguageServer/client.ts b/Extension/src/LanguageServer/client.ts index 5b1cb6bc0..1ef86e03c 100644 --- a/Extension/src/LanguageServer/client.ts +++ b/Extension/src/LanguageServer/client.ts @@ -82,12 +82,6 @@ interface OutputNotificationBody { output: string; } -interface SyntacticColorizationRegionsParams { - uri: string; - regions: InputColorizationRegion[]; - editVersion: number; -} - interface SemanticColorizationRegionsParams { uri: string; regions: InputColorizationRegion[]; @@ -159,12 +153,12 @@ interface DidChangeVisibleRangesParams { ranges: Range[]; } -interface SyntacticColorizationRegionsReceiptParams { +interface SemanticColorizationRegionsReceiptParams { uri: string; } -interface SemanticColorizationRegionsReceiptParams { - uri: string; +interface ColorThemeChangedParams { + name: string; } // Requests @@ -193,8 +187,8 @@ const CustomBrowseConfigurationNotification: NotificationType = new NotificationType('cpptools/clearCustomConfigurations'); const RescanFolderNotification: NotificationType = new NotificationType('cpptools/rescanFolder'); const DidChangeVisibleRangesNotification: NotificationType = new NotificationType('cpptools/didChangeVisibleRanges'); -const SyntacticColorizationRegionsReceiptNotification: NotificationType = new NotificationType('cpptools/syntacticColorizationRegionsReceipt'); const SemanticColorizationRegionsReceiptNotification: NotificationType = new NotificationType('cpptools/semanticColorizationRegionsReceipt'); +const ColorThemeChangedNotification: NotificationType = new NotificationType('cpptools/colorThemeChanged'); // Notifications from the server const ReloadWindowNotification: NotificationType = new NotificationType('cpptools/reloadWindow'); @@ -204,7 +198,6 @@ const ReportTagParseStatusNotification: NotificationType = new NotificationType('cpptools/reportStatus'); const DebugProtocolNotification: NotificationType = new NotificationType('cpptools/debugProtocol'); const DebugLogNotification: NotificationType = new NotificationType('cpptools/debugLog'); -const SyntacticColorizationRegionsNotification: NotificationType = new NotificationType('cpptools/syntacticColorizationRegions'); const SemanticColorizationRegionsNotification: NotificationType = new NotificationType('cpptools/semanticColorizationRegions'); const CompileCommandsPathsNotification: NotificationType = new NotificationType('cpptools/compileCommandsPaths'); const UpdateClangFormatPathNotification: NotificationType = new NotificationType('cpptools/updateClangFormatPath'); @@ -479,7 +472,6 @@ class DefaultClient implements Client { autocomplete: settings.autoComplete, errorSquiggles: settings.errorSquiggles, dimInactiveRegions: settings.dimInactiveRegions, - textMateColorization: settings.textMateColorization, enhancedColorization: settings.enhancedColorization, suggestSnippets: settings.suggestSnippets, loggingLevel: settings.loggingLevel, @@ -528,9 +520,6 @@ class DefaultClient implements Client { } public onDidChangeSettings(event: vscode.ConfigurationChangeEvent): { [key: string] : string } { - if (event.affectsConfiguration("C_Cpp.textMateColorization", this.RootUri)) { - this.colorizationSettings.updateGrammars(); - } let colorizationNeedsReload: boolean = event.affectsConfiguration("workbench.colorTheme") || event.affectsConfiguration("editor.tokenColorCustomizations"); @@ -541,6 +530,12 @@ class DefaultClient implements Client { || event.affectsConfiguration("C_Cpp.inactiveRegionForegroundColor", this.RootUri) || event.affectsConfiguration("C_Cpp.inactiveRegionBackgroundColor", this.RootUri); + let colorThemeChanged: boolean = event.affectsConfiguration("workbench.colorTheme", this.RootUri); + if (colorThemeChanged) { + let otherSettings: OtherSettings = new OtherSettings(this.RootUri); + this.languageClient.sendNotification(ColorThemeChangedNotification, { name: otherSettings.colorTheme } ); + } + if (colorizationNeedsReload) { this.colorizationSettings.reload(); } @@ -1000,7 +995,6 @@ class DefaultClient implements Client { this.languageClient.onNotification(ReportNavigationNotification, (e) => this.navigate(e)); this.languageClient.onNotification(ReportStatusNotification, (e) => this.updateStatus(e)); this.languageClient.onNotification(ReportTagParseStatusNotification, (e) => this.updateTagParseStatus(e)); - this.languageClient.onNotification(SyntacticColorizationRegionsNotification, (e) => this.updateSyntacticColorizationRegions(e)); this.languageClient.onNotification(SemanticColorizationRegionsNotification, (e) => this.updateSemanticColorizationRegions(e)); this.languageClient.onNotification(CompileCommandsPathsNotification, (e) => this.promptCompileCommands(e)); this.setupOutputHandlers(); @@ -1216,21 +1210,6 @@ class DefaultClient implements Client { return colorizationState; } - private updateSyntacticColorizationRegions(params: SyntacticColorizationRegionsParams): void { - // Convert the params to vscode.Range's before passing to colorizationState.updateSyntactic() - let syntacticRanges: vscode.Range[][] = new Array(TokenKind.Count); - for (let i: number = 0; i < TokenKind.Count; i++) { - syntacticRanges[i] = []; - } - params.regions.forEach(element => { - let newRange : vscode.Range = new vscode.Range(element.range.start.line, element.range.start.character, element.range.end.line, element.range.end.character); - syntacticRanges[element.kind].push(newRange); - }); - let colorizationState: ColorizationState = this.getColorizationState(params.uri); - colorizationState.updateSyntactic(params.uri, syntacticRanges, params.editVersion); - this.languageClient.sendNotification(SyntacticColorizationRegionsReceiptNotification, { uri: params.uri }); - } - private updateSemanticColorizationRegions(params: SemanticColorizationRegionsParams): void { // Convert the params to vscode.Range's before passing to colorizationState.updateSemantic() let semanticRanges: vscode.Range[][] = new Array(TokenKind.Count); diff --git a/Extension/src/LanguageServer/colorization.ts b/Extension/src/LanguageServer/colorization.ts index f879df27f..4009838b4 100644 --- a/Extension/src/LanguageServer/colorization.ts +++ b/Extension/src/LanguageServer/colorization.ts @@ -7,25 +7,13 @@ import * as path from 'path'; import * as vscode from 'vscode'; import * as util from '../common'; -import { CppSettings, OtherSettings, TextMateRule, TextMateRuleSettings, TextMateContributesGrammar } from './settings'; +import { CppSettings, OtherSettings, TextMateRule, TextMateRuleSettings } from './settings'; import * as jsonc from 'jsonc-parser'; import * as plist from 'plist'; export enum TokenKind { // These need to match the token_kind enum in the server - // Syntactic/Lexical tokens - Identifier, - Comment, - Keyword, - PreprocessorKeyword, - Operator, - Variable, - NumberLiteral, - StringLiteral, - XmlDocComment, - XmlDocTag, - // Semantic tokens Macro, Enumerator, @@ -90,7 +78,6 @@ export class ColorizationSettings { constructor(uri: vscode.Uri) { this.uri = uri; - this.updateGrammars(); this.reload(); } @@ -99,7 +86,7 @@ export class ColorizationSettings { if (textMateRuleSettings.foreground) { baseStyle.foreground = textMateRuleSettings.foreground; } - if (textMateRuleSettings.background && textMateRuleSettings.background !== this.editorBackground) { + if (textMateRuleSettings.background && textMateRuleSettings.background.toUpperCase() !== this.editorBackground.toUpperCase()) { baseStyle.background = textMateRuleSettings.background; } // Any (even empty) string for fontStyle removes inherited value @@ -197,16 +184,6 @@ export class ColorizationSettings { this.themeStyleCppMap[i] = Object.assign({}, defaultStyle); } - this.calculateStyleForToken(TokenKind.Identifier, "entity.name", themeName, textMateRules); - this.calculateStyleForToken(TokenKind.Comment, "comment", themeName, textMateRules); - this.calculateStyleForToken(TokenKind.Keyword, "keyword.control", themeName, textMateRules); - this.calculateStyleForToken(TokenKind.PreprocessorKeyword, "keyword.control.directive", themeName, textMateRules); - this.calculateStyleForToken(TokenKind.Operator, "keyword.operator", themeName, textMateRules); - this.calculateStyleForToken(TokenKind.Variable, "variable", themeName, textMateRules); - this.calculateStyleForToken(TokenKind.NumberLiteral, "constant.numeric", themeName, textMateRules); - this.calculateStyleForToken(TokenKind.StringLiteral, "string.quoted", themeName, textMateRules); - this.calculateStyleForToken(TokenKind.XmlDocComment, "comment.xml.doc", themeName, textMateRules); - this.calculateStyleForToken(TokenKind.XmlDocTag, "comment.xml.doc.tag", themeName, textMateRules); this.calculateStyleForToken(TokenKind.Macro, "entity.name.function.preprocessor", themeName, textMateRules); this.calculateStyleForToken(TokenKind.Enumerator, "variable.other.enummember", themeName, textMateRules); this.calculateStyleForToken(TokenKind.GlobalVariable, "variable.other.global", themeName, textMateRules); @@ -225,7 +202,7 @@ export class ColorizationSettings { this.calculateStyleForToken(TokenKind.ClassTemplate, "entity.name.class.template", themeName, textMateRules); this.calculateStyleForToken(TokenKind.GenericType, "entity.name.class.generic", themeName, textMateRules); this.calculateStyleForToken(TokenKind.FunctionTemplate, "entity.name.function.template", themeName, textMateRules); - this.calculateStyleForToken(TokenKind.Namespace, "entity.name.namespace", themeName, textMateRules); + this.calculateStyleForToken(TokenKind.Namespace, "entity.name.type.namespace", themeName, textMateRules); this.calculateStyleForToken(TokenKind.Label, "entity.name.label", themeName, textMateRules); this.calculateStyleForToken(TokenKind.UdlRaw, "entity.name.user-defined-literal", themeName, textMateRules); this.calculateStyleForToken(TokenKind.UdlNumber, "entity.name.user-defined-literal.number", themeName, textMateRules); @@ -348,58 +325,16 @@ export class ColorizationSettings { return null; } - - public useEmptyGrammars(): void { - let packageJson: any = util.getRawPackageJson(); - if (!packageJson.contributes.grammars || !packageJson.contributes.grammars.length) { - let cppGrammarContributesNode: TextMateContributesGrammar = { - language: "cpp", - scopeName: "source.cpp", - path: "./nogrammar.cpp.json" - }; - let cGrammarContributesNode: TextMateContributesGrammar = { - language: "c", - scopeName: "source.c", - path: "./nogrammar.c.json" - }; - packageJson.contributes.grammars = []; - packageJson.contributes.grammars.push(cppGrammarContributesNode); - packageJson.contributes.grammars.push(cGrammarContributesNode); - util.writeFileText(util.getPackageJsonPath(), util.stringifyPackageJson(packageJson)); - util.promptForReloadWindowDueToSettingsChange(); - } - } - - public useStandardGrammars(): void { - let packageJson: any = util.getRawPackageJson(); - if (packageJson.contributes.grammars && packageJson.contributes.grammars.length > 0) { - packageJson.contributes.grammars = []; - util.writeFileText(util.getPackageJsonPath(), util.stringifyPackageJson(packageJson)); - util.promptForReloadWindowDueToSettingsChange(); - } - } - - public updateGrammars(): void { - let settings: CppSettings = new CppSettings(this.uri); - if (settings.textMateColorization === "Disabled") { - this.useEmptyGrammars(); - } else { - this.useStandardGrammars(); - } - } } export class ColorizationState { private uri: vscode.Uri; private colorizationSettings: ColorizationSettings; private decorations: vscode.TextEditorDecorationType[] = new Array(TokenKind.Count); - private syntacticRanges: vscode.Range[][] = new Array(TokenKind.Count); private semanticRanges: vscode.Range[][] = new Array(TokenKind.Count); private inactiveDecoration: vscode.TextEditorDecorationType = null; private inactiveRanges: vscode.Range[] = []; private versionedEdits: VersionedEdits[] = []; - private currentSyntacticVersion: number = 0; - private lastReceivedSyntacticVersion: number = 0; private currentSemanticVersion: number = 0; private lastReceivedSemanticVersion: number = 0; @@ -410,7 +345,7 @@ export class ColorizationState { private createColorizationDecorations(isCpp: boolean): void { let settings: CppSettings = new CppSettings(this.uri); - if (settings.enhancedColorization === "Enabled" && settings.intelliSenseEngine === "Default") { + if (settings.enhancedColorization) { // Create new decorators // The first decorator created takes precedence, so these need to be created in reverse order for (let i: number = TokenKind.Count; i > 0;) { @@ -454,17 +389,10 @@ export class ColorizationState { private refreshInner(e: vscode.TextEditor): void { let settings: CppSettings = new CppSettings(this.uri); - if (settings.enhancedColorization === "Enabled" && settings.intelliSenseEngine === "Default") { + if (settings.enhancedColorization) { for (let i: number = 0; i < TokenKind.Count; i++) { if (this.decorations[i]) { - let ranges: vscode.Range[] = this.syntacticRanges[i]; - if (this.semanticRanges[i]) { - if (!ranges || !ranges.length) { - ranges = this.semanticRanges[i]; - } else { - ranges = ranges.concat(this.semanticRanges[i]); - } - } + let ranges: vscode.Range[] = this.semanticRanges[i]; if (ranges && ranges.length > 0) { e.setDecorations(this.decorations[i], ranges); } @@ -633,12 +561,6 @@ export class ColorizationState { // Apply any pending edits to the currently cached tokens private applyEdits() : void { this.versionedEdits.forEach((edit) => { - if (edit.editVersion > this.currentSyntacticVersion) { - for (let i: number = 0; i < TokenKind.Count; i++) { - this.syntacticRanges[i] = this.fixRanges(this.syntacticRanges[i], edit.changes); - } - this.currentSyntacticVersion = edit.editVersion; - } if (edit.editVersion > this.currentSemanticVersion) { for (let i: number = 0; i < TokenKind.Count; i++) { this.semanticRanges[i] = this.fixRanges(this.semanticRanges[i], edit.changes); @@ -651,7 +573,7 @@ export class ColorizationState { // Remove any edits from the list if we will never receive tokens that old. private purgeOldVersionedEdits(): void { - let minVersion: number = Math.min(this.lastReceivedSemanticVersion, this.lastReceivedSyntacticVersion); + let minVersion: number = this.lastReceivedSemanticVersion; let index: number = this.versionedEdits.findIndex((edit) => edit.editVersion > minVersion); if (index === -1) { this.versionedEdits = []; @@ -699,15 +621,6 @@ export class ColorizationState { this.colorizationSettings.syncWithLoadingSettings(f); } - public updateSyntactic(uri: string, syntacticRanges: vscode.Range[][], editVersion: number): void { - for (let i: number = 0; i < TokenKind.Count; i++) { - this.syntacticRanges[i] = syntacticRanges[i]; - } - this.currentSyntacticVersion = editVersion; - this.lastReceivedSyntacticVersion = editVersion; - this.updateColorizationRanges(uri); - } - public updateSemantic(uri: string, semanticRanges: vscode.Range[][], inactiveRanges: vscode.Range[], editVersion: number): void { this.inactiveRanges = inactiveRanges; for (let i: number = 0; i < TokenKind.Count; i++) { diff --git a/Extension/src/LanguageServer/settings.ts b/Extension/src/LanguageServer/settings.ts index a26507951..fd19a1a53 100644 --- a/Extension/src/LanguageServer/settings.ts +++ b/Extension/src/LanguageServer/settings.ts @@ -42,9 +42,6 @@ export class CppSettings extends Settings { public get intelliSenseCachePath(): string { return super.Section.get("intelliSenseCachePath"); } public get intelliSenseCacheSize(): number { return super.Section.get("intelliSenseCacheSize"); } public get errorSquiggles(): string { return super.Section.get("errorSquiggles"); } - public get textMateColorization(): string { return super.Section.get("textMateColorization"); } - public get enhancedColorization(): string { return super.Section.get("enhancedColorization"); } - public get dimInactiveRegions(): boolean { return super.Section.get("dimInactiveRegions"); } public get inactiveRegionOpacity(): number { return super.Section.get("inactiveRegionOpacity"); } public get inactiveRegionForegroundColor(): string { return super.Section.get("inactiveRegionForegroundColor"); } public get inactiveRegionBackgroundColor(): string { return super.Section.get("inactiveRegionBackgroundColor"); } @@ -76,6 +73,18 @@ export class CppSettings extends Settings { public get defaultSystemIncludePath(): string[] { return super.Section.get("default.systemIncludePath"); } public get defaultEnableConfigurationSquiggles(): boolean { return super.Section.get("default.enableConfigurationSquiggles"); } + public get enhancedColorization(): boolean { + return super.Section.get("enhancedColorization") === "Enabled" + && super.Section.get("intelliSenseEngine") === "Default" + && vscode.workspace.getConfiguration("workbench").get("colorTheme") !== "Default High Contrast"; + } + + public get dimInactiveRegions(): boolean { + return super.Section.get("dimInactiveRegions") + && super.Section.get("intelliSenseEngine") === "Default" + && vscode.workspace.getConfiguration("workbench").get("colorTheme") !== "Default High Contrast"; + } + public toggleSetting(name: string, value1: string, value2: string): void { let value: string = super.Section.get(name); super.Section.update(name, value === value1 ? value2 : value1, getTarget()); @@ -96,12 +105,6 @@ export interface TextMateRule { settings: TextMateRuleSettings; } -export interface TextMateContributesGrammar { - language: string; - scopeName: string; - path: string; -} - export class OtherSettings { private resource: vscode.Uri;