editorActions.ts 46.9 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';

J
Johannes Rieken 已提交
7
import { TPromise } from 'vs/base/common/winjs.base';
E
Erich Gamma 已提交
8
import nls = require('vs/nls');
J
Johannes Rieken 已提交
9
import { Action } from 'vs/base/common/actions';
10
import { mixin } from 'vs/base/common/objects';
11
import { getCodeEditor } from 'vs/editor/browser/services/codeEditorService';
12
import { EditorInput, TextEditorOptions, EditorOptions, IEditorIdentifier, IEditorContext, ActiveEditorMoveArguments, ActiveEditorMovePositioning, EditorCommands, ConfirmResult } from 'vs/workbench/common/editor';
J
Johannes Rieken 已提交
13 14 15
import { QuickOpenEntryGroup } from 'vs/base/parts/quickopen/browser/quickOpenModel';
import { EditorQuickOpenEntry, EditorQuickOpenEntryGroup, IEditorQuickOpenEntry, QuickOpenAction } from 'vs/workbench/browser/quickopen';
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
J
Johannes Rieken 已提交
16
import { IQuickOpenService } from 'vs/platform/quickOpen/common/quickOpen';
J
Johannes Rieken 已提交
17
import { IPartService } from 'vs/workbench/services/part/common/partService';
18
import { Position, IEditor, Direction, IResourceInput, IEditorInput } from 'vs/platform/editor/common/editor';
J
Johannes Rieken 已提交
19 20 21 22
import { IHistoryService } from 'vs/workbench/services/history/common/history';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IEditorGroupService, GroupArrangement } from 'vs/workbench/services/group/common/groupService';
import { ICommandService } from 'vs/platform/commands/common/commands';
23
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
C
22768  
Cristian 已提交
24
import { IWindowsService } from 'vs/platform/windows/common/windows';
E
Erich Gamma 已提交
25 26 27

export class SplitEditorAction extends Action {

M
Matt Bierner 已提交
28 29
	public static readonly ID = 'workbench.action.splitEditor';
	public static readonly LABEL = nls.localize('splitEditor', "Split Editor");
30

31 32 33 34 35 36
	constructor(
		id: string,
		label: string,
		@IWorkbenchEditorService private editorService: IWorkbenchEditorService,
		@IEditorGroupService private editorGroupService: IEditorGroupService
	) {
I
isidor 已提交
37
		super(id, label, 'split-editor-action');
E
Erich Gamma 已提交
38 39
	}

B
Benjamin Pasero 已提交
40
	public run(context?: IEditorContext): TPromise<any> {
41 42 43 44 45 46
		let editorToSplit: IEditor;
		if (context) {
			editorToSplit = this.editorService.getVisibleEditors()[this.editorGroupService.getStacksModel().positionOfGroup(context.group)];
		} else {
			editorToSplit = this.editorService.getActiveEditor();
		}
E
Erich Gamma 已提交
47

48 49
		// Can only split with target editor
		if (!editorToSplit) {
A
Alex Dima 已提交
50
			return TPromise.as(true);
E
Erich Gamma 已提交
51 52 53
		}

		// Return if the editor to split does not support split editing
54
		if (editorToSplit.input instanceof EditorInput && !(<EditorInput>editorToSplit.input).supportsSplitEditor()) {
A
Alex Dima 已提交
55
			return TPromise.as(true);
E
Erich Gamma 已提交
56 57
		}

58 59
		// Options
		let options: EditorOptions;
S
Sandeep Somavarapu 已提交
60 61
		const codeEditor = getCodeEditor(editorToSplit);
		if (codeEditor) {
62
			options = TextEditorOptions.fromEditor(codeEditor);
63 64 65 66 67
		} else {
			options = new EditorOptions();
		}
		options.pinned = true;

E
Erich Gamma 已提交
68
		// Count editors
69 70
		const visibleEditors = this.editorService.getVisibleEditors();
		const editorCount = visibleEditors.length;
E
Erich Gamma 已提交
71 72 73 74
		let targetPosition: Position;

		switch (editorCount) {

B
Benjamin Pasero 已提交
75
			// Open split editor to the right/bottom of left/top one
E
Erich Gamma 已提交
76
			case 1:
77
				targetPosition = Position.TWO;
E
Erich Gamma 已提交
78 79 80 81 82
				break;

			// Special case two editors opened
			case 2:

B
Benjamin Pasero 已提交
83
				// Continue splitting to the right/bottom
84 85
				if (editorToSplit.position === Position.TWO) {
					targetPosition = Position.THREE;
E
Erich Gamma 已提交
86 87
				}

88
				// Push the second group to the right/bottom to make room for the splitted input
89
				else if (editorToSplit.position === Position.ONE) {
E
Erich Gamma 已提交
90 91
					options.preserveFocus = true;

92 93 94
					return this.editorService.openEditor(editorToSplit.input, options, Position.THREE).then(() => {
						this.editorGroupService.moveGroup(Position.THREE, Position.TWO);
						this.editorGroupService.focusGroup(Position.TWO);
E
Erich Gamma 已提交
95 96 97 98
					});
				}
		}

99 100
		// Only split if we have a target position to split to
		if (typeof targetPosition === 'number') {
101
			return this.editorService.openEditor(editorToSplit.input, options, targetPosition);
E
Erich Gamma 已提交
102 103
		}

A
Alex Dima 已提交
104
		return TPromise.as(true);
E
Erich Gamma 已提交
105 106 107
	}
}

108
export class JoinTwoGroupsAction extends Action {
I
initialshl 已提交
109

M
Matt Bierner 已提交
110 111
	public static readonly ID = 'workbench.action.joinTwoGroups';
	public static readonly LABEL = nls.localize('joinTwoGroups', "Join Editors of Two Groups");
I
initialshl 已提交
112 113 114 115 116 117

	constructor(
		id: string,
		label: string,
		@IEditorGroupService private editorGroupService: IEditorGroupService
	) {
118
		super(id, label);
I
initialshl 已提交
119 120 121 122
	}

	public run(context?: IEditorContext): TPromise<any> {

123
		const editorStacksModel = this.editorGroupService.getStacksModel();
I
initialshl 已提交
124 125

		// Return if has no other group to join to
126
		if (editorStacksModel.groups.length < 2) {
I
initialshl 已提交
127 128 129
			return TPromise.as(true);
		}

130 131 132 133 134 135 136 137 138
		let fromPosition: number;
		let toPosition: number;

		// Joining group is from context, or the active group
		if (context) {
			fromPosition = editorStacksModel.positionOfGroup(context.group);
		} else {
			fromPosition = editorStacksModel.positionOfGroup(editorStacksModel.activeGroup);
		}
I
initialshl 已提交
139

140 141 142
		// Target group is next group if joining from position one, otherwise it is the previous group
		if (fromPosition === Position.ONE) {
			toPosition = fromPosition + 1;
I
initialshl 已提交
143
		} else {
144
			toPosition = fromPosition - 1;
I
initialshl 已提交
145 146
		}

147 148
		const fromGroup = editorStacksModel.groupAt(fromPosition);
		const toGroup = editorStacksModel.groupAt(toPosition);
I
initialshl 已提交
149

150 151
		const activeEditor = fromGroup.activeEditor;
		const fromGroupEditors = fromGroup.getEditors();
I
initialshl 已提交
152

153 154 155 156 157 158 159 160 161 162 163
		// Insert the editors to the start if moving to the next group, otherwise insert to the end
		// If an editor exists in both groups, its index is respected as in the joining group
		const movingToNextGroup = fromPosition < toPosition;
		let index = movingToNextGroup ? 0 : toGroup.count;

		// Inactive and preserve focus options are used to prevent unnecessary switchings of active editor or group
		fromGroupEditors.forEach(e => {
			const inactive = e !== activeEditor;
			this.editorGroupService.moveEditor(e, fromPosition, toPosition, { index, inactive, preserveFocus: inactive });
			index = movingToNextGroup ? index + 1 : toGroup.count;
		});
I
initialshl 已提交
164

165 166
		// Focus may be lost when the joining group is closed, regain focus on the target group
		this.editorGroupService.focusGroup(toGroup);
I
initialshl 已提交
167 168 169 170 171

		return TPromise.as(true);
	}
}

