editorActions.ts 46.5 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';
8
import * as nls from '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';
B
Benjamin Pasero 已提交
12
import { EditorInput, TextEditorOptions, EditorOptions, IEditorIdentifier, ActiveEditorMoveArguments, ActiveEditorMovePositioning, EditorCommands, ConfirmResult, IEditorCommandsContext } 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';
B
Benjamin Pasero 已提交
18
import { Position, IEditor, Direction, IResourceInput, IEditorInput, POSITIONS } 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';
25
import { CLOSE_EDITOR_COMMAND_ID, NAVIGATE_IN_GROUP_ONE_PREFIX, NAVIGATE_ALL_EDITORS_GROUP_PREFIX, NAVIGATE_IN_GROUP_THREE_PREFIX, NAVIGATE_IN_GROUP_TWO_PREFIX } from 'vs/workbench/browser/parts/editor/editorCommands';
B
Benjamin Pasero 已提交
26
import { INextEditorGroupsService, GroupDirection as SplitDirection, INextEditorGroup } from 'vs/workbench/services/group/common/nextEditorGroupsService';
E
Erich Gamma 已提交
27

28
// TODo@grid this action should be removed in favour of the split vertical/horizontal actions
E
Erich Gamma 已提交
29 30
export class SplitEditorAction extends Action {

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

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

B
Benjamin Pasero 已提交
43
	public run(context?: IEditorCommandsContext): TPromise<any> {
44 45
		let editorToSplit: IEditor;
		if (context) {
B
Benjamin Pasero 已提交
46 47
			const stacks = this.editorGroupService.getStacksModel();
			editorToSplit = this.editorService.getVisibleEditors()[stacks.positionOfGroup(stacks.getGroup(context.groupId))];
48 49 50
		} else {
			editorToSplit = this.editorService.getActiveEditor();
		}
E
Erich Gamma 已提交
51

52 53
		// Can only split with target editor
		if (!editorToSplit) {
A
Alex Dima 已提交
54
			return TPromise.as(true);
E
Erich Gamma 已提交
55 56 57
		}

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

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

E
Erich Gamma 已提交
72
		// Count editors
73 74
		const visibleEditors = this.editorService.getVisibleEditors();
		const editorCount = visibleEditors.length;
E
Erich Gamma 已提交
75 76 77 78
		let targetPosition: Position;

		switch (editorCount) {

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

			// Special case two editors opened
			case 2:

B
Benjamin Pasero 已提交
87
				// Continue splitting to the right/bottom
88 89
				if (editorToSplit.position === Position.TWO) {
					targetPosition = Position.THREE;
E
Erich Gamma 已提交
90 91
				}

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

96 97 98
					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 已提交
99 100 101 102
					});
				}
		}

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

A
Alex Dima 已提交
108
		return TPromise.as(true);
E
Erich Gamma 已提交
109 110 111
	}
}

112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
export class BaseSplitEditorGroupAction extends Action {

	constructor(
		id: string,
		label: string,
		clazz: string,
		private direction: SplitDirection,
		private nextEditorGroupsService: INextEditorGroupsService
	) {
		super(id, label, clazz);
	}

	public run(context?: IEditorIdentifier): TPromise<any> {
		let group: INextEditorGroup;
		if (context && context.group) {
			group = this.nextEditorGroupsService.getGroup(context.group.id);
		}

		if (!group) {
			group = this.nextEditorGroupsService.activeGroup;
		}

134 135 136 137 138 139 140 141 142
		const activeEditor = group.activeEditor;
		if (activeEditor instanceof EditorInput && !activeEditor.supportsSplitEditor()) {
			return TPromise.as(false);
		}

		// Add group
		const newGroup = this.nextEditorGroupsService.addGroup(group, this.direction);

		// Open editor
143 144 145 146 147 148 149 150 151 152 153
		if (activeEditor) {
			let options: EditorOptions;
			const codeEditor = getCodeEditor(group.activeControl);
			if (codeEditor) {
				options = TextEditorOptions.fromEditor(codeEditor);
			} else {
				options = new EditorOptions();
			}
			options.pinned = true;

			newGroup.openEditor(activeEditor, options);
154
		}
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187

		return TPromise.as(true);
	}
}

export class SplitEditorGroupVerticalAction extends BaseSplitEditorGroupAction {

	public static readonly ID = 'workbench.action.splitEditorGroupVertical';
	public static readonly LABEL = nls.localize('splitEditorGroupVertical', "Split Editor Group Vertically");

	constructor(
		id: string,
		label: string,
		@INextEditorGroupsService nextEditorGroupsService: INextEditorGroupsService
	) {
		super(id, label, 'split-editor-vertical-action', SplitDirection.DOWN, nextEditorGroupsService);
	}
}

export class SplitEditorGroupHorizontalAction extends BaseSplitEditorGroupAction {

	public static readonly ID = 'workbench.action.splitEditorGroupHorizontal';
	public static readonly LABEL = nls.localize('splitEditorGroupHorizontal', "Split Editor Group Horizontally");

	constructor(
		id: string,
		label: string,
		@INextEditorGroupsService nextEditorGroupsService: INextEditorGroupsService
	) {
		super(id, label, 'split-editor-horizontal-action', SplitDirection.RIGHT, nextEditorGroupsService);
	}
}

188
export class JoinTwoGroupsAction extends Action {
I
initialshl 已提交
189

M
Matt Bierner 已提交
190 191
	public static readonly ID = 'workbench.action.joinTwoGroups';
	public static readonly LABEL = nls.localize('joinTwoGroups', "Join Editors of Two Groups");
I
initialshl 已提交
192 193 194 195 196 197

