mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-03-30 16:50:30 -04:00
Merge from vscode 3a6dcb42008d509900b3a3b2d695564eeb4dbdac (#5098)
This commit is contained in:
@@ -738,6 +738,7 @@ export class ReviewController implements IEditorContribution {
|
||||
|
||||
this._commentInfos.forEach(info => {
|
||||
let providerCacheStore = this._pendingCommentCache[info.owner];
|
||||
info.threads = info.threads.filter(thread => !thread.isDisposed);
|
||||
info.threads.forEach(thread => {
|
||||
let pendingComment: string | null = null;
|
||||
if (providerCacheStore) {
|
||||
|
||||
@@ -18,7 +18,7 @@ import {
|
||||
ITreeElement, IExpression, IExpressionContainer, IDebugSession, IStackFrame, IExceptionBreakpoint, IBreakpoint, IFunctionBreakpoint, IDebugModel, IReplElementSource,
|
||||
IThread, IRawModelUpdate, IScope, IRawStoppedDetails, IEnablement, IBreakpointData, IExceptionInfo, IReplElement, IBreakpointsChangeEvent, IBreakpointUpdateData, IBaseBreakpoint, State
|
||||
} from 'vs/workbench/contrib/debug/common/debug';
|
||||
import { Source } from 'vs/workbench/contrib/debug/common/debugSource';
|
||||
import { Source, UNKNOWN_SOURCE_LABEL } from 'vs/workbench/contrib/debug/common/debugSource';
|
||||
import { commonSuffixLength } from 'vs/base/common/strings';
|
||||
import { posix } from 'vs/base/common/path';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
@@ -381,7 +381,10 @@ export class StackFrame implements IStackFrame {
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return `${this.name} (${this.source.inMemory ? this.source.name : this.source.uri.fsPath}:${this.range.startLineNumber})`;
|
||||
const lineNumberToString = typeof this.range.startLineNumber === 'number' ? `:${this.range.startLineNumber}` : '';
|
||||
const sourceToString = `${this.source.inMemory ? this.source.name : this.source.uri.fsPath}${lineNumberToString}`;
|
||||
|
||||
return sourceToString === UNKNOWN_SOURCE_LABEL ? this.name : `${this.name} (${sourceToString})`;
|
||||
}
|
||||
|
||||
openInEditor(editorService: IEditorService, preserveFocus?: boolean, sideBySide?: boolean, pinned?: boolean): Promise<any> {
|
||||
|
||||
@@ -13,7 +13,7 @@ import { IEditorService, SIDE_GROUP, ACTIVE_GROUP } from 'vs/workbench/services/
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { isUri } from 'vs/workbench/contrib/debug/common/debugUtils';
|
||||
|
||||
const UNKNOWN_SOURCE_LABEL = nls.localize('unknownSource', "Unknown Source");
|
||||
export const UNKNOWN_SOURCE_LABEL = nls.localize('unknownSource', "Unknown Source");
|
||||
|
||||
/**
|
||||
* Debug URI format
|
||||
|
||||
@@ -394,6 +394,22 @@ suite('Debug - Model', () => {
|
||||
assert.equal(secondStackFrame.getSpecificSourceName(), '.../x/c/d/internalModule.js');
|
||||
});
|
||||
|
||||
test('stack frame toString()', () => {
|
||||
const session = createMockSession(model);
|
||||
const thread = new Thread(session, 'mockthread', 1);
|
||||
const firstSource = new Source({
|
||||
name: 'internalModule.js',
|
||||
path: 'a/b/c/d/internalModule.js',
|
||||
sourceReference: 10,
|
||||
}, 'aDebugSessionId');
|
||||
const stackFrame = new StackFrame(thread, 1, firstSource, 'app', 'normal', { startLineNumber: 1, startColumn: 1, endLineNumber: 1, endColumn: 10 }, 1);
|
||||
assert.equal(stackFrame.toString(), 'app (internalModule.js:1)');
|
||||
|
||||
const secondSource = new Source(undefined, 'aDebugSessionId');
|
||||
const stackFrame2 = new StackFrame(thread, 2, secondSource, 'module', 'normal', { startLineNumber: undefined!, startColumn: undefined!, endLineNumber: undefined!, endColumn: undefined! }, 2);
|
||||
assert.equal(stackFrame2.toString(), 'module');
|
||||
});
|
||||
|
||||
test('debug child sessions are added in correct order', () => {
|
||||
const session = createMockSession(model);
|
||||
model.addSession(session);
|
||||
|
||||
@@ -252,35 +252,6 @@ Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration)
|
||||
scope: ConfigurationScope.APPLICATION,
|
||||
default: ExtensionsPolicy.allowAll
|
||||
},
|
||||
'extensions.extensionKind': {
|
||||
type: 'object',
|
||||
description: localize('extensions.extensionKind', "Configure ui or workspace extensions and allow them to run locally or remotely in a remote window."),
|
||||
properties: {
|
||||
'ui': {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string',
|
||||
pattern: '^([a-z0-9A-Z][a-z0-9\-A-Z]*)\\.([a-z0-9A-Z][a-z0-9\-A-Z]*)$',
|
||||
}
|
||||
},
|
||||
'workspace': {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string',
|
||||
pattern: '^([a-z0-9A-Z][a-z0-9\-A-Z]*)\\.([a-z0-9A-Z][a-z0-9\-A-Z]*)$',
|
||||
}
|
||||
}
|
||||
},
|
||||
default: {
|
||||
ui: [],
|
||||
workspace: []
|
||||
}
|
||||
},
|
||||
'extensions.showInstalledExtensionsByDefault': {
|
||||
type: 'boolean',
|
||||
description: localize('extensions.showInstalledExtensionsByDefault', "When enabled, extensions view shows installed extensions view by default."),
|
||||
default: false
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ import { IExtension, ExtensionState, IExtensionsWorkbenchService, VIEWLET_ID, IE
|
||||
import { ExtensionsConfigurationInitialContent } from 'vs/workbench/contrib/extensions/common/extensionsFileTemplate';
|
||||
import { IExtensionEnablementService, IExtensionTipsService, EnablementState, ExtensionsLabel, IExtensionRecommendation, IGalleryExtension, IExtensionsConfigContent, IExtensionGalleryService, INSTALL_ERROR_MALICIOUS, INSTALL_ERROR_INCOMPATIBLE, IGalleryExtensionVersion, ILocalExtension, IExtensionManagementServerService, IExtensionManagementServer } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
|
||||
import { ExtensionType, ExtensionIdentifier, IExtensionDescription, IExtensionManifest } from 'vs/platform/extensions/common/extensions';
|
||||
import { ExtensionType, ExtensionIdentifier, IExtensionDescription, IExtensionManifest, isLanguagePackExtension } from 'vs/platform/extensions/common/extensions';
|
||||
import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ShowViewletAction } from 'vs/workbench/browser/viewlet';
|
||||
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
|
||||
@@ -176,14 +176,17 @@ export class InstallAction extends ExtensionAction {
|
||||
}
|
||||
|
||||
update(): void {
|
||||
if (!this.extension || this.extension.type === ExtensionType.System) {
|
||||
if (!this.extension || this.extension.type === ExtensionType.System || this.extension.state === ExtensionState.Installed) {
|
||||
this.enabled = false;
|
||||
this.class = InstallAction.Class;
|
||||
this.label = InstallAction.INSTALL_LABEL;
|
||||
return;
|
||||
}
|
||||
|
||||
this.enabled = this.extensionsWorkbenchService.canInstall(this.extension) && !this.extensionsWorkbenchService.local.some(e => areSameExtensions(e.identifier, this.extension.identifier));
|
||||
this.enabled = false;
|
||||
if (this.extensionsWorkbenchService.canInstall(this.extension)) {
|
||||
const local = this.extensionsWorkbenchService.local.filter(e => areSameExtensions(e.identifier, this.extension.identifier))[0];
|
||||
this.enabled = !local || (!!local.local && isLanguagePackExtension(local.local.manifest));
|
||||
}
|
||||
this.class = this.extension.state === ExtensionState.Installing ? InstallAction.InstallingClass : InstallAction.Class;
|
||||
this.updateLabel();
|
||||
}
|
||||
@@ -2590,6 +2593,9 @@ export class DisabledLabelAction extends ExtensionAction {
|
||||
this.class = `${DisabledLabelAction.Class} hide`;
|
||||
this.label = '';
|
||||
this.enabled = false;
|
||||
if (this.extension && this.extension.local && isLanguagePackExtension(this.extension.local.manifest)) {
|
||||
return;
|
||||
}
|
||||
if (this.warningAction.enabled) {
|
||||
this.enabled = true;
|
||||
this.class = DisabledLabelAction.Class;
|
||||
@@ -2649,6 +2655,9 @@ export class SystemDisabledWarningAction extends ExtensionAction {
|
||||
this.enabled = false;
|
||||
this.class = `${SystemDisabledWarningAction.Class} hide`;
|
||||
this.tooltip = '';
|
||||
if (this.extension && this.extension.local && isLanguagePackExtension(this.extension.local.manifest)) {
|
||||
return;
|
||||
}
|
||||
if (this.extension && this.extension.local && this.extension.server && this._runningExtensions && this.workbenchEnvironmentService.configuration.remoteAuthority && this.extensionManagementServerService.remoteExtensionManagementServer) {
|
||||
const runningExtension = this._runningExtensions.filter(e => areSameExtensions({ id: e.identifier.value }, this.extension.identifier))[0];
|
||||
const runningExtensionServer = runningExtension ? this.extensionManagementServerService.getExtensionManagementServer(runningExtension.extensionLocation) : null;
|
||||
|
||||
@@ -19,6 +19,7 @@ import { Label, RatingsWidget, InstallCountWidget, RecommendationWidget, RemoteB
|
||||
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { IExtensionManagementServerService } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { isLanguagePackExtension } from 'vs/platform/extensions/common/extensions';
|
||||
|
||||
export interface IExtensionsViewState {
|
||||
onFocus: Event<IExtension>;
|
||||
@@ -154,7 +155,7 @@ export class Renderer implements IPagedRenderer<IExtension, ITemplateData> {
|
||||
|
||||
const updateEnablement = async () => {
|
||||
const runningExtensions = await this.extensionService.getExtensions();
|
||||
if (extension.local) {
|
||||
if (extension.local && !isLanguagePackExtension(extension.local.manifest)) {
|
||||
const runningExtension = runningExtensions.filter(e => areSameExtensions({ id: e.identifier.value }, extension.identifier))[0];
|
||||
const isSameExtensionRunning = runningExtension && extension.server === this.extensionManagementServerService.getExtensionManagementServer(runningExtension.extensionLocation);
|
||||
toggleClass(data.root, 'disabled', !isSameExtensionRunning);
|
||||
|
||||
@@ -54,6 +54,7 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment'
|
||||
import { ExtensionType } from 'vs/platform/extensions/common/extensions';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { ViewContainerViewlet } from 'vs/workbench/browser/parts/views/viewsViewlet';
|
||||
import { RemoteAuthorityContext } from 'vs/workbench/common/contextkeys';
|
||||
|
||||
interface SearchInputEvent extends Event {
|
||||
target: HTMLInputElement;
|
||||
@@ -139,7 +140,7 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio
|
||||
id,
|
||||
name: viewIdNameMappings[id],
|
||||
ctorDescriptor: { ctor: EnabledExtensionsView },
|
||||
when: ContextKeyExpr.and(ContextKeyExpr.has('defaultExtensionViews'), ContextKeyExpr.has('hasInstalledExtensions'), ContextKeyExpr.not('config.extensions.showInstalledExtensionsByDefault')),
|
||||
when: ContextKeyExpr.and(ContextKeyExpr.has('defaultExtensionViews'), ContextKeyExpr.has('hasInstalledExtensions'), RemoteAuthorityContext.isEqualTo('')),
|
||||
weight: 40,
|
||||
canToggleVisibility: true,
|
||||
order: 1
|
||||
@@ -154,7 +155,7 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio
|
||||
id,
|
||||
name: viewIdNameMappings[id],
|
||||
ctorDescriptor: { ctor: DisabledExtensionsView },
|
||||
when: ContextKeyExpr.and(ContextKeyExpr.has('defaultExtensionViews'), ContextKeyExpr.has('hasInstalledExtensions'), ContextKeyExpr.not('config.extensions.showInstalledExtensionsByDefault')),
|
||||
when: ContextKeyExpr.and(ContextKeyExpr.has('defaultExtensionViews'), ContextKeyExpr.has('hasInstalledExtensions'), RemoteAuthorityContext.isEqualTo('')),
|
||||
weight: 10,
|
||||
canToggleVisibility: true,
|
||||
order: 3,
|
||||
@@ -195,7 +196,7 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio
|
||||
id: `extensions.${server.authority}.default`,
|
||||
name: localize('installed', "Installed"),
|
||||
ctorDescriptor: { ctor: ServerExtensionsView, arguments: [server] },
|
||||
when: ContextKeyExpr.and(ContextKeyExpr.has('defaultExtensionViews'), ContextKeyExpr.has('hasInstalledExtensions'), ContextKeyExpr.has('config.extensions.showInstalledExtensionsByDefault')),
|
||||
when: ContextKeyExpr.and(ContextKeyExpr.has('defaultExtensionViews'), ContextKeyExpr.has('hasInstalledExtensions'), RemoteAuthorityContext.notEqualsTo('')),
|
||||
weight: 40,
|
||||
order: 1
|
||||
}];
|
||||
@@ -512,7 +513,6 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio
|
||||
|
||||
private doSearch(): Promise<void> {
|
||||
const value = this.normalizedQuery();
|
||||
this.defaultViewsContextKey.set(!value);
|
||||
const isRecommendedExtensionsQuery = ExtensionsListView.isRecommendedExtensionsQuery(value);
|
||||
this.searchInstalledExtensionsContextKey.set(ExtensionsListView.isInstalledExtensionsQuery(value));
|
||||
this.searchOutdatedExtensionsContextKey.set(ExtensionsListView.isOutdatedExtensionsQuery(value));
|
||||
@@ -522,6 +522,7 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio
|
||||
this.recommendedExtensionsContextKey.set(isRecommendedExtensionsQuery);
|
||||
this.searchMarketplaceExtensionsContextKey.set(!!value && !ExtensionsListView.isLocalExtensionsQuery(value) && !isRecommendedExtensionsQuery);
|
||||
this.nonEmptyWorkspaceContextKey.set(this.contextService.getWorkbenchState() !== WorkbenchState.EMPTY);
|
||||
this.defaultViewsContextKey.set(!value);
|
||||
|
||||
return this.progress(Promise.all(this.panels.map(view =>
|
||||
(<ExtensionsListView>view).show(this.normalizedQuery())
|
||||
|
||||
@@ -41,7 +41,7 @@ import { IListContextMenuEvent } from 'vs/base/browser/ui/list/list';
|
||||
import { createErrorWithActions } from 'vs/base/common/errorsWithActions';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { IAction } from 'vs/base/common/actions';
|
||||
import { ExtensionType, ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions';
|
||||
import { ExtensionType, ExtensionIdentifier, IExtensionDescription, isLanguagePackExtension } from 'vs/platform/extensions/common/extensions';
|
||||
import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
|
||||
import product from 'vs/platform/product/node/product';
|
||||
import { CancelablePromise, createCancelablePromise } from 'vs/base/common/async';
|
||||
@@ -343,6 +343,11 @@ export class ExtensionsListView extends ViewletPanel {
|
||||
if ((isE1Running && isE2Running) || (!isE1Running && !isE2Running)) {
|
||||
return e1.displayName.localeCompare(e2.displayName);
|
||||
}
|
||||
const isE1LanguagePackExtension = e1.local && isLanguagePackExtension(e1.local.manifest);
|
||||
const isE2LanguagePackExtension = e2.local && isLanguagePackExtension(e2.local.manifest);
|
||||
if ((isE1Running && isE2LanguagePackExtension) || (isE2Running && isE1LanguagePackExtension)) {
|
||||
return e1.displayName.localeCompare(e2.displayName);
|
||||
}
|
||||
return isE1Running ? -1 : 1;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ import { dispose, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { VIEWLET_ID, IExplorerService } from 'vs/workbench/contrib/files/common/files';
|
||||
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
import { IFileService, AutoSaveConfiguration } from 'vs/platform/files/common/files';
|
||||
import { toResource, ITextEditor, SideBySideEditor } from 'vs/workbench/common/editor';
|
||||
import { toResource, SideBySideEditor } from 'vs/workbench/common/editor';
|
||||
import { ExplorerViewlet } from 'vs/workbench/contrib/files/browser/explorerViewlet';
|
||||
import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
|
||||
import { IQuickOpenService } from 'vs/platform/quickOpen/common/quickOpen';
|
||||
@@ -356,64 +356,6 @@ function containsBothDirectoryAndFile(distinctElements: ExplorerItem[]): boolean
|
||||
return directories.length > 0 && files.length > 0;
|
||||
}
|
||||
|
||||
let pasteShouldMove = false;
|
||||
// Paste File/Folder
|
||||
class PasteFileAction extends Action {
|
||||
|
||||
public static readonly ID = 'filesExplorer.paste';
|
||||
|
||||
constructor(
|
||||
private element: ExplorerItem,
|
||||
@IFileService private fileService: IFileService,
|
||||
@INotificationService private notificationService: INotificationService,
|
||||
@IEditorService private readonly editorService: IEditorService,
|
||||
@IExplorerService private readonly explorerService: IExplorerService
|
||||
) {
|
||||
super(PasteFileAction.ID, PASTE_FILE_LABEL);
|
||||
|
||||
if (!this.element) {
|
||||
this.element = this.explorerService.roots[0];
|
||||
}
|
||||
}
|
||||
|
||||
public run(fileToPaste: URI): Promise<any> {
|
||||
|
||||
// Check if target is ancestor of pasted folder
|
||||
if (this.element.resource.toString() !== fileToPaste.toString() && resources.isEqualOrParent(this.element.resource, fileToPaste, !isLinux /* ignorecase */)) {
|
||||
throw new Error(nls.localize('fileIsAncestor', "File to paste is an ancestor of the destination folder"));
|
||||
}
|
||||
|
||||
return this.fileService.resolve(fileToPaste).then(fileToPasteStat => {
|
||||
|
||||
// Find target
|
||||
let target: ExplorerItem;
|
||||
if (this.element.resource.toString() === fileToPaste.toString()) {
|
||||
target = this.element.parent!;
|
||||
} else {
|
||||
target = this.element.isDirectory ? this.element : this.element.parent!;
|
||||
}
|
||||
|
||||
const targetFile = findValidPasteFileTarget(target, { resource: fileToPaste, isDirectory: fileToPasteStat.isDirectory, allowOverwirte: pasteShouldMove });
|
||||
|
||||
// Copy File
|
||||
const promise = pasteShouldMove ? this.fileService.move(fileToPaste, targetFile) : this.fileService.copy(fileToPaste, targetFile);
|
||||
return promise.then<ITextEditor | undefined>(stat => {
|
||||
if (pasteShouldMove) {
|
||||
// Cut is done. Make sure to clear cut state.
|
||||
this.explorerService.setToCopy([], false);
|
||||
}
|
||||
if (!stat.isDirectory) {
|
||||
return this.editorService.openEditor({ resource: stat.resource, options: { pinned: true, preserveFocus: true } })
|
||||
.then(types.withNullAsUndefined);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}, e => onError(this.notificationService, e));
|
||||
}, error => {
|
||||
onError(this.notificationService, new Error(nls.localize('fileDeleted', "File to paste was deleted or moved meanwhile")));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function findValidPasteFileTarget(targetFolder: ExplorerItem, fileToPaste: { resource: URI, isDirectory?: boolean, allowOverwirte: boolean }): URI {
|
||||
let name = resources.basenameOrAuthority(fileToPaste.resource);
|
||||
@@ -1083,6 +1025,7 @@ export const deleteFileHandler = (accessor: ServicesAccessor) => {
|
||||
return deleteFiles(accessor, stats, false);
|
||||
};
|
||||
|
||||
let pasteShouldMove = false;
|
||||
export const copyFileHandler = (accessor: ServicesAccessor) => {
|
||||
const listService = accessor.get(IListService);
|
||||
if (!listService.lastFocusedList) {
|
||||
@@ -1112,16 +1055,50 @@ export const cutFileHandler = (accessor: ServicesAccessor) => {
|
||||
};
|
||||
|
||||
export const pasteFileHandler = (accessor: ServicesAccessor) => {
|
||||
const instantiationService = accessor.get(IInstantiationService);
|
||||
const listService = accessor.get(IListService);
|
||||
const clipboardService = accessor.get(IClipboardService);
|
||||
if (!listService.lastFocusedList) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
const explorerContext = getContext(listService.lastFocusedList);
|
||||
const explorerService = accessor.get(IExplorerService);
|
||||
const fileService = accessor.get(IFileService);
|
||||
const notificationService = accessor.get(INotificationService);
|
||||
const editorService = accessor.get(IEditorService);
|
||||
|
||||
return sequence(resources.distinctParents(clipboardService.readResources(), r => r).map(toCopy => {
|
||||
const pasteFileAction = instantiationService.createInstance(PasteFileAction, explorerContext.stat);
|
||||
return () => pasteFileAction.run(toCopy);
|
||||
}));
|
||||
if (listService.lastFocusedList) {
|
||||
const explorerContext = getContext(listService.lastFocusedList);
|
||||
const toPaste = resources.distinctParents(clipboardService.readResources(), r => r);
|
||||
const element = explorerContext.stat || explorerService.roots[0];
|
||||
|
||||
// Check if target is ancestor of pasted folder
|
||||
sequence(toPaste.map(fileToPaste => () => {
|
||||
|
||||
if (element.resource.toString() !== fileToPaste.toString() && resources.isEqualOrParent(element.resource, fileToPaste, !isLinux /* ignorecase */)) {
|
||||
throw new Error(nls.localize('fileIsAncestor', "File to paste is an ancestor of the destination folder"));
|
||||
}
|
||||
|
||||
return fileService.resolve(fileToPaste).then(fileToPasteStat => {
|
||||
|
||||
// Find target
|
||||
let target: ExplorerItem;
|
||||
if (element.resource.toString() === fileToPaste.toString()) {
|
||||
target = element.parent!;
|
||||
} else {
|
||||
target = element.isDirectory ? element : element.parent!;
|
||||
}
|
||||
|
||||
const targetFile = findValidPasteFileTarget(target, { resource: fileToPaste, isDirectory: fileToPasteStat.isDirectory, allowOverwirte: pasteShouldMove });
|
||||
|
||||
// Copy File
|
||||
return pasteShouldMove ? fileService.move(fileToPaste, targetFile) : fileService.copy(fileToPaste, targetFile);
|
||||
}, error => {
|
||||
onError(notificationService, new Error(nls.localize('fileDeleted', "File to paste was deleted or moved meanwhile")));
|
||||
});
|
||||
})).then((stat) => {
|
||||
if (pasteShouldMove) {
|
||||
// Cut is done. Make sure to clear cut state.
|
||||
explorerService.setToCopy([], false);
|
||||
}
|
||||
if (stat.length === 1 && !stat[0].isDirectory) {
|
||||
editorService.openEditor({ resource: stat[0].resource, options: { pinned: true, preserveFocus: true } }).then(undefined, onUnexpectedError);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
|
||||
import * as nls from 'vs/nls';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
// {{SQL CARBON EDIT}} - Import EditorInput
|
||||
import { toResource, IEditorCommandsContext, EditorInput, SideBySideEditor } from 'vs/workbench/common/editor';
|
||||
import { IWindowsService, IWindowService, IURIToOpen, IOpenSettings, INewWindowOptions } from 'vs/platform/windows/common/windows';
|
||||
// {{SQL CARBON EDIT}} import EditorInput
|
||||
import { toResource, IEditorCommandsContext, SideBySideEditor, EditorInput } from 'vs/workbench/common/editor';
|
||||
import { IWindowsService, IWindowService, IURIToOpen, IOpenSettings, INewWindowOptions, isWorkspaceToOpen } from 'vs/platform/windows/common/windows';
|
||||
import { ServicesAccessor, IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
|
||||
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||
@@ -35,14 +35,15 @@ import { getMultiSelectedEditorContexts } from 'vs/workbench/browser/parts/edito
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
|
||||
// {{SQL CARBON EDIT}} - Import EditorInput
|
||||
import { IEditorService, SIDE_GROUP, IResourceEditorReplacement } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { ILabelService } from 'vs/platform/label/common/label';
|
||||
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { basename, toLocalResource } from 'vs/base/common/resources';
|
||||
import { basename, toLocalResource, joinPath } from 'vs/base/common/resources';
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { UNTITLED_WORKSPACE_NAME } from 'vs/platform/workspaces/common/workspaces';
|
||||
|
||||
// {{SQL CARBON EDIT}}
|
||||
import { IQueryEditorService } from 'sql/workbench/services/queryEditor/common/queryEditorService';
|
||||
@@ -86,6 +87,19 @@ export const REMOVE_ROOT_FOLDER_LABEL = nls.localize('removeFolderFromWorkspace'
|
||||
export const openWindowCommand = (accessor: ServicesAccessor, urisToOpen: IURIToOpen[], options?: IOpenSettings) => {
|
||||
if (Array.isArray(urisToOpen)) {
|
||||
const windowService = accessor.get(IWindowService);
|
||||
const environmentService = accessor.get(IEnvironmentService);
|
||||
|
||||
// rewrite untitled: workspace URIs to the absolute path on disk
|
||||
urisToOpen = urisToOpen.map(uriToOpen => {
|
||||
if (isWorkspaceToOpen(uriToOpen) && uriToOpen.workspaceUri.scheme === Schemas.untitled) {
|
||||
return {
|
||||
workspaceUri: joinPath(environmentService.untitledWorkspacesHome, uriToOpen.workspaceUri.path, UNTITLED_WORKSPACE_NAME)
|
||||
};
|
||||
}
|
||||
|
||||
return uriToOpen;
|
||||
});
|
||||
|
||||
windowService.openWindow(urisToOpen, options);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -228,6 +228,10 @@ export class SettingsTreeSettingElement extends SettingsTreeElement {
|
||||
return this.setting.scope === ConfigurationScope.WINDOW || this.setting.scope === ConfigurationScope.RESOURCE;
|
||||
}
|
||||
|
||||
if (configTarget === ConfigurationTarget.USER_REMOTE) {
|
||||
return this.setting.scope === ConfigurationScope.MACHINE || this.setting.scope === ConfigurationScope.WINDOW || this.setting.scope === ConfigurationScope.RESOURCE;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,13 +16,11 @@ import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace
|
||||
import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { REMOTE_HOST_SCHEME, getRemoteAuthority } from 'vs/platform/remote/common/remoteHosts';
|
||||
import { sanitizeProcessEnvironment } from 'vs/base/common/processes';
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
import { IProductService } from 'vs/platform/product/common/product';
|
||||
import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
|
||||
/** The amount of time to consider terminal errors to be related to the launch */
|
||||
const LAUNCHING_DURATION = 500;
|
||||
@@ -173,53 +171,20 @@ export class TerminalProcessManager implements ITerminalProcessManager {
|
||||
if (!shellLaunchConfig.executable) {
|
||||
this._configHelper.mergeDefaultShellPathAndArgs(shellLaunchConfig);
|
||||
}
|
||||
|
||||
const activeWorkspaceRootUri = this._historyService.getLastActiveWorkspaceRoot(Schemas.file);
|
||||
const initialCwd = terminalEnvironment.getCwd(shellLaunchConfig, this._environmentService.userHome, activeWorkspaceRootUri, this._configHelper.config.cwd);
|
||||
const env = this._createEnvironment(shellLaunchConfig, activeWorkspaceRootUri);
|
||||
|
||||
const platformKey = platform.isWindows ? 'windows' : (platform.isMacintosh ? 'osx' : 'linux');
|
||||
const lastActiveWorkspace = activeWorkspaceRootUri ? this._workspaceContextService.getWorkspaceFolder(activeWorkspaceRootUri) : null;
|
||||
const envFromConfigValue = this._workspaceConfigurationService.inspect<ITerminalEnvironment | undefined>(`terminal.integrated.env.${platformKey}`);
|
||||
const isWorkspaceShellAllowed = this._configHelper.checkWorkspaceShellPermissions();
|
||||
const env = terminalEnvironment.createTerminalEnvironment(shellLaunchConfig, lastActiveWorkspace, envFromConfigValue, this._configurationResolverService, isWorkspaceShellAllowed, this._productService.version, this._configHelper.config.setLocaleVariables);
|
||||
|
||||
this._logService.debug(`Terminal process launching`, shellLaunchConfig, initialCwd, cols, rows, env);
|
||||
return this._terminalInstanceService.createTerminalProcess(shellLaunchConfig, initialCwd, cols, rows, env, this._configHelper.config.windowsEnableConpty);
|
||||
}
|
||||
|
||||
private _createEnvironment(shellLaunchConfig: IShellLaunchConfig, activeWorkspaceRootUri: URI | undefined): platform.IProcessEnvironment {
|
||||
// Create a terminal environment based on settings, launch config and permissions
|
||||
let env: platform.IProcessEnvironment = {};
|
||||
if (shellLaunchConfig.strictEnv) {
|
||||
// strictEnv is true, only use the requested env (ignoring null entries)
|
||||
terminalEnvironment.mergeNonNullKeys(env, shellLaunchConfig.env);
|
||||
} else {
|
||||
// Merge process env with the env from config and from shellLaunchConfig
|
||||
terminalEnvironment.mergeNonNullKeys(env, process.env);
|
||||
|
||||
// Determine config env based on workspace shell permissions
|
||||
const lastActiveWorkspaceRoot = activeWorkspaceRootUri ? this._workspaceContextService.getWorkspaceFolder(activeWorkspaceRootUri) : null;
|
||||
const platformKey = platform.isWindows ? 'windows' : (platform.isMacintosh ? 'osx' : 'linux');
|
||||
const isWorkspaceShellAllowed = this._configHelper.checkWorkspaceShellPermissions();
|
||||
const envFromConfigValue = this._workspaceConfigurationService.inspect<ITerminalEnvironment | undefined>(`terminal.integrated.env.${platformKey}`);
|
||||
const allowedEnvFromConfig = { ...(isWorkspaceShellAllowed ? envFromConfigValue.value : envFromConfigValue.user) };
|
||||
|
||||
// Resolve env vars from config and shell
|
||||
if (allowedEnvFromConfig) {
|
||||
terminalEnvironment.resolveConfigurationVariables(this._configurationResolverService, allowedEnvFromConfig, lastActiveWorkspaceRoot);
|
||||
}
|
||||
if (shellLaunchConfig.env) {
|
||||
terminalEnvironment.resolveConfigurationVariables(this._configurationResolverService, shellLaunchConfig.env, lastActiveWorkspaceRoot);
|
||||
}
|
||||
|
||||
// Merge config (settings) and ShellLaunchConfig environments
|
||||
terminalEnvironment.mergeEnvironments(env, allowedEnvFromConfig);
|
||||
terminalEnvironment.mergeEnvironments(env, shellLaunchConfig.env);
|
||||
|
||||
// Sanitize the environment, removing any undesirable VS Code and Electron environment
|
||||
// variables
|
||||
sanitizeProcessEnvironment(env, 'VSCODE_IPC_HOOK_CLI');
|
||||
|
||||
// Adding other env keys necessary to create the process
|
||||
terminalEnvironment.addTerminalEnvironmentKeys(env, this._productService.version, platform.locale, this._configHelper.config.setLocaleVariables);
|
||||
}
|
||||
return env;
|
||||
}
|
||||
|
||||
public setDimensions(cols: number, rows: number): void {
|
||||
if (!this._process) {
|
||||
return;
|
||||
|
||||
@@ -9,6 +9,7 @@ import { URI as Uri } from 'vs/base/common/uri';
|
||||
import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
|
||||
import { IShellLaunchConfig, ITerminalEnvironment } from 'vs/workbench/contrib/terminal/common/terminal';
|
||||
import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver';
|
||||
import { sanitizeProcessEnvironment } from 'vs/base/common/processes';
|
||||
|
||||
/**
|
||||
* This module contains utility functions related to the environment, cwd and paths.
|
||||
@@ -59,7 +60,7 @@ export function addTerminalEnvironmentKeys(env: platform.IProcessEnvironment, ve
|
||||
}
|
||||
}
|
||||
|
||||
export function mergeNonNullKeys(env: platform.IProcessEnvironment, other: ITerminalEnvironment | NodeJS.ProcessEnv | undefined) {
|
||||
function mergeNonNullKeys(env: platform.IProcessEnvironment, other: ITerminalEnvironment | NodeJS.ProcessEnv | undefined) {
|
||||
if (!other) {
|
||||
return;
|
||||
}
|
||||
@@ -71,7 +72,7 @@ export function mergeNonNullKeys(env: platform.IProcessEnvironment, other: ITerm
|
||||
}
|
||||
}
|
||||
|
||||
export function resolveConfigurationVariables(configurationResolverService: IConfigurationResolverService, env: ITerminalEnvironment, lastActiveWorkspaceRoot: IWorkspaceFolder | null): ITerminalEnvironment {
|
||||
function resolveConfigurationVariables(configurationResolverService: IConfigurationResolverService, env: ITerminalEnvironment, lastActiveWorkspaceRoot: IWorkspaceFolder | null): ITerminalEnvironment {
|
||||
Object.keys(env).forEach((key) => {
|
||||
const value = env[key];
|
||||
if (typeof value === 'string' && lastActiveWorkspaceRoot !== null) {
|
||||
@@ -189,3 +190,49 @@ export function mergeDefaultShellPathAndArgs(
|
||||
shell.executable = shell.executable.replace(/\//g, '\\');
|
||||
}
|
||||
}
|
||||
|
||||
export function createTerminalEnvironment(
|
||||
shellLaunchConfig: IShellLaunchConfig,
|
||||
lastActiveWorkspace: IWorkspaceFolder | null,
|
||||
envFromConfig: { user: ITerminalEnvironment | undefined, value: ITerminalEnvironment | undefined, default: ITerminalEnvironment | undefined },
|
||||
configurationResolverService: IConfigurationResolverService | undefined,
|
||||
isWorkspaceShellAllowed: boolean,
|
||||
version: string | undefined,
|
||||
setLocaleVariables: boolean
|
||||
): platform.IProcessEnvironment {
|
||||
// Create a terminal environment based on settings, launch config and permissions
|
||||
let env: platform.IProcessEnvironment = {};
|
||||
if (shellLaunchConfig.strictEnv) {
|
||||
// strictEnv is true, only use the requested env (ignoring null entries)
|
||||
mergeNonNullKeys(env, shellLaunchConfig.env);
|
||||
} else {
|
||||
// Merge process env with the env from config and from shellLaunchConfig
|
||||
mergeNonNullKeys(env, process.env);
|
||||
|
||||
// const platformKey = platform.isWindows ? 'windows' : (platform.isMacintosh ? 'osx' : 'linux');
|
||||
// const envFromConfigValue = this._workspaceConfigurationService.inspect<ITerminalEnvironment | undefined>(`terminal.integrated.env.${platformKey}`);
|
||||
const allowedEnvFromConfig = { ...(isWorkspaceShellAllowed ? envFromConfig.value : envFromConfig.user) };
|
||||
|
||||
// Resolve env vars from config and shell
|
||||
if (configurationResolverService) {
|
||||
if (allowedEnvFromConfig) {
|
||||
resolveConfigurationVariables(configurationResolverService, allowedEnvFromConfig, lastActiveWorkspace);
|
||||
}
|
||||
if (shellLaunchConfig.env) {
|
||||
resolveConfigurationVariables(configurationResolverService, shellLaunchConfig.env, lastActiveWorkspace);
|
||||
}
|
||||
}
|
||||
|
||||
// Merge config (settings) and ShellLaunchConfig environments
|
||||
mergeEnvironments(env, allowedEnvFromConfig);
|
||||
mergeEnvironments(env, shellLaunchConfig.env);
|
||||
|
||||
// Sanitize the environment, removing any undesirable VS Code and Electron environment
|
||||
// variables
|
||||
sanitizeProcessEnvironment(env, 'VSCODE_IPC_HOOK_CLI');
|
||||
|
||||
// Adding other env keys necessary to create the process
|
||||
addTerminalEnvironmentKeys(env, version, platform.locale, setLocaleVariables);
|
||||
}
|
||||
return env;
|
||||
}
|
||||
Reference in New Issue
Block a user