B
Benjamin Pasero 已提交
172
export class NavigateBetweenGroupsAction extends Action {
173

M
Matt Bierner 已提交
174 175
	public static readonly ID = 'workbench.action.navigateEditorGroups';
	public static readonly LABEL = nls.localize('navigateEditorGroups', "Navigate Between Editor Groups");
E
Erich Gamma 已提交
176

177 178 179 180 181 182
	constructor(
		id: string,
		label: string,
		@IWorkbenchEditorService private editorService: IWorkbenchEditorService,
		@IEditorGroupService private editorGroupService: IEditorGroupService
	) {
E
Erich Gamma 已提交
183 184 185
		super(id, label);
	}

186
	public run(): TPromise<any> {
E
Erich Gamma 已提交
187 188

		// Can cycle split with active editor
189
		const activeEditor = this.editorService.getActiveEditor();
E
Erich Gamma 已提交
190
		if (!activeEditor) {
A
Alex Dima 已提交
191
			return TPromise.as(false);
E
Erich Gamma 已提交
192 193
		}

B
Benjamin Pasero 已提交
194
		// Cycle to the left/top and use module to start at 0 again
195 196 197
		const visibleEditors = this.editorService.getVisibleEditors();
		const editorCount = visibleEditors.length;
		const newIndex = (activeEditor.position + 1) % editorCount;
E
Erich Gamma 已提交
198

199
		this.editorGroupService.focusGroup(<Position>newIndex);
200 201

		return TPromise.as(true);
E
Erich Gamma 已提交
202 203 204
	}
}

205 206
export class FocusActiveGroupAction extends Action {

M
Matt Bierner 已提交
207 208
	public static readonly ID = 'workbench.action.focusActiveEditorGroup';
	public static readonly LABEL = nls.localize('focusActiveEditorGroup', "Focus Active Editor Group");
209 210 211 212 213 214 215 216 217 218

	constructor(
		id: string,
		label: string,
		@IWorkbenchEditorService private editorService: IWorkbenchEditorService
	) {
		super(id, label);
	}

	public run(): TPromise<any> {
B
hygiene  
Benjamin Pasero 已提交
219 220
		const activeEditor = this.editorService.getActiveEditor();
		if (activeEditor) {
D
Daniel Imms 已提交
221
			activeEditor.focus();
B
hygiene  
Benjamin Pasero 已提交
222
		}
D
Daniel Imms 已提交
223

224
		return TPromise.as(true);
E
Erich Gamma 已提交
225 226 227
	}
}

228 229
export class FocusFirstGroupAction extends Action {

M
Matt Bierner 已提交
230 231
	public static readonly ID = 'workbench.action.focusFirstEditorGroup';
	public static readonly LABEL = nls.localize('focusFirstEditorGroup', "Focus First Editor Group");
E
Erich Gamma 已提交
232 233 234 235 236

	constructor(
		id: string,
		label: string,
		@IWorkbenchEditorService private editorService: IWorkbenchEditorService,
237
		@IEditorGroupService private editorGroupService: IEditorGroupService,
238
		@IHistoryService private historyService: IHistoryService
E
Erich Gamma 已提交
239 240 241 242
	) {
		super(id, label);
	}

243
	public run(): TPromise<any> {
E
Erich Gamma 已提交
244

B
Benjamin Pasero 已提交
245
		// Find left/top editor and focus it
246
		const editors = this.editorService.getVisibleEditors();
B
Benjamin Pasero 已提交
247
		for (let editor of editors) {
248 249
			if (editor.position === Position.ONE) {
				this.editorGroupService.focusGroup(Position.ONE);
250 251

				return TPromise.as(true);
E
Erich Gamma 已提交
252 253 254 255
			}
		}

		// Since no editor is currently opened, try to open last history entry to the target side
256
		const history = this.historyService.getHistory();
257 258
		if (history.length > 0) {
			const input = history[0];
259
			if (input instanceof EditorInput) {
260
				return this.editorService.openEditor(input, null, Position.ONE);
E
Erich Gamma 已提交
261
			}
262 263

			return this.editorService.openEditor(input as IResourceInput, Position.ONE);
E
Erich Gamma 已提交
264 265
		}

A
Alex Dima 已提交
266
		return TPromise.as(true);
E
Erich Gamma 已提交
267 268 269
	}
}

270
export abstract class BaseFocusSideGroupAction extends Action {
E
Erich Gamma 已提交
271 272 273 274 275

	constructor(
		id: string,
		label: string,
		@IWorkbenchEditorService private editorService: IWorkbenchEditorService,
276
		@IEditorGroupService private editorGroupService: IEditorGroupService,
277
		@IHistoryService private historyService: IHistoryService
E
Erich Gamma 已提交
278 279 280 281 282 283 284 285
	) {
		super(id, label);
	}

	protected abstract getReferenceEditorSide(): Position;

	protected abstract getTargetEditorSide(): Position;

286
	public run(): TPromise<any> {
E
Erich Gamma 已提交
287 288

		// Require at least the reference editor to be visible
289
		const editors = this.editorService.getVisibleEditors();
E
Erich Gamma 已提交
290 291
		let referenceEditor: IEditor;
		for (let i = 0; i < editors.length; i++) {
292
			const editor = editors[i];
E
Erich Gamma 已提交
293 294 295

			// Target editor exists so focus it
			if (editor.position === this.getTargetEditorSide()) {
296
				this.editorGroupService.focusGroup(editor.position);
297 298

				return TPromise.as(true);
E
Erich Gamma 已提交
299 300 301 302 303 304 305 306 307
			}

			// Remember reference editor
			if (editor.position === this.getReferenceEditorSide()) {
				referenceEditor = editor;
			}
		}

		// Require the reference editor to be visible and supporting split editor
308
		if (referenceEditor && (<EditorInput>referenceEditor.input).supportsSplitEditor()) {
309 310 311

			// Options
			let options: EditorOptions;
S
Sandeep Somavarapu 已提交
312 313
			const codeEditor = getCodeEditor(referenceEditor);
			if (codeEditor) {
314
				options = TextEditorOptions.fromEditor(codeEditor, { pinned: true });
315 316
			} else {
				options = EditorOptions.create({ pinned: true });
317 318 319
			}

			return this.editorService.openEditor(referenceEditor.input, options, this.getTargetEditorSide());
E
Erich Gamma 已提交
320 321 322 323
		}

		// Otherwise try to find a history entry to open to the target editor side
		else if (referenceEditor) {
324
			const history = this.historyService.getHistory();
B
Benjamin Pasero 已提交
325
			for (let input of history) {
B
Benjamin Pasero 已提交
326 327 328 329 330 331
				if (input instanceof EditorInput) {
					if (input.supportsSplitEditor()) {
						return this.editorService.openEditor(input, { pinned: true }, this.getTargetEditorSide());
					}
				} else {
					return this.editorService.openEditor({ resource: (input as IResourceInput).resource, options: { pinned: true } }, this.getTargetEditorSide());
E
Erich Gamma 已提交
332 333 334 335
				}
			}
		}

A
Alex Dima 已提交
336
		return TPromise.as(true);
E
Erich Gamma 已提交
337 338 339
	}
}

340 341
export class FocusSecondGroupAction extends BaseFocusSideGroupAction {

M
Matt Bierner 已提交
342 343
	public static readonly ID = 'workbench.action.focusSecondEditorGroup';
	public static readonly LABEL = nls.localize('focusSecondEditorGroup', "Focus Second Editor Group");
E
Erich Gamma 已提交
344 345 346 347 348

	constructor(
		id: string,
		label: string,
		@IWorkbenchEditorService editorService: IWorkbenchEditorService,
349
		@IEditorGroupService editorGroupService: IEditorGroupService,
350
		@IHistoryService historyService: IHistoryService
E
Erich Gamma 已提交
351
	) {
352
		super(id, label, editorService, editorGroupService, historyService);
E
Erich Gamma 已提交
353 354 355
	}

	protected getReferenceEditorSide(): Position {
356
		return Position.ONE;
E
Erich Gamma 已提交
357 358 359
	}

	protected getTargetEditorSide(): Position {
360
		return Position.TWO;
E
Erich Gamma 已提交
361 362 363
	}
}

