src/vs/editor/common/cursor/cursorTypeOperations.ts/TypeOperations/_typeInterceptorElectricChar
class TypeOperations:	private static _typeInterceptorElectricChar(prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selection: Selection, ch: string): EditOperationResult | null {
		if (!config.electricChars.hasOwnProperty(ch) || !selection.isEmpty()) {
			return null;
		}

		const position = selection.getPosition();
		model.tokenization.forceTokenization(position.lineNumber);
		const lineTokens = model.tokenization.getLineTokens(position.lineNumber);

		let electricAction: IElectricAction | null;
		try {
			electricAction = config.onElectricCharacter(ch, lineTokens, position.column);
		} catch (e) {
			onUnexpectedError(e);
			return null;
		}

		if (!electricAction) {
			return null;
		}

		if (electricAction.matchOpenBracket) {
			const endColumn = (lineTokens.getLineContent() + ch).lastIndexOf(electricAction.matchOpenBracket) + 1;
			const match = model.bracketPairs.findMatchingBracketUp(electricAction.matchOpenBracket, {
				lineNumber: position.lineNumber,
				column: endColumn
			}, 500 /* give at most 500ms to compute */);

			if (match) {
				if (match.startLineNumber === position.lineNumber) {
					// matched something on the same line => no change in indentation
					return null;
				}
				const matchLine = model.getLineContent(match.startLineNumber);
				const matchLineIndentation = strings.getLeadingWhitespace(matchLine);
				const newIndentation = config.normalizeIndentation(matchLineIndentation);

				const lineText = model.getLineContent(position.lineNumber);
				const lineFirstNonBlankColumn = model.getLineFirstNonWhitespaceColumn(position.lineNumber) || position.column;

				const prefix = lineText.substring(lineFirstNonBlankColumn - 1, position.column - 1);
				const typeText = newIndentation + prefix + ch;

				const typeSelection = new Range(position.lineNumber, 1, position.lineNumber, position.column);

				const command = new ReplaceCommand(typeSelection, typeText);
				return new EditOperationResult(getTypingOperation(typeText, prevEditOperationType), [command], {
					shouldPushStackElementBefore: false,
					shouldPushStackElementAfter: true
				});
			}
		}

		return null;
	}