mainThreadEditors.ts 8.8 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';

7
import URI from 'vs/base/common/uri';
J
Johannes Rieken 已提交
8 9 10
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { TPromise } from 'vs/base/common/winjs.base';
import { IThreadService } from 'vs/workbench/services/thread/common/threadService';
A
Alex Dima 已提交
11
import { ISingleEditOperation, ISelection, IDecorationRenderOptions, IDecorationOptions, ILineChange } from 'vs/editor/common/editorCommon';
J
Johannes Rieken 已提交
12 13 14 15
import { ICodeEditorService } from 'vs/editor/common/services/codeEditorService';
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IEditorGroupService } from 'vs/workbench/services/group/common/groupService';
import { Position as EditorPosition } from 'vs/platform/editor/common/editor';
J
Johannes Rieken 已提交
16 17
import { TextEditorRevealType, MainThreadTextEditor, IApplyEditsOptions, IUndoStopOptions, ITextEditorConfigurationUpdate } from 'vs/workbench/api/node/mainThreadEditor';
import { MainThreadDocumentsAndEditors } from './mainThreadDocumentsAndEditors';
J
Johannes Rieken 已提交
18 19 20
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { equals as objectEquals } from 'vs/base/common/objects';
import { ExtHostContext, MainThreadEditorsShape, ExtHostEditorsShape, ITextEditorPositionData } from './extHost.protocol';
A
Alex Dima 已提交
21
import { IRange } from "vs/editor/common/core/range";
22

