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

import EditorCommon = require('vs/editor/common/editorCommon');
8
import modes = require('vs/editor/common/modes');
9
import URI from 'vs/base/common/uri';
E
Erich Gamma 已提交
10 11 12 13
import WinJS = require('vs/base/common/winjs.base');
import Platform = require('vs/platform/platform');
import jsonWorker = require('vs/languages/json/common/jsonWorker');
import tokenization = require('vs/languages/json/common/features/tokenization');
14
import {AbstractMode, createWordRegExp, ModeWorkerManager} from 'vs/editor/common/modes/abstractMode';
E
Erich Gamma 已提交
15
import {OneWorkerAttr, AllWorkersAttr} from 'vs/platform/thread/common/threadService';
16
import {IThreadService, ThreadAffinity} from 'vs/platform/thread/common/thread';
M
Martin Aeschlimann 已提交
17
import {IJSONContributionRegistry, Extensions, ISchemaContributions} from 'vs/platform/jsonschemas/common/jsonContributionRegistry';
E
Erich Gamma 已提交
18
import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation';
19
import {RichEditSupport} from 'vs/editor/common/modes/supports/richEditSupport';
20
import {wireCancellationToken} from 'vs/base/common/async';
E
Erich Gamma 已提交
21

22
export class JSONMode extends AbstractMode implements modes.IOutlineSupport {
E
Erich Gamma 已提交
23

24 25 26 27
	public tokenizationSupport: modes.ITokenizationSupport;
	public richEditSupport: modes.IRichEditSupport;
	public configSupport:modes.IConfigurationSupport;
	public inplaceReplaceSupport:modes.IInplaceReplaceSupport;
E
Erich Gamma 已提交
28

29
	private _modeWorkerManager: ModeWorkerManager<jsonWorker.JSONWorker>;
30
	private _threadService:IThreadService;
31

E
Erich Gamma 已提交
32
	constructor(
33
		descriptor:modes.IModeDescriptor,
E
Erich Gamma 已提交
34 35 36
		@IInstantiationService instantiationService: IInstantiationService,
		@IThreadService threadService: IThreadService
	) {
37
		super(descriptor.id);
38
		this._modeWorkerManager = new ModeWorkerManager<jsonWorker.JSONWorker>(descriptor, 'vs/languages/json/common/jsonWorker', 'JSONWorker', null, instantiationService);
39
		this._threadService = threadService;
E
Erich Gamma 已提交
40 41

		this.tokenizationSupport = tokenization.createTokenizationSupport(this, true);
42

43
		this.richEditSupport = new RichEditSupport(this.getId(), null, {
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64

			wordPattern: createWordRegExp('.-'),

			comments: {
				lineComment: '//',
				blockComment: ['/*', '*/']
			},

			brackets: [
				['{', '}'],
				['[', ']']
			],

			__characterPairSupport: {
				autoClosingPairs: [
					{ open: '{', close: '}', notIn: ['string'] },
					{ open: '[', close: ']', notIn: ['string'] },
					{ open: '"', close: '"', notIn: ['string'] }
				]
			}
		});
E
Erich Gamma 已提交
65

66 67 68 69 70 71
		modes.HoverProviderRegistry.register(this.getId(), {
			provideHover: (model, position, token): Thenable<modes.Hover> => {
				return wireCancellationToken(token, this._provideHover(model.getAssociatedResource(), position));
			}
		});

72
		this.inplaceReplaceSupport = this;
73

74
		this.configSupport = this;
E
Erich Gamma 已提交
75 76

		// Initialize Outline support
77 78 79
		modes.OutlineRegistry.register(this.getId(), this);

		modes.FormatRegistry.register(this.getId(), this);
E
Erich Gamma 已提交
80

81
		modes.FormatOnTypeRegistry.register(this.getId(), this);
E
Erich Gamma 已提交
82

83
		modes.SuggestRegistry.register(this.getId(), {
E
Erich Gamma 已提交
84
			triggerCharacters: [],
85
			shouldAutotriggerSuggest: true,
86 87 88
			provideCompletionItems: (model, position, token): Thenable<modes.ISuggestResult[]> => {
				return wireCancellationToken(token, this._provideCompletionItems(model.getAssociatedResource(), position));
			}
89
		});
E
Erich Gamma 已提交
90 91 92 93
	}