364 365
export class FocusThirdGroupAction extends BaseFocusSideGroupAction {

M
Matt Bierner 已提交
366 367
	public static readonly ID = 'workbench.action.focusThirdEditorGroup';
	public static readonly LABEL = nls.localize('focusThirdEditorGroup', "Focus Third Editor Group");
E
Erich Gamma 已提交
368 369 370 371 372

	constructor(
		id: string,
		label: string,
		@IWorkbenchEditorService editorService: IWorkbenchEditorService,
373
		@IEditorGroupService editorGroupService: IEditorGroupService,
374
		@IHistoryService historyService: IHistoryService
E
Erich Gamma 已提交
375
	) {
376
		super(id, label, editorService, editorGroupService, historyService);
E
Erich Gamma 已提交
377 378 379
	}

	protected getReferenceEditorSide(): Position {
380
		return Position.TWO;
E
Erich Gamma 已提交
381 382 383
	}

	protected getTargetEditorSide(): Position {
384
		return Position.THREE;
E
Erich Gamma 已提交
385 386 387
	}
}

B
Benjamin Pasero 已提交
388
export class FocusPreviousGroup extends Action {
389

M
Matt Bierner 已提交
390 391
	public static readonly ID = 'workbench.action.focusPreviousGroup';
	public static readonly LABEL = nls.localize('focusPreviousGroup', "Focus Previous Group");
E
Erich Gamma 已提交
392

393 394 395 396 397 398
	constructor(
		id: string,
		label: string,
		@IEditorGroupService private editorGroupService: IEditorGroupService,
		@IWorkbenchEditorService private editorService: IWorkbenchEditorService
	) {
E
Erich Gamma 已提交
399 400 401
		super(id, label);
	}

402
	public run(): TPromise<any> {
E
Erich Gamma 已提交
403 404

		// Require an active editor
405
		const activeEditor = this.editorService.getActiveEditor();
E
Erich Gamma 已提交
406
		if (!activeEditor) {
A
Alex Dima 已提交
407
			return TPromise.as(true);
E
Erich Gamma 已提交
408 409
		}

410 411
		const stacks = this.editorGroupService.getStacksModel();
		const groupCount = stacks.groups.length;
E
Erich Gamma 已提交
412

413 414 415
		// Nothing to do if the only group
		if (groupCount === 1) {
			return TPromise.as(true);
E
Erich Gamma 已提交
416 417
		}

418 419 420
		// Nevigate to the previous group or to the last group if the first group is active
		const newPositionIndex = (activeEditor.position + groupCount - 1) % groupCount;
		this.editorGroupService.focusGroup(<Position>newPositionIndex);
421 422

		return TPromise.as(true);
E
Erich Gamma 已提交
423 424 425
	}
}

B
Benjamin Pasero 已提交
426
export class FocusNextGroup extends Action {
427

M
Matt Bierner 已提交
428 429
	public static readonly ID = 'workbench.action.focusNextGroup';
	public static readonly LABEL = nls.localize('focusNextGroup', "Focus Next Group");
430

E
Erich Gamma 已提交
431 432 433
	constructor(
		id: string,
		label: string,
434 435
		@IEditorGroupService private editorGroupService: IEditorGroupService,
		@IWorkbenchEditorService private editorService: IWorkbenchEditorService
E
Erich Gamma 已提交
436 437 438 439
	) {
		super(id, label);
	}

440
	public run(event?: any): TPromise<any> {
E
Erich Gamma 已提交
441

442
		const activeEditor = this.editorService.getActiveEditor();
443

444 445
		if (!activeEditor) {
			return TPromise.as(true);
E
Erich Gamma 已提交
446 447
		}

448 449 450 451 452 453
		const stacks = this.editorGroupService.getStacksModel();
		const groupCount = stacks.groups.length;

		// Nowhere to switch if the only group
		if (groupCount === 1) {
			return TPromise.as(true);
E
Erich Gamma 已提交
454 455
		}

456 457 458 459
		// Nevigate to the next group or to the first group if the last group is active
		const newPositionIndex = (activeEditor.position + 1) % groupCount;
		this.editorGroupService.focusGroup(<Position>newPositionIndex);

A
Alex Dima 已提交
460
		return TPromise.as(true);
E
Erich Gamma 已提交
461 462 463 464 465
	}
}

export class OpenToSideAction extends Action {

M
Matt Bierner 已提交
466 467
	public static readonly OPEN_TO_SIDE_ID = 'workbench.action.openToSide';
	public static readonly OPEN_TO_SIDE_LABEL = nls.localize('openToSide', "Open to the Side");
E
Erich Gamma 已提交
468

469 470
	constructor(
		@IWorkbenchEditorService private editorService: IWorkbenchEditorService,
471
		@IEditorGroupService private editorGroupService: IEditorGroupService
472
	) {
E
Erich Gamma 已提交
473 474 475
		super(OpenToSideAction.OPEN_TO_SIDE_ID, OpenToSideAction.OPEN_TO_SIDE_LABEL);

		this.updateEnablement();
476 477 478 479
		this.updateClass();
	}

	public updateClass(): void {
480
		const editorGroupLayoutVertical = (this.editorGroupService.getGroupOrientation() !== 'horizontal');
481

482
		this.class = editorGroupLayoutVertical ? 'quick-open-sidebyside-vertical' : 'quick-open-sidebyside-horizontal';
E
Erich Gamma 已提交
483 484 485
	}

	private updateEnablement(): void {
486
		const activeEditor = this.editorService.getActiveEditor();
487
		this.enabled = (!activeEditor || activeEditor.position !== Position.THREE);
E
Erich Gamma 已提交
488 489
	}

490
	public run(context: any): TPromise<any> {
E
Erich Gamma 已提交
491 492
		let entry = toEditorQuickOpenEntry(context);
		if (entry) {
493
			const input = entry.getInput();
B
Benjamin Pasero 已提交
494
			if (input instanceof EditorInput) {
495
				return this.editorService.openEditor(input, entry.getOptions(), true);
B
Benjamin Pasero 已提交
496 497
			}

498 499 500 501
			const resourceInput = input as IResourceInput;
			resourceInput.options = mixin(resourceInput.options, entry.getOptions());

			return this.editorService.openEditor(resourceInput, true);
E
Erich Gamma 已提交
502 503
		}

A
Alex Dima 已提交
504
		return TPromise.as(false);
E
Erich Gamma 已提交
505 506 507
	}
}

508
export function toEditorQuickOpenEntry(element: any): IEditorQuickOpenEntry {
E
Erich Gamma 已提交
509 510 511

	// QuickOpenEntryGroup
	if (element instanceof QuickOpenEntryGroup) {
512
		const group = <QuickOpenEntryGroup>element;
E
Erich Gamma 已提交
513 514 515 516 517 518 519 520 521 522 523 524 525 526
		if (group.getEntry()) {
			element = group.getEntry();
		}
	}

	// EditorQuickOpenEntry or EditorQuickOpenEntryGroup both implement IEditorQuickOpenEntry
	if (element instanceof EditorQuickOpenEntry || element instanceof EditorQuickOpenEntryGroup) {
		return element;
	}

	return null;
}

export class CloseEditorAction extends Action {
527

M
Matt Bierner 已提交
528 529
	public static readonly ID = 'workbench.action.closeActiveEditor';
	public static readonly LABEL = nls.localize('closeEditor', "Close Editor");
530

531 532 533 534 535 536
	constructor(
		id: string,
		label: string,
		@IEditorGroupService private editorGroupService: IEditorGroupService,
		@IWorkbenchEditorService private editorService: IWorkbenchEditorService
	) {
I
isidor 已提交
537
		super(id, label, 'close-editor-action');
E
Erich Gamma 已提交
538 539
	}

B
Benjamin Pasero 已提交
540
	public run(context?: IEditorContext): TPromise<any> {
541
		const position = context ? this.editorGroupService.getStacksModel().positionOfGroup(context.group) : null;
542

543
		// Close Active Editor
544
		if (typeof position !== 'number') {
545
			const activeEditor = this.editorService.getActiveEditor();
B
Benjamin Pasero 已提交
546
			if (activeEditor) {
547
				return this.editorService.closeEditor(activeEditor.position, activeEditor.input);
B
Benjamin Pasero 已提交
548
			}
549 550
		}

I
isidor 已提交
551
		let input = context ? context.editor : null;
I
isidor 已提交
552
		if (!input) {
B
Benjamin Pasero 已提交
553

I
isidor 已提交
554
			// Get Top Editor at Position
555
			const visibleEditors = this.editorService.getVisibleEditors();
I
isidor 已提交
556
			if (visibleEditors[position]) {
557
				input = visibleEditors[position].input;
I
isidor 已提交
558 559 560 561 562
			}
		}

		if (input) {
			return this.editorService.closeEditor(position, input);
E
Erich Gamma 已提交
563 564
		}

A
Alex Dima 已提交
565
		return TPromise.as(false);
E
Erich Gamma 已提交
566 567 568
	}
}