	constructor(
		id: string,
		label: string,
		@IEditorGroupService private editorGroupService: IEditorGroupService
	) {
198
		super(id, label);
I
initialshl 已提交
199 200
	}

201
	public run(context?: IEditorIdentifier): TPromise<any> {
I
initialshl 已提交
202

203
		const editorStacksModel = this.editorGroupService.getStacksModel();
I
initialshl 已提交
204 205

		// Return if has no other group to join to
206
		if (editorStacksModel.groups.length < 2) {
I
initialshl 已提交
207 208 209
			return TPromise.as(true);
		}

210 211 212 213 214 215 216 217 218
		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 已提交
219

220 221 222
		// 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 已提交
223
		} else {
224
			toPosition = fromPosition - 1;
I
initialshl 已提交
225 226
		}

227 228
		const fromGroup = editorStacksModel.groupAt(fromPosition);
		const toGroup = editorStacksModel.groupAt(toPosition);
I
initialshl 已提交
229

230 231
		const activeEditor = fromGroup.activeEditor;
		const fromGroupEditors = fromGroup.getEditors();
I
initialshl 已提交
232

233 234 235 236 237 238 239 240 241 242 243
		// 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 已提交
244

245 246
		// Focus may be lost when the joining group is closed, regain focus on the target group
		this.editorGroupService.focusGroup(toGroup);
I
initialshl 已提交
247 248 249 250 251

		return TPromise.as(true);
	}
}

B
Benjamin Pasero 已提交
252
export class NavigateBetweenGroupsAction extends Action {
253

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

257 258 259 260 261 262
	constructor(
		id: string,
		label: string,
		@IWorkbenchEditorService private editorService: IWorkbenchEditorService,
		@IEditorGroupService private editorGroupService: IEditorGroupService
	) {
E
Erich Gamma 已提交
263 264 265
		super(id, label);
	}

266
	public run(): TPromise<any> {
E
Erich Gamma 已提交
267 268

		// Can cycle split with active editor
269
		const activeEditor = this.editorService.getActiveEditor();
E
Erich Gamma 已提交
270
		if (!activeEditor) {
A
Alex Dima 已提交
271
			return TPromise.as(false);
E
Erich Gamma 已提交
272 273
		}

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

279
		this.editorGroupService.focusGroup(<Position>newIndex);
280 281

		return TPromise.as(true);
E
Erich Gamma 已提交
282 283 284
	}
}

285 286
export class FocusActiveGroupAction extends Action {

M
Matt Bierner 已提交
287 288
	public static readonly ID = 'workbench.action.focusActiveEditorGroup';
	public static readonly LABEL = nls.localize('focusActiveEditorGroup', "Focus Active Editor Group");
289 290 291 292 293 294 295 296 297 298

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

	public run(): TPromise<any> {
B
hygiene  
Benjamin Pasero 已提交
299 300
		const activeEditor = this.editorService.getActiveEditor();
		if (activeEditor) {
D
Daniel Imms 已提交
301
			activeEditor.focus();
B
hygiene  
Benjamin Pasero 已提交
302
		}
D
Daniel Imms 已提交
303

304
		return TPromise.as(true);
E
Erich Gamma 已提交
305 306 307
	}
}

308 309
export class FocusFirstGroupAction extends Action {

M
Matt Bierner 已提交
310 311
	public static readonly ID = 'workbench.action.focusFirstEditorGroup';
	public static readonly LABEL = nls.localize('focusFirstEditorGroup', "Focus First Editor Group");
E
Erich Gamma 已提交
312 313 314 315 316

	constructor(
		id: string,
		label: string,
		@IWorkbenchEditorService private editorService: IWorkbenchEditorService,
317
		@IEditorGroupService private editorGroupService: IEditorGroupService,
318
		@IHistoryService private historyService: IHistoryService
E
Erich Gamma 已提交
319 320 321 322
	) {
		super(id, label);
	}

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

B
Benjamin Pasero 已提交
325
		// Find left/top editor and focus it
326
		const editors = this.editorService.getVisibleEditors();
B
Benjamin Pasero 已提交
327
		for (let editor of editors) {
328 329
			if (editor.position === Position.ONE) {
				this.editorGroupService.focusGroup(Position.ONE);
330 331

				return TPromise.as(true);
E
Erich Gamma 已提交
332 333 334 335
			}
		}

		// Since no editor is currently opened, try to open last history entry to the target side
336
		const history = this.historyService.getHistory();
337 338
		if (history.length > 0) {
			const input = history[0];
339
			if (input instanceof EditorInput) {
340
				return this.editorService.openEditor(input, null, Position.ONE);
E
Erich Gamma 已提交
341
			}
342 343

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

A
Alex Dima 已提交
346
		return TPromise.as(true);
E
Erich Gamma 已提交
347 348 349
	}
}

350
export abstract class BaseFocusSideGroupAction extends Action {
E
Erich Gamma 已提交
351 352 353 354 355

	constructor(
		id: string,
		label: string,
		@IWorkbenchEditorService private editorService: IWorkbenchEditorService,
356
		@IEditorGroupService private editorGroupService: IEditorGroupService,
357
		@IHistoryService private historyService: IHistoryService
E
Erich Gamma 已提交
358 359 360 361 362 363 364 365
	) {
		super(id, label);
	}

	protected abstract getReferenceEditorSide(): Position;

