supports.ts 4.7 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, ReducedModeTransition} 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 {
A
Alex Dima 已提交
46
	let modeTransitions = context.modeTransitions;
E
Erich Gamma 已提交
47
	if (modeTransitions.length === 1) {
A
Alex Dima 已提交
48
		return runner(modeTransitions[0].modeId, context, offset);
E
Erich Gamma 已提交
49 50
	}

A
Alex Dima 已提交
51 52 53
	let modeIndex = ReducedModeTransition.findIndexInSegmentsArray(modeTransitions, offset);
	let nestedModeId = modeTransitions[modeIndex].modeId;
	let modeStartIndex = modeTransitions[modeIndex].startIndex;
E
Erich Gamma 已提交
54

A
Alex Dima 已提交
55 56 57
	let firstTokenInModeIndex = context.findIndexOfOffset(modeStartIndex);
	let nextCharacterAfterModeIndex = -1;
	let nextTokenAfterMode = -1;
E
Erich Gamma 已提交
58 59 60 61 62 63 64 65
	if (modeIndex + 1 < modeTransitions.length) {
		nextTokenAfterMode = context.findIndexOfOffset(modeTransitions[modeIndex + 1].startIndex);
		nextCharacterAfterModeIndex = context.getTokenStartIndex(nextTokenAfterMode);
	} else {
		nextTokenAfterMode = context.getTokenCount();
		nextCharacterAfterModeIndex = context.getLineContent().length;
	}

A
Alex Dima 已提交
66 67 68
	let firstTokenCharacterOffset = context.getTokenStartIndex(firstTokenInModeIndex);
	let newCtx = new FilteredLineContext(context, nestedModeId, firstTokenInModeIndex, nextTokenAfterMode, firstTokenCharacterOffset, nextCharacterAfterModeIndex);
	return runner(nestedModeId, 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: ReducedModeTransition[];
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, modeId:string,
E
Erich Gamma 已提交
82 83 84
			firstTokenInModeIndex:number, nextTokenAfterMode:number,
			firstTokenCharacterOffset:number, nextCharacterAfterModeIndex:number) {

A
Alex Dima 已提交
85
		this.modeTransitions = [new ReducedModeTransition(0, modeId)];
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
}