A
Alex Dima 已提交
23
export class MainThreadEditors extends MainThreadEditorsShape {
24

25
	private _proxy: ExtHostEditorsShape;
J
Johannes Rieken 已提交
26
	private _documentsAndEditors: MainThreadDocumentsAndEditors;
27 28 29 30 31
	private _workbenchEditorService: IWorkbenchEditorService;
	private _telemetryService: ITelemetryService;
	private _toDispose: IDisposable[];
	private _textEditorsListenersMap: { [editorId: string]: IDisposable[]; };
	private _editorPositionData: ITextEditorPositionData;
E
Erich Gamma 已提交
32

33
	constructor(
J
Johannes Rieken 已提交
34 35
		documentsAndEditors: MainThreadDocumentsAndEditors,
		@ICodeEditorService private _codeEditorService: ICodeEditorService,
36 37 38
		@IThreadService threadService: IThreadService,
		@IWorkbenchEditorService workbenchEditorService: IWorkbenchEditorService,
		@IEditorGroupService editorGroupService: IEditorGroupService,
J
Johannes Rieken 已提交
39
		@ITelemetryService telemetryService: ITelemetryService
40
	) {
A
Alex Dima 已提交
41
		super();
42
		this._proxy = threadService.get(ExtHostContext.ExtHostEditors);
J
Johannes Rieken 已提交
43
		this._documentsAndEditors = documentsAndEditors;
44 45 46 47 48
		this._workbenchEditorService = workbenchEditorService;
		this._telemetryService = telemetryService;
		this._toDispose = [];
		this._textEditorsListenersMap = Object.create(null);
		this._editorPositionData = null;
E
Erich Gamma 已提交
49

J
Johannes Rieken 已提交
50 51
		this._toDispose.push(documentsAndEditors.onTextEditorAdd(editors => editors.forEach(this._onTextEditorAdd, this)));
		this._toDispose.push(documentsAndEditors.onTextEditorRemove(editors => editors.forEach(this._onTextEditorRemove, this)));
E
Erich Gamma 已提交
52

53 54
		this._toDispose.push(editorGroupService.onEditorsChanged(() => this._updateActiveAndVisibleTextEditors()));
		this._toDispose.push(editorGroupService.onEditorsMoved(() => this._updateActiveAndVisibleTextEditors()));
E
Erich Gamma 已提交
55 56
	}

57 58 59 60 61 62
	public dispose(): void {
		Object.keys(this._textEditorsListenersMap).forEach((editorId) => {
			dispose(this._textEditorsListenersMap[editorId]);
		});
		this._textEditorsListenersMap = Object.create(null);
		this._toDispose = dispose(this._toDispose);
E
Erich Gamma 已提交
63 64
	}

65 66 67 68
	private _onTextEditorAdd(textEditor: MainThreadTextEditor): void {
		let id = textEditor.getId();
		let toDispose: IDisposable[] = [];
		toDispose.push(textEditor.onConfigurationChanged((opts) => {
69
			this._proxy.$acceptOptionsChanged(id, opts);
70
		}));
71 72
		toDispose.push(textEditor.onSelectionChanged((event) => {
			this._proxy.$acceptSelectionsChanged(id, event);
73
		}));
E
Erich Gamma 已提交
74

75
		this._textEditorsListenersMap[id] = toDispose;
E
Erich Gamma 已提交
76 77
	}

J
Johannes Rieken 已提交
78
	private _onTextEditorRemove(id: string): void {
79 80
		dispose(this._textEditorsListenersMap[id]);
		delete this._textEditorsListenersMap[id];
E
Erich Gamma 已提交
81 82
	}

83
	private _updateActiveAndVisibleTextEditors(): void {
E
Erich Gamma 已提交
84

85 86 87 88
		// editor columns
		let editorPositionData = this._getTextEditorPositionData();
		if (!objectEquals(this._editorPositionData, editorPositionData)) {
			this._editorPositionData = editorPositionData;
89
			this._proxy.$acceptEditorPositionData(this._editorPositionData);
E
Erich Gamma 已提交
90 91 92
		}
	}

93 94 95
	private _getTextEditorPositionData(): ITextEditorPositionData {
		let result: ITextEditorPositionData = Object.create(null);
		for (let workbenchEditor of this._workbenchEditorService.getVisibleEditors()) {
J
Johannes Rieken 已提交
96 97 98
			const id = this._documentsAndEditors.findTextEditorIdFor(workbenchEditor);
			if (id) {
				result[id] = workbenchEditor.position;
99
			}
E
Erich Gamma 已提交
100
		}
101
		return result;
E
Erich Gamma 已提交
102 103
	}

104
	// --- from extension host process
E
Erich Gamma 已提交
105

106
	$tryShowTextDocument(resource: URI, position: EditorPosition, preserveFocus: boolean): TPromise<string> {
E
Erich Gamma 已提交
107

108 109
		const input = {
			resource,
J
Johannes Rieken 已提交
110
			options: { preserveFocus, pinned: true }
E
Erich Gamma 已提交
111 112
		};

113 114
		return this._workbenchEditorService.openEditor(input, position).then(editor => {
			if (!editor) {
M
Matt Bierner 已提交
115
				return undefined;
E
Erich Gamma 已提交
116
			}
J
Johannes Rieken 已提交
117
			return this._documentsAndEditors.findTextEditorIdFor(editor);
E
Erich Gamma 已提交
118 119 120
		});
	}

121
	$tryShowEditor(id: string, position: EditorPosition): TPromise<void> {
122 123
		// check how often this is used
		this._telemetryService.publicLog('api.deprecated', { function: 'TextEditor.show' });
E
Erich Gamma 已提交
124

J
Johannes Rieken 已提交
125
		let mainThreadEditor = this._documentsAndEditors.getEditor(id);
126 127 128 129 130 131
		if (mainThreadEditor) {
			let model = mainThreadEditor.getModel();
			return this._workbenchEditorService.openEditor({
				resource: model.uri,
				options: { preserveFocus: false }
			}, position).then(() => { return; });
E
Erich Gamma 已提交
132
		}
M
Matt Bierner 已提交
133
		return undefined;
E
Erich Gamma 已提交
134 135
	}

136
	$tryHideEditor(id: string): TPromise<void> {
137 138 139
		// check how often this is used
		this._telemetryService.publicLog('api.deprecated', { function: 'TextEditor.hide' });

J
Johannes Rieken 已提交
140
		let mainThreadEditor = this._documentsAndEditors.getEditor(id);
141 142 143 144 145
		if (mainThreadEditor) {
			let editors = this._workbenchEditorService.getVisibleEditors();
			for (let editor of editors) {
				if (mainThreadEditor.matches(editor)) {
					return this._workbenchEditorService.closeEditor(editor.position, editor.input).then(() => { return; });
E
Erich Gamma 已提交
146 147 148
				}
			}
		}
M
Matt Bierner 已提交
149
		return undefined;
E
Erich Gamma 已提交
150 151
	}

152
	$trySetSelections(id: string, selections: ISelection[]): TPromise<any> {
J
Johannes Rieken 已提交
153
		if (!this._documentsAndEditors.getEditor(id)) {
154
			return TPromise.wrapError('TextEditor disposed');
E
Erich Gamma 已提交
155
		}
J
Johannes Rieken 已提交
156
		this._documentsAndEditors.getEditor(id).setSelections(selections);
157
		return TPromise.as(null);
E
Erich Gamma 已提交
158 159
	}

160
	$trySetDecorations(id: string, key: string, ranges: IDecorationOptions[]): TPromise<any> {
J
Johannes Rieken 已提交
161
		if (!this._documentsAndEditors.getEditor(id)) {
162 163
			return TPromise.wrapError('TextEditor disposed');
		}
J
Johannes Rieken 已提交
164
		this._documentsAndEditors.getEditor(id).setDecorations(key, ranges);
165
		return TPromise.as(null);
E
Erich Gamma 已提交
166 167
	}

168
	$tryRevealRange(id: string, range: IRange, revealType: TextEditorRevealType): TPromise<any> {
J
Johannes Rieken 已提交
169
		if (!this._documentsAndEditors.getEditor(id)) {
170 171
			return TPromise.wrapError('TextEditor disposed');
		}
J
Johannes Rieken 已提交
172
		this._documentsAndEditors.getEditor(id).revealRange(range, revealType);
M
Matt Bierner 已提交
173
		return undefined;
E
Erich Gamma 已提交
174 175
	}

176
	$trySetOptions(id: string, options: ITextEditorConfigurationUpdate): TPromise<any> {
J
Johannes Rieken 已提交
177
		if (!this._documentsAndEditors.getEditor(id)) {
178
			return TPromise.wrapError('TextEditor disposed');
E
Erich Gamma 已提交
179
		}
J
Johannes Rieken 已提交
180
		this._documentsAndEditors.getEditor(id).setConfiguration(options);
181
		return TPromise.as(null);
E
Erich Gamma 已提交
182 183
	}

J
Johannes Rieken 已提交
184
	$tryApplyEdits(id: string, modelVersionId: number, edits: ISingleEditOperation[], opts: IApplyEditsOptions): TPromise<boolean> {
J
Johannes Rieken 已提交
185
		if (!this._documentsAndEditors.getEditor(id)) {
186 187
			return TPromise.wrapError('TextEditor disposed');
		}
J
Johannes Rieken 已提交
188
		return TPromise.as(this._documentsAndEditors.getEditor(id).applyEdits(modelVersionId, edits, opts));
E
Erich Gamma 已提交
189 190
	}

191
	$tryInsertSnippet(id: string, template: string, ranges: IRange[], opts: IUndoStopOptions): TPromise<boolean> {
J
Johannes Rieken 已提交
192
		if (!this._documentsAndEditors.getEditor(id)) {
193 194
			return TPromise.wrapError('TextEditor disposed');
		}
J
Johannes Rieken 已提交
195
		return TPromise.as(this._documentsAndEditors.getEditor(id).insertSnippet(template, ranges, opts));
196 197
	}

198
	$registerTextEditorDecorationType(key: string, options: IDecorationRenderOptions): void {
J
Johannes Rieken 已提交
199
		this._codeEditorService.registerDecorationType(key, options);
E
Erich Gamma 已提交
200 201
	}

202
	$removeTextEditorDecorationType(key: string): void {
J
Johannes Rieken 已提交
203
		this._codeEditorService.removeDecorationType(key);
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220
	}

	$getDiffInformation(id: string): TPromise<ILineChange[]> {
		const editor = this._documentsAndEditors.getEditor(id);

		if (!editor) {
			return TPromise.wrapError('No such TextEditor');
		}

		const codeEditor = editor.getCodeEditor();
		const codeEditorId = codeEditor.getId();
		const diffEditors = this._codeEditorService.listDiffEditors();
		const [diffEditor] = diffEditors.filter(d => d.getOriginalEditor().getId() === codeEditorId || d.getModifiedEditor().getId() === codeEditorId);

		if (!diffEditor) {
			return TPromise.as([]);
		}
J
Johannes Rieken 已提交
221

222
		return TPromise.as(diffEditor.getLineChanges());
E
Erich Gamma 已提交
223
	}
A
Alex Dima 已提交
224
}