supports.ts 4.6 KB
Newer Older
E
Erich Gamma 已提交
1 2 3 4 5 6
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
'use strict';

A
Alex Dima 已提交
7
import {TPromise} from 'vs/base/common/winjs.base';
A
Alex Dima 已提交
8
import * as modes from 'vs/editor/common/modes';
A
Alex Dima 已提交
9
import {ModeTransition} from 'vs/editor/common/core/modeTransition';
E
Erich Gamma 已提交
10

A
Alex Dima 已提交
11
export class Token implements modes.IToken {
A
Alex Dima 已提交
12
	_tokenBrand: void;
A
Alex Dima 已提交
13

E
Erich Gamma 已提交
14 15 16
	public startIndex:number;
	public type:string;

17
	constructor(startIndex:number, type:string) {
E
Erich Gamma 已提交
18 19 20 21 22
		this.startIndex = startIndex;
		this.type = type;
	}

	public toString(): string {
23
		return '(' + this.startIndex + ', ' + this.type + ')';
E
Erich Gamma 已提交
24 25 26
	}
}

A
Alex Dima 已提交
27
export class LineTokens implements modes.ILineTokens {
A
Alex Dima 已提交
28
	_lineTokensBrand: void;
A
Alex Dima 已提交
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44

	tokens: Token[];
	modeTransitions: ModeTransition[];
	actualStopOffset: number;
	endState: modes.IState;
	retokenize: TPromise<void>;

	constructor(tokens:Token[], modeTransitions: ModeTransition[], actualStopOffset:number, endState:modes.IState) {
		this.tokens = tokens;
		this.modeTransitions = modeTransitions;
		this.actualStopOffset = actualStopOffset;
		this.endState = endState;
		this.retokenize = null;
	}
}

A
Alex Dima 已提交
45
export function handleEvent<T>(context:modes.ILineContext, offset:number, runner:(modeId:string, newContext:modes.ILineContext, offset:number)=>T):T {
E
Erich Gamma 已提交
46 47
	var modeTransitions = context.modeTransitions;
	if (modeTransitions.length === 1) {
A
Alex Dima 已提交
48
		return runner(modeTransitions[0].modeId, context, offset);
E
Erich Gamma 已提交
49 50
	}

A
Alex Dima 已提交
51
	var modeIndex = ModeTransition.findIndexInSegmentsArray(modeTransitions, offset);
E
Erich Gamma 已提交
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
	var nestedMode = modeTransitions[modeIndex].mode;
	var modeStartIndex = modeTransitions[modeIndex].startIndex;

	var firstTokenInModeIndex = context.findIndexOfOffset(modeStartIndex);
	var nextCharacterAfterModeIndex = -1;
	var nextTokenAfterMode = -1;
	if (modeIndex + 1 < modeTransitions.length) {
		nextTokenAfterMode = context.findIndexOfOffset(modeTransitions[modeIndex + 1].startIndex);
		nextCharacterAfterModeIndex = context.getTokenStartIndex(nextTokenAfterMode);
	} else {
		nextTokenAfterMode = context.getTokenCount();
		nextCharacterAfterModeIndex = context.getLineContent().length;
	}

	var firstTokenCharacterOffset = context.getTokenStartIndex(firstTokenInModeIndex);
	var newCtx = new FilteredLineContext(context, nestedMode, firstTokenInModeIndex, nextTokenAfterMode, firstTokenCharacterOffset, nextCharacterAfterModeIndex);
A
Alex Dima 已提交
68
	return runner(nestedMode.getId(), newCtx, offset - firstTokenCharacterOffset);
E
Erich Gamma 已提交
69 70
}

A
Alex Dima 已提交
71
export class FilteredLineContext implements modes.ILineContext {
E
Erich Gamma 已提交
72

A
Alex Dima 已提交
73
	public modeTransitions: ModeTransition[];
E
Erich Gamma 已提交
74

A
Alex Dima 已提交
75
	private _actual:modes.ILineContext;
E
Erich Gamma 已提交
76 77 78 79 80
	private _firstTokenInModeIndex:number;
	private _nextTokenAfterMode:number;
	private _firstTokenCharacterOffset:number;
	private _nextCharacterAfterModeIndex:number;

A
Alex Dima 已提交
81
	constructor(actual:modes.ILineContext, mode:modes.IMode,
E
Erich Gamma 已提交
82 83 84
			firstTokenInModeIndex:number, nextTokenAfterMode:number,
			firstTokenCharacterOffset:number, nextCharacterAfterModeIndex:number) {

A
Alex Dima 已提交
85
		this.modeTransitions = [new ModeTransition(0, mode)];
E
Erich Gamma 已提交
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
		this._actual = actual;
		this._firstTokenInModeIndex = firstTokenInModeIndex;
		this._nextTokenAfterMode = nextTokenAfterMode;
		this._firstTokenCharacterOffset = firstTokenCharacterOffset;
		this._nextCharacterAfterModeIndex = nextCharacterAfterModeIndex;
	}

	public getLineContent(): string {
		var actualLineContent = this._actual.getLineContent();
		return actualLineContent.substring(this._firstTokenCharacterOffset, this._nextCharacterAfterModeIndex);
	}

	public getTokenCount(): number {
		return this._nextTokenAfterMode - this._firstTokenInModeIndex;
	}

	public findIndexOfOffset(offset:number): number {
		return this._actual.findIndexOfOffset(offset + this._firstTokenCharacterOffset) - this._firstTokenInModeIndex;
	}

	public getTokenStartIndex(tokenIndex:number): number {
		return this._actual.getTokenStartIndex(tokenIndex + this._firstTokenInModeIndex) - this._firstTokenCharacterOffset;
	}

	public getTokenEndIndex(tokenIndex:number): number {
		return this._actual.getTokenEndIndex(tokenIndex + this._firstTokenInModeIndex) - this._firstTokenCharacterOffset;
	}

	public getTokenType(tokenIndex:number): string {
		return this._actual.getTokenType(tokenIndex + this._firstTokenInModeIndex);
	}

	public getTokenText(tokenIndex:number): string {
		return this._actual.getTokenText(tokenIndex + this._firstTokenInModeIndex);
	}
}

A
Alex Dima 已提交
123
const IGNORE_IN_TOKENS = /\b(comment|string|regex)\b/;
124
export function ignoreBracketsInToken(tokenType:string): boolean {
A
Alex Dima 已提交
125
	return IGNORE_IN_TOKENS.test(tokenType);
126
}