From d54c705f6567958a732ac88b1c3ec4d2303fb026 Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Tue, 8 Mar 2022 17:22:12 +0100 Subject: [PATCH] Fixes #131027 by introducing editor.bracketPairColorization.useIndependentColorPoolPerBracketType --- src/vs/editor/common/config/editorOptions.ts | 18 ++++++++-- .../editor/common/core/textModelDefaults.ts | 5 ++- src/vs/editor/common/model.ts | 1 + .../bracketPairsTree/ast.ts | 4 ++- .../bracketPairsTree/bracketPairsTree.ts | 34 +++++++++++++------ .../bracketPairsTree/brackets.ts | 4 +-- ...colorizedBracketPairsDecorationProvider.ts | 14 +++++--- src/vs/editor/common/services/modelService.ts | 3 +- src/vs/editor/common/textModelBracketPairs.ts | 1 + src/vs/monaco.d.ts | 5 +++ 10 files changed, 67 insertions(+), 22 deletions(-) diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index 54b671b6eb6..5ee0070afd9 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -3550,6 +3550,11 @@ export interface IBracketPairColorizationOptions { * Enable or disable bracket pair colorization. */ enabled?: boolean; + + /** + * Use independent color pool per bracket type. + */ + useIndependentColorPoolPerBracketType?: boolean; } /** @@ -3563,7 +3568,8 @@ export type InternalBracketPairColorizationOptions = Readonly { constructor() { const defaults: InternalBracketPairColorizationOptions = { - enabled: EDITOR_MODEL_DEFAULTS.bracketPairColorizationOptions.enabled + enabled: EDITOR_MODEL_DEFAULTS.bracketPairColorizationOptions.enabled, + useIndependentColorPoolPerBracketType: EDITOR_MODEL_DEFAULTS.bracketPairColorizationOptions.useIndependentColorPoolPerBracketType, }; super( @@ -3573,7 +3579,12 @@ class BracketPairColorization extends BaseEditorOption ): BracketAstNode { - const node = new BracketAstNode(length, languageId, bracketIds); + const node = new BracketAstNode(length, languageId, text, bracketIds); return node; } @@ -644,6 +645,7 @@ export class BracketAstNode extends ImmutableLeafAstNode { private constructor( length: Length, public readonly languageId: string, + public readonly text: string, /** * In case of a opening bracket, this is the id of the opening bracket. * In case of a closing bracket, this contains the ids of all opening brackets it can close. diff --git a/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/bracketPairsTree.ts b/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/bracketPairsTree.ts index 53ad4b6a524..12a1886b0e9 100644 --- a/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/bracketPairsTree.ts +++ b/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/bracketPairsTree.ts @@ -128,7 +128,7 @@ export class BracketPairsTree extends Disposable { const endOffset = toLength(range.endLineNumber - 1, range.endColumn - 1); const result = new Array(); const node = this.initialAstWithoutTokens || this.astWithTokens!; - collectBrackets(node, lengthZero, node.length, startOffset, endOffset, result); + collectBrackets(node, lengthZero, node.length, startOffset, endOffset, result, 0, new Map()); return result; } @@ -146,25 +146,35 @@ export class BracketPairsTree extends Disposable { } } -function collectBrackets(node: AstNode, nodeOffsetStart: Length, nodeOffsetEnd: Length, startOffset: Length, endOffset: Length, result: BracketInfo[], level: number = 0): void { +function collectBrackets(node: AstNode, nodeOffsetStart: Length, nodeOffsetEnd: Length, startOffset: Length, endOffset: Length, result: BracketInfo[], level: number = 0, levelPerBracketType?: Map): void { if (node.kind === AstNodeKind.List) { for (const child of node.children) { nodeOffsetEnd = lengthAdd(nodeOffsetStart, child.length); if (lengthLessThanEqual(nodeOffsetStart, endOffset) && lengthGreaterThanEqual(nodeOffsetEnd, startOffset)) { - collectBrackets(child, nodeOffsetStart, nodeOffsetEnd, startOffset, endOffset, result, level); + collectBrackets(child, nodeOffsetStart, nodeOffsetEnd, startOffset, endOffset, result, level, levelPerBracketType); } nodeOffsetStart = nodeOffsetEnd; } } else if (node.kind === AstNodeKind.Pair) { - // Don't use node.children here to improve performance - level++; + let levelPerBracket = 0; + if (levelPerBracketType) { + let existing = levelPerBracketType.get(node.openingBracket.text); + if (existing === undefined) { + existing = 0; + } + levelPerBracket = existing; + existing++; + levelPerBracketType.set(node.openingBracket.text, existing); + } + + // Don't use node.children here to improve performance { const child = node.openingBracket; nodeOffsetEnd = lengthAdd(nodeOffsetStart, child.length); if (lengthLessThanEqual(nodeOffsetStart, endOffset) && lengthGreaterThanEqual(nodeOffsetEnd, startOffset)) { const range = lengthsToRange(nodeOffsetStart, nodeOffsetEnd); - result.push(new BracketInfo(range, level - 1, !node.closingBracket)); + result.push(new BracketInfo(range, level, levelPerBracket, !node.closingBracket)); } nodeOffsetStart = nodeOffsetEnd; } @@ -173,7 +183,7 @@ function collectBrackets(node: AstNode, nodeOffsetStart: Length, nodeOffsetEnd: const child = node.child; nodeOffsetEnd = lengthAdd(nodeOffsetStart, child.length); if (lengthLessThanEqual(nodeOffsetStart, endOffset) && lengthGreaterThanEqual(nodeOffsetEnd, startOffset)) { - collectBrackets(child, nodeOffsetStart, nodeOffsetEnd, startOffset, endOffset, result, level); + collectBrackets(child, nodeOffsetStart, nodeOffsetEnd, startOffset, endOffset, result, level + 1, levelPerBracketType); } nodeOffsetStart = nodeOffsetEnd; } @@ -182,16 +192,20 @@ function collectBrackets(node: AstNode, nodeOffsetStart: Length, nodeOffsetEnd: nodeOffsetEnd = lengthAdd(nodeOffsetStart, child.length); if (lengthLessThanEqual(nodeOffsetStart, endOffset) && lengthGreaterThanEqual(nodeOffsetEnd, startOffset)) { const range = lengthsToRange(nodeOffsetStart, nodeOffsetEnd); - result.push(new BracketInfo(range, level - 1, false)); + result.push(new BracketInfo(range, level, levelPerBracket, false)); } nodeOffsetStart = nodeOffsetEnd; } + + if (levelPerBracketType) { + levelPerBracketType.set(node.openingBracket.text, levelPerBracket); + } } else if (node.kind === AstNodeKind.UnexpectedClosingBracket) { const range = lengthsToRange(nodeOffsetStart, nodeOffsetEnd); - result.push(new BracketInfo(range, level - 1, true)); + result.push(new BracketInfo(range, level - 1, 0, true)); } else if (node.kind === AstNodeKind.Bracket) { const range = lengthsToRange(nodeOffsetStart, nodeOffsetEnd); - result.push(new BracketInfo(range, level - 1, false)); + result.push(new BracketInfo(range, level - 1, 0, false)); } } diff --git a/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/brackets.ts b/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/brackets.ts index bfc3e727224..458001931b1 100644 --- a/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/brackets.ts +++ b/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/brackets.ts @@ -41,7 +41,7 @@ export class BracketTokens { TokenKind.ClosingBracket, info.first, info.openingBrackets, - BracketAstNode.create(length, configuration.languageId, info.openingBrackets) + BracketAstNode.create(length, configuration.languageId, closingText, info.openingBrackets) )); } @@ -54,7 +54,7 @@ export class BracketTokens { TokenKind.OpeningBracket, openingTextId, bracketIds, - BracketAstNode.create(length, configuration.languageId, bracketIds) + BracketAstNode.create(length, configuration.languageId, openingText, bracketIds) )); } diff --git a/src/vs/editor/common/model/bracketPairsTextModelPart/colorizedBracketPairsDecorationProvider.ts b/src/vs/editor/common/model/bracketPairsTextModelPart/colorizedBracketPairsDecorationProvider.ts index e698380ca34..594e27fb2f6 100644 --- a/src/vs/editor/common/model/bracketPairsTextModelPart/colorizedBracketPairsDecorationProvider.ts +++ b/src/vs/editor/common/model/bracketPairsTextModelPart/colorizedBracketPairsDecorationProvider.ts @@ -55,9 +55,15 @@ export class ColorizedBracketPairsDecorationProvider extends Disposable implemen for (const bracket of bracketsInRange) { result.push({ id: `bracket${bracket.range.toString()}-${bracket.nestingLevel}`, - options: { description: 'BracketPairColorization', inlineClassName: this.colorProvider.getInlineClassName(bracket) }, + options: { + description: 'BracketPairColorization', + inlineClassName: this.colorProvider.getInlineClassName( + bracket, + this.colorizationOptions.useIndependentColorPoolPerBracketType + ), + }, ownerId: 0, - range: bracket.range + range: bracket.range, }); } return result; @@ -81,11 +87,11 @@ export class ColorizedBracketPairsDecorationProvider extends Disposable implemen class ColorProvider { public readonly unexpectedClosingBracketClassName = 'unexpected-closing-bracket'; - getInlineClassName(bracket: BracketInfo): string { + getInlineClassName(bracket: BracketInfo, useIndependentColorPoolPerBracketType: boolean): string { if (bracket.isInvalid) { return this.unexpectedClosingBracketClassName; } - return this.getInlineClassNameOfLevel(bracket.nestingLevel); + return this.getInlineClassNameOfLevel(useIndependentColorPoolPerBracketType ? bracket.nestingLevelOfEqualBracketType : bracket.nestingLevel); } getInlineClassNameOfLevel(level: number): string { diff --git a/src/vs/editor/common/services/modelService.ts b/src/vs/editor/common/services/modelService.ts index 6af5b0c879c..b9772cfd08d 100644 --- a/src/vs/editor/common/services/modelService.ts +++ b/src/vs/editor/common/services/modelService.ts @@ -237,7 +237,8 @@ export class ModelService extends Disposable implements IModelService { let bracketPairColorizationOptions = EDITOR_MODEL_DEFAULTS.bracketPairColorizationOptions; if (config.editor?.bracketPairColorization && typeof config.editor.bracketPairColorization === 'object') { bracketPairColorizationOptions = { - enabled: !!config.editor.bracketPairColorization.enabled + enabled: !!config.editor.bracketPairColorization.enabled, + useIndependentColorPoolPerBracketType: !!config.editor.bracketPairColorization.useIndependentColorPoolPerBracketType }; } diff --git a/src/vs/editor/common/textModelBracketPairs.ts b/src/vs/editor/common/textModelBracketPairs.ts index 3a161c57706..a17f11405be 100644 --- a/src/vs/editor/common/textModelBracketPairs.ts +++ b/src/vs/editor/common/textModelBracketPairs.ts @@ -75,6 +75,7 @@ export class BracketInfo { public readonly range: Range, /** 0-based level */ public readonly nestingLevel: number, + public readonly nestingLevelOfEqualBracketType: number, public readonly isInvalid: boolean, ) { } } diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 19f6773a063..f46f5507d82 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -1686,6 +1686,7 @@ declare namespace monaco.editor { export interface BracketPairColorizationOptions { enabled: boolean; + useIndependentColorPoolPerBracketType: boolean; } export interface ITextModelUpdateOptions { @@ -3974,6 +3975,10 @@ declare namespace monaco.editor { * Enable or disable bracket pair colorization. */ enabled?: boolean; + /** + * Use independent color pool per bracket type. + */ + useIndependentColorPoolPerBracketType?: boolean; } export interface IGuidesOptions {