	public creationDone(): void {
		if (this._threadService.isInMainThread) {
94 95 96
			// Pick a worker to do validation
			this._pickAWorkerToValidate();

E
Erich Gamma 已提交
97 98 99 100 101 102 103 104 105
			// Configure all workers
			this._configureWorkerSchemas(this.getSchemaConfiguration());
			var contributionRegistry = <IJSONContributionRegistry> Platform.Registry.as(Extensions.JSONContribution);
			contributionRegistry.addRegistryChangedListener(e => {
				this._configureWorkerSchemas(this.getSchemaConfiguration());
			});
		}
	}

106 107 108 109
	private _worker<T>(runner:(worker:jsonWorker.JSONWorker)=>WinJS.TPromise<T>): WinJS.TPromise<T> {
		return this._modeWorkerManager.worker(runner);
	}

E
Erich Gamma 已提交
110 111 112 113 114
	private getSchemaConfiguration() : ISchemaContributions {
		var contributionRegistry = <IJSONContributionRegistry> Platform.Registry.as(Extensions.JSONContribution);
		return contributionRegistry.getSchemaContributions();
	}

115 116 117 118 119 120 121 122 123 124 125 126 127
	public configure(options:any): WinJS.TPromise<void> {
		if (this._threadService.isInMainThread) {
			return this._configureWorkers(options);
		} else {
			return this._worker((w) => w._doConfigure(options));
		}
	}

	static $_configureWorkers = AllWorkersAttr(JSONMode, JSONMode.prototype._configureWorkers);
	private _configureWorkers(options:any): WinJS.TPromise<void> {
		return this._worker((w) => w._doConfigure(options));
	}

E
Erich Gamma 已提交
128 129 130 131 132
	static $_configureWorkerSchemas = AllWorkersAttr(JSONMode, JSONMode.prototype._configureWorkerSchemas);
	private _configureWorkerSchemas(data:ISchemaContributions): WinJS.TPromise<boolean> {
		return this._worker((w) => w.setSchemaContributions(data));
	}

133 134 135 136 137
	static $_pickAWorkerToValidate = OneWorkerAttr(JSONMode, JSONMode.prototype._pickAWorkerToValidate, ThreadAffinity.Group1);
	private _pickAWorkerToValidate(): WinJS.TPromise<void> {
		return this._worker((w) => w.enableValidator());
	}

138
	static $navigateValueSet = OneWorkerAttr(JSONMode, JSONMode.prototype.navigateValueSet);
139
	public navigateValueSet(resource:URI, position:EditorCommon.IRange, up:boolean):WinJS.TPromise<modes.IInplaceReplaceSupportResult> {
140 141 142
		return this._worker((w) => w.navigateValueSet(resource, position, up));
	}

143
	static $_provideCompletionItems = OneWorkerAttr(JSONMode, JSONMode.prototype._provideCompletionItems);
144
	private _provideCompletionItems(resource:URI, position:EditorCommon.IPosition):WinJS.TPromise<modes.ISuggestResult[]> {
145
		return this._worker((w) => w.provideCompletionItems(resource, position));
146 147
	}

148
	static $_provideHover = OneWorkerAttr(JSONMode, JSONMode.prototype._provideHover);
149
	private _provideHover(resource:URI, position:EditorCommon.IPosition): WinJS.TPromise<modes.Hover> {
150
		return this._worker((w) => w.provideHover(resource, position));
E
Erich Gamma 已提交
151 152 153
	}

	static $getOutline = OneWorkerAttr(JSONMode, JSONMode.prototype.getOutline);
154
	public getOutline(resource:URI):WinJS.TPromise<modes.IOutlineEntry[]> {
E
Erich Gamma 已提交
155 156 157 158
		return this._worker((w) => w.getOutline(resource));
	}

	static $formatDocument = OneWorkerAttr(JSONMode, JSONMode.prototype.formatDocument);
159
	public formatDocument(resource:URI, options:modes.IFormattingOptions):WinJS.TPromise<EditorCommon.ISingleEditOperation[]> {
E
Erich Gamma 已提交
160 161 162 163
		return this._worker((w) => w.format(resource, null, options));
	}

	static $formatRange = OneWorkerAttr(JSONMode, JSONMode.prototype.formatRange);
164
	public formatRange(resource:URI, range:EditorCommon.IRange, options:modes.IFormattingOptions):WinJS.TPromise<EditorCommon.ISingleEditOperation[]> {
E
Erich Gamma 已提交
165 166 167
		return this._worker((w) => w.format(resource, range, options));
	}
}