M
misoguy 已提交
569 570
export class RevertAndCloseEditorAction extends Action {

M
Matt Bierner 已提交
571 572
	public static readonly ID = 'workbench.action.revertAndCloseActiveEditor';
	public static readonly LABEL = nls.localize('revertAndCloseActiveEditor', "Revert and Close Editor");
M
misoguy 已提交
573 574 575 576 577 578 579 580 581 582 583

	constructor(
		id: string,
		label: string,
		@IWorkbenchEditorService private editorService: IWorkbenchEditorService,
	) {
		super(id, label);
	}

	public run(): TPromise<any> {
		const activeEditor = this.editorService.getActiveEditor();
B
Benjamin Pasero 已提交
584 585 586 587
		if (activeEditor && activeEditor.input) {
			const input = activeEditor.input;
			const position = activeEditor.position;

588 589 590 591 592 593 594 595
			// first try a normal revert where the contents of the editor are restored
			return activeEditor.input.revert().then(() => this.editorService.closeEditor(position, input), error => {
				// if that fails, since we are about to close the editor, we accept that
				// the editor cannot be reverted and instead do a soft revert that just
				// enables us to close the editor. With this, a user can always close a
				// dirty editor even when reverting fails.
				return activeEditor.input.revert({ soft: true }).then(() => this.editorService.closeEditor(position, input));
			});
M
misoguy 已提交
596 597 598 599 600 601
		}

		return TPromise.as(false);
	}
}

B
Benjamin Pasero 已提交
602
export class CloseLeftEditorsInGroupAction extends Action {
603

M
Matt Bierner 已提交
604 605
	public static readonly ID = 'workbench.action.closeEditorsToTheLeft';
	public static readonly LABEL = nls.localize('closeEditorsToTheLeft', "Close Editors to the Left");
606

607 608 609
	constructor(
		id: string,
		label: string,
B
Benjamin Pasero 已提交
610 611
		@IWorkbenchEditorService private editorService: IWorkbenchEditorService,
		@IEditorGroupService private groupService: IEditorGroupService
612
	) {
613 614 615
		super(id, label);
	}

B
Benjamin Pasero 已提交
616
	public run(context?: IEditorContext): TPromise<any> {
617
		const editor = getTarget(this.editorService, this.groupService, context);
B
Benjamin Pasero 已提交
618
		if (editor) {
B
Benjamin Pasero 已提交
619
			return this.editorService.closeEditors(editor.position, { except: editor.input, direction: Direction.LEFT });
620 621 622 623 624 625 626 627
		}

		return TPromise.as(false);
	}
}

export class CloseRightEditorsInGroupAction extends Action {

M
Matt Bierner 已提交
628 629
	public static readonly ID = 'workbench.action.closeEditorsToTheRight';
	public static readonly LABEL = nls.localize('closeEditorsToTheRight', "Close Editors to the Right");
630

B
Benjamin Pasero 已提交
631 632 633 634 635 636
	constructor(
		id: string,
		label: string,
		@IWorkbenchEditorService private editorService: IWorkbenchEditorService,
		@IEditorGroupService private groupService: IEditorGroupService
	) {
637 638 639
		super(id, label);
	}

B
Benjamin Pasero 已提交
640
	public run(context?: IEditorContext): TPromise<any> {
641
		const editor = getTarget(this.editorService, this.groupService, context);
B
Benjamin Pasero 已提交
642
		if (editor) {
B
Benjamin Pasero 已提交
643
			return this.editorService.closeEditors(editor.position, { except: editor.input, direction: Direction.RIGHT });
644 645 646 647 648 649
		}

		return TPromise.as(false);
	}
}

E
Erich Gamma 已提交
650 651
export class CloseAllEditorsAction extends Action {

M
Matt Bierner 已提交
652 653
	public static readonly ID = 'workbench.action.closeAllEditors';
	public static readonly LABEL = nls.localize('closeAllEditors', "Close All Editors");
654

655 656 657 658 659 660
	constructor(
		id: string,
		label: string,
		@ITextFileService private textFileService: ITextFileService,
		@IWorkbenchEditorService private editorService: IWorkbenchEditorService
	) {
I
isidor 已提交
661
		super(id, label, 'action-close-all-files');
E
Erich Gamma 已提交
662 663
	}

664
	public run(): TPromise<any> {
665 666 667 668 669 670 671

		// Just close all if there are no or one dirty editor
		if (this.textFileService.getDirty().length < 2) {
			return this.editorService.closeAllEditors();
		}

		// Otherwise ask for combined confirmation
672 673 674 675
		return this.textFileService.confirmSave().then(confirm => {
			if (confirm === ConfirmResult.CANCEL) {
				return void 0;
			}
676

677 678 679 680 681
			let saveOrRevertPromise: TPromise<boolean>;
			if (confirm === ConfirmResult.DONT_SAVE) {
				saveOrRevertPromise = this.textFileService.revertAll(null, { soft: true }).then(() => true);
			} else {
				saveOrRevertPromise = this.textFileService.saveAll(true).then(res => res.results.every(r => r.success));
682
			}
683

684 685 686 687 688 689 690
			return saveOrRevertPromise.then(success => {
				if (success) {
					return this.editorService.closeAllEditors();
				}

				return void 0;
			});
691
		});
E
Erich Gamma 已提交
692 693 694
	}
}

695 696
export class CloseUnmodifiedEditorsInGroupAction extends Action {

M
Matt Bierner 已提交
697 698
	public static readonly ID = 'workbench.action.closeUnmodifiedEditors';
	public static readonly LABEL = nls.localize('closeUnmodifiedEditors', "Close Unmodified Editors in Group");
699 700 701 702 703 704 705 706 707 708 709

	constructor(
		id: string,
		label: string,
		@IEditorGroupService private editorGroupService: IEditorGroupService,
		@IWorkbenchEditorService private editorService: IWorkbenchEditorService
	) {
		super(id, label);
	}

	public run(context?: IEditorContext): TPromise<any> {
B
Benjamin Pasero 已提交
710 711 712 713 714 715 716 717 718 719 720 721
		let position = context ? this.editorGroupService.getStacksModel().positionOfGroup(context.group) : null;

		// If position is not passed in take the position of the active editor.
		if (typeof position !== 'number') {
			const active = this.editorService.getActiveEditor();
			if (active) {
				position = active.position;
			}
		}

		if (typeof position === 'number') {
			return this.editorService.closeEditors(position, { unmodifiedOnly: true });
722 723 724 725 726 727
		}

		return TPromise.as(false);
	}
}

728 729
export class CloseEditorsInOtherGroupsAction extends Action {

M
Matt Bierner 已提交
730 731
	public static readonly ID = 'workbench.action.closeEditorsInOtherGroups';
	public static readonly LABEL = nls.localize('closeEditorsInOtherGroups', "Close Editors in Other Groups");
732

733 734 735 736 737 738
	constructor(
		id: string,
		label: string,
		@IEditorGroupService private editorGroupService: IEditorGroupService,
		@IWorkbenchEditorService private editorService: IWorkbenchEditorService
	) {
739 740 741
		super(id, label);
	}

B
Benjamin Pasero 已提交
742
	public run(context?: IEditorContext): TPromise<any> {
743
		let position = context ? this.editorGroupService.getStacksModel().positionOfGroup(context.group) : null;
744
		if (typeof position !== 'number') {
745
			const activeEditor = this.editorService.getActiveEditor();
746 747 748 749 750 751 752 753 754 755 756 757 758 759 760
			if (activeEditor) {
				position = activeEditor.position;
			}
		}

		if (typeof position === 'number') {
			return this.editorService.closeAllEditors(position);
		}

		return TPromise.as(false);
	}
}