	protected abstract getTargetEditorSide(): Position;

366
	public run(): TPromise<any> {
E
Erich Gamma 已提交
367 368

		// Require at least the reference editor to be visible
369
		const editors = this.editorService.getVisibleEditors();
E
Erich Gamma 已提交
370 371
		let referenceEditor: IEditor;
		for (let i = 0; i < editors.length; i++) {
372
			const editor = editors[i];
E
Erich Gamma 已提交
373 374 375

			// Target editor exists so focus it
			if (editor.position === this.getTargetEditorSide()) {
376
				this.editorGroupService.focusGroup(editor.position);
377 378

				return TPromise.as(true);
E
Erich Gamma 已提交
379 380 381 382 383 384 385 386 387
			}

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

		// Require the reference editor to be visible and supporting split editor
388
		if (referenceEditor && (<EditorInput>referenceEditor.input).supportsSplitEditor()) {
389 390 391

			// Options
			let options: EditorOptions;
S
Sandeep Somavarapu 已提交
392 393
			const codeEditor = getCodeEditor(referenceEditor);
			if (codeEditor) {
394
				options = TextEditorOptions.fromEditor(codeEditor, { pinned: true });
395 396
			} else {
				options = EditorOptions.create({ pinned: true });
397 398 399
			}

			return this.editorService.openEditor(referenceEditor.input, options, this.getTargetEditorSide());
E
Erich Gamma 已提交
400 401 402 403
		}

		// Otherwise try to find a history entry to open to the target editor side
		else if (referenceEditor) {
404
			const history = this.historyService.getHistory();
B
Benjamin Pasero 已提交
405
			for (let input of history) {
B
Benjamin Pasero 已提交
406 407 408 409 410 411
				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 已提交
412 413 414 415
				}
			}
		}

A
Alex Dima 已提交
416
		return TPromise.as(true);
E
Erich Gamma 已提交
417 418 419
	}
}

420 421
export class FocusSecondGroupAction extends BaseFocusSideGroupAction {

M
Matt Bierner 已提交
422 423
	public static readonly ID = 'workbench.action.focusSecondEditorGroup';
	public static readonly LABEL = nls.localize('focusSecondEditorGroup', "Focus Second Editor Group");
E
Erich Gamma 已提交
424 425 426 427 428

	constructor(
		id: string,
		label: string,
		@IWorkbenchEditorService editorService: IWorkbenchEditorService,
429
		@IEditorGroupService editorGroupService: IEditorGroupService,
430
		@IHistoryService historyService: IHistoryService
E
Erich Gamma 已提交
431
	) {
432
		super(id, label, editorService, editorGroupService, historyService);
E
Erich Gamma 已提交
433 434 435
	}

	protected getReferenceEditorSide(): Position {
436
		return Position.ONE;
E
Erich Gamma 已提交
437 438 439
	}

	protected getTargetEditorSide(): Position {
440
		return Position.TWO;
E
Erich Gamma 已提交
441 442 443
	}
}

444 445
export class FocusThirdGroupAction extends BaseFocusSideGroupAction {

M
Matt Bierner 已提交
446 447
	public static readonly ID = 'workbench.action.focusThirdEditorGroup';
	public static readonly LABEL = nls.localize('focusThirdEditorGroup', "Focus Third Editor Group");
E
Erich Gamma 已提交
448 449 450 451 452

	constructor(
		id: string,
		label: string,
		@IWorkbenchEditorService editorService: IWorkbenchEditorService,
453
		@IEditorGroupService editorGroupService: IEditorGroupService,
454
		@IHistoryService historyService: IHistoryService
E
Erich Gamma 已提交
455
	) {
456
		super(id, label, editorService, editorGroupService, historyService);
E
Erich Gamma 已提交
457 458 459
	}

	protected getReferenceEditorSide(): Position {
460
		return Position.TWO;
E
Erich Gamma 已提交
461 462 463
	}

	protected getTargetEditorSide(): Position {
464
		return Position.THREE;
E
Erich Gamma 已提交
465 466 467
	}
}

B
Benjamin Pasero 已提交
468
export class FocusPreviousGroup extends Action {
469

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

473 474 475 476 477 478
	constructor(
		id: string,
		label: string,
		@IEditorGroupService private editorGroupService: IEditorGroupService,
		@IWorkbenchEditorService private editorService: IWorkbenchEditorService
	) {
E
Erich Gamma 已提交
479 480 481
		super(id, label);
	}

482
	public run(): TPromise<any> {
E
Erich Gamma 已提交
483 484

		// Require an active editor
485
		const activeEditor = this.editorService.getActiveEditor();
E
Erich Gamma 已提交
486
		if (!activeEditor) {
A
Alex Dima 已提交
487
			return TPromise.as(true);
E
Erich Gamma 已提交
488 489
		}

490 491
		const stacks = this.editorGroupService.getStacksModel();
		const groupCount = stacks.groups.length;
E
Erich Gamma 已提交
492

493 494 495
		// Nothing to do if the only group
		if (groupCount === 1) {
			return TPromise.as(true);
E
Erich Gamma 已提交
496 497
		}

498 499 500
		// 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);
501 502

		return TPromise.as(true);
E
Erich Gamma 已提交
503 504 505
	}
}

B
Benjamin Pasero 已提交
506
export class FocusNextGroup extends Action {
507

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

E
Erich Gamma 已提交
511 512 513
	constructor(
		id: string,
		label: string,
514 515
		@IEditorGroupService private editorGroupService: IEditorGroupService,
		@IWorkbenchEditorService private editorService: IWorkbenchEditorService
E
Erich Gamma 已提交
516 517 518 519
	) {
		super(id, label);
	}

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

522
		const activeEditor = this.editorService.getActiveEditor();
523

524 525
		if (!activeEditor) {
			return TPromise.as(true);
E
Erich Gamma 已提交
526 527
		}

528 529 530 531 532 533
		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 已提交
534 535
		}

536 537 538 539
		// 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 已提交
540
		return TPromise.as(true);
E
Erich Gamma 已提交
541 542 543 544 545
	}
}

