supports.ts 4.1 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';
9
import {ModeTransition} from 'vs/editor/common/core/modeTransition';
10
import {Token} from 'vs/editor/common/core/token';
E
Erich Gamma 已提交
11

A
Alex Dima 已提交
12
export class LineTokens implements modes.ILineTokens {
A
Alex Dima 已提交
13
	_lineTokensBrand: void;
A
Alex Dima 已提交
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29

	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 已提交
30
export function handleEvent<T>(context:modes.ILineContext, offset:number, runner:(modeId:string, newContext:modes.ILineContext, offset:number)=>T):T {
A
Alex Dima 已提交
31
	let modeTransitions = context.modeTransitions;
E
Erich Gamma 已提交
32
	if (modeTransitions.length === 1) {
A
Alex Dima 已提交
33
		return runner(modeTransitions[0].modeId, context, offset);
E
Erich Gamma 已提交
34 35
	}

36
	let modeIndex = ModeTransition.findIndexInSegmentsArray(modeTransitions, offset);
A
Alex Dima 已提交
37 38
	let nestedModeId = modeTransitions[modeIndex].modeId;
	let modeStartIndex = modeTransitions[modeIndex].startIndex;
E
Erich Gamma 已提交
39

A
Alex Dima 已提交
40 41 42
	let firstTokenInModeIndex = context.findIndexOfOffset(modeStartIndex);
	let nextCharacterAfterModeIndex = -1;
	let nextTokenAfterMode = -1;
E
Erich Gamma 已提交
43 44
	if (modeIndex + 1 < modeTransitions.length) {
		nextTokenAfterMode = context.findIndexOfOffset(modeTransitions[modeIndex + 1].startIndex);
A
Alex Dima 已提交
45
		nextCharacterAfterModeIndex = context.getTokenStartOffset(nextTokenAfterMode);
E
Erich Gamma 已提交
46 47 48 49 50
	} else {
		nextTokenAfterMode = context.getTokenCount();
		nextCharacterAfterModeIndex = context.getLineContent().length;
	}

A
Alex Dima 已提交
51
	let firstTokenCharacterOffset = context.getTokenStartOffset(firstTokenInModeIndex);
A
Alex Dima 已提交
52 53
	let newCtx = new FilteredLineContext(context, nestedModeId, firstTokenInModeIndex, nextTokenAfterMode, firstTokenCharacterOffset, nextCharacterAfterModeIndex);
	return runner(nestedModeId, newCtx, offset - firstTokenCharacterOffset);
E
Erich Gamma 已提交
54 55
}

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

58
	public modeTransitions: ModeTransition[];
E
Erich Gamma 已提交
59

A
Alex Dima 已提交
60
	private _actual:modes.ILineContext;
E
Erich Gamma 已提交
61 62 63 64 65
	private _firstTokenInModeIndex:number;
	private _nextTokenAfterMode:number;
	private _firstTokenCharacterOffset:number;
	private _nextCharacterAfterModeIndex:number;

A
Alex Dima 已提交
66
	constructor(actual:modes.ILineContext, modeId:string,
E
Erich Gamma 已提交
67 68 69
			firstTokenInModeIndex:number, nextTokenAfterMode:number,
			firstTokenCharacterOffset:number, nextCharacterAfterModeIndex:number) {

70
		this.modeTransitions = [new ModeTransition(0, modeId)];
E
Erich Gamma 已提交
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
		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;
	}

A
Alex Dima 已提交
91 92
	public getTokenStartOffset(tokenIndex:number): number {
		return this._actual.getTokenStartOffset(tokenIndex + this._firstTokenInModeIndex) - this._firstTokenCharacterOffset;
E
Erich Gamma 已提交
93 94 95 96 97 98 99
	}

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

A
Alex Dima 已提交
100
const IGNORE_IN_TOKENS = /\b(comment|string|regex)\b/;
101
export function ignoreBracketsInToken(tokenType:string): boolean {
A
Alex Dima 已提交
102
	return IGNORE_IN_TOKENS.test(tokenType);
103
}