export class CloseOtherEditorsInGroupAction extends Action {

M
Matt Bierner 已提交
761 762
	public static readonly ID = 'workbench.action.closeOtherEditors';
	public static readonly LABEL = nls.localize('closeOtherEditorsInGroup', "Close Other Editors");
E
Erich Gamma 已提交
763

764 765 766 767 768 769
	constructor(
		id: string,
		label: string,
		@IEditorGroupService private editorGroupService: IEditorGroupService,
		@IWorkbenchEditorService private editorService: IWorkbenchEditorService
	) {
E
Erich Gamma 已提交
770 771 772
		super(id, label);
	}

B
Benjamin Pasero 已提交
773
	public run(context?: IEditorContext): TPromise<any> {
774
		let position = context ? this.editorGroupService.getStacksModel().positionOfGroup(context.group) : null;
I
isidor 已提交
775
		let input = context ? context.editor : null;
I
isidor 已提交
776 777

		// If position or input are not passed in take the position and input of the active editor.
778 779
		const active = this.editorService.getActiveEditor();
		if (active) {
I
isidor 已提交
780
			position = typeof position === 'number' ? position : active.position;
781
			input = input ? input : <EditorInput>active.input;
I
isidor 已提交
782 783 784
		}

		if (typeof position === 'number' && input) {
B
Benjamin Pasero 已提交
785
			return this.editorService.closeEditors(position, { except: input });
786 787 788
		}

		return TPromise.as(false);
E
Erich Gamma 已提交
789 790 791
	}
}

B
Benjamin Pasero 已提交
792
export class CloseEditorsInGroupAction extends Action {
I
isidor 已提交
793

M
Matt Bierner 已提交
794 795
	public static readonly ID = 'workbench.action.closeEditorsInGroup';
	public static readonly LABEL = nls.localize('closeEditorsInGroup', "Close All Editors in Group");
I
isidor 已提交
796

797 798 799 800 801 802
	constructor(
		id: string,
		label: string,
		@IEditorGroupService private editorGroupService: IEditorGroupService,
		@IWorkbenchEditorService private editorService: IWorkbenchEditorService
	) {
B
Benjamin Pasero 已提交
803
		super(id, label);
I
isidor 已提交
804 805
	}

B
Benjamin Pasero 已提交
806
	public run(context?: IEditorContext): TPromise<any> {
807
		let position = context ? this.editorGroupService.getStacksModel().positionOfGroup(context.group) : null;
I
isidor 已提交
808
		if (typeof position !== 'number') {
809
			const activeEditor = this.editorService.getActiveEditor();
I
isidor 已提交
810 811 812 813 814 815 816 817
			if (activeEditor) {
				position = activeEditor.position;
			}
		}

		if (typeof position === 'number') {
			return this.editorService.closeEditors(position);
		}
B
Benjamin Pasero 已提交
818 819

		return TPromise.as(false);
I
isidor 已提交
820 821 822
	}
}

B
Benjamin Pasero 已提交
823
export class MoveGroupLeftAction extends Action {
E
Erich Gamma 已提交
824

M
Matt Bierner 已提交
825 826
	public static readonly ID = 'workbench.action.moveActiveEditorGroupLeft';
	public static readonly LABEL = nls.localize('moveActiveGroupLeft', "Move Editor Group Left");
827

828 829 830 831 832 833
	constructor(
		id: string,
		label: string,
		@IEditorGroupService private editorGroupService: IEditorGroupService,
		@IWorkbenchEditorService private editorService: IWorkbenchEditorService
	) {
E
Erich Gamma 已提交
834 835 836
		super(id, label);
	}

B
Benjamin Pasero 已提交
837
	public run(context?: IEditorContext): TPromise<any> {
838
		let position = context ? this.editorGroupService.getStacksModel().positionOfGroup(context.group) : null;
839
		if (typeof position !== 'number') {
840
			const activeEditor = this.editorService.getActiveEditor();
841
			if (activeEditor && (activeEditor.position === Position.TWO || activeEditor.position === Position.THREE)) {
842 843 844 845 846
				position = activeEditor.position;
			}
		}

		if (typeof position === 'number') {
847
			const newPosition = (position === Position.TWO) ? Position.ONE : Position.TWO;
E
Erich Gamma 已提交
848

B
Benjamin Pasero 已提交
849
			// Move group
850
			this.editorGroupService.moveGroup(position, newPosition);
E
Erich Gamma 已提交
851 852
		}

A
Alex Dima 已提交
853
		return TPromise.as(false);
E
Erich Gamma 已提交
854 855 856
	}
}

B
Benjamin Pasero 已提交
857
export class MoveGroupRightAction extends Action {
E
Erich Gamma 已提交
858

M
Matt Bierner 已提交
859 860
	public static readonly ID = 'workbench.action.moveActiveEditorGroupRight';
	public static readonly LABEL = nls.localize('moveActiveGroupRight', "Move Editor Group Right");
861

862 863 864 865 866 867
	constructor(
		id: string,
		label: string,
		@IEditorGroupService private editorGroupService: IEditorGroupService,
		@IWorkbenchEditorService private editorService: IWorkbenchEditorService
	) {
E
Erich Gamma 已提交
868 869 870
		super(id, label);
	}

B
Benjamin Pasero 已提交
871
	public run(context?: IEditorContext): TPromise<any> {
872
		let position = context ? this.editorGroupService.getStacksModel().positionOfGroup(context.group) : null;
873
		if (typeof position !== 'number') {
874 875
			const activeEditor = this.editorService.getActiveEditor();
			const editors = this.editorService.getVisibleEditors();
876

877
			if ((editors.length === 2 && activeEditor.position === Position.ONE) || (editors.length === 3 && activeEditor.position !== Position.THREE)) {
878 879 880 881 882
				position = activeEditor.position;
			}
		}

		if (typeof position === 'number') {
883
			const newPosition = (position === Position.ONE) ? Position.TWO : Position.THREE;
E
Erich Gamma 已提交
884

B
Benjamin Pasero 已提交
885
			// Move group
886
			this.editorGroupService.moveGroup(position, newPosition);
E
Erich Gamma 已提交
887 888
		}

A
Alex Dima 已提交
889
		return TPromise.as(false);
E
Erich Gamma 已提交
890 891 892
	}
}

893
export class MinimizeOtherGroupsAction extends Action {
E
Erich Gamma 已提交
894

M
Matt Bierner 已提交
895 896
	public static readonly ID = 'workbench.action.minimizeOtherEditors';
	public static readonly LABEL = nls.localize('minimizeOtherEditorGroups', "Minimize Other Editor Groups");
897

898
	constructor(id: string, label: string, @IEditorGroupService private editorGroupService: IEditorGroupService) {
E
Erich Gamma 已提交
899 900 901
		super(id, label);
	}

902
	public run(): TPromise<any> {
903
		this.editorGroupService.arrangeGroups(GroupArrangement.MINIMIZE_OTHERS);
E
Erich Gamma 已提交
904

A
Alex Dima 已提交
905
		return TPromise.as(false);
E
Erich Gamma 已提交
906 907 908
	}
}

909
export class EvenGroupWidthsAction extends Action {
E
Erich Gamma 已提交
910

M
Matt Bierner 已提交
911 912
	public static readonly ID = 'workbench.action.evenEditorWidths';
	public static readonly LABEL = nls.localize('evenEditorGroups', "Even Editor Group Widths");
913

914
	constructor(id: string, label: string, @IEditorGroupService private editorGroupService: IEditorGroupService) {
E
Erich Gamma 已提交
915 916 917
		super(id, label);
	}

918
	public run(): TPromise<any> {
B
Benjamin Pasero 已提交
919
		this.editorGroupService.arrangeGroups(GroupArrangement.EVEN);
E
Erich Gamma 已提交
920

A
Alex Dima 已提交
921
		return TPromise.as(false);
E
Erich Gamma 已提交
922 923 924
	}
}

