Implements language configurable colorizedBracketPairs property.

This commit is contained in:
Henning Dieterichs 2021-08-23 15:21:51 +02:00
parent 43666f33a1
commit 9f6e7a7e9f
No known key found for this signature in database
GPG key ID: 771381EFFDB9EC06
8 changed files with 81 additions and 14 deletions

View file

@ -24,6 +24,10 @@
{ "open": "(", "close": ")" },
{ "open": "<", "close": ">" }
],
"colorizedBracketPairs": [
["{", "}"],
["(", ")"]
],
"folding": {
"markers": {
"start": "^\\s*<!--\\s*#region\\b.*-->",

View file

@ -8,6 +8,11 @@
["(", ")"],
["<", ">"]
],
"colorizedBracketPairs": [
["{", "}"],
["[", "]"],
["(", ")"]
],
"autoClosingPairs": [
{ "open": "{", "close": "}" },
{ "open": "[", "close": "]" },

View file

@ -12,22 +12,15 @@ import { Token, TokenKind } from './tokenizer';
export class BracketTokens {
static createFromLanguage(languageId: LanguageId, customBracketPairs: readonly [string, string][]): BracketTokens {
const brackets = [...(LanguageConfigurationRegistry.getBracketsSupport(languageId)?.brackets || [])];
const brackets = [...(LanguageConfigurationRegistry.getColorizedBracketPairs(languageId))];
const tokens = new BracketTokens();
let idxOffset = 0;
for (const pair of brackets) {
const brackets = [
...pair.open.map((value, idx) => ({ value, kind: TokenKind.OpeningBracket, idx: idx + idxOffset })),
...pair.close.map((value, idx) => ({ value, kind: TokenKind.ClosingBracket, idx: idx + idxOffset })),
];
idxOffset += Math.max(pair.open.length, pair.close.length);
for (const bracket of brackets) {
tokens.addBracket(languageId, bracket.value, bracket.kind, bracket.idx);
}
tokens.addBracket(languageId, pair[0], TokenKind.OpeningBracket, idxOffset);
tokens.addBracket(languageId, pair[1], TokenKind.ClosingBracket, idxOffset);
idxOffset++;
}
for (const pair of customBracketPairs) {

View file

@ -60,7 +60,11 @@ export interface LanguageConfiguration {
* settings will be used.
*/
surroundingPairs?: IAutoClosingPair[];
/**
* Defines a list of bracket pairs that are colorized depending on their nesting level.
* If not set, the configured brackets will be used.
*/
colorizedBracketPairs?: CharacterPair[];
/**
* Defines what characters must be after the cursor for bracket or quote autoclosing to occur when using the \'languageDefined\' autoclosing setting.
*

View file

@ -11,7 +11,7 @@ import { Range } from 'vs/editor/common/core/range';
import { ITextModel } from 'vs/editor/common/model';
import { DEFAULT_WORD_REGEXP, ensureValidWordDefinition } from 'vs/editor/common/model/wordHelper';
import { LanguageId, LanguageIdentifier } from 'vs/editor/common/modes';
import { EnterAction, FoldingRules, IAutoClosingPair, IndentAction, IndentationRule, LanguageConfiguration, StandardAutoClosingPairConditional, CompleteEnterAction, AutoClosingPairs } from 'vs/editor/common/modes/languageConfiguration';
import { EnterAction, FoldingRules, IAutoClosingPair, IndentAction, IndentationRule, LanguageConfiguration, StandardAutoClosingPairConditional, CompleteEnterAction, AutoClosingPairs, CharacterPair } from 'vs/editor/common/modes/languageConfiguration';
import { createScopedLineTokens, ScopedLineTokens } from 'vs/editor/common/modes/supports';
import { CharacterPairSupport } from 'vs/editor/common/modes/supports/characterPair';
import { BracketElectricCharacterSupport, IElectricAction } from 'vs/editor/common/modes/supports/electricCharacter';
@ -198,6 +198,7 @@ class LanguageConfigurationEntries {
result.surroundingPairs = conf.surroundingPairs || result.surroundingPairs;
result.autoCloseBefore = conf.autoCloseBefore || result.autoCloseBefore;
result.folding = conf.folding || result.folding;
result.colorizedBracketPairs = conf.colorizedBracketPairs || result.colorizedBracketPairs;
result.__electricCharacterSupport = conf.__electricCharacterSupport || result.__electricCharacterSupport;
}
return result;
@ -827,6 +828,10 @@ export class LanguageConfigurationRegistryImpl {
}
return value.brackets || null;
}
public getColorizedBracketPairs(languageId: LanguageId): CharacterPair[] {
return this._getRichEditSupport(languageId)?.characterPair.getColorizedBrackets() || [];
}
}
export const LanguageConfigurationRegistry = new LanguageConfigurationRegistryImpl();

View file

@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IAutoClosingPair, StandardAutoClosingPairConditional, LanguageConfiguration } from 'vs/editor/common/modes/languageConfiguration';
import { IAutoClosingPair, StandardAutoClosingPairConditional, LanguageConfiguration, CharacterPair } from 'vs/editor/common/modes/languageConfiguration';
import { ScopedLineTokens } from 'vs/editor/common/modes/supports';
export class CharacterPairSupport {
@ -14,6 +14,7 @@ export class CharacterPairSupport {
private readonly _autoClosingPairs: StandardAutoClosingPairConditional[];
private readonly _surroundingPairs: IAutoClosingPair[];
private readonly _autoCloseBefore: string;
private readonly _colorizedBracketPairs: CharacterPair[];
constructor(config: LanguageConfiguration) {
if (config.autoClosingPairs) {
@ -24,6 +25,14 @@ export class CharacterPairSupport {
this._autoClosingPairs = [];
}
if (config.colorizedBracketPairs) {
this._colorizedBracketPairs = config.colorizedBracketPairs.map(b => [b[0], b[1]]);
} else if (config.brackets) {
this._colorizedBracketPairs = config.brackets.map(b => [b[0], b[1]]);
} else {
this._colorizedBracketPairs = [];
}
if (config.__electricCharacterSupport && config.__electricCharacterSupport.docComment) {
const docComment = config.__electricCharacterSupport.docComment;
// IDocComment is legacy, only partially supported
@ -57,4 +66,8 @@ export class CharacterPairSupport {
public getSurroundingPairs(): IAutoClosingPair[] {
return this._surroundingPairs;
}
public getColorizedBrackets(): CharacterPair[] {
return this._colorizedBracketPairs;
}
}

5
src/vs/monaco.d.ts vendored
View file

@ -5503,6 +5503,11 @@ declare namespace monaco.languages {
* settings will be used.
*/
surroundingPairs?: IAutoClosingPair[];
/**
* Defines a list of bracket pairs that are colorized depending on their nesting level.
* If not set, the configured brackets will be used.
*/
colorizedBracketPairs?: CharacterPair[];
/**
* Defines what characters must be after the cursor for bracket or quote autoclosing to occur when using the \'languageDefined\' autoclosing setting.
*

View file

@ -49,6 +49,7 @@ interface ILanguageConfiguration {
brackets?: CharacterPair[];
autoClosingPairs?: Array<CharacterPair | IAutoClosingPairConditional>;
surroundingPairs?: Array<CharacterPair | IAutoClosingPair>;
colorizedBracketPairs?: Array<CharacterPair>;
wordPattern?: string | IRegExp;
indentationRules?: IIndentationRules;
folding?: FoldingRules;
@ -268,6 +269,30 @@ export class LanguageConfigurationFileHandler {
return result;
}
private _extractValidColorizedBracketPairs(languageIdentifier: LanguageIdentifier, configuration: ILanguageConfiguration): CharacterPair[] | null {
const source = configuration.colorizedBracketPairs;
if (typeof source === 'undefined') {
return null;
}
if (!Array.isArray(source)) {
console.warn(`[${languageIdentifier.language}]: language configuration: expected \`colorizedBracketPairs\` to be an array.`);
return null;
}
let result: CharacterPair[] | null = null;
for (let i = 0, len = source.length; i < len; i++) {
const pair = source[i];
if (!isCharacterPair(pair)) {
console.warn(`[${languageIdentifier.language}]: language configuration: expected \`colorizedBracketPairs[${i}]\` to be an array of two strings.`);
continue;
}
result = result || [];
result.push([pair[0], pair[1]]);
}
return result;
}
private _extractValidOnEnterRules(languageIdentifier: LanguageIdentifier, configuration: ILanguageConfiguration): OnEnterRule[] | null {
const source = configuration.onEnterRules;
if (typeof source === 'undefined') {
@ -365,6 +390,11 @@ export class LanguageConfigurationFileHandler {
richEditConfig.surroundingPairs = surroundingPairs;
}
const colorizedBracketPairs = this._extractValidColorizedBracketPairs(languageIdentifier, configuration);
if (colorizedBracketPairs) {
richEditConfig.colorizedBracketPairs = colorizedBracketPairs;
}
const autoCloseBefore = configuration.autoCloseBefore;
if (typeof autoCloseBefore === 'string') {
richEditConfig.autoCloseBefore = autoCloseBefore;
@ -521,6 +551,14 @@ const schema: IJSONSchema = {
$ref: '#definitions/bracketPair'
}
},
colorizedBracketPairs: {
default: [['(', ')'], ['[', ']'], ['{', '}']],
description: nls.localize('schema.colorizedBracketPairs', 'Defines the bracket pairs that are colorized by their nesting level if bracket pair colorization is enabled.'),
type: 'array',
items: {
$ref: '#definitions/bracketPair'
}
},
autoClosingPairs: {
default: [['(', ')'], ['[', ']'], ['{', '}']],
description: nls.localize('schema.autoClosingPairs', 'Defines the bracket pairs. When a opening bracket is entered, the closing bracket is inserted automatically.'),