export class OpenToSideAction extends Action {

M
Matt Bierner 已提交
546 547
	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 已提交
548

549 550
	constructor(
		@IWorkbenchEditorService private editorService: IWorkbenchEditorService,
551
		@IEditorGroupService private editorGroupService: IEditorGroupService
552
	) {
E
Erich Gamma 已提交
553 554 555
		super(OpenToSideAction.OPEN_TO_SIDE_ID, OpenToSideAction.OPEN_TO_SIDE_LABEL);

		this.updateEnablement();
556 557 558 559
		this.updateClass();
	}

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

562
		this.class = editorGroupLayoutVertical ? 'quick-open-sidebyside-vertical' : 'quick-open-sidebyside-horizontal';
E
Erich Gamma 已提交
563 564 565
	}

	private updateEnablement(): void {
566
		const activeEditor = this.editorService.getActiveEditor();
567
		this.enabled = (!activeEditor || activeEditor.position !== Position.THREE);
E
Erich Gamma 已提交
568 569
	}

570
	public run(context: any): TPromise<any> {
E
Erich Gamma 已提交
571 572
		let entry = toEditorQuickOpenEntry(context);
		if (entry) {
573
			const input = entry.getInput();
B
Benjamin Pasero 已提交
574
			if (input instanceof EditorInput) {
575
				return this.editorService.openEditor(input, entry.getOptions(), true);
B
Benjamin Pasero 已提交
576 577
			}

578 579 580 581
			const resourceInput = input as IResourceInput;
			resourceInput.options = mixin(resourceInput.options, entry.getOptions());

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

A
Alex Dima 已提交
584
		return TPromise.as(false);
E
Erich Gamma 已提交
585 586 587
	}
}

588
export function toEditorQuickOpenEntry(element: any): IEditorQuickOpenEntry {
E
Erich Gamma 已提交
589 590 591

	// QuickOpenEntryGroup
	if (element instanceof QuickOpenEntryGroup) {
592
		const group = <QuickOpenEntryGroup>element;
E
Erich Gamma 已提交
593 594 595 596 597 598 599 600 601 602 603 604 605 606
		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 {
607

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

611 612 613
	constructor(
		id: string,
		label: string,
I
isidor 已提交
614
		@ICommandService private commandService: ICommandService
615
	) {
I
isidor 已提交
616
		super(id, label, 'close-editor-action');
E
Erich Gamma 已提交
617 618
	}

I
isidor 已提交
619
	public run(context?: IEditorCommandsContext): TPromise<any> {
620
		return this.commandService.executeCommand(CLOSE_EDITOR_COMMAND_ID, void 0, context);
E
Erich Gamma 已提交
621 622 623
	}
}

624 625 626 627 628 629 630 631
export class CloseOneEditorAction extends Action {

	public static readonly ID = 'workbench.action.closeActiveEditor';
	public static readonly LABEL = nls.localize('closeOneEditor', "Close");

	constructor(
		id: string,
		label: string,
632
		@INextEditorGroupsService private nextEditorGroupsService: INextEditorGroupsService
633 634 635 636 637
	) {
		super(id, label, 'close-editor-action');
	}

	public run(context?: IEditorCommandsContext): TPromise<any> {
638 639 640 641
		let group: INextEditorGroup;
		let editorIndex: number;
		if (context) {
			group = this.nextEditorGroupsService.getGroup(context.groupId);
642

643 644
			if (group) {
				editorIndex = context.editorIndex; // only allow editor at index if group is valid
645 646 647
			}
		}

648 649
		if (!group) {
			group = this.nextEditorGroupsService.activeGroup;
650 651
		}

652 653 654 655 656 657 658 659 660 661 662
		// Close specific editor in group
		if (typeof editorIndex === 'number') {
			const editorAtIndex = group.getEditor(editorIndex);
			if (editorAtIndex) {
				return group.closeEditor(editorAtIndex) as TPromise;
			}
		}

		// Otherwise close active editor in group
		if (group.activeEditor) {
			return group.closeEditor(group.activeEditor) as TPromise;
663 664 665 666 667 668
		}

		return TPromise.as(false);
	}
}

M
misoguy 已提交
669 670
export class RevertAndCloseEditorAction extends Action {

M
Matt Bierner 已提交
671 672
	public static readonly ID = 'workbench.action.revertAndCloseActiveEditor';
	public static readonly LABEL = nls.localize('revertAndCloseActiveEditor', "Revert and Close Editor");
M
misoguy 已提交
673 674 675 676 677 678 679 680 681 682 683

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

	public run(): TPromise<any> {
		const activeEditor = this.editorService.getActiveEditor();
B
Benjamin Pasero 已提交
684 685 686 687
		if (activeEditor && activeEditor.input) {
			const input = activeEditor.input;
			const position = activeEditor.position;

688 689 690 691 692 693 694 695
			// 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 已提交
696 697 698 699 700 701
		}

		return TPromise.as(false);
	}
}

B
Benjamin Pasero 已提交
702
export class CloseLeftEditorsInGroupAction extends Action {
703

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

707 708 709
	constructor(
		id: string,
		label: string,
B
Benjamin Pasero 已提交
710 711
		@IWorkbenchEditorService private editorService: IWorkbenchEditorService,
		@IEditorGroupService private groupService: IEditorGroupService
712
	) {
713 714 715
		super(id, label);
	}

716
	public run(context?: IEditorIdentifier): TPromise<any> {
717
		const editor = getTarget(this.editorService, this.groupService, context);
B
Benjamin Pasero 已提交
718
		if (editor) {
B
Benjamin Pasero 已提交
719
			return this.editorService.closeEditors(editor.position, { except: editor.input, direction: Direction.LEFT });
720 721 722 723 724 725
		}

		return TPromise.as(false);
	}
}

E
Erich Gamma 已提交
726 727
export class CloseAllEditorsAction extends Action {

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

731 732 733 734 735 736
	constructor(
		id: string,
		label: string,
		@ITextFileService private textFileService: ITextFileService,
		@IWorkbenchEditorService private editorService: IWorkbenchEditorService
	) {
I
isidor 已提交
737
		super(id, label, 'action-close-all-files');
E
Erich Gamma 已提交
738 739
	}

740
	public run(): TPromise<any> {
741 742 743

		// Just close all if there are no or one dirty editor
		if (this.textFileService.getDirty().length < 2) {
B
Benjamin Pasero 已提交
744
			return this.editorService.closeEditors();
745 746 747
		}

		// Otherwise ask for combined confirmation
748 749 750 751
		return this.textFileService.confirmSave().then(confirm => {
			if (confirm === ConfirmResult.CANCEL) {
				return void 0;
			}
752

753 754 755 756 757
			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));
758
			}
759

760 761
			return saveOrRevertPromise.then(success => {
				if (success) {
B
Benjamin Pasero 已提交
762
					return this.editorService.closeEditors();
763 764 765 766
				}

				return void 0;
			});
767
		});
E
Erich Gamma 已提交
768 769 770
	}
}

