mirror of
https://github.com/Microsoft/vscode
synced 2024-10-12 06:17:18 +00:00
Merge pull request #5106 from Microsoft/tyriar/open_recently_closed_file
Implement open recently closed file(s) action
This commit is contained in:
commit
a4bc227c1d
|
@ -392,14 +392,19 @@ export class VSCodeMenu {
|
|||
}
|
||||
|
||||
private setOpenRecentMenu(openRecentMenu: Electron.Menu): void {
|
||||
openRecentMenu.append(this.createMenuItem(nls.localize({ key: 'miReopenClosedFile', comment: ['&& denotes a mnemonic'] }, "&&Reopen Closed File"), 'workbench.files.action.reopenClosedFile'));
|
||||
|
||||
let recentList = this.getOpenedPathsList();
|
||||
|
||||
// Folders
|
||||
recentList.folders.forEach((folder, index) => {
|
||||
if (index < VSCodeMenu.MAX_RECENT_ENTRIES) {
|
||||
openRecentMenu.append(this.createOpenRecentMenuItem(folder));
|
||||
}
|
||||
});
|
||||
if (recentList.folders.length > 0) {
|
||||
openRecentMenu.append(__separator__());
|
||||
recentList.folders.forEach((folder, index) => {
|
||||
if (index < VSCodeMenu.MAX_RECENT_ENTRIES) {
|
||||
openRecentMenu.append(this.createOpenRecentMenuItem(folder));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Files
|
||||
let files = recentList.files;
|
||||
|
@ -408,9 +413,7 @@ export class VSCodeMenu {
|
|||
}
|
||||
|
||||
if (files.length > 0) {
|
||||
if (recentList.folders.length > 0) {
|
||||
openRecentMenu.append(__separator__());
|
||||
}
|
||||
openRecentMenu.append(__separator__());
|
||||
|
||||
files.forEach((file, index) => {
|
||||
if (index < VSCodeMenu.MAX_RECENT_ENTRIES) {
|
||||
|
|
|
@ -10,7 +10,7 @@ import {Action, IAction} from 'vs/base/common/actions';
|
|||
import {ActionItem, BaseActionItem, Separator} from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import {Scope, IActionBarRegistry, Extensions as ActionBarExtensions, ActionBarContributor} from 'vs/workbench/browser/actionBarRegistry';
|
||||
import {IEditorInputActionContext, IEditorInputAction, EditorInputActionContributor} from 'vs/workbench/browser/parts/editor/baseEditor';
|
||||
import {AddToWorkingFiles, FocusWorkingFiles, FocusFilesExplorer, OpenPreviousWorkingFile, OpenNextWorkingFile, CloseAllFilesAction, CloseFileAction, CloseOtherFilesAction, GlobalCompareResourcesAction, GlobalNewFileAction, GlobalNewFolderAction, RevertFileAction, SaveFilesAction, SaveAllAction, SaveFileAction, keybindingForAction, MoveFileToTrashAction, TriggerRenameFileAction, PasteFileAction, CopyFileAction, SelectResourceForCompareAction, CompareResourcesAction, NewFolderAction, NewFileAction, OpenToSideAction, ShowActiveFileInExplorer} from 'vs/workbench/parts/files/browser/fileActions';
|
||||
import {AddToWorkingFiles, FocusWorkingFiles, FocusFilesExplorer, OpenPreviousWorkingFile, OpenNextWorkingFile, CloseAllFilesAction, CloseFileAction, CloseOtherFilesAction, GlobalCompareResourcesAction, GlobalNewFileAction, GlobalNewFolderAction, RevertFileAction, SaveFilesAction, SaveAllAction, SaveFileAction, keybindingForAction, MoveFileToTrashAction, TriggerRenameFileAction, PasteFileAction, CopyFileAction, SelectResourceForCompareAction, CompareResourcesAction, NewFolderAction, NewFileAction, ReopenClosedFileAction, OpenToSideAction, ShowActiveFileInExplorer} from 'vs/workbench/parts/files/browser/fileActions';
|
||||
import {RevertLocalChangesAction, AcceptLocalChangesAction, ConflictResolutionDiffEditorInput} from 'vs/workbench/parts/files/browser/saveErrorHandler';
|
||||
import {SyncActionDescriptor} from 'vs/platform/actions/common/actions';
|
||||
import {IWorkbenchActionRegistry, Extensions as ActionExtensions} from 'vs/workbench/common/actionRegistry';
|
||||
|
@ -172,9 +172,10 @@ registry.registerWorkbenchAction(new SyncActionDescriptor(GlobalCompareResources
|
|||
registry.registerWorkbenchAction(new SyncActionDescriptor(CloseFileAction, CloseFileAction.ID, CloseFileAction.LABEL, { primary: KeyMod.chord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.KEY_W) }), category, ['close', 'file']);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(CloseOtherFilesAction, CloseOtherFilesAction.ID, CloseOtherFilesAction.LABEL, { primary: KeyMod.chord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_W) }), category, ['close', 'other', 'files']);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(CloseAllFilesAction, CloseAllFilesAction.ID, CloseAllFilesAction.LABEL, { primary: KeyMod.chord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_W) }), category, ['close', 'all', 'files']);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(ReopenClosedFileAction, ReopenClosedFileAction.ID, ReopenClosedFileAction.LABEL, { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_T }), category, ['reopen', 'open', 'closed', 'file']);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(OpenNextWorkingFile, OpenNextWorkingFile.ID, OpenNextWorkingFile.LABEL, { primary: KeyMod.chord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.DownArrow) }), category, ['open', 'next', 'working', 'file']);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(OpenPreviousWorkingFile, OpenPreviousWorkingFile.ID, OpenPreviousWorkingFile.LABEL, { primary: KeyMod.chord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.UpArrow) }), category, ['open', 'previous', 'working', 'file']);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(AddToWorkingFiles, AddToWorkingFiles.ID, AddToWorkingFiles.LABEL, { primary: KeyMod.chord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.Enter) }), category, ['add', 'to', 'working', 'files']);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(FocusWorkingFiles, FocusWorkingFiles.ID, FocusWorkingFiles.LABEL, { primary: KeyMod.chord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.KEY_E) }), category, ['focus', 'working', 'files']);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(FocusFilesExplorer, FocusFilesExplorer.ID, FocusFilesExplorer.LABEL), category, ['focus', 'files', 'explorer']);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(ShowActiveFileInExplorer, ShowActiveFileInExplorer.ID, ShowActiveFileInExplorer.LABEL), category, ['show', 'active', 'file', 'explorer']);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(ShowActiveFileInExplorer, ShowActiveFileInExplorer.ID, ShowActiveFileInExplorer.LABEL), category, ['show', 'active', 'file', 'explorer']);
|
||||
|
|
|
@ -1800,6 +1800,58 @@ export class OpenResourcesAction extends Action {
|
|||
}
|
||||
}
|
||||
|
||||
export class ReopenClosedFileAction extends Action {
|
||||
|
||||
public static ID = 'workbench.files.action.reopenClosedFile';
|
||||
public static LABEL = nls.localize('reopenClosedFile', "Reopen Closed File");
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@IPartService private partService: IPartService,
|
||||
@IWorkbenchEditorService private editorService: IWorkbenchEditorService,
|
||||
@IViewletService private viewletService: IViewletService,
|
||||
@ITextFileService private textFileService: ITextFileService,
|
||||
@IFileService private fileService: IFileService
|
||||
) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
public run(): TPromise<any> {
|
||||
let viewletPromise = TPromise.as(null);
|
||||
if (!this.partService.isSideBarHidden()) {
|
||||
viewletPromise = this.viewletService.openViewlet(Files.VIEWLET_ID, false);
|
||||
}
|
||||
|
||||
return viewletPromise.then(() => {
|
||||
let workingFilesModel: Files.IWorkingFilesModel = this.textFileService.getWorkingFilesModel();
|
||||
let entry: Files.IWorkingFileEntry = workingFilesModel.popLastClosedEntry();
|
||||
|
||||
if (entry === null) {
|
||||
return TPromise.as(true);
|
||||
}
|
||||
|
||||
// If the current resource is the recently closed resource, run action again
|
||||
let activeResource = getUntitledOrFileResource(this.editorService.getActiveEditorInput());
|
||||
if (activeResource && activeResource.path === entry.resource.path) {
|
||||
return this.run();
|
||||
}
|
||||
|
||||
return this.fileService.resolveFile(entry.resource).then(() => {
|
||||
workingFilesModel.addEntry(entry.resource);
|
||||
return this.editorService.openEditor(entry);
|
||||
}, (e: any) => {
|
||||
// If the files no longer exists, run action again
|
||||
if (e.code === 'ENOENT') {
|
||||
return this.run();
|
||||
}
|
||||
|
||||
return TPromise.wrapError(e);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export abstract class BaseCloseWorkingFileAction extends Action {
|
||||
protected model: WorkingFilesModel;
|
||||
private elements: URI[];
|
||||
|
|
|
@ -105,6 +105,8 @@ export interface IWorkingFilesModel {
|
|||
removeEntry(entry: IWorkingFileEntry): IWorkingFileEntry;
|
||||
removeEntry(arg1: IWorkingFileEntry | URI): IWorkingFileEntry;
|
||||
|
||||
popLastClosedEntry(): IWorkingFileEntry;
|
||||
|
||||
reorder(source: IWorkingFileEntry, target: IWorkingFileEntry): void;
|
||||
|
||||
hasEntry(resource: URI): boolean;
|
||||
|
|
|
@ -18,7 +18,7 @@ import {IUntitledEditorService} from 'vs/workbench/services/untitled/common/unti
|
|||
import {IWorkbenchEditorService} from 'vs/workbench/services/editor/common/editorService';
|
||||
import {IPartService} from 'vs/workbench/services/part/common/partService';
|
||||
import {IWorkspaceContextService} from 'vs/workbench/services/workspace/common/contextService';
|
||||
import {asFileEditorInput} from 'vs/workbench/common/editor';
|
||||
import {asFileEditorInput, getUntitledOrFileResource} from 'vs/workbench/common/editor';
|
||||
import {IStorageService, StorageScope} from 'vs/platform/storage/common/storage';
|
||||
import {IEventService} from 'vs/platform/event/common/event';
|
||||
|
||||
|
@ -27,6 +27,7 @@ export class WorkingFilesModel implements IWorkingFilesModel {
|
|||
private static STORAGE_KEY = 'workingFiles.model.entries';
|
||||
|
||||
private entries: WorkingFileEntry[];
|
||||
private recentlyClosedEntries: WorkingFileEntry[];
|
||||
private pathLabelProvider: labels.PathLabelProvider;
|
||||
private mapEntryToResource: { [resource: string]: WorkingFileEntry; };
|
||||
private _onModelChange: Emitter<IWorkingFileModelChangeEvent>;
|
||||
|
@ -44,6 +45,7 @@ export class WorkingFilesModel implements IWorkingFilesModel {
|
|||
) {
|
||||
this.pathLabelProvider = new labels.PathLabelProvider(this.contextService);
|
||||
this.entries = [];
|
||||
this.recentlyClosedEntries = [];
|
||||
this.toDispose = [];
|
||||
this.mapEntryToResource = Object.create(null);
|
||||
this._onModelChange = new Emitter<IWorkingFileModelChangeEvent>();
|
||||
|
@ -276,6 +278,9 @@ export class WorkingFilesModel implements IWorkingFilesModel {
|
|||
let resource: uri = arg1 instanceof WorkingFileEntry ? (<WorkingFileEntry>arg1).resource : <uri>arg1;
|
||||
let index = this.indexOf(resource);
|
||||
if (index >= 0) {
|
||||
if (resource.scheme === 'file') {
|
||||
this.recordRecentlyClosedEntries([this.mapEntryToResource[resource.toString()]]);
|
||||
}
|
||||
|
||||
// Remove entry
|
||||
let removed = this.entries.splice(index, 1)[0];
|
||||
|
@ -300,6 +305,13 @@ export class WorkingFilesModel implements IWorkingFilesModel {
|
|||
return null;
|
||||
}
|
||||
|
||||
public popLastClosedEntry(): WorkingFileEntry {
|
||||
if (this.recentlyClosedEntries.length > 0) {
|
||||
return this.recentlyClosedEntries.pop();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public reorder(source: WorkingFileEntry, target: WorkingFileEntry): void {
|
||||
let sortedEntries = this.entries.slice(0).sort(WorkingFilesModel.compare);
|
||||
|
||||
|
@ -319,6 +331,7 @@ export class WorkingFilesModel implements IWorkingFilesModel {
|
|||
}
|
||||
|
||||
public clear(): void {
|
||||
this.recordRecentlyClosedEntries(this.entries);
|
||||
let deleted = this.entries;
|
||||
this.entries = [];
|
||||
this.mapEntryToResource = Object.create(null);
|
||||
|
@ -333,6 +346,28 @@ export class WorkingFilesModel implements IWorkingFilesModel {
|
|||
return this.mapEntryToResource[resource.toString()];
|
||||
}
|
||||
|
||||
private recordRecentlyClosedEntries(resources: WorkingFileEntry[]): void {
|
||||
if (resources.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Put the active entry on the top of the stack
|
||||
let input = this.editorService.getActiveEditorInput();
|
||||
let resource: uri = getUntitledOrFileResource(input);
|
||||
let activeEntry: WorkingFileEntry;
|
||||
if (resource) {
|
||||
activeEntry = this.findEntry(resource);
|
||||
}
|
||||
|
||||
this.recentlyClosedEntries = this.recentlyClosedEntries.concat(resources.filter(e => {
|
||||
return !activeEntry || e.resource.path !== activeEntry.resource.path;
|
||||
}));
|
||||
|
||||
if (activeEntry) {
|
||||
this.recentlyClosedEntries.push(activeEntry);
|
||||
}
|
||||
}
|
||||
|
||||
private indexOf(resource: uri): number {
|
||||
let entry = this.findEntry(resource);
|
||||
if (entry) {
|
||||
|
@ -375,7 +410,7 @@ export class WorkingFilesModel implements IWorkingFilesModel {
|
|||
if (options && options.filesToDiff) {
|
||||
files.push(...options.filesToDiff);
|
||||
}
|
||||
|
||||
|
||||
arrays
|
||||
.distinct(files, (r) => r.resource.toString()) // no duplicates
|
||||
.map((f) => f.resource) // just the resource
|
||||
|
|
|
@ -0,0 +1,146 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import paths = require('vs/base/common/paths');
|
||||
import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation';
|
||||
import {ITelemetryService, NullTelemetryService} from 'vs/platform/telemetry/common/telemetry';
|
||||
import {IEventService} from 'vs/platform/event/common/event';
|
||||
import {IMessageService} from 'vs/platform/message/common/message';
|
||||
import {IModelService} from 'vs/editor/common/services/modelService';
|
||||
import {IModeService} from 'vs/editor/common/services/modeService';
|
||||
import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace';
|
||||
import {IStorageService} from 'vs/platform/storage/common/storage';
|
||||
import {IConfigurationService} from 'vs/platform/configuration/common/configuration';
|
||||
import {ILifecycleService, NullLifecycleService} from 'vs/platform/lifecycle/common/lifecycle';
|
||||
import {IFileService} from 'vs/platform/files/common/files';
|
||||
import {IUntitledEditorService} from 'vs/workbench/services/untitled/common/untitledEditorService';
|
||||
import {InstantiationService} from 'vs/platform/instantiation/common/instantiationService';
|
||||
import {IWorkbenchEditorService} from 'vs/workbench/services/editor/common/editorService';
|
||||
import {IPartService} from 'vs/workbench/services/part/common/partService';
|
||||
import {ServiceCollection} from 'vs/platform/instantiation/common/serviceCollection';
|
||||
import {TestFileService, TestPartService, TestEditorService, TestConfigurationService, TestUntitledEditorService, TestStorageService, TestContextService, TestMessageService, TestEventService} from 'vs/workbench/test/browser/servicesTestUtils';
|
||||
import {WorkingFileEntry, WorkingFilesModel} from 'vs/workbench/parts/files/common/workingFilesModel';
|
||||
import {TextFileService} from 'vs/workbench/parts/files/browser/textFileServices';
|
||||
import {createMockModelService, createMockModeService} from 'vs/editor/test/common/servicesTestUtils';
|
||||
import {EditorInput} from 'vs/workbench/common/editor';
|
||||
import {FileEditorInput} from 'vs/workbench/parts/files/browser/editors/fileEditorInput';
|
||||
|
||||
let baseInstantiationService: IInstantiationService;
|
||||
let editorService: TestEditorService;
|
||||
let eventService: TestEventService;
|
||||
let textFileService: TextFileService;
|
||||
|
||||
suite('Files - WorkingFilesModel', () => {
|
||||
|
||||
setup(() => {
|
||||
editorService = new TestEditorService();
|
||||
eventService = new TestEventService();
|
||||
|
||||
let services = new ServiceCollection();
|
||||
|
||||
services.set(IEventService, eventService);
|
||||
services.set(IMessageService, new TestMessageService());
|
||||
services.set(IFileService, <any> TestFileService);
|
||||
services.set(IWorkspaceContextService, new TestContextService());
|
||||
services.set(ITelemetryService, NullTelemetryService);
|
||||
services.set(IStorageService, new TestStorageService());
|
||||
services.set(IUntitledEditorService, new TestUntitledEditorService());
|
||||
services.set(IWorkbenchEditorService, editorService);
|
||||
services.set(IPartService, new TestPartService());
|
||||
services.set(IModeService, createMockModeService());
|
||||
services.set(IModelService, createMockModelService());
|
||||
services.set(ILifecycleService, NullLifecycleService);
|
||||
services.set(IConfigurationService, new TestConfigurationService());
|
||||
|
||||
baseInstantiationService = new InstantiationService(services);
|
||||
});
|
||||
|
||||
teardown(() => {
|
||||
eventService.dispose();
|
||||
});
|
||||
|
||||
test("Removed files are added to the closed entries stack", function () {
|
||||
let model = baseInstantiationService.createInstance(WorkingFilesModel);
|
||||
let file1: URI = URI.create('file', null, '/file1');
|
||||
let file2: URI = URI.create('file', null, '/file2');
|
||||
let file3: URI = URI.create('file', null, '/file3');
|
||||
model.addEntry(file1);
|
||||
model.addEntry(file2);
|
||||
model.addEntry(file3);
|
||||
|
||||
model.removeEntry(file2);
|
||||
model.removeEntry(file3);
|
||||
model.removeEntry(file1);
|
||||
|
||||
let lastClosedEntry1: WorkingFileEntry = model.popLastClosedEntry();
|
||||
let lastClosedEntry2: WorkingFileEntry = model.popLastClosedEntry();
|
||||
let lastClosedEntry3: WorkingFileEntry = model.popLastClosedEntry();
|
||||
assert.equal(model.popLastClosedEntry(), null);
|
||||
|
||||
assert.equal(lastClosedEntry1.resource, file1);
|
||||
assert.equal(lastClosedEntry2.resource, file3);
|
||||
assert.equal(lastClosedEntry3.resource, file2);
|
||||
});
|
||||
|
||||
test("Untitled entries are not added to the closed entries stack", function () {
|
||||
let model = baseInstantiationService.createInstance(WorkingFilesModel);
|
||||
let fileUri: URI = URI.create('file', null, '/test');
|
||||
let untitledUri: URI = URI.create('untitled', null);
|
||||
model.addEntry(fileUri);
|
||||
model.addEntry(untitledUri);
|
||||
|
||||
model.removeEntry(fileUri);
|
||||
let lastClosedEntry: WorkingFileEntry = model.popLastClosedEntry();
|
||||
assert.equal(lastClosedEntry.resource, fileUri);
|
||||
|
||||
model.removeEntry(untitledUri);
|
||||
assert.equal(model.popLastClosedEntry(), null);
|
||||
});
|
||||
|
||||
test("Clearing the model adds all entries to the closed entries stack", function() {
|
||||
let model = baseInstantiationService.createInstance(WorkingFilesModel);
|
||||
model.addEntry(URI.create('file', null, '/foo'));
|
||||
model.addEntry(URI.create('file', null, '/bar'));
|
||||
|
||||
assert.equal(model.popLastClosedEntry(), null);
|
||||
model.clear();
|
||||
|
||||
assert.ok(model.popLastClosedEntry().isFile);
|
||||
assert.ok(model.popLastClosedEntry().isFile);
|
||||
assert.equal(model.popLastClosedEntry(), null);
|
||||
});
|
||||
|
||||
test("Reopening multiple files will open the editor in the previously opened file", function() {
|
||||
let model = baseInstantiationService.createInstance(WorkingFilesModel);
|
||||
|
||||
// Open /foo then /bar, set /foo as active input
|
||||
let fooEntry = model.addEntry(URI.create('file', null, '/foo'));
|
||||
editorService.getActiveEditorInput = () => {
|
||||
return baseInstantiationService.createInstance(FileEditorInput, fooEntry.resource, 'text/javascript', void 0);
|
||||
};
|
||||
model.addEntry(URI.create('file', null, '/bar'));
|
||||
model.clear();
|
||||
|
||||
assert.equal(model.popLastClosedEntry().resource.path, '/foo');
|
||||
assert.equal(model.popLastClosedEntry().resource.path, '/bar');
|
||||
assert.equal(model.popLastClosedEntry(), null);
|
||||
|
||||
// Open /bar then /foo, set /foo as active input
|
||||
model.addEntry(URI.create('file', null, '/bar'));
|
||||
fooEntry = model.addEntry(URI.create('file', null, '/foo'));
|
||||
editorService.getActiveEditorInput = () => {
|
||||
return baseInstantiationService.createInstance(FileEditorInput, fooEntry.resource, 'text/javascript', void 0);
|
||||
};
|
||||
model.clear();
|
||||
|
||||
assert.equal(model.popLastClosedEntry().resource.path, '/foo');
|
||||
assert.equal(model.popLastClosedEntry().resource.path, '/bar');
|
||||
assert.equal(model.popLastClosedEntry(), null);
|
||||
});
|
||||
});
|
|
@ -890,7 +890,7 @@ let tasksCategory = nls.localize('tasksCategory', "Tasks");
|
|||
let workbenchActionsRegistry = <IWorkbenchActionRegistry>Registry.as(WorkbenchActionExtensions.WorkbenchActions);
|
||||
workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(ConfigureTaskRunnerAction, ConfigureTaskRunnerAction.ID, ConfigureTaskRunnerAction.TEXT), tasksCategory, ['configure', 'task', 'runner']);
|
||||
workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(BuildAction, BuildAction.ID, BuildAction.TEXT, { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_B }), tasksCategory, ['run', 'build', 'task']);
|
||||
workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(TestAction, TestAction.ID, TestAction.TEXT, { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_T }), tasksCategory, ['run', 'test', 'talk']);
|
||||
workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(TestAction, TestAction.ID, TestAction.TEXT), tasksCategory, ['run', 'test', 'talk']);
|
||||
// workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(RebuildAction, RebuildAction.ID, RebuildAction.TEXT), tasksCategory);
|
||||
// workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(CleanAction, CleanAction.ID, CleanAction.TEXT), tasksCategory);
|
||||
workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(TerminateAction, TerminateAction.ID, TerminateAction.TEXT), tasksCategory, ['terminate', 'running', 'task']);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
## Run
|
||||
|
||||
The best way to run the Code tests is from within VS Code. Simply press `CMD+Shift+T` (`Ctrl+Shift+T` on Windows) to launch the tests. To make development changes to unit tests you need to be running `gulp`. See [Development Workflow](https://github.com/Microsoft/vscode/tree/master/wiki/contributing/how-to-contribute.md#incremental-build) for more details.
|
||||
The best way to run the Code tests is from within VS Code. Simply press<kbd>F1</kbd>, type "run test" and press <kbd>enter</kbd> to launch the tests. To make development changes to unit tests you need to be running `gulp`. See [Development Workflow](https://github.com/Microsoft/vscode/tree/master/wiki/contributing/how-to-contribute.md#incremental-build) for more details.
|
||||
|
||||
If you wish to run the tests from a terminal, from the `vscode` folder run:
|
||||
|
||||
|
|
Loading…
Reference in a new issue