925
export class MaximizeGroupAction extends Action {
926

M
Matt Bierner 已提交
927 928
	public static readonly ID = 'workbench.action.maximizeEditor';
	public static readonly LABEL = nls.localize('maximizeEditor', "Maximize Editor Group and Hide Sidebar");
929

930 931 932 933
	constructor(
		id: string,
		label: string,
		@IWorkbenchEditorService private editorService: IWorkbenchEditorService,
934
		@IEditorGroupService private editorGroupService: IEditorGroupService,
935 936 937 938 939
		@IPartService private partService: IPartService
	) {
		super(id, label);
	}

940
	public run(): TPromise<any> {
941
		if (this.editorService.getActiveEditor()) {
942
			this.editorGroupService.arrangeGroups(GroupArrangement.MINIMIZE_OTHERS);
943
			return this.partService.setSideBarHidden(true);
944 945
		}

A
Alex Dima 已提交
946
		return TPromise.as(false);
947 948 949
	}
}

B
Benjamin Pasero 已提交
950
export class KeepEditorAction extends Action {
951

M
Matt Bierner 已提交
952 953
	public static readonly ID = 'workbench.action.keepEditor';
	public static readonly LABEL = nls.localize('keepEditor', "Keep Editor");
954 955 956 957

	constructor(
		id: string,
		label: string,
958
		@IEditorGroupService private editorGroupService: IEditorGroupService,
959 960 961 962 963
		@IWorkbenchEditorService private editorService: IWorkbenchEditorService
	) {
		super(id, label);
	}

B
Benjamin Pasero 已提交
964
	public run(context?: IEditorContext): TPromise<any> {
965
		const target = getTarget(this.editorService, this.editorGroupService, context);
B
Benjamin Pasero 已提交
966 967
		if (target) {
			this.editorGroupService.pinEditor(target.position, target.input);
968 969 970 971 972 973
		}

		return TPromise.as(true);
	}
}

B
Benjamin Pasero 已提交
974 975 976 977 978 979 980 981 982 983 984 985 986
function getTarget(editorService: IWorkbenchEditorService, editorGroupService: IEditorGroupService, context?: IEditorContext): { input: IEditorInput, position: Position } {
	if (context) {
		return { input: context.editor, position: editorGroupService.getStacksModel().positionOfGroup(context.group) };
	}

	const activeEditor = editorService.getActiveEditor();
	if (activeEditor) {
		return { input: activeEditor.input, position: activeEditor.position };
	}

	return null;
}

987 988
export abstract class BaseNavigateEditorAction extends Action {

989 990 991 992 993 994
	constructor(
		id: string,
		label: string,
		protected editorGroupService: IEditorGroupService,
		protected editorService: IWorkbenchEditorService
	) {
995 996 997 998
		super(id, label);
	}

	public run(): TPromise<any> {
999
		const model = this.editorGroupService.getStacksModel();
1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012
		const result = this.navigate();
		if (result) {
			return this.editorService.openEditor(result.editor, null, model.positionOfGroup(result.group));
		}

		return TPromise.as(false);
	}

	protected abstract navigate(): IEditorIdentifier;
}

export class OpenNextEditor extends BaseNavigateEditorAction {

M
Matt Bierner 已提交
1013 1014
	public static readonly ID = 'workbench.action.nextEditor';
	public static readonly LABEL = nls.localize('openNextEditor', "Open Next Editor");
1015

1016 1017 1018 1019 1020 1021 1022
	constructor(
		id: string,
		label: string,
		@IEditorGroupService editorGroupService: IEditorGroupService,
		@IWorkbenchEditorService editorService: IWorkbenchEditorService
	) {
		super(id, label, editorGroupService, editorService);
1023 1024 1025
	}

	protected navigate(): IEditorIdentifier {
1026
		return this.editorGroupService.getStacksModel().next(true /* jump groups */);
1027 1028 1029 1030 1031
	}
}

export class OpenPreviousEditor extends BaseNavigateEditorAction {

M
Matt Bierner 已提交
1032 1033
	public static readonly ID = 'workbench.action.previousEditor';
	public static readonly LABEL = nls.localize('openPreviousEditor', "Open Previous Editor");
1034

1035 1036 1037 1038 1039 1040 1041
	constructor(
		id: string,
		label: string,
		@IEditorGroupService editorGroupService: IEditorGroupService,
		@IWorkbenchEditorService editorService: IWorkbenchEditorService
	) {
		super(id, label, editorGroupService, editorService);
1042 1043 1044
	}

	protected navigate(): IEditorIdentifier {
1045 1046 1047 1048 1049 1050
		return this.editorGroupService.getStacksModel().previous(true /* jump groups */);
	}
}

export class OpenNextEditorInGroup extends BaseNavigateEditorAction {

M
Matt Bierner 已提交
1051 1052
	public static readonly ID = 'workbench.action.nextEditorInGroup';
	public static readonly LABEL = nls.localize('nextEditorInGroup', "Open Next Editor in Group");
1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069

	constructor(
		id: string,
		label: string,
		@IEditorGroupService editorGroupService: IEditorGroupService,
		@IWorkbenchEditorService editorService: IWorkbenchEditorService
	) {
		super(id, label, editorGroupService, editorService);
	}

	protected navigate(): IEditorIdentifier {
		return this.editorGroupService.getStacksModel().next(false /* do NOT jump groups */);
	}
}

export class OpenPreviousEditorInGroup extends BaseNavigateEditorAction {

M
Matt Bierner 已提交
1070 1071
	public static readonly ID = 'workbench.action.previousEditorInGroup';
	public static readonly LABEL = nls.localize('openPreviousEditorInGroup', "Open Previous Editor in Group");
1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083

	constructor(
		id: string,
		label: string,
		@IEditorGroupService editorGroupService: IEditorGroupService,
		@IWorkbenchEditorService editorService: IWorkbenchEditorService
	) {
		super(id, label, editorGroupService, editorService);
	}

	protected navigate(): IEditorIdentifier {
		return this.editorGroupService.getStacksModel().previous(false /* do NOT jump groups */);
1084
	}
B
Benjamin Pasero 已提交
1085 1086
}

1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105
export class OpenLastEditorInGroup extends BaseNavigateEditorAction {

	public static readonly ID = 'workbench.action.lastEditorInGroup';
	public static readonly LABEL = nls.localize('lastEditorInGroup', "Open Last Editor in Group");

	constructor(
		id: string,
		label: string,
		@IEditorGroupService editorGroupService: IEditorGroupService,
		@IWorkbenchEditorService editorService: IWorkbenchEditorService
	) {
		super(id, label, editorGroupService, editorService);
	}

	protected navigate(): IEditorIdentifier {
		return this.editorGroupService.getStacksModel().last();
	}
}

B
Benjamin Pasero 已提交
1106 1107
export class NavigateForwardAction extends Action {

M
Matt Bierner 已提交
1108 1109
	public static readonly ID = 'workbench.action.navigateForward';
	public static readonly LABEL = nls.localize('navigateNext', "Go Forward");
B
Benjamin Pasero 已提交
1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123

	constructor(id: string, label: string, @IHistoryService private historyService: IHistoryService) {
		super(id, label);
	}

	public run(): TPromise<any> {
		this.historyService.forward();

		return TPromise.as(null);
	}
}

export class NavigateBackwardsAction extends Action {

M
Matt Bierner 已提交
1124 1125
	public static readonly ID = 'workbench.action.navigateBack';
	public static readonly LABEL = nls.localize('navigatePrevious', "Go Back");
B
Benjamin Pasero 已提交
1126 1127 1128 1129 1130 1131 1132 1133 1134 1135

	constructor(id: string, label: string, @IHistoryService private historyService: IHistoryService) {
		super(id, label);
	}

	public run(): TPromise<any> {
		this.historyService.back();

		return TPromise.as(null);
	}
I
isidor 已提交
1136
}
1137

1138 1139
export class NavigateLastAction extends Action {

M
Matt Bierner 已提交
1140 1141
	public static readonly ID = 'workbench.action.navigateLast';
	public static readonly LABEL = nls.localize('navigateLast', "Go Last");
1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153

	constructor(id: string, label: string, @IHistoryService private historyService: IHistoryService) {
		super(id, label);
	}

	public run(): TPromise<any> {
		this.historyService.last();

		return TPromise.as(null);
	}
}

1154 1155
export class ReopenClosedEditorAction extends Action {

M
Matt Bierner 已提交
1156 1157
	public static readonly ID = 'workbench.action.reopenClosedEditor';
	public static readonly LABEL = nls.localize('reopenClosedEditor', "Reopen Closed Editor");
1158 1159 1160 1161

