Merge from vscode f5d3ffa6a0d655c87e1eb0e1e90773df58f7ff25 (#7929)

* Merge from vscode f5d3ffa6a0d655c87e1eb0e1e90773df58f7ff25

* fix launch script

* add missing files
This commit is contained in:
Anthony Dresser
2019-10-22 21:49:55 -07:00
committed by GitHub
parent 4a68ab4659
commit a94cbb528e
189 changed files with 1976 additions and 1541 deletions

View File

@@ -323,6 +323,9 @@ namespace TaskDTO {
if (task.configurationProperties.group) {
result.group = task.configurationProperties.group;
}
if (task.configurationProperties.detail) {
result.detail = task.configurationProperties.detail;
}
if (!ConfiguringTask.is(task) && task.command) {
if (task.command.runtime === RuntimeType.Process) {
result.execution = ProcessExecutionDTO.from(task.command);
@@ -380,6 +383,7 @@ namespace TaskDTO {
group: task.group,
isBackground: !!task.isBackground,
problemMatchers: task.problemMatchers.slice(),
detail: task.detail
}
);
return result;

View File

@@ -1198,7 +1198,7 @@ export interface ExtHostTerminalServiceShape {
$acceptTerminalTitleChange(id: number, name: string): void;
$acceptTerminalDimensions(id: number, cols: number, rows: number): void;
$acceptTerminalMaximumDimensions(id: number, cols: number, rows: number): void;
$spawnExtHostProcess(id: number, shellLaunchConfig: IShellLaunchConfigDto, activeWorkspaceRootUri: UriComponents, cols: number, rows: number, isWorkspaceShellAllowed: boolean): void;
$spawnExtHostProcess(id: number, shellLaunchConfig: IShellLaunchConfigDto, activeWorkspaceRootUri: UriComponents | undefined, cols: number, rows: number, isWorkspaceShellAllowed: boolean): void;
$startExtensionTerminal(id: number, initialDimensions: ITerminalDimensionsDto | undefined): void;
$acceptProcessInput(id: number, data: string): void;
$acceptProcessResize(id: number, cols: number, rows: number): void;

View File

@@ -740,14 +740,14 @@ class SuggestAdapter {
// 'insertText'-logic
if (item.textEdit) {
result.h = item.textEdit.newText;
result[extHostProtocol.ISuggestDataDtoField.insertText] = item.textEdit.newText;
} else if (typeof item.insertText === 'string') {
result.h = item.insertText;
result[extHostProtocol.ISuggestDataDtoField.insertText] = item.insertText;
} else if (item.insertText instanceof SnippetString) {
result.h = item.insertText.value;
result.i! |= modes.CompletionItemInsertTextRule.InsertAsSnippet;
result[extHostProtocol.ISuggestDataDtoField.insertText] = item.insertText.value;
result[extHostProtocol.ISuggestDataDtoField.insertTextRules]! |= modes.CompletionItemInsertTextRule.InsertAsSnippet;
}
// 'overwrite[Before|After]'-logic
@@ -757,7 +757,7 @@ class SuggestAdapter {
} else if (item.range) {
range = item.range;
}
result.j = typeConvert.Range.from(range);
result[extHostProtocol.ISuggestDataDtoField.range] = typeConvert.Range.from(range);
if (range && (!range.isSingleLine || range.start.line !== position.line)) {
console.warn('INVALID text edit -> must be single line and on the same line');

View File

@@ -62,7 +62,7 @@ export abstract class RequireInterceptor {
this.register(new SqlopsNodeModuleFactory(this._apiFactory.sqlops, extensionPaths)); // {{SQL CARBON EDIT}} // add node module
this.register(this._instaService.createInstance(KeytarNodeModuleFactory));
if (this._initData.remote.isRemote) {
this.register(this._instaService.createInstance(OpenNodeModuleFactory, extensionPaths));
this.register(this._instaService.createInstance(OpenNodeModuleFactory, extensionPaths, this._initData.environment.appUriScheme));
}
}
@@ -233,6 +233,7 @@ class OpenNodeModuleFactory implements INodeModuleFactory {
constructor(
private readonly _extensionPaths: TernarySearchTree<IExtensionDescription>,
private readonly _appUriScheme: string,
@IExtHostRpcService rpcService: IExtHostRpcService,
) {
@@ -247,7 +248,7 @@ class OpenNodeModuleFactory implements INodeModuleFactory {
}
if (uri.scheme === 'http' || uri.scheme === 'https') {
return mainThreadWindow.$openUri(uri, { allowTunneling: true });
} else if (uri.scheme === 'mailto') {
} else if (uri.scheme === 'mailto' || uri.scheme === this._appUriScheme) {
return mainThreadWindow.$openUri(uri, {});
}
return this.callOriginal(target, options);

View File

@@ -225,8 +225,8 @@ export namespace TaskDTO {
execution = ProcessExecutionDTO.from(value.execution);
} else if (value.execution instanceof types.ShellExecution) {
execution = ShellExecutionDTO.from(value.execution);
} else if ((<vscode.Task2>value).execution2 && (<vscode.Task2>value).execution2 instanceof types.CustomExecution) {
execution = CustomExecutionDTO.from(<types.CustomExecution>(<vscode.Task2>value).execution2);
} else if (value.execution && value.execution instanceof types.CustomExecution) {
execution = CustomExecutionDTO.from(<types.CustomExecution>value.execution);
}
const definition: tasks.TaskDefinitionDTO | undefined = TaskDefinitionDTO.from(value.definition);
@@ -261,6 +261,7 @@ export namespace TaskDTO {
problemMatchers: value.problemMatchers,
hasDefinedMatchers: (value as types.Task).hasDefinedMatchers,
runOptions: (<vscode.Task>value).runOptions ? (<vscode.Task>value).runOptions : { reevaluateOnRerun: true },
detail: (<vscode.Task2>value).detail
};
return result;
}
@@ -303,6 +304,9 @@ export namespace TaskDTO {
if (value._id) {
result._id = value._id;
}
if (value.detail) {
result.detail = value.detail;
}
return result;
}
}
@@ -574,7 +578,7 @@ export abstract class ExtHostTaskBase implements ExtHostTaskShape {
}
if (CustomExecutionDTO.is(resolvedTaskDTO.execution)) {
await this.addCustomExecution(resolvedTaskDTO, <vscode.Task2>resolvedTask, true);
await this.addCustomExecution(resolvedTaskDTO, resolvedTask, true);
}
return await this.resolveTaskInternal(resolvedTaskDTO);
@@ -588,12 +592,12 @@ export abstract class ExtHostTaskBase implements ExtHostTaskShape {
return this._handleCounter++;
}
protected async addCustomExecution(taskDTO: tasks.TaskDTO, task: vscode.Task2, isProvided: boolean): Promise<void> {
protected async addCustomExecution(taskDTO: tasks.TaskDTO, task: vscode.Task, isProvided: boolean): Promise<void> {
const taskId = await this._proxy.$createTaskId(taskDTO);
if (!isProvided && !this._providedCustomExecutions2.has(taskId)) {
this._notProvidedCustomExecutions.add(taskId);
}
this._providedCustomExecutions2.set(taskId, <types.CustomExecution>(<vscode.Task2>task).execution2);
this._providedCustomExecutions2.set(taskId, <types.CustomExecution>task.execution);
}
protected async getTaskExecution(execution: tasks.TaskExecutionDTO | string, task?: vscode.Task): Promise<TaskExecutionImpl> {
@@ -675,7 +679,7 @@ export class WorkerExtHostTask extends ExtHostTaskBase {
// in the provided custom execution map that is cleaned up after the
// task is executed.
if (CustomExecutionDTO.is(dto.execution)) {
await this.addCustomExecution(dto, <vscode.Task2>task, false);
await this.addCustomExecution(dto, task, false);
} else {
throw new Error('Not implemented');
}
@@ -697,7 +701,7 @@ export class WorkerExtHostTask extends ExtHostTaskBase {
// The ID is calculated on the main thread task side, so, let's call into it here.
// We need the task id's pre-computed for custom task executions because when OnDidStartTask
// is invoked, we have to be able to map it back to our data.
taskIdPromises.push(this.addCustomExecution(taskDTO, <vscode.Task2>task, true));
taskIdPromises.push(this.addCustomExecution(taskDTO, task, true));
} else {
console.warn('Only custom execution tasks supported.');
}

View File

@@ -1815,6 +1815,7 @@ export class Task implements vscode.Task2 {
private _group: TaskGroup | undefined;
private _presentationOptions: vscode.TaskPresentationOptions;
private _runOptions: vscode.RunOptions;
private _detail: string | undefined;
constructor(definition: vscode.TaskDefinition, name: string, source: string, execution?: ProcessExecution | ShellExecution | CustomExecution, problemMatchers?: string | string[]);
constructor(definition: vscode.TaskDefinition, scope: vscode.TaskScope.Global | vscode.TaskScope.Workspace | vscode.WorkspaceFolder, name: string, source: string, execution?: ProcessExecution | ShellExecution | CustomExecution, problemMatchers?: string | string[]);
@@ -1928,19 +1929,11 @@ export class Task implements vscode.Task2 {
this._name = value;
}
get execution(): ProcessExecution | ShellExecution | undefined {
return (this._execution instanceof CustomExecution) ? undefined : this._execution;
}
set execution(value: ProcessExecution | ShellExecution | undefined) {
this.execution2 = value;
}
get execution2(): ProcessExecution | ShellExecution | CustomExecution | undefined {
get execution(): ProcessExecution | ShellExecution | CustomExecution | undefined {
return this._execution;
}
set execution2(value: ProcessExecution | ShellExecution | CustomExecution | undefined) {
set execution(value: ProcessExecution | ShellExecution | CustomExecution | undefined) {
if (value === null) {
value = undefined;
}
@@ -2009,6 +2002,17 @@ export class Task implements vscode.Task2 {
this._group = value;
}
get detail(): string | undefined {
return this._detail;
}
set detail(value: string | undefined) {
if (value === null) {
value = undefined;
}
this._detail = value;
}
get presentationOptions(): vscode.TaskPresentationOptions {
return this._presentationOptions;
}

View File

@@ -89,6 +89,7 @@ export interface TaskDTO {
isBackground?: boolean;
source: TaskSourceDTO;
group?: string;
detail?: string;
presentationOptions?: TaskPresentationOptionsDTO;
problemMatchers: string[];
hasDefinedMatchers: boolean;

View File

@@ -57,7 +57,7 @@ export class ExtHostTask extends ExtHostTaskBase {
// in the provided custom execution map that is cleaned up after the
// task is executed.
if (CustomExecutionDTO.is(dto.execution)) {
await this.addCustomExecution(dto, <vscode.Task2>task, false);
await this.addCustomExecution(dto, task, false);
}
return this._proxy.$executeTask(dto).then(value => this.getTaskExecution(value, task));

View File

@@ -123,7 +123,7 @@ export class ExtHostTerminalService extends BaseExtHostTerminalService {
this._variableResolver = new ExtHostVariableResolverService(workspaceFolders || [], this._extHostDocumentsAndEditors, configProvider);
}
public async $spawnExtHostProcess(id: number, shellLaunchConfigDto: IShellLaunchConfigDto, activeWorkspaceRootUriComponents: UriComponents, cols: number, rows: number, isWorkspaceShellAllowed: boolean): Promise<void> {
public async $spawnExtHostProcess(id: number, shellLaunchConfigDto: IShellLaunchConfigDto, activeWorkspaceRootUriComponents: UriComponents | undefined, cols: number, rows: number, isWorkspaceShellAllowed: boolean): Promise<void> {
const shellLaunchConfig: IShellLaunchConfig = {
name: shellLaunchConfigDto.name,
executable: shellLaunchConfigDto.executable,
@@ -156,16 +156,21 @@ export class ExtHostTerminalService extends BaseExtHostTerminalService {
}
const activeWorkspaceRootUri = URI.revive(activeWorkspaceRootUriComponents);
// Get the environment
const apiLastActiveWorkspace = await this._extHostWorkspace.getWorkspaceFolder(activeWorkspaceRootUri);
const lastActiveWorkspace = apiLastActiveWorkspace ? {
uri: apiLastActiveWorkspace.uri,
name: apiLastActiveWorkspace.name,
index: apiLastActiveWorkspace.index,
toResource: () => {
throw new Error('Not implemented');
let lastActiveWorkspace: IWorkspaceFolder | null = null;
if (activeWorkspaceRootUriComponents && activeWorkspaceRootUri) {
// Get the environment
const apiLastActiveWorkspace = await this._extHostWorkspace.getWorkspaceFolder(activeWorkspaceRootUri);
if (apiLastActiveWorkspace) {
lastActiveWorkspace = {
uri: apiLastActiveWorkspace.uri,
name: apiLastActiveWorkspace.name,
index: apiLastActiveWorkspace.index,
toResource: () => {
throw new Error('Not implemented');
}
};
}
} as IWorkspaceFolder : null;
}
// Get the initial cwd
const terminalConfig = configProvider.getConfiguration('terminal.integrated');

View File

@@ -13,7 +13,7 @@ import { ICommandService, CommandsRegistry } from 'vs/platform/commands/common/c
import { ADD_ROOT_FOLDER_COMMAND_ID, ADD_ROOT_FOLDER_LABEL, PICK_WORKSPACE_FOLDER_COMMAND_ID } from 'vs/workbench/browser/actions/workspaceCommands';
import { IFileDialogService } from 'vs/platform/dialogs/common/dialogs';
import { MenuRegistry, MenuId, SyncActionDescriptor } from 'vs/platform/actions/common/actions';
import { WorkbenchStateContext, SupportsWorkspacesContext, WorkspaceFolderCountContext } from 'vs/workbench/browser/contextkeys';
import { WorkbenchStateContext, WorkspaceFolderCountContext } from 'vs/workbench/browser/contextkeys';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { Registry } from 'vs/platform/registry/common/platform';
import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actions';
@@ -22,6 +22,7 @@ import { IHostService } from 'vs/workbench/services/host/browser/host';
import { KeyChord, KeyCode, KeyMod } from 'vs/base/common/keyCodes';
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { IWorkspacesService } from 'vs/platform/workspaces/common/workspaces';
export class OpenFileAction extends Action {
@@ -195,14 +196,74 @@ export class GlobalRemoveRootFolderAction extends Action {
}
}
export class SaveWorkspaceAsAction extends Action {
static readonly ID = 'workbench.action.saveWorkspaceAs';
static readonly LABEL = nls.localize('saveWorkspaceAsAction', "Save Workspace As...");
constructor(
id: string,
label: string,
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
@IWorkspaceEditingService private readonly workspaceEditingService: IWorkspaceEditingService
) {
super(id, label);
}
async run(): Promise<any> {
const configPathUri = await this.workspaceEditingService.pickNewWorkspacePath();
if (configPathUri) {
switch (this.contextService.getWorkbenchState()) {
case WorkbenchState.EMPTY:
case WorkbenchState.FOLDER:
const folders = this.contextService.getWorkspace().folders.map(folder => ({ uri: folder.uri }));
return this.workspaceEditingService.createAndEnterWorkspace(folders, configPathUri);
case WorkbenchState.WORKSPACE:
return this.workspaceEditingService.saveAndEnterWorkspace(configPathUri);
}
}
}
}
export class DuplicateWorkspaceInNewWindowAction extends Action {
static readonly ID = 'workbench.action.duplicateWorkspaceInNewWindow';
static readonly LABEL = nls.localize('duplicateWorkspaceInNewWindow', "Duplicate Workspace in New Window");
constructor(
id: string,
label: string,
@IWorkspaceContextService private readonly workspaceContextService: IWorkspaceContextService,
@IWorkspaceEditingService private readonly workspaceEditingService: IWorkspaceEditingService,
@IHostService private readonly hostService: IHostService,
@IWorkspacesService private readonly workspacesService: IWorkspacesService,
@IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService
) {
super(id, label);
}
async run(): Promise<any> {
const folders = this.workspaceContextService.getWorkspace().folders;
const remoteAuthority = this.environmentService.configuration.remoteAuthority;
const newWorkspace = await this.workspacesService.createUntitledWorkspace(folders, remoteAuthority);
await this.workspaceEditingService.copyWorkspaceSettings(newWorkspace);
return this.hostService.openWindow([{ workspaceUri: newWorkspace.configPath }], { forceNewWindow: true });
}
}
// --- Actions Registration
const registry = Registry.as<IWorkbenchActionRegistry>(Extensions.WorkbenchActions);
const workspacesCategory = nls.localize('workspaces', "Workspaces");
registry.registerWorkbenchAction(new SyncActionDescriptor(AddRootFolderAction, AddRootFolderAction.ID, AddRootFolderAction.LABEL), 'Workspaces: Add Folder to Workspace...', workspacesCategory, SupportsWorkspacesContext);
registry.registerWorkbenchAction(new SyncActionDescriptor(GlobalRemoveRootFolderAction, GlobalRemoveRootFolderAction.ID, GlobalRemoveRootFolderAction.LABEL), 'Workspaces: Remove Folder from Workspace...', workspacesCategory, SupportsWorkspacesContext);
registry.registerWorkbenchAction(new SyncActionDescriptor(CloseWorkspaceAction, CloseWorkspaceAction.ID, CloseWorkspaceAction.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.KEY_F) }), 'Workspaces: Close Workspace', workspacesCategory, SupportsWorkspacesContext);
registry.registerWorkbenchAction(new SyncActionDescriptor(AddRootFolderAction, AddRootFolderAction.ID, AddRootFolderAction.LABEL), 'Workspaces: Add Folder to Workspace...', workspacesCategory);
registry.registerWorkbenchAction(new SyncActionDescriptor(GlobalRemoveRootFolderAction, GlobalRemoveRootFolderAction.ID, GlobalRemoveRootFolderAction.LABEL), 'Workspaces: Remove Folder from Workspace...', workspacesCategory);
registry.registerWorkbenchAction(new SyncActionDescriptor(CloseWorkspaceAction, CloseWorkspaceAction.ID, CloseWorkspaceAction.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.KEY_F) }), 'Workspaces: Close Workspace', workspacesCategory);
registry.registerWorkbenchAction(new SyncActionDescriptor(SaveWorkspaceAsAction, SaveWorkspaceAsAction.ID, SaveWorkspaceAsAction.LABEL), 'Workspaces: Save Workspace As...', workspacesCategory);
registry.registerWorkbenchAction(new SyncActionDescriptor(DuplicateWorkspaceInNewWindowAction, DuplicateWorkspaceInNewWindowAction.ID, DuplicateWorkspaceInNewWindowAction.LABEL), 'Workspaces: Duplicate Workspace in New Window', workspacesCategory);
// --- Menu Registration
@@ -216,8 +277,16 @@ MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, {
id: ADD_ROOT_FOLDER_COMMAND_ID,
title: nls.localize({ key: 'miAddFolderToWorkspace', comment: ['&& denotes a mnemonic'] }, "A&&dd Folder to Workspace...")
},
order: 1,
when: SupportsWorkspacesContext
order: 1
});
MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, {
group: '3_workspace',
command: {
id: SaveWorkspaceAsAction.ID,
title: nls.localize('miSaveWorkspaceAs', "Save Workspace As...")
},
order: 2
});
MenuRegistry.appendMenuItem(MenuId.CommandPalette, {
@@ -246,5 +315,5 @@ MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, {
title: nls.localize({ key: 'miCloseWorkspace', comment: ['&& denotes a mnemonic'] }, "Close &&Workspace")
},
order: 3,
when: ContextKeyExpr.and(WorkbenchStateContext.isEqualTo('workspace'), SupportsWorkspacesContext)
when: ContextKeyExpr.and(WorkbenchStateContext.isEqualTo('workspace'))
});

View File

@@ -38,8 +38,6 @@ export const RemoteConnectionState = new RawContextKey<'' | 'initializing' | 'di
export const HasMacNativeTabsContext = new RawContextKey<boolean>('hasMacNativeTabs', false);
export const SupportsWorkspacesContext = new RawContextKey<boolean>('supportsWorkspaces', true);
export const IsDevelopmentContext = new RawContextKey<boolean>('isDevelopment', false);
export const WorkbenchStateContext = new RawContextKey<string>('workbenchState', undefined);
@@ -107,11 +105,6 @@ export class WorkbenchContextKeysHandler extends Disposable {
// Development
IsDevelopmentContext.bindTo(this.contextKeyService).set(!this.environmentService.isBuilt || this.environmentService.isExtensionDevelopment);
// Workspaces Support
// - web: only if already in workspace state
// - desktop: always
SupportsWorkspacesContext.bindTo(this.contextKeyService).set(isWeb ? this.contextService.getWorkbenchState() === WorkbenchState.WORKSPACE : true);
// Editors
this.activeEditorContext = ActiveEditorContext.bindTo(this.contextKeyService);
this.activeEditorIsSaveable = ActiveEditorIsSaveableContext.bindTo(this.contextKeyService);

View File

@@ -260,8 +260,6 @@ export class ActivitybarPart extends Part implements IActivityBarService {
this.createGlobalActivityActionBar(globalActivities);
this.element.style.display = this.layoutService.isVisible(Parts.ACTIVITYBAR_PART) ? '' : 'none';
return this.content;
}

View File

@@ -402,7 +402,7 @@ export class CompositeBar extends Widget implements ICompositeBar {
() => this.model.activeItem ? this.model.activeItem.id : undefined,
(compositeId: string) => {
const item = this.model.findItem(compositeId);
return item?.activity?.[0].badge;
return item?.activity[0]?.badge;
},
this.options.getOnCompositeClickAction,
this.options.colors

View File

@@ -17,7 +17,7 @@
text-decoration-line: underline;
}
.monaco-workbench .monaco-breadcrumb-item.shows-symbol-icon .symbol-icon.block {
.monaco-workbench .monaco-breadcrumb-item.shows-symbol-icon .codicon[class*='codicon-symbol-'] {
padding-right: 6px;
}

View File

@@ -275,8 +275,11 @@
}
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-breadcrumbs .breadcrumbs-control .monaco-breadcrumb-item::before {
min-width: 16px;
width: 16px;
height: 22px;
display: flex;
align-items: center;
justify-content: center;
}
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-breadcrumbs .breadcrumbs-control .monaco-breadcrumb-item:last-child {

View File

@@ -48,6 +48,7 @@ import { toLocalISOString } from 'vs/base/common/date';
import { IndexedDBLogProvider } from 'vs/workbench/services/log/browser/indexedDBLogProvider';
import { InMemoryLogProvider } from 'vs/workbench/services/log/common/inMemoryLogProvider';
import { isWorkspaceToOpen, isFolderToOpen } from 'vs/platform/windows/common/windows';
import { getWorkspaceIdentifier } from 'vs/workbench/services/workspaces/browser/workspaces';
class BrowserMain extends Disposable {
@@ -292,7 +293,7 @@ class BrowserMain extends Disposable {
// Multi-root workspace
if (workspace && isWorkspaceToOpen(workspace)) {
return { id: hash(workspace.workspaceUri.toString()).toString(16), configPath: workspace.workspaceUri };
return getWorkspaceIdentifier(workspace.workspaceUri);
}
// Single-folder workspace

View File

@@ -289,6 +289,13 @@ export class DebugService implements IDebugService {
throw new Error(nls.localize({ key: 'compoundMustHaveConfigurations', comment: ['compound indicates a "compounds" configuration item', '"configurations" is an attribute and should not be localized'] },
"Compound must have \"configurations\" attribute set in order to start multiple configurations."));
}
if (compound.preLaunchTask) {
const taskResult = await this.runTaskAndCheckErrors(launch?.workspace || this.contextService.getWorkspace(), compound.preLaunchTask);
if (taskResult === TaskRunResult.Failure) {
this.endInitializingState();
return false;
}
}
const values = await Promise.all(compound.configurations.map(configData => {
const name = typeof configData === 'string' ? configData : configData.name;
@@ -394,10 +401,10 @@ export class DebugService implements IDebugService {
return false;
}
const workspace = launch ? launch.workspace : undefined;
const workspace = launch ? launch.workspace : this.contextService.getWorkspace();
const taskResult = await this.runTaskAndCheckErrors(workspace, resolvedConfig.preLaunchTask);
if (taskResult === TaskRunResult.Success) {
return this.doCreateSession(workspace, { resolved: resolvedConfig, unresolved: unresolvedConfig }, options);
return this.doCreateSession(launch?.workspace, { resolved: resolvedConfig, unresolved: unresolvedConfig }, options);
}
return false;
} catch (err) {
@@ -701,7 +708,7 @@ export class DebugService implements IDebugService {
//---- task management
private async runTaskAndCheckErrors(root: IWorkspaceFolder | undefined, taskId: string | TaskIdentifier | undefined): Promise<TaskRunResult> {
private async runTaskAndCheckErrors(root: IWorkspaceFolder | IWorkspace | undefined, taskId: string | TaskIdentifier | undefined): Promise<TaskRunResult> {
try {
const taskSummary = await this.runTask(root, taskId);

View File

@@ -571,21 +571,18 @@ export class RawDebugSession implements IDisposable {
const args: string[] = [];
for (let arg of vscodeArgs.args) {
if (arg.prefix) {
const a2 = (arg.prefix || '') + (arg.path || '');
const match = /^--(.+)=(.+)$/.exec(a2);
if (match && match.length === 3) {
const key = match[1];
let value = match[2];
const a2 = (arg.prefix || '') + (arg.path || '');
const match = /^--(.+)=(.+)$/.exec(a2);
if (match && match.length === 3) {
const key = match[1];
let value = match[2];
if ((key === 'file-uri' || key === 'folder-uri') && !isUri(arg.path)) {
value = URI.file(value).toString();
}
args.push(`--${key}=${value}`);
} else {
args.push(a2);
if ((key === 'file-uri' || key === 'folder-uri') && !isUri(arg.path)) {
value = URI.file(value).toString();
}
args.push(`--${key}=${value}`);
} else {
args.push(a2);
}
}

View File

@@ -505,6 +505,7 @@ export interface IConfig extends IEnvConfig {
export interface ICompound {
name: string;
preLaunchTask?: string | TaskIdentifier;
configurations: (string | { name: string, folder: string })[];
}

View File

@@ -190,6 +190,11 @@ export const launchSchema: IJSONSchema = {
}]
},
description: nls.localize('app.launch.json.compounds.configurations', "Names of configurations that will be started as part of this compound.")
},
preLaunchTask: {
type: 'string',
default: '',
description: nls.localize('compoundPrelaunchTask', "Task to run before any of the compound configurations start.")
}
},
default: defaultCompound

View File

@@ -23,7 +23,7 @@ import { ResourceContextKey } from 'vs/workbench/common/resources';
import { WorkbenchListDoubleSelection } from 'vs/platform/list/browser/listService';
import { URI } from 'vs/base/common/uri';
import { Schemas } from 'vs/base/common/network';
import { SupportsWorkspacesContext, IsWebContext, WorkspaceFolderCountContext } from 'vs/workbench/browser/contextkeys';
import { IsWebContext, WorkspaceFolderCountContext } from 'vs/workbench/browser/contextkeys';
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { OpenFileFolderAction, OpenFileAction, OpenFolderAction, OpenWorkspaceAction } from 'vs/workbench/browser/actions/workspaceActions';
import { ActiveEditorIsSaveableContext } from 'vs/workbench/common/editor';
@@ -496,7 +496,7 @@ MenuRegistry.appendMenuItem(MenuId.ExplorerContext, {
id: ADD_ROOT_FOLDER_COMMAND_ID,
title: ADD_ROOT_FOLDER_LABEL
},
when: ContextKeyExpr.and(ExplorerRootContext, SupportsWorkspacesContext)
when: ContextKeyExpr.and(ExplorerRootContext)
});
MenuRegistry.appendMenuItem(MenuId.ExplorerContext, {
@@ -506,7 +506,7 @@ MenuRegistry.appendMenuItem(MenuId.ExplorerContext, {
id: REMOVE_ROOT_FOLDER_COMMAND_ID,
title: REMOVE_ROOT_FOLDER_LABEL
},
when: ContextKeyExpr.and(ExplorerRootContext, ExplorerFolderContext, SupportsWorkspacesContext)
when: ContextKeyExpr.and(ExplorerRootContext, ExplorerFolderContext)
});
MenuRegistry.appendMenuItem(MenuId.ExplorerContext, {

View File

@@ -581,7 +581,8 @@ class OpenEditorRenderer implements IListRenderer<OpenEditor, IOpenEditorTemplat
italic: editor.isPreview(),
extraClasses: ['open-editor'],
fileDecorations: this.configurationService.getValue<IFilesConfiguration>().explorer.decorations,
descriptionVerbosity: Verbosity.MEDIUM
descriptionVerbosity: Verbosity.MEDIUM,
title: editor.editor.getTitle(Verbosity.LONG)
});
}

View File

@@ -10,7 +10,7 @@ import { URI } from 'vs/base/common/uri';
import { EncodingMode, ConfirmResult, EditorInput, IFileEditorInput, ITextEditorModel, Verbosity, IRevertOptions } from 'vs/workbench/common/editor';
import { TextFileEditorModel } from 'vs/workbench/services/textfile/common/textFileEditorModel';
import { BinaryEditorModel } from 'vs/workbench/common/editor/binaryEditorModel';
import { FileOperationError, FileOperationResult } from 'vs/platform/files/common/files';
import { FileOperationError, FileOperationResult, IFileService } from 'vs/platform/files/common/files';
import { ITextFileService, AutoSaveMode, ModelState, TextFileModelChangeEvent, LoadReason, TextFileOperationError, TextFileOperationResult } from 'vs/workbench/services/textfile/common/textfiles';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IReference } from 'vs/base/common/lifecycle';
@@ -48,7 +48,8 @@ export class FileEditorInput extends EditorInput implements IFileEditorInput {
@IInstantiationService private readonly instantiationService: IInstantiationService,
@ITextFileService private readonly textFileService: ITextFileService,
@ITextModelService private readonly textModelResolverService: ITextModelService,
@ILabelService private readonly labelService: ILabelService
@ILabelService private readonly labelService: ILabelService,
@IFileService private readonly fileService: IFileService
) {
super();
@@ -72,6 +73,7 @@ export class FileEditorInput extends EditorInput implements IFileEditorInput {
this._register(this.textFileService.models.onModelReverted(e => this.onDirtyStateChange(e)));
this._register(this.textFileService.models.onModelOrphanedChanged(e => this.onModelOrphanedChanged(e)));
this._register(this.labelService.onDidChangeFormatters(() => FileEditorInput.MEMOIZER.clear()));
this._register(this.fileService.onDidChangeFileSystemProviderRegistrations(() => FileEditorInput.MEMOIZER.clear()));
}
private onDirtyStateChange(e: TextFileModelChangeEvent): void {

View File

@@ -44,7 +44,16 @@
padding: 0px 8px;
border-radius: 2px;
position: absolute;
right: 10px;
right: 35px;
top: 0;
}
.settings-editor > .settings-header > .search-container > .settings-clear-widget {
margin: 6px 0px;
padding: 0px 8px;
border-radius: 2px;
position: absolute;
right: 0px;
top: 0;
}

View File

@@ -39,11 +39,13 @@ import { AbstractSettingRenderer, ISettingLinkClickEvent, ISettingOverrideClickE
import { ISettingsEditorViewState, parseQuery, SearchResultIdx, SearchResultModel, SettingsTreeElement, SettingsTreeGroupChild, SettingsTreeGroupElement, SettingsTreeModel, SettingsTreeSettingElement } from 'vs/workbench/contrib/preferences/browser/settingsTreeModels';
import { settingsTextInputBorder } from 'vs/workbench/contrib/preferences/browser/settingsWidgets';
import { createTOCIterator, TOCTree, TOCTreeModel } from 'vs/workbench/contrib/preferences/browser/tocTree';
import { CONTEXT_SETTINGS_EDITOR, CONTEXT_SETTINGS_SEARCH_FOCUS, CONTEXT_TOC_ROW_FOCUS, EXTENSION_SETTING_TAG, IPreferencesSearchService, ISearchProvider, MODIFIED_SETTING_TAG, SETTINGS_EDITOR_COMMAND_SHOW_CONTEXT_MENU } from 'vs/workbench/contrib/preferences/common/preferences';
import { CONTEXT_SETTINGS_EDITOR, CONTEXT_SETTINGS_SEARCH_FOCUS, CONTEXT_TOC_ROW_FOCUS, EXTENSION_SETTING_TAG, IPreferencesSearchService, ISearchProvider, MODIFIED_SETTING_TAG, SETTINGS_EDITOR_COMMAND_SHOW_CONTEXT_MENU, SETTINGS_EDITOR_COMMAND_CLEAR_SEARCH_RESULTS } from 'vs/workbench/contrib/preferences/common/preferences';
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
import { IPreferencesService, ISearchResult, ISettingsEditorModel, ISettingsEditorOptions, SettingsEditorOptions, SettingValueType } from 'vs/workbench/services/preferences/common/preferences';
import { SettingsEditor2Input } from 'vs/workbench/services/preferences/common/preferencesEditorInput';
import { Settings2EditorModel } from 'vs/workbench/services/preferences/common/preferencesModels';
import { Action } from 'vs/base/common/actions';
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
function createGroupIterator(group: SettingsTreeGroupElement): Iterator<ITreeElement<SettingsTreeGroupChild>> {
const groupsIt = Iterator.fromArray(group.children);
@@ -132,6 +134,9 @@ export class SettingsEditor2 extends BaseEditor {
private scheduledRefreshes: Map<string, DOM.IFocusTracker>;
private lastFocusedSettingElement: string | null = null;
private actionBar: ActionBar;
private actionsContainer: HTMLElement;
/** Don't spam warnings */
private hasWarnedMissingSettings = false;
@@ -385,11 +390,18 @@ export class SettingsEditor2 extends BaseEditor {
this.searchWidget.setValue(query.trim());
}
clearSearch(): void {
this.clearSearchResults();
this.focusSearch();
}
private createHeader(parent: HTMLElement): void {
this.headerContainer = DOM.append(parent, $('.settings-header'));
const searchContainer = DOM.append(this.headerContainer, $('.search-container'));
const clearInputAction = new Action(SETTINGS_EDITOR_COMMAND_CLEAR_SEARCH_RESULTS, localize('clearInput', "Clear Settings Search Input"), 'codicon-clear-all', false, () => { this.clearSearch(); return Promise.resolve(null); });
const searchBoxLabel = localize('SearchSettings.AriaLabel', "Search settings");
this.searchWidget = this._register(this.instantiationService.createInstance(SuggestEnabledInput, `${SettingsEditor2.ID}.searchbox`, searchContainer, {
triggerCharacters: ['@'],
@@ -425,13 +437,26 @@ export class SettingsEditor2 extends BaseEditor {
this.countElement.style.borderColor = border;
}));
this._register(this.searchWidget.onInputDidChange(() => this.onSearchInputChanged()));
this._register(this.searchWidget.onInputDidChange(() => {
const searchVal = this.searchWidget.getValue();
clearInputAction.enabled = !!searchVal;
this.onSearchInputChanged();
}));
const headerControlsContainer = DOM.append(this.headerContainer, $('.settings-header-controls'));
const targetWidgetContainer = DOM.append(headerControlsContainer, $('.settings-target-container'));
this.settingsTargetsWidget = this._register(this.instantiationService.createInstance(SettingsTargetsWidget, targetWidgetContainer, { enableRemoteSettings: true }));
this.settingsTargetsWidget.settingsTarget = ConfigurationTarget.USER_LOCAL;
this.settingsTargetsWidget.onDidTargetChange(target => this.onDidSettingsTargetChange(target));
this.actionsContainer = DOM.append(searchContainer, DOM.$('.settings-clear-widget'));
this.actionBar = this._register(new ActionBar(this.actionsContainer, {
animated: false,
actionViewItemProvider: (action: Action) => { return undefined; }
}));
this.actionBar.push([clearInputAction], { label: false, icon: true });
}
private onDidSettingsTargetChange(target: SettingsTarget): void {

View File

@@ -245,7 +245,7 @@ export class SearchView extends ViewletPanel {
if (this.searchWidget.isReplaceActive()) {
this.searchWidget.focusReplaceAllAction();
} else {
this.searchWidget.focusRegexAction();
this.searchWidget.isReplaceShown() ? this.searchWidget.replaceInput.focusOnPreserve() : this.searchWidget.focusRegexAction();
}
dom.EventHelper.stop(e);
}

View File

@@ -389,6 +389,7 @@ export class SearchWidget extends Widget {
this.replaceInputFocusTracker = this._register(dom.trackFocus(this.replaceInput.inputBox.inputElement));
this._register(this.replaceInputFocusTracker.onDidFocus(() => this.replaceInputBoxFocused.set(true)));
this._register(this.replaceInputFocusTracker.onDidBlur(() => this.replaceInputBoxFocused.set(false)));
this._register(this.replaceInput.onPreserveCaseKeyDown((keyboardEvent: IKeyboardEvent) => this.onPreserveCaseKeyDown(keyboardEvent)));
}
triggerReplaceAll(): Promise<any> {
@@ -495,6 +496,15 @@ export class SearchWidget extends Widget {
}
private onRegexKeyDown(keyboardEvent: IKeyboardEvent) {
if (keyboardEvent.equals(KeyCode.Tab)) {
if (this.isReplaceShown()) {
this.replaceInput.focusOnPreserve();
keyboardEvent.preventDefault();
}
}
}
private onPreserveCaseKeyDown(keyboardEvent: IKeyboardEvent) {
if (keyboardEvent.equals(KeyCode.Tab)) {
if (this.isReplaceActive()) {
this.focusReplaceAllAction();
@@ -503,6 +513,10 @@ export class SearchWidget extends Widget {
}
keyboardEvent.preventDefault();
}
else if (KeyMod.Shift | KeyCode.Tab) {
this.focusRegexAction();
keyboardEvent.preventDefault();
}
}
private onReplaceInputKeyDown(keyboardEvent: IKeyboardEvent) {

View File

@@ -81,6 +81,7 @@ import { find } from 'vs/base/common/arrays';
import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation';
const QUICKOPEN_HISTORY_LIMIT_CONFIG = 'task.quickOpen.history';
const QUICKOPEN_DETAIL_CONFIG = 'task.quickOpen.detail';
export namespace ConfigureTaskAction {
export const ID = 'workbench.action.tasks.configureTaskRunner';
@@ -744,7 +745,8 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
}
if (CustomTask.is(task)) {
let configProperties: TaskConfig.ConfigurationProperties = task._source.config.element;
return configProperties.problemMatcher === undefined && !task.hasDefinedMatchers;
const type: string = (<any>configProperties).type;
return configProperties.problemMatcher === undefined && !task.hasDefinedMatchers && (Types.isStringArray(settingValue) && (settingValue.indexOf(type) < 0));
}
return false;
}
@@ -1297,7 +1299,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
this.notificationService.prompt(Severity.Warning, nls.localize('TaskSystem.slowProvider', "The {0} task provider is slow. The extension that provides {0} tasks may provide a setting to disable it, or you can disable all tasks providers", type),
[settings, disableAll, dontShow]);
}
}, 1000);
}, 2000);
}
});
}
@@ -1876,6 +1878,10 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
return true;
}
private showDetail(): boolean {
return this.configurationService.getValue<boolean>(QUICKOPEN_DETAIL_CONFIG);
}
private createTaskQuickPickEntries(tasks: Task[], group: boolean = false, sort: boolean = false, selectedEntry?: TaskQuickPickEntry): TaskQuickPickEntry[] {
if (tasks === undefined || tasks === null || tasks.length === 0) {
return [];
@@ -1892,7 +1898,8 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
description = workspaceFolder.name;
}
}
return { label: task._label, description, task };
return { label: task._label, description, task, detail: this.showDetail() ? task.configurationProperties.detail : undefined };
};
function fillEntries(entries: QuickPickInput<TaskQuickPickEntry>[], tasks: Task[], groupLabel: string): void {
if (tasks.length) {

View File

@@ -358,5 +358,10 @@ configurationRegistry.registerConfiguration({
type: 'number',
default: 30, minimum: 0, maximum: 30
},
'task.quickOpen.detail': {
markdownDescription: nls.localize('task.quickOpen.detail', "Controls whether to show the task detail for task that have a detail in the Run Task quick pick."),
type: 'boolean',
default: true
}
}
});

View File

@@ -89,6 +89,11 @@ const dependsOrder: IJSONSchema = {
description: nls.localize('JsonSchema.tasks.dependsOrder', 'Determines the order of the dependsOn tasks for this task. Note that this property is not recursive.')
};
const detail: IJSONSchema = {
type: 'string',
description: nls.localize('JsonSchema.tasks.detail', 'An optional description of a task that shows in the Run Task quick pick as a detail.')
};
const presentation: IJSONSchema = {
type: 'object',
default: {
@@ -365,7 +370,8 @@ let taskConfiguration: IJSONSchema = {
},
runOptions: Objects.deepClone(runOptions),
dependsOn: Objects.deepClone(dependsOn),
dependsOrder: Objects.deepClone(dependsOrder)
dependsOrder: Objects.deepClone(dependsOrder),
detail: Objects.deepClone(detail),
}
};
@@ -425,6 +431,7 @@ taskDescriptionProperties.presentation = Objects.deepClone(presentation);
taskDescriptionProperties.terminal = terminal;
taskDescriptionProperties.group = Objects.deepClone(group);
taskDescriptionProperties.runOptions = Objects.deepClone(runOptions);
taskDescriptionProperties.detail = detail;
taskDescriptionProperties.taskName.deprecationMessage = nls.localize(
'JsonSchema.tasks.taskName.deprecated',
'The task\'s name property is deprecated. Use the label property instead.'

View File

@@ -309,6 +309,11 @@ export interface ConfigurationProperties {
*/
group?: string | GroupKind;
/**
* A description of the task.
*/
detail?: string;
/**
* The other tasks the task depend on
*/
@@ -1326,6 +1331,9 @@ namespace ConfigurationProperties {
if (configProblemMatcher !== undefined) {
result.problemMatchers = configProblemMatcher;
}
if (external.detail) {
result.detail = external.detail;
}
return isEmpty(result) ? undefined : result;
}
@@ -1587,6 +1595,7 @@ namespace CustomTask {
assignProperty(resultConfigProps, configuredProps.configurationProperties, 'dependsOn');
assignProperty(resultConfigProps, configuredProps.configurationProperties, 'problemMatchers');
assignProperty(resultConfigProps, configuredProps.configurationProperties, 'promptOnClose');
assignProperty(resultConfigProps, configuredProps.configurationProperties, 'detail');
result.command.presentation = CommandConfiguration.PresentationOptions.assignProperties(
result.command.presentation!, configuredProps.configurationProperties.presentation)!;
result.command.options = CommandOptions.assignProperties(result.command.options, configuredProps.configurationProperties.options);
@@ -1598,6 +1607,7 @@ namespace CustomTask {
fillProperty(resultConfigProps, contributedConfigProps, 'dependsOn');
fillProperty(resultConfigProps, contributedConfigProps, 'problemMatchers');
fillProperty(resultConfigProps, contributedConfigProps, 'promptOnClose');
fillProperty(resultConfigProps, contributedConfigProps, 'detail');
result.command.presentation = CommandConfiguration.PresentationOptions.fillProperties(
result.command.presentation!, contributedConfigProps.presentation)!;
result.command.options = CommandOptions.fillProperties(result.command.options, contributedConfigProps.options);

View File

@@ -504,6 +504,11 @@ export interface ConfigurationProperties {
*/
dependsOrder?: DependsOrder;
/**
* A description of the task.
*/
detail?: string;
/**
* The problem watchers to use for this task
*/

View File

@@ -219,10 +219,11 @@ configurationRegistry.registerConfiguration({
},
'terminal.integrated.rightClickBehavior': {
type: 'string',
enum: ['default', 'copyPaste', 'selectWord'],
enum: ['default', 'copyPaste', 'paste', 'selectWord'],
enumDescriptions: [
nls.localize('terminal.integrated.rightClickBehavior.default', "Show the context menu."),
nls.localize('terminal.integrated.rightClickBehavior.copyPaste', "Copy when there is a selection, otherwise paste."),
nls.localize('terminal.integrated.rightClickBehavior.paste', "Paste on right click."),
nls.localize('terminal.integrated.rightClickBehavior.selectWord', "Select the word under the cursor and show the context menu.")
],
default: platform.isMacintosh ? 'selectWord' : platform.isWindows ? 'copyPaste' : 'default',
@@ -361,9 +362,7 @@ actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FocusNextTermina
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FocusPreviousTerminalAction, FocusPreviousTerminalAction.ID, FocusPreviousTerminalAction.LABEL), 'Terminal: Focus Previous Terminal', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(TerminalPasteAction, TerminalPasteAction.ID, TerminalPasteAction.LABEL, {
primary: KeyMod.CtrlCmd | KeyCode.KEY_V,
linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_V },
// Don't apply to Mac since cmd+v works
mac: { primary: 0 }
linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_V }
}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Paste into Active Terminal', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(SelectAllTerminalAction, SelectAllTerminalAction.ID, SelectAllTerminalAction.LABEL, {
// Don't use ctrl+a by default as that would override the common go to start

View File

@@ -144,7 +144,7 @@ export interface ITerminalService {
preparePathForTerminalAsync(path: string, executable: string | undefined, title: string): Promise<string>;
extHostReady(remoteAuthority: string): void;
requestSpawnExtHostProcess(proxy: ITerminalProcessExtHostProxy, shellLaunchConfig: IShellLaunchConfig, activeWorkspaceRootUri: URI, cols: number, rows: number, isWorkspaceShellAllowed: boolean): void;
requestSpawnExtHostProcess(proxy: ITerminalProcessExtHostProxy, shellLaunchConfig: IShellLaunchConfig, activeWorkspaceRootUri: URI | undefined, cols: number, rows: number, isWorkspaceShellAllowed: boolean): void;
requestStartExtensionTerminal(proxy: ITerminalProcessExtHostProxy, cols: number, rows: number): void;
}

View File

@@ -218,12 +218,13 @@ export class TerminalPanel extends Panel {
terminal.focus();
}
} else if (event.which === 3) {
if (this._terminalService.configHelper.config.rightClickBehavior === 'copyPaste') {
const rightClickBehavior = this._terminalService.configHelper.config.rightClickBehavior;
if (rightClickBehavior === 'copyPaste' || rightClickBehavior === 'paste') {
const terminal = this._terminalService.getActiveInstance();
if (!terminal) {
return;
}
if (terminal.hasSelection()) {
if (rightClickBehavior === 'copyPaste' && terminal.hasSelection()) {
await terminal.copySelection();
terminal.clearSelection();
} else {

View File

@@ -48,7 +48,7 @@ export class TerminalProcessExtHostProxy extends Disposable implements ITerminal
constructor(
public terminalId: number,
shellLaunchConfig: IShellLaunchConfig,
activeWorkspaceRootUri: URI,
activeWorkspaceRootUri: URI | undefined,
cols: number,
rows: number,
configHelper: ITerminalConfigHelper,

View File

@@ -134,7 +134,7 @@ export class TerminalService implements ITerminalService {
return activeInstance ? activeInstance : this.createTerminal(undefined);
}
public requestSpawnExtHostProcess(proxy: ITerminalProcessExtHostProxy, shellLaunchConfig: IShellLaunchConfig, activeWorkspaceRootUri: URI, cols: number, rows: number, isWorkspaceShellAllowed: boolean): void {
public requestSpawnExtHostProcess(proxy: ITerminalProcessExtHostProxy, shellLaunchConfig: IShellLaunchConfig, activeWorkspaceRootUri: URI | undefined, cols: number, rows: number, isWorkspaceShellAllowed: boolean): void {
this._extensionService.whenInstalledExtensionsRegistered().then(async () => {
// Wait for the remoteAuthority to be ready (and listening for events) before firing
// the event to spawn the ext host process

View File

@@ -88,7 +88,7 @@ export interface ITerminalConfiguration {
macOptionIsMeta: boolean;
macOptionClickForcesSelection: boolean;
rendererType: 'auto' | 'canvas' | 'dom';
rightClickBehavior: 'default' | 'copyPaste' | 'selectWord';
rightClickBehavior: 'default' | 'copyPaste' | 'paste' | 'selectWord';
cursorBlinking: boolean;
cursorStyle: string;
drawBoldTextInBrightColors: boolean;
@@ -343,7 +343,7 @@ export interface ITerminalProcessExtHostProxy extends IDisposable {
export interface ISpawnExtHostProcessRequest {
proxy: ITerminalProcessExtHostProxy;
shellLaunchConfig: IShellLaunchConfig;
activeWorkspaceRootUri: URI;
activeWorkspaceRootUri: URI | undefined;
cols: number;
rows: number;
isWorkspaceShellAllowed: boolean;

View File

@@ -479,6 +479,7 @@
newFrame.contentWindow.addEventListener('click', handleInnerClick);
newFrame.contentWindow.addEventListener('auxclick', handleAuxClick);
newFrame.contentWindow.addEventListener('keydown', handleInnerKeydown);
newFrame.contentWindow.addEventListener('contextmenu', e => e.preventDefault());
if (host.onIframeLoaded) {
host.onIframeLoaded(newFrame);

View File

@@ -92,9 +92,13 @@ export class IFrameWebview extends BaseWebview<HTMLIFrameElement> implements Web
}
private preprocessHtml(value: string): string {
return value.replace(/(["'])vscode-resource:(\/\/([^\s'"]+?)(?=\/))?([^\s'"]+?)(["'])/gi, (_, startQuote, _1, scheme, path, endQuote) => {
return `${startQuote}${this.externalEndpoint}/vscode-resource/${scheme || ''}${path}${endQuote}`;
});
return value
.replace(/(["'])vscode-resource:(\/\/([^\s\/'"]+?)(?=\/))?([^\s'"]+?)(["'])/gi, (match, startQuote, _1, scheme, path, endQuote) => {
if (scheme) {
return `${startQuote}${this.externalEndpoint}/vscode-resource/${scheme}${path}${endQuote}`;
}
return `${startQuote}${this.externalEndpoint}/vscode-resource/file${path}${endQuote}`;
});
}
protected get extraContentOptions() {

View File

@@ -1,70 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Action } from 'vs/base/common/actions';
import * as nls from 'vs/nls';
import { IHostService } from 'vs/workbench/services/host/browser/host';
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { IWorkspaceEditingService } from 'vs/workbench/services/workspaces/common/workspaceEditing';
import { IWorkspacesService } from 'vs/platform/workspaces/common/workspaces';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
export class SaveWorkspaceAsAction extends Action {
static readonly ID = 'workbench.action.saveWorkspaceAs';
static readonly LABEL = nls.localize('saveWorkspaceAsAction', "Save Workspace As...");
constructor(
id: string,
label: string,
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
@IWorkspaceEditingService private readonly workspaceEditingService: IWorkspaceEditingService
) {
super(id, label);
}
async run(): Promise<any> {
const configPathUri = await this.workspaceEditingService.pickNewWorkspacePath();
if (configPathUri) {
switch (this.contextService.getWorkbenchState()) {
case WorkbenchState.EMPTY:
case WorkbenchState.FOLDER:
const folders = this.contextService.getWorkspace().folders.map(folder => ({ uri: folder.uri }));
return this.workspaceEditingService.createAndEnterWorkspace(folders, configPathUri);
case WorkbenchState.WORKSPACE:
return this.workspaceEditingService.saveAndEnterWorkspace(configPathUri);
}
}
}
}
export class DuplicateWorkspaceInNewWindowAction extends Action {
static readonly ID = 'workbench.action.duplicateWorkspaceInNewWindow';
static readonly LABEL = nls.localize('duplicateWorkspaceInNewWindow', "Duplicate Workspace in New Window");
constructor(
id: string,
label: string,
@IWorkspaceContextService private readonly workspaceContextService: IWorkspaceContextService,
@IWorkspaceEditingService private readonly workspaceEditingService: IWorkspaceEditingService,
@IHostService private readonly hostService: IHostService,
@IWorkspacesService private readonly workspacesService: IWorkspacesService,
@IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService
) {
super(id, label);
}
async run(): Promise<any> {
const folders = this.workspaceContextService.getWorkspace().folders;
const remoteAuthority = this.environmentService.configuration.remoteAuthority;
const newWorkspace = await this.workspacesService.createUntitledWorkspace(folders, remoteAuthority);
await this.workspaceEditingService.copyWorkspaceSettings(newWorkspace);
return this.hostService.openWindow([{ workspaceUri: newWorkspace.configPath }], { forceNewWindow: true });
}
}

View File

@@ -13,12 +13,11 @@ import { KeyMod, KeyCode } from 'vs/base/common/keyCodes';
import { isWindows, isLinux, isMacintosh } from 'vs/base/common/platform';
import { ToggleSharedProcessAction, ToggleDevToolsAction, ConfigureRuntimeArgumentsAction } from 'vs/workbench/electron-browser/actions/developerActions';
import { ZoomResetAction, ZoomOutAction, ZoomInAction, CloseCurrentWindowAction, SwitchWindow, QuickSwitchWindow, ReloadWindowWithExtensionsDisabledAction, NewWindowTabHandler, ShowPreviousWindowTabHandler, ShowNextWindowTabHandler, MoveWindowTabToNewWindowHandler, MergeWindowTabsHandlerHandler, ToggleWindowTabsBarHandler } from 'vs/workbench/electron-browser/actions/windowActions';
import { SaveWorkspaceAsAction, DuplicateWorkspaceInNewWindowAction } from 'vs/workbench/electron-browser/actions/workspaceActions';
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { SupportsWorkspacesContext, IsMacContext, HasMacNativeTabsContext, IsDevelopmentContext } from 'vs/workbench/browser/contextkeys';
import { IsMacContext, HasMacNativeTabsContext, IsDevelopmentContext } from 'vs/workbench/browser/contextkeys';
import { NoEditorsVisibleContext, SingleEditorGroupsContext } from 'vs/workbench/common/editor';
import { IElectronService } from 'vs/platform/electron/node/electron';
import { IJSONContributionRegistry, Extensions as JSONExtensions } from 'vs/platform/jsonschemas/common/jsonContributionRegistry';
@@ -68,14 +67,6 @@ import { InstallVSIXAction } from 'vs/workbench/contrib/extensions/browser/exten
});
})();
// Actions: Workspaces
(function registerWorkspaceActions(): void {
const workspacesCategory = nls.localize('workspaces', "Workspaces");
registry.registerWorkbenchAction(new SyncActionDescriptor(SaveWorkspaceAsAction, SaveWorkspaceAsAction.ID, SaveWorkspaceAsAction.LABEL), 'Workspaces: Save Workspace As...', workspacesCategory, SupportsWorkspacesContext);
registry.registerWorkbenchAction(new SyncActionDescriptor(DuplicateWorkspaceInNewWindowAction, DuplicateWorkspaceInNewWindowAction.ID, DuplicateWorkspaceInNewWindowAction.LABEL), 'Workspaces: Duplicate Workspace in New Window', workspacesCategory, SupportsWorkspacesContext);
})();
// Actions: macOS Native Tabs
(function registerMacOSNativeTabsActions(): void {
if (isMacintosh) {
@@ -117,18 +108,7 @@ import { InstallVSIXAction } from 'vs/workbench/contrib/extensions/browser/exten
// Menu
(function registerMenu(): void {
MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, {
group: '3_workspace',
command: {
id: SaveWorkspaceAsAction.ID,
title: nls.localize('miSaveWorkspaceAs', "Save Workspace As...")
},
order: 2,
when: SupportsWorkspacesContext
});
// {{SQL CARBON EDIT}} - Add install VSIX menu item
MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, {
MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { // {{SQL CARBON EDIT}} - Add install VSIX menu item
group: '5.1_installExtension',
command: {
id: InstallVSIXAction.ID,

View File

@@ -153,7 +153,7 @@ export class EditorService extends Disposable implements EditorServiceImpl {
for (const handler of this.openEditorHandlers) {
const result = handler(event.editor, event.options, group);
const override = result ? result.override : undefined;
const override = result?.override;
if (override) {
event.prevent((() => override.then(editor => withNullAsUndefined(editor))));
break;
@@ -162,9 +162,7 @@ export class EditorService extends Disposable implements EditorServiceImpl {
}
get activeControl(): IVisibleEditor | undefined {
const activeGroup = this.editorGroupService.activeGroup;
return activeGroup ? activeGroup.activeControl : undefined;
return this.editorGroupService.activeGroup?.activeControl;
}
get activeTextEditorWidget(): ICodeEditor | IDiffEditor | undefined {

View File

@@ -91,6 +91,7 @@ export class BrowserWorkbenchEnvironmentService implements IWorkbenchEnvironment
this.keyboardLayoutResource = joinPath(this.userRoamingDataHome, 'keyboardLayout.json');
this.argvResource = joinPath(this.userRoamingDataHome, 'argv.json');
this.backupHome = joinPath(this.userRoamingDataHome, BACKUPS);
this.untitledWorkspacesHome = joinPath(this.userRoamingDataHome, 'Workspaces');
this.configuration.backupWorkspaceResource = joinPath(this.backupHome, options.workspaceId);
this.configuration.connectionToken = options.connectionToken || getCookieValue('vscode-tkn');
@@ -99,8 +100,6 @@ export class BrowserWorkbenchEnvironmentService implements IWorkbenchEnvironment
break: false
};
this.untitledWorkspacesHome = URI.from({ scheme: Schemas.untitled, path: 'Workspaces' });
// Fill in selected extra environmental properties
if (options.workspaceProvider && Array.isArray(options.workspaceProvider.payload)) {
const environment = serializableToMap(options.workspaceProvider.payload);
@@ -207,7 +206,7 @@ export class BrowserWorkbenchEnvironmentService implements IWorkbenchEnvironment
get webviewExternalEndpoint(): string {
// TODO: get fallback from product.json
return (this.options.webviewEndpoint || 'https://{{uuid}}.vscode-webview-test.com/{{commit}}')
.replace('{{commit}}', product.commit || '211fa02efe8c041fd7baa8ec3dce199d5185aa44');
.replace('{{commit}}', product.commit || 'c58aaab8a1cc22a7139b761166a0d4f37d41e998');
}
get webviewResourceRoot(): string {

View File

@@ -20,7 +20,7 @@ export class WorkbenchEnvironmentService extends EnvironmentService implements I
get webviewExternalEndpoint(): string {
const baseEndpoint = 'https://{{uuid}}.vscode-webview-test.com/{{commit}}';
return baseEndpoint.replace('{{commit}}', product.commit || '211fa02efe8c041fd7baa8ec3dce199d5185aa44');
return baseEndpoint.replace('{{commit}}', product.commit || 'c58aaab8a1cc22a7139b761166a0d4f37d41e998');
}
readonly webviewResourceRoot = 'vscode-resource://{{resource}}';

View File

@@ -142,7 +142,7 @@ class ExtensionUrlHandler implements IExtensionUrlHandler, IURLHandler {
}
if (showConfirm) {
let uriString = uri.toString();
let uriString = uri.toString(false);
// {{SQL CARBON EDIT}} - Begin
// Dialog service starts truncating words longer than 80 characters and adds ellipses to it.

View File

@@ -7,7 +7,7 @@ import { onUnexpectedError } from 'vs/base/common/errors';
import { URI, UriComponents } from 'vs/base/common/uri';
import { IEditor } from 'vs/editor/common/editorCommon';
import { ITextEditorOptions, IResourceInput, ITextEditorSelection } from 'vs/platform/editor/common/editor';
import { IEditorInput, IEditor as IBaseEditor, Extensions as EditorExtensions, EditorInput, IEditorCloseEvent, IEditorInputFactoryRegistry, toResource, Extensions as EditorInputExtensions, IFileInputFactory, IEditorIdentifier } from 'vs/workbench/common/editor';
import { IEditorInput, IEditor as IBaseEditor, Extensions as EditorExtensions, EditorInput, IEditorCloseEvent, IEditorInputFactoryRegistry, toResource, IEditorIdentifier } from 'vs/workbench/common/editor';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IHistoryService } from 'vs/workbench/services/history/common/history';
import { FileChangesEvent, IFileService, FileChangeType, FILES_EXCLUDE_CONFIG } from 'vs/platform/files/common/files';
@@ -125,8 +125,6 @@ export class HistoryService extends Disposable implements IHistoryService {
private loaded: boolean;
private resourceFilter: ResourceGlobMatcher;
private fileInputFactory: IFileInputFactory;
private canNavigateBackContextKey: IContextKey<boolean>;
private canNavigateForwardContextKey: IContextKey<boolean>;
private canNavigateToLastEditLocationContextKey: IContextKey<boolean>;
@@ -149,8 +147,6 @@ export class HistoryService extends Disposable implements IHistoryService {
this.canNavigateForwardContextKey = (new RawContextKey<boolean>('canNavigateForward', false)).bindTo(this.contextKeyService);
this.canNavigateToLastEditLocationContextKey = (new RawContextKey<boolean>('canNavigateToLastEditLocation', false)).bindTo(this.contextKeyService);
this.fileInputFactory = Registry.as<IEditorInputFactoryRegistry>(EditorInputExtensions.EditorInputFactories).getFileInputFactory();
this.index = -1;
this.lastIndex = -1;
this.stack = [];
@@ -486,7 +482,7 @@ export class HistoryService extends Disposable implements IHistoryService {
}
private handleEditorEventInHistory(editor?: IBaseEditor): void {
const input = editor ? editor.input : undefined;
const input = editor?.input;
// Ensure we have at least a name to show and not configured to exclude input
if (!input || !input.getName() || !this.include(input)) {
@@ -738,8 +734,9 @@ export class HistoryService extends Disposable implements IHistoryService {
}
private preferResourceInput(input: IEditorInput): IEditorInput | IResourceInput {
if (this.fileInputFactory.isFileInput(input)) {
return { resource: input.getResource() };
const resource = input.getResource();
if (resource && this.fileService.canHandleResource(resource)) {
return { resource: resource };
}
return input;

View File

@@ -13,7 +13,6 @@ import { Registry } from 'vs/platform/registry/common/platform';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { IWorkspaceContextService, IWorkspace } from 'vs/platform/workspace/common/workspace';
import { isEqual, basenameOrAuthority, isEqualOrParent, basename, joinPath, dirname } from 'vs/base/common/resources';
import { isWindows } from 'vs/base/common/platform';
import { tildify, getPathLabel } from 'vs/base/common/labels';
import { ltrim, endsWith } from 'vs/base/common/strings';
import { IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, WORKSPACE_EXTENSION, toWorkspaceIdentifier, isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
@@ -71,7 +70,7 @@ const sepRegexp = /\//g;
const labelMatchingRegexp = /\$\{(scheme|authority|path|(query)\.(.+?))\}/g;
function hasDriveLetter(path: string): boolean {
return !!(isWindows && path && path[2] === ':');
return !!(path && path[2] === ':');
}
class ResourceLabelFormattersHandler implements IWorkbenchContribution {

View File

@@ -11,8 +11,13 @@
padding-right: 5px;
}
.monaco-workbench .progress-badge > .badge-content {
background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNCIgaGVpZ2h0PSIxNCIgdmlld0JveD0iMiAyIDE0IDE0IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDIgMiAxNCAxNCI+PHBhdGggZmlsbD0iI2ZmZiIgZD0iTTkgMTZjLTMuODYgMC03LTMuMTQtNy03czMuMTQtNyA3LTdjMy44NTkgMCA3IDMuMTQxIDcgN3MtMy4xNDEgNy03IDd6bTAtMTIuNmMtMy4wODggMC01LjYgMi41MTMtNS42IDUuNnMyLjUxMiA1LjYgNS42IDUuNiA1LjYtMi41MTIgNS42LTUuNi0yLjUxMi01LjYtNS42LTUuNnptMy44NiA3LjFsLTMuMTYtMS44OTZ2LTMuODA0aC0xLjR2NC41OTZsMy44NCAyLjMwNS43Mi0xLjIwMXoiLz48L3N2Zz4=");
background-position: center center;
background-repeat: no-repeat;
.monaco-workbench .progress-badge > .badge-content::before {
-webkit-mask: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNCIgaGVpZ2h0PSIxNCIgdmlld0JveD0iMiAyIDE0IDE0IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDIgMiAxNCAxNCI+PHBhdGggZmlsbD0iI2ZmZiIgZD0iTTkgMTZjLTMuODYgMC03LTMuMTQtNy03czMuMTQtNyA3LTdjMy44NTkgMCA3IDMuMTQxIDcgN3MtMy4xNDEgNy03IDd6bTAtMTIuNmMtMy4wODggMC01LjYgMi41MTMtNS42IDUuNnMyLjUxMiA1LjYgNS42IDUuNiA1LjYtMi41MTIgNS42LTUuNi0yLjUxMi01LjYtNS42LTUuNnptMy44NiA3LjFsLTMuMTYtMS44OTZ2LTMuODA0aC0xLjR2NC41OTZsMy44NCAyLjMwNS43Mi0xLjIwMXoiLz48L3N2Zz4=");
width: 14px;
height: 14px;
position: absolute;
top: 1px;
left: 1px;
background-color: currentColor;
content: '';
}

View File

@@ -0,0 +1,15 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
import { URI } from 'vs/base/common/uri';
import { hash } from 'vs/base/common/hash';
export function getWorkspaceIdentifier(workspacePath: URI): IWorkspaceIdentifier {
return {
id: hash(workspacePath.toString()).toString(16),
configPath: workspacePath
};
}

View File

@@ -4,13 +4,19 @@
*--------------------------------------------------------------------------------------------*/
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { IWorkspacesService, IWorkspaceFolderCreationData, IWorkspaceIdentifier, IEnterWorkspaceResult, IRecentlyOpened, restoreRecentlyOpened, IRecent, isRecentFile, isRecentFolder, toStoreData } from 'vs/platform/workspaces/common/workspaces';
import { IWorkspacesService, IWorkspaceFolderCreationData, IWorkspaceIdentifier, IEnterWorkspaceResult, IRecentlyOpened, restoreRecentlyOpened, IRecent, isRecentFile, isRecentFolder, toStoreData, IStoredWorkspaceFolder, getStoredWorkspaceFolder, WORKSPACE_EXTENSION, IStoredWorkspace } from 'vs/platform/workspaces/common/workspaces';
import { URI } from 'vs/base/common/uri';
import { Event, Emitter } from 'vs/base/common/event';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { ILogService } from 'vs/platform/log/common/log';
import { Disposable } from 'vs/base/common/lifecycle';
import { getWorkspaceIdentifier } from 'vs/workbench/services/workspaces/browser/workspaces';
import { IHostService } from 'vs/workbench/services/host/browser/host';
import { IFileService } from 'vs/platform/files/common/files';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { joinPath } from 'vs/base/common/resources';
import { VSBuffer } from 'vs/base/common/buffer';
export class BrowserWorkspacesService extends Disposable implements IWorkspacesService {
@@ -25,6 +31,9 @@ export class BrowserWorkspacesService extends Disposable implements IWorkspacesS
@IStorageService private readonly storageService: IStorageService,
@IWorkspaceContextService private readonly workspaceService: IWorkspaceContextService,
@ILogService private readonly logService: ILogService,
@IHostService private readonly hostService: IHostService,
@IFileService private readonly fileService: IFileService,
@IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService
) {
super();
@@ -113,20 +122,41 @@ export class BrowserWorkspacesService extends Disposable implements IWorkspacesS
//#region Workspace Management
enterWorkspace(path: URI): Promise<IEnterWorkspaceResult | null> {
throw new Error('Untitled workspaces are currently unsupported in Web');
async enterWorkspace(path: URI): Promise<IEnterWorkspaceResult | null> {
// Open workspace in same window
await this.hostService.openWindow([{ workspaceUri: path }], { forceReuseWindow: true });
return {
workspace: await this.getWorkspaceIdentifier(path)
};
}
createUntitledWorkspace(folders?: IWorkspaceFolderCreationData[], remoteAuthority?: string): Promise<IWorkspaceIdentifier> {
throw new Error('Untitled workspaces are currently unsupported in Web');
async createUntitledWorkspace(folders?: IWorkspaceFolderCreationData[], remoteAuthority?: string): Promise<IWorkspaceIdentifier> {
const randomId = (Date.now() + Math.round(Math.random() * 1000)).toString();
const newUntitledWorkspacePath = joinPath(this.environmentService.untitledWorkspacesHome, `${randomId}.${WORKSPACE_EXTENSION}`);
// Build array of workspace folders to store
const storedWorkspaceFolder: IStoredWorkspaceFolder[] = [];
if (folders) {
for (const folder of folders) {
storedWorkspaceFolder.push(getStoredWorkspaceFolder(folder.uri, folder.name, this.environmentService.untitledWorkspacesHome));
}
}
// Store at untitled workspaces location
const storedWorkspace: IStoredWorkspace = { folders: storedWorkspaceFolder, remoteAuthority };
await this.fileService.writeFile(newUntitledWorkspacePath, VSBuffer.fromString(JSON.stringify(storedWorkspace, null, '\t')));
return this.getWorkspaceIdentifier(newUntitledWorkspacePath);
}
deleteUntitledWorkspace(workspace: IWorkspaceIdentifier): Promise<void> {
throw new Error('Untitled workspaces are currently unsupported in Web');
return this.fileService.del(workspace.configPath);
}
getWorkspaceIdentifier(workspacePath: URI): Promise<IWorkspaceIdentifier> {
throw new Error('Untitled workspaces are currently unsupported in Web');
async getWorkspaceIdentifier(workspacePath: URI): Promise<IWorkspaceIdentifier> {
return getWorkspaceIdentifier(workspacePath);
}
//#endregion