771 772
export class CloseEditorsInOtherGroupsAction extends Action {

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

776 777 778 779 780 781
	constructor(
		id: string,
		label: string,
		@IEditorGroupService private editorGroupService: IEditorGroupService,
		@IWorkbenchEditorService private editorService: IWorkbenchEditorService
	) {
782 783 784
		super(id, label);
	}

785
	public run(context?: IEditorIdentifier): TPromise<any> {
786
		let position = context ? this.editorGroupService.getStacksModel().positionOfGroup(context.group) : null;
787
		if (typeof position !== 'number') {
788
			const activeEditor = this.editorService.getActiveEditor();
789 790 791 792 793 794
			if (activeEditor) {
				position = activeEditor.position;
			}
		}

		if (typeof position === 'number') {
B
Benjamin Pasero 已提交
795
			return this.editorService.closeEditors(POSITIONS.filter(p => p !== position));
796 797 798 799 800 801
		}

		return TPromise.as(false);
	}
}

B
Benjamin Pasero 已提交
802
export class MoveGroupLeftAction extends Action {
E
Erich Gamma 已提交
803

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

807 808 809 810 811 812
	constructor(
		id: string,
		label: string,
		@IEditorGroupService private editorGroupService: IEditorGroupService,
		@IWorkbenchEditorService private editorService: IWorkbenchEditorService
	) {
E
Erich Gamma 已提交
813 814 815
		super(id, label);
	}

816
	public run(context?: IEditorIdentifier): TPromise<any> {
817
		let position = context ? this.editorGroupService.getStacksModel().positionOfGroup(context.group) : null;
818
		if (typeof position !== 'number') {
819
			const activeEditor = this.editorService.getActiveEditor();
820
			if (activeEditor && (activeEditor.position === Position.TWO || activeEditor.position === Position.THREE)) {
821 822 823 824 825
				position = activeEditor.position;
			}
		}

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

B
Benjamin Pasero 已提交
828
			// Move group
829
			this.editorGroupService.moveGroup(position, newPosition);
E
Erich Gamma 已提交
830 831
		}

A
Alex Dima 已提交
832
		return TPromise.as(false);
E
Erich Gamma 已提交
833 834 835
	}
}

B
Benjamin Pasero 已提交
836
export class MoveGroupRightAction extends Action {
E
Erich Gamma 已提交
837

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

841 842 843 844 845 846
	constructor(
		id: string,
		label: string,
		@IEditorGroupService private editorGroupService: IEditorGroupService,
		@IWorkbenchEditorService private editorService: IWorkbenchEditorService
	) {
E
Erich Gamma 已提交
847 848 849
		super(id, label);
	}

850
	public run(context?: IEditorIdentifier): TPromise<any> {
851
		let position = context ? this.editorGroupService.getStacksModel().positionOfGroup(context.group) : null;
852
		if (typeof position !== 'number') {
853 854
			const activeEditor = this.editorService.getActiveEditor();
			const editors = this.editorService.getVisibleEditors();
855

856
			if ((editors.length === 2 && activeEditor.position === Position.ONE) || (editors.length === 3 && activeEditor.position !== Position.THREE)) {
857 858 859 860 861
				position = activeEditor.position;
			}
		}

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

B
Benjamin Pasero 已提交
864
			// Move group
865
			this.editorGroupService.moveGroup(position, newPosition);
E
Erich Gamma 已提交
866 867
		}

A
Alex Dima 已提交
868
		return TPromise.as(false);
E
Erich Gamma 已提交
869 870 871
	}
}

872
export class MinimizeOtherGroupsAction extends Action {
E
Erich Gamma 已提交
873

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

877
	constructor(id: string, label: string, @IEditorGroupService private editorGroupService: IEditorGroupService) {
E
Erich Gamma 已提交
878 879 880
		super(id, label);
	}

881
	public run(): TPromise<any> {
882
		this.editorGroupService.arrangeGroups(GroupArrangement.MINIMIZE_OTHERS);
E
Erich Gamma 已提交
883

A
Alex Dima 已提交
884
		return TPromise.as(false);
E
Erich Gamma 已提交
885 886 887
	}
}

888
export class EvenGroupWidthsAction extends Action {
E
Erich Gamma 已提交
889

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

893
	constructor(id: string, label: string, @IEditorGroupService private editorGroupService: IEditorGroupService) {
E
Erich Gamma 已提交
894 895 896
		super(id, label);
	}

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

A
Alex Dima 已提交
900
		return TPromise.as(false);
E
Erich Gamma 已提交
901 902 903
	}
}