	constructor(
		id: string,
		label: string,
B
Benjamin Pasero 已提交
1162
		@IHistoryService private historyService: IHistoryService
1163 1164 1165 1166 1167
	) {
		super(id, label);
	}

	public run(): TPromise<any> {
1168
		this.historyService.reopenLastClosedEditor();
1169 1170 1171

		return TPromise.as(false);
	}
B
Benjamin Pasero 已提交
1172 1173
}

1174
export class ClearRecentFilesAction extends Action {
C
22768  
Cristian 已提交
1175

M
Matt Bierner 已提交
1176 1177
	public static readonly ID = 'workbench.action.clearRecentFiles';
	public static readonly LABEL = nls.localize('clearRecentFiles', "Clear Recently Opened");
C
22768  
Cristian 已提交
1178 1179 1180 1181 1182 1183 1184 1185 1186 1187

	constructor(
		id: string,
		label: string,
		@IWindowsService private windowsService: IWindowsService
	) {
		super(id, label);
	}

	public run(): TPromise<any> {
B
Benjamin Pasero 已提交
1188
		this.windowsService.clearRecentlyOpened();
C
22768  
Cristian 已提交
1189 1190 1191 1192 1193

		return TPromise.as(false);
	}
}

1194
export const NAVIGATE_IN_GROUP_ONE_PREFIX = 'edt one ';
B
Benjamin Pasero 已提交
1195

1196
export class ShowEditorsInGroupOneAction extends QuickOpenAction {
B
Benjamin Pasero 已提交
1197

M
Matt Bierner 已提交
1198 1199
	public static readonly ID = 'workbench.action.showEditorsInFirstGroup';
	public static readonly LABEL = nls.localize('showEditorsInFirstGroup', "Show Editors in First Group");
B
Benjamin Pasero 已提交
1200

1201 1202 1203
	constructor(
		actionId: string,
		actionLabel: string,
1204
		@IQuickOpenService quickOpenService: IQuickOpenService
1205
	) {
1206
		super(actionId, actionLabel, NAVIGATE_IN_GROUP_ONE_PREFIX, quickOpenService);
1207 1208

		this.class = 'show-group-editors-action';
B
Benjamin Pasero 已提交
1209
	}
1210
}
1211

1212
export const NAVIGATE_IN_GROUP_TWO_PREFIX = 'edt two ';
1213

1214
export class ShowEditorsInGroupTwoAction extends QuickOpenAction {
1215

M
Matt Bierner 已提交
1216 1217
	public static readonly ID = 'workbench.action.showEditorsInSecondGroup';
	public static readonly LABEL = nls.localize('showEditorsInSecondGroup', "Show Editors in Second Group");
1218 1219 1220 1221

	constructor(
		actionId: string,
		actionLabel: string,
1222
		@IQuickOpenService quickOpenService: IQuickOpenService
1223
	) {
1224
		super(actionId, actionLabel, NAVIGATE_IN_GROUP_TWO_PREFIX, quickOpenService);
1225 1226

		this.class = 'show-group-editors-action';
1227 1228
	}
}
1229

1230
export const NAVIGATE_IN_GROUP_THREE_PREFIX = 'edt three ';
1231

1232
export class ShowEditorsInGroupThreeAction extends QuickOpenAction {
1233

M
Matt Bierner 已提交
1234 1235
	public static readonly ID = 'workbench.action.showEditorsInThirdGroup';
	public static readonly LABEL = nls.localize('showEditorsInThirdGroup', "Show Editors in Third Group");
1236 1237 1238 1239

	constructor(
		actionId: string,
		actionLabel: string,
1240
		@IQuickOpenService quickOpenService: IQuickOpenService
1241
	) {
1242
		super(actionId, actionLabel, NAVIGATE_IN_GROUP_THREE_PREFIX, quickOpenService);
1243 1244

		this.class = 'show-group-editors-action';
1245
	}
B
Benjamin Pasero 已提交
1246 1247
}

B
Benjamin Pasero 已提交
1248 1249
export class ShowEditorsInGroupAction extends Action {

M
Matt Bierner 已提交
1250 1251
	public static readonly ID = 'workbench.action.showEditorsInGroup';
	public static readonly LABEL = nls.localize('showEditorsInGroup', "Show Editors in Group");
B
Benjamin Pasero 已提交
1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269

	constructor(
		id: string,
		label: string,
		@IQuickOpenService private quickOpenService: IQuickOpenService,
		@IEditorGroupService private editorGroupService: IEditorGroupService
	) {
		super(id, label);
	}

	public run(context?: IEditorContext): TPromise<any> {
		const stacks = this.editorGroupService.getStacksModel();
		const groupCount = stacks.groups.length;
		if (groupCount <= 1 || !context) {
			return this.quickOpenService.show(NAVIGATE_ALL_EDITORS_GROUP_PREFIX);
		}

		switch (stacks.positionOfGroup(context.group)) {
1270
			case Position.TWO:
B
Benjamin Pasero 已提交
1271
				return this.quickOpenService.show(NAVIGATE_IN_GROUP_TWO_PREFIX);
1272
			case Position.THREE:
1273
				return this.quickOpenService.show(NAVIGATE_IN_GROUP_THREE_PREFIX);
B
Benjamin Pasero 已提交
1274 1275
		}

1276
		return this.quickOpenService.show(NAVIGATE_IN_GROUP_ONE_PREFIX);
B
Benjamin Pasero 已提交
1277 1278 1279
	}
}

1280
export const NAVIGATE_ALL_EDITORS_GROUP_PREFIX = 'edt ';
B
Benjamin Pasero 已提交
1281 1282 1283

export class ShowAllEditorsAction extends QuickOpenAction {

M
Matt Bierner 已提交
1284 1285
	public static readonly ID = 'workbench.action.showAllEditors';
	public static readonly LABEL = nls.localize('showAllEditors', "Show All Editors");
B
Benjamin Pasero 已提交
1286 1287 1288 1289 1290 1291

	constructor(actionId: string, actionLabel: string, @IQuickOpenService quickOpenService: IQuickOpenService) {
		super(actionId, actionLabel, NAVIGATE_ALL_EDITORS_GROUP_PREFIX, quickOpenService);
	}
}

1292
export class BaseQuickOpenEditorInGroupAction extends Action {
B
Benjamin Pasero 已提交
1293 1294 1295 1296 1297

	constructor(
		id: string,
		label: string,
		@IQuickOpenService private quickOpenService: IQuickOpenService,
1298
		@IKeybindingService private keybindingService: IKeybindingService,
1299
		@IEditorGroupService private editorGroupService: IEditorGroupService
B
Benjamin Pasero 已提交
1300 1301 1302 1303 1304
	) {
		super(id, label);
	}

	public run(): TPromise<any> {
1305
		const keys = this.keybindingService.lookupKeybindings(this.id);
B
Benjamin Pasero 已提交
1306

1307
		const stacks = this.editorGroupService.getStacksModel();
1308 1309
		if (stacks.activeGroup) {
			const activePosition = stacks.positionOfGroup(stacks.activeGroup);
1310
			let prefix = NAVIGATE_IN_GROUP_ONE_PREFIX;
1311

B
Benjamin Pasero 已提交
1312
			if (activePosition === Position.TWO) {
1313
				prefix = NAVIGATE_IN_GROUP_TWO_PREFIX;
B
Benjamin Pasero 已提交
1314
			} else if (activePosition === Position.THREE) {
1315
				prefix = NAVIGATE_IN_GROUP_THREE_PREFIX;
1316 1317
			}

B
Benjamin Pasero 已提交
1318
			this.quickOpenService.show(prefix, { quickNavigateConfiguration: { keybindings: keys } });
1319
		}
B
Benjamin Pasero 已提交
1320 1321 1322 1323 1324

		return TPromise.as(true);
	}
}

1325 1326
export class OpenPreviousRecentlyUsedEditorInGroupAction extends BaseQuickOpenEditorInGroupAction {

M
Matt Bierner 已提交
1327 1328
	public static readonly ID = 'workbench.action.openPreviousRecentlyUsedEditorInGroup';
	public static readonly LABEL = nls.localize('openPreviousRecentlyUsedEditorInGroup', "Open Previous Recently Used Editor in Group");
1329 1330 1331 1332 1333 1334

