/*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { Emitter } from '../../../../base/common/event.js'; import { Disposable } from '../../../../base/common/lifecycle.js'; import { Range } from '../../core/range.js'; import { editorBracketHighlightingForeground1, editorBracketHighlightingForeground2, editorBracketHighlightingForeground3, editorBracketHighlightingForeground4, editorBracketHighlightingForeground5, editorBracketHighlightingForeground6, editorBracketHighlightingUnexpectedBracketForeground } from '../../core/editorColorRegistry.js'; import { registerThemingParticipant } from '../../../../platform/theme/common/themeService.js'; export class ColorizedBracketPairsDecorationProvider extends Disposable { constructor(textModel) { super(); this.textModel = textModel; this.colorProvider = new ColorProvider(); this.onDidChangeEmitter = new Emitter(); this.onDidChange = this.onDidChangeEmitter.event; this.colorizationOptions = textModel.getOptions().bracketPairColorizationOptions; this._register(textModel.bracketPairs.onDidChange(e => { this.onDidChangeEmitter.fire(); })); } //#region TextModel events handleDidChangeOptions(e) { this.colorizationOptions = this.textModel.getOptions().bracketPairColorizationOptions; } //#endregion getDecorationsInRange(range, ownerId, filterOutValidation) { if (ownerId === undefined) { return []; } if (!this.colorizationOptions.enabled) { return []; } const result = new Array(); const bracketsInRange = this.textModel.bracketPairs.getBracketsInRange(range); for (const bracket of bracketsInRange) { result.push({ id: `bracket${bracket.range.toString()}-${bracket.nestingLevel}`, options: { description: 'BracketPairColorization', inlineClassName: this.colorProvider.getInlineClassName(bracket, this.colorizationOptions.independentColorPoolPerBracketType), }, ownerId: 0, range: bracket.range, }); } return result; } getAllDecorations(ownerId, filterOutValidation) { if (ownerId === undefined) { return []; } if (!this.colorizationOptions.enabled) { return []; } return this.getDecorationsInRange(new Range(1, 1, this.textModel.getLineCount(), 1), ownerId, filterOutValidation); } } class ColorProvider { constructor() { this.unexpectedClosingBracketClassName = 'unexpected-closing-bracket'; } getInlineClassName(bracket, independentColorPoolPerBracketType) { if (bracket.isInvalid) { return this.unexpectedClosingBracketClassName; } return this.getInlineClassNameOfLevel(independentColorPoolPerBracketType ? bracket.nestingLevelOfEqualBracketType : bracket.nestingLevel); } getInlineClassNameOfLevel(level) { // To support a dynamic amount of colors up to 6 colors, // we use a number that is a lcm of all numbers from 1 to 6. return `bracket-highlighting-${level % 30}`; } } registerThemingParticipant((theme, collector) => { const colors = [ editorBracketHighlightingForeground1, editorBracketHighlightingForeground2, editorBracketHighlightingForeground3, editorBracketHighlightingForeground4, editorBracketHighlightingForeground5, editorBracketHighlightingForeground6 ]; const colorProvider = new ColorProvider(); collector.addRule(`.monaco-editor .${colorProvider.unexpectedClosingBracketClassName} { color: ${theme.getColor(editorBracketHighlightingUnexpectedBracketForeground)}; }`); const colorValues = colors .map(c => theme.getColor(c)) .filter((c) => !!c) .filter(c => !c.isTransparent()); for (let level = 0; level < 30; level++) { const color = colorValues[level % colorValues.length]; collector.addRule(`.monaco-editor .${colorProvider.getInlineClassNameOfLevel(level)} { color: ${color}; }`); } });