904
export class MaximizeGroupAction extends Action {
905

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

909 910 911 912
	constructor(
		id: string,
		label: string,
		@IWorkbenchEditorService private editorService: IWorkbenchEditorService,
913
		@IEditorGroupService private editorGroupService: IEditorGroupService,
914 915 916 917 918
		@IPartService private partService: IPartService
	) {
		super(id, label);
	}

919
	public run(): TPromise<any> {
920
		if (this.editorService.getActiveEditor()) {
921
			this.editorGroupService.arrangeGroups(GroupArrangement.MINIMIZE_OTHERS);
922
			return this.partService.setSideBarHidden(true);
923 924
		}

A
Alex Dima 已提交
925
		return TPromise.as(false);
926 927 928
	}
}

929
function getTarget(editorService: IWorkbenchEditorService, editorGroupService: IEditorGroupService, context?: IEditorIdentifier): { input: IEditorInput, position: Position } {
B
Benjamin Pasero 已提交
930 931 932 933 934 935 936 937 938 939 940 941
	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;
}

942 943
export abstract class BaseNavigateEditorAction extends Action {

944 945 946 947 948 949
	constructor(
		id: string,
		label: string,
		protected editorGroupService: IEditorGroupService,
		protected editorService: IWorkbenchEditorService
	) {
950 951 952 953
		super(id, label);
	}

	public run(): TPromise<any> {
954
		const model = this.editorGroupService.getStacksModel();
955 956 957 958 959 960 961 962 963 964 965 966 967
		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 已提交
968 969
	public static readonly ID = 'workbench.action.nextEditor';
	public static readonly LABEL = nls.localize('openNextEditor', "Open Next Editor");
970

971 972 973 974 975 976 977
	constructor(
		id: string,
		label: string,
		@IEditorGroupService editorGroupService: IEditorGroupService,
		@IWorkbenchEditorService editorService: IWorkbenchEditorService
	) {
		super(id, label, editorGroupService, editorService);
978 979 980
	}

	protected navigate(): IEditorIdentifier {
981
		return this.editorGroupService.getStacksModel().next(true /* jump groups */);
982 983 984 985 986
	}
}

export class OpenPreviousEditor extends BaseNavigateEditorAction {

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

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

	protected navigate(): IEditorIdentifier {
1000 1001 1002 1003 1004 1005
		return this.editorGroupService.getStacksModel().previous(true /* jump groups */);
	}
}

export class OpenNextEditorInGroup extends BaseNavigateEditorAction {

M
Matt Bierner 已提交
1006 1007
	public static readonly ID = 'workbench.action.nextEditorInGroup';
	public static readonly LABEL = nls.localize('nextEditorInGroup', "Open Next Editor in Group");
1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024

	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 已提交
1025 1026
	public static readonly ID = 'workbench.action.previousEditorInGroup';
	public static readonly LABEL = nls.localize('openPreviousEditorInGroup', "Open Previous Editor in Group");
1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038

	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 */);
1039
	}
B
Benjamin Pasero 已提交
1040 1041
}

1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060
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 已提交
1061 1062
export class NavigateForwardAction extends Action {

M
Matt Bierner 已提交
1063 1064
	public static readonly ID = 'workbench.action.navigateForward';
	public static readonly LABEL = nls.localize('navigateNext', "Go Forward");
B
Benjamin Pasero 已提交
1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078

	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 已提交
1079 1080
	public static readonly ID = 'workbench.action.navigateBack';
	public static readonly LABEL = nls.localize('navigatePrevious', "Go Back");
B
Benjamin Pasero 已提交
1081 1082 1083 1084 1085 1086 1087 1088 1089 1090

	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 已提交
1091
}
1092

1093 1094
export class NavigateLastAction extends Action {

M
Matt Bierner 已提交
1095 1096
	public static readonly ID = 'workbench.action.navigateLast';
	public static readonly LABEL = nls.localize('navigateLast', "Go Last");
1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108

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

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

		return TPromise.as(null);
	}
}

1109 1110
export class ReopenClosedEditorAction extends Action {

M
Matt Bierner 已提交
1111 1112
	public static readonly ID = 'workbench.action.reopenClosedEditor';
	public static readonly LABEL = nls.localize('reopenClosedEditor', "Reopen Closed Editor");
1113 1114 1115 1116

	constructor(
		id: string,
		label: string,
B
Benjamin Pasero 已提交
1117
		@IHistoryService private historyService: IHistoryService
1118 1119 1120 1121 1122
	) {
		super(id, label);
	}

	public run(): TPromise<any> {
1123
		this.historyService.reopenLastClosedEditor();
1124 1125 1126

		return TPromise.as(false);
	}
B
Benjamin Pasero 已提交
1127 1128
}

1129
export class ClearRecentFilesAction extends Action {
C
22768  
Cristian 已提交
1130

M
Matt Bierner 已提交
1131 1132
	public static readonly ID = 'workbench.action.clearRecentFiles';
	public static readonly LABEL = nls.localize('clearRecentFiles', "Clear Recently Opened");
C
22768  
Cristian 已提交
1133 1134 1135 1136 1137 1138 1139 1140 1141 1142

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

	public run(): TPromise<any> {
B
Benjamin Pasero 已提交
1143
		this.windowsService.clearRecentlyOpened();
C
22768  
Cristian 已提交
1144 1145 1146 1147 1148

		return TPromise.as(false);
	}
}

1149
export class ShowEditorsInGroupOneAction extends QuickOpenAction {
B
Benjamin Pasero 已提交
1150

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

1154 1155 1156
	constructor(
		actionId: string,
		actionLabel: string,
1157
		@IQuickOpenService quickOpenService: IQuickOpenService
1158
	) {
1159
		super(actionId, actionLabel, NAVIGATE_IN_GROUP_ONE_PREFIX, quickOpenService);
1160 1161

		this.class = 'show-group-editors-action';
B
Benjamin Pasero 已提交
1162
	}
1163
}
1164

1165
export class ShowEditorsInGroupTwoAction extends QuickOpenAction {
1166

M
Matt Bierner 已提交
1167 1168
	public static readonly ID = 'workbench.action.showEditorsInSecondGroup';
	public static readonly LABEL = nls.localize('showEditorsInSecondGroup', "Show Editors in Second Group");
1169 1170 1171 1172

	constructor(
		actionId: string,
		actionLabel: string,
1173
		@IQuickOpenService quickOpenService: IQuickOpenService
1174
	) {
1175
		super(actionId, actionLabel, NAVIGATE_IN_GROUP_TWO_PREFIX, quickOpenService);
1176 1177

		this.class = 'show-group-editors-action';
1178 1179
	}
}
1180

1181
export class ShowEditorsInGroupThreeAction extends QuickOpenAction {
1182

M
Matt Bierner 已提交
1183 1184
	public static readonly ID = 'workbench.action.showEditorsInThirdGroup';
	public static readonly LABEL = nls.localize('showEditorsInThirdGroup', "Show Editors in Third Group");
1185 1186 1187 1188

	constructor(
		actionId: string,
		actionLabel: string,
1189
		@IQuickOpenService quickOpenService: IQuickOpenService
1190
	) {
1191
		super(actionId, actionLabel, NAVIGATE_IN_GROUP_THREE_PREFIX, quickOpenService);
1192 1193

		this.class = 'show-group-editors-action';
1194
	}
B
Benjamin Pasero 已提交
1195 1196
}

B
Benjamin Pasero 已提交
1197 1198
export class ShowAllEditorsAction extends QuickOpenAction {

M
Matt Bierner 已提交
1199 1200
	public static readonly ID = 'workbench.action.showAllEditors';
	public static readonly LABEL = nls.localize('showAllEditors', "Show All Editors");
B
Benjamin Pasero 已提交
1201 1202 1203 1204 1205 1206

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

1207
export class BaseQuickOpenEditorInGroupAction extends Action {
B
Benjamin Pasero 已提交
1208 1209 1210 1211 1212

	constructor(
		id: string,
		label: string,
		@IQuickOpenService private quickOpenService: IQuickOpenService,
1213
		@IKeybindingService private keybindingService: IKeybindingService,
1214
		@IEditorGroupService private editorGroupService: IEditorGroupService
B
Benjamin Pasero 已提交
1215 1216 1217 1218 1219
	) {
		super(id, label);
	}

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

1222
		const stacks = this.editorGroupService.getStacksModel();
1223 1224
		if (stacks.activeGroup) {
			const activePosition = stacks.positionOfGroup(stacks.activeGroup);
1225
			let prefix = NAVIGATE_IN_GROUP_ONE_PREFIX;
1226

B
Benjamin Pasero 已提交
1227
			if (activePosition === Position.TWO) {
1228
				prefix = NAVIGATE_IN_GROUP_TWO_PREFIX;
B
Benjamin Pasero 已提交
1229
			} else if (activePosition === Position.THREE) {
1230
				prefix = NAVIGATE_IN_GROUP_THREE_PREFIX;
1231 1232
			}

B
Benjamin Pasero 已提交
1233
			this.quickOpenService.show(prefix, { quickNavigateConfiguration: { keybindings: keys } });
1234
		}
B
Benjamin Pasero 已提交
1235 1236 1237 1238 1239

		return TPromise.as(true);
	}
}

1240 1241
export class OpenPreviousRecentlyUsedEditorInGroupAction extends BaseQuickOpenEditorInGroupAction {

M
Matt Bierner 已提交
1242 1243
	public static readonly ID = 'workbench.action.openPreviousRecentlyUsedEditorInGroup';
	public static readonly LABEL = nls.localize('openPreviousRecentlyUsedEditorInGroup', "Open Previous Recently Used Editor in Group");
1244 1245 1246 1247 1248 1249

	constructor(
		id: string,
		label: string,
		@IQuickOpenService quickOpenService: IQuickOpenService,
		@IKeybindingService keybindingService: IKeybindingService,
1250
		@IEditorGroupService editorGroupService: IEditorGroupService
1251
	) {
1252
		super(id, label, quickOpenService, keybindingService, editorGroupService);
1253 1254 1255 1256 1257
	}
}

export class OpenNextRecentlyUsedEditorInGroupAction extends BaseQuickOpenEditorInGroupAction {

M
Matt Bierner 已提交
1258 1259
	public static readonly ID = 'workbench.action.openNextRecentlyUsedEditorInGroup';
	public static readonly LABEL = nls.localize('openNextRecentlyUsedEditorInGroup', "Open Next Recently Used Editor in Group");
1260 1261 1262 1263 1264 1265

	constructor(
		id: string,
		label: string,
		@IQuickOpenService quickOpenService: IQuickOpenService,
		@IKeybindingService keybindingService: IKeybindingService,
1266
		@IEditorGroupService editorGroupService: IEditorGroupService
1267
	) {
1268
		super(id, label, quickOpenService, keybindingService, editorGroupService);
1269 1270 1271
	}
}