	constructor(
		id: string,
		label: string,
		@IQuickOpenService quickOpenService: IQuickOpenService,
		@IKeybindingService keybindingService: IKeybindingService,
1335
		@IEditorGroupService editorGroupService: IEditorGroupService
1336
	) {
1337
		super(id, label, quickOpenService, keybindingService, editorGroupService);
1338 1339 1340 1341 1342
	}
}

export class OpenNextRecentlyUsedEditorInGroupAction extends BaseQuickOpenEditorInGroupAction {

M
Matt Bierner 已提交
1343 1344
	public static readonly ID = 'workbench.action.openNextRecentlyUsedEditorInGroup';
	public static readonly LABEL = nls.localize('openNextRecentlyUsedEditorInGroup', "Open Next Recently Used Editor in Group");
1345 1346 1347 1348 1349 1350

	constructor(
		id: string,
		label: string,
		@IQuickOpenService quickOpenService: IQuickOpenService,
		@IKeybindingService keybindingService: IKeybindingService,
1351
		@IEditorGroupService editorGroupService: IEditorGroupService
1352
	) {
1353
		super(id, label, quickOpenService, keybindingService, editorGroupService);
1354 1355 1356
	}
}

1357
export class OpenPreviousEditorFromHistoryAction extends Action {
B
Benjamin Pasero 已提交
1358

M
Matt Bierner 已提交
1359 1360
	public static readonly ID = 'workbench.action.openPreviousEditorFromHistory';
	public static readonly LABEL = nls.localize('navigateEditorHistoryByInput', "Open Previous Editor from History");
B
Benjamin Pasero 已提交
1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371

	constructor(
		id: string,
		label: string,
		@IQuickOpenService private quickOpenService: IQuickOpenService,
		@IKeybindingService private keybindingService: IKeybindingService
	) {
		super(id, label);
	}

	public run(): TPromise<any> {
1372
		const keys = this.keybindingService.lookupKeybindings(this.id);
B
Benjamin Pasero 已提交
1373

B
Benjamin Pasero 已提交
1374
		this.quickOpenService.show(null, { quickNavigateConfiguration: { keybindings: keys } });
B
Benjamin Pasero 已提交
1375 1376 1377 1378 1379

		return TPromise.as(true);
	}
}

1380 1381
export class OpenNextRecentlyUsedEditorAction extends Action {

M
Matt Bierner 已提交
1382 1383
	public static readonly ID = 'workbench.action.openNextRecentlyUsedEditor';
	public static readonly LABEL = nls.localize('openNextRecentlyUsedEditor', "Open Next Recently Used Editor");
1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397

	constructor(id: string, label: string, @IHistoryService private historyService: IHistoryService) {
		super(id, label);
	}

	public run(): TPromise<any> {
		this.historyService.forward(true);

		return TPromise.as(null);
	}
}

export class OpenPreviousRecentlyUsedEditorAction extends Action {

M
Matt Bierner 已提交
1398 1399
	public static readonly ID = 'workbench.action.openPreviousRecentlyUsedEditor';
	public static readonly LABEL = nls.localize('openPreviousRecentlyUsedEditor', "Open Previous Recently Used Editor");
1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411

	constructor(id: string, label: string, @IHistoryService private historyService: IHistoryService) {
		super(id, label);
	}

	public run(): TPromise<any> {
		this.historyService.back(true);

		return TPromise.as(null);
	}
}

1412 1413
export class ClearEditorHistoryAction extends Action {

M
Matt Bierner 已提交
1414 1415
	public static readonly ID = 'workbench.action.clearEditorHistory';
	public static readonly LABEL = nls.localize('clearEditorHistory', "Clear Editor History");
1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426

	constructor(
		id: string,
		label: string,
		@IHistoryService private historyService: IHistoryService
	) {
		super(id, label);
	}

	public run(): TPromise<any> {

1427
		// Editor history
1428 1429 1430 1431 1432 1433
		this.historyService.clear();

		return TPromise.as(true);
	}
}

1434 1435
export class FocusLastEditorInStackAction extends Action {

M
Matt Bierner 已提交
1436 1437
	public static readonly ID = 'workbench.action.openLastEditorInGroup';
	public static readonly LABEL = nls.localize('focusLastEditorInStack', "Open Last Editor in Group");
1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458

	constructor(
		id: string,
		label: string,
		@IEditorGroupService private editorGroupService: IEditorGroupService,
		@IWorkbenchEditorService private editorService: IWorkbenchEditorService
	) {
		super(id, label);
	}

	public run(): TPromise<any> {
		const active = this.editorService.getActiveEditor();
		if (active) {
			const group = this.editorGroupService.getStacksModel().groupAt(active.position);
			const editor = group.getEditor(group.count - 1);

			if (editor) {
				return this.editorService.openEditor(editor);
			}
		}

1459 1460 1461 1462
		return TPromise.as(true);
	}
}

1463 1464
export class MoveEditorLeftInGroupAction extends Action {

M
Matt Bierner 已提交
1465 1466
	public static readonly ID = 'workbench.action.moveEditorLeftInGroup';
	public static readonly LABEL = nls.localize('moveEditorLeft', "Move Editor Left");
1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477

	constructor(
		id: string,
		label: string,
		@ICommandService private commandService: ICommandService
	) {
		super(id, label);
	}

	public run(): TPromise<any> {
		const args: ActiveEditorMoveArguments = {
1478
			to: ActiveEditorMovePositioning.LEFT
1479 1480 1481 1482 1483 1484 1485 1486 1487
		};
		this.commandService.executeCommand(EditorCommands.MoveActiveEditor, args);

		return TPromise.as(true);
	}
}

export class MoveEditorRightInGroupAction extends Action {

M
Matt Bierner 已提交
1488 1489
	public static readonly ID = 'workbench.action.moveEditorRightInGroup';
	public static readonly LABEL = nls.localize('moveEditorRight', "Move Editor Right");
1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500

	constructor(
		id: string,
		label: string,
		@ICommandService private commandService: ICommandService
	) {
		super(id, label);
	}

	public run(): TPromise<any> {
		const args: ActiveEditorMoveArguments = {
1501
			to: ActiveEditorMovePositioning.RIGHT
1502 1503 1504 1505 1506 1507 1508
		};
		this.commandService.executeCommand(EditorCommands.MoveActiveEditor, args);

		return TPromise.as(true);
	}
}

1509
export class MoveEditorToPreviousGroupAction extends Action {
1510

M
Matt Bierner 已提交
1511 1512
	public static readonly ID = 'workbench.action.moveEditorToPreviousGroup';
	public static readonly LABEL = nls.localize('moveEditorToPreviousGroup', "Move Editor into Previous Group");
1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524

	constructor(
		id: string,
		label: string,
		@IEditorGroupService private editorGroupService: IEditorGroupService,
		@IWorkbenchEditorService private editorService: IWorkbenchEditorService
	) {
		super(id, label);
	}

	public run(): TPromise<any> {
		const activeEditor = this.editorService.getActiveEditor();
1525
		if (activeEditor && activeEditor.position !== Position.ONE) {
1526 1527 1528 1529 1530 1531 1532
			this.editorGroupService.moveEditor(activeEditor.input, activeEditor.position, activeEditor.position - 1);
		}

		return TPromise.as(true);
	}
}

1533
export class MoveEditorToNextGroupAction extends Action {
1534

M
Matt Bierner 已提交
1535 1536
	public static readonly ID = 'workbench.action.moveEditorToNextGroup';
	public static readonly LABEL = nls.localize('moveEditorToNextGroup', "Move Editor into Next Group");
1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548

	constructor(
		id: string,
		label: string,
		@IEditorGroupService private editorGroupService: IEditorGroupService,
		@IWorkbenchEditorService private editorService: IWorkbenchEditorService
	) {
		super(id, label);
	}

	public run(): TPromise<any> {
		const activeEditor = this.editorService.getActiveEditor();
1549
		if (activeEditor && activeEditor.position !== Position.THREE) {
1550 1551 1552
			this.editorGroupService.moveEditor(activeEditor.input, activeEditor.position, activeEditor.position + 1);
		}

1553 1554
		return TPromise.as(true);
	}
D
Daniel Imms 已提交
1555
}