1272
export class OpenPreviousEditorFromHistoryAction extends Action {
B
Benjamin Pasero 已提交
1273

M
Matt Bierner 已提交
1274 1275
	public static readonly ID = 'workbench.action.openPreviousEditorFromHistory';
	public static readonly LABEL = nls.localize('navigateEditorHistoryByInput', "Open Previous Editor from History");
B
Benjamin Pasero 已提交
1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286

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

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

B
Benjamin Pasero 已提交
1289
		this.quickOpenService.show(null, { quickNavigateConfiguration: { keybindings: keys } });
B
Benjamin Pasero 已提交
1290 1291 1292 1293 1294

		return TPromise.as(true);
	}
}

1295 1296
export class OpenNextRecentlyUsedEditorAction extends Action {

M
Matt Bierner 已提交
1297 1298
	public static readonly ID = 'workbench.action.openNextRecentlyUsedEditor';
	public static readonly LABEL = nls.localize('openNextRecentlyUsedEditor', "Open Next Recently Used Editor");
1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312

	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 已提交
1313 1314
	public static readonly ID = 'workbench.action.openPreviousRecentlyUsedEditor';
	public static readonly LABEL = nls.localize('openPreviousRecentlyUsedEditor', "Open Previous Recently Used Editor");
1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326

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

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

		return TPromise.as(null);
	}
}

1327 1328
export class ClearEditorHistoryAction extends Action {

M
Matt Bierner 已提交
1329 1330
	public static readonly ID = 'workbench.action.clearEditorHistory';
	public static readonly LABEL = nls.localize('clearEditorHistory', "Clear Editor History");
1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341

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

	public run(): TPromise<any> {

1342
		// Editor history
1343 1344 1345 1346 1347 1348
		this.historyService.clear();

		return TPromise.as(true);
	}
}

1349 1350
export class FocusLastEditorInStackAction extends Action {

M
Matt Bierner 已提交
1351 1352
	public static readonly ID = 'workbench.action.openLastEditorInGroup';
	public static readonly LABEL = nls.localize('focusLastEditorInStack', "Open Last Editor in Group");
1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373

	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);
			}
		}

1374 1375 1376 1377
		return TPromise.as(true);
	}
}

1378 1379
export class MoveEditorLeftInGroupAction extends Action {

M
Matt Bierner 已提交
1380 1381
	public static readonly ID = 'workbench.action.moveEditorLeftInGroup';
	public static readonly LABEL = nls.localize('moveEditorLeft', "Move Editor Left");
1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392

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

	public run(): TPromise<any> {
		const args: ActiveEditorMoveArguments = {
1393
			to: ActiveEditorMovePositioning.LEFT
1394 1395 1396 1397 1398 1399 1400 1401 1402
		};
		this.commandService.executeCommand(EditorCommands.MoveActiveEditor, args);

		return TPromise.as(true);
	}
}

export class MoveEditorRightInGroupAction extends Action {

M
Matt Bierner 已提交
1403 1404
	public static readonly ID = 'workbench.action.moveEditorRightInGroup';
	public static readonly LABEL = nls.localize('moveEditorRight', "Move Editor Right");
1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415

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

	public run(): TPromise<any> {
		const args: ActiveEditorMoveArguments = {
1416
			to: ActiveEditorMovePositioning.RIGHT
1417 1418 1419 1420 1421 1422 1423
		};
		this.commandService.executeCommand(EditorCommands.MoveActiveEditor, args);

		return TPromise.as(true);
	}
}

1424
export class MoveEditorToPreviousGroupAction extends Action {
1425

M
Matt Bierner 已提交
1426 1427
	public static readonly ID = 'workbench.action.moveEditorToPreviousGroup';
	public static readonly LABEL = nls.localize('moveEditorToPreviousGroup', "Move Editor into Previous Group");
1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439

	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();
1440
		if (activeEditor && activeEditor.position !== Position.ONE) {
1441 1442 1443 1444 1445 1446 1447
			this.editorGroupService.moveEditor(activeEditor.input, activeEditor.position, activeEditor.position - 1);
		}

		return TPromise.as(true);
	}
}

1448
export class MoveEditorToNextGroupAction extends Action {
1449

M
Matt Bierner 已提交
1450 1451
	public static readonly ID = 'workbench.action.moveEditorToNextGroup';
	public static readonly LABEL = nls.localize('moveEditorToNextGroup', "Move Editor into Next Group");
1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463

	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();
1464
		if (activeEditor && activeEditor.position !== Position.THREE) {
1465 1466 1467
			this.editorGroupService.moveEditor(activeEditor.input, activeEditor.position, activeEditor.position + 1);
		}

1468 1469
		return TPromise.as(true);
	}
D
Daniel Imms 已提交
1470
}
1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536

export abstract class MoveEditorToSpecificGroup extends Action {

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

	public run(): TPromise<any> {
		const activeEditor = this.editorService.getActiveEditor();
		if (activeEditor && activeEditor.position !== this.position) {
			this.editorGroupService.moveEditor(activeEditor.input, activeEditor.position, this.position);
		}

		return TPromise.as(true);
	}
}

export class MoveEditorToFirstGroupAction extends MoveEditorToSpecificGroup {

	public static readonly ID = 'workbench.action.moveEditorToFirstGroup';
	public static readonly LABEL = nls.localize('moveEditorToFirstGroup', "Move Editor into First Group");

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

export class MoveEditorToSecondGroupAction extends MoveEditorToSpecificGroup {

	public static readonly ID = 'workbench.action.moveEditorToSecondGroup';
	public static readonly LABEL = nls.localize('moveEditorToSecondGroup', "Move Editor into Second Group");

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

export class MoveEditorToThirdGroupAction extends MoveEditorToSpecificGroup {

	public static readonly ID = 'workbench.action.moveEditorToThirdGroup';
	public static readonly LABEL = nls.localize('moveEditorToThirdGroup', "Move Editor into Third Group");

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