mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Merge from vscode 112fa76c775ecb79ac2c9e9e5dba0d711d523543 (#6388)
This commit is contained in:
@@ -18,8 +18,7 @@ import { TerminalProcess } from 'vs/workbench/contrib/terminal/node/terminalProc
|
||||
import { timeout } from 'vs/base/common/async';
|
||||
import { ExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace';
|
||||
import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
|
||||
// {{SQL CARBON EDIT}}
|
||||
// import { ExtHostVariableResolverService } from 'vs/workbench/api/node/extHostDebugService';
|
||||
import { ExtHostVariableResolverService } from 'vs/workbench/api/node/extHostDebugService';
|
||||
import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors';
|
||||
import { getSystemShell, detectAvailableShells } from 'vs/workbench/contrib/terminal/node/terminal';
|
||||
import { getMainProcessParentEnv } from 'vs/workbench/contrib/terminal/node/terminalEnvironment';
|
||||
@@ -287,6 +286,8 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
|
||||
private _terminalProcesses: { [id: number]: ITerminalChildProcess } = {};
|
||||
private _terminalRenderers: ExtHostTerminalRenderer[] = [];
|
||||
private _getTerminalPromises: { [id: number]: Promise<ExtHostTerminal> } = {};
|
||||
private _variableResolver: ExtHostVariableResolverService | undefined;
|
||||
private _lastActiveWorkspace: IWorkspaceFolder | undefined;
|
||||
|
||||
// TODO: Pull this from main side
|
||||
private _isWorkspaceShellAllowed: boolean = false;
|
||||
@@ -308,9 +309,12 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
|
||||
private _extHostConfiguration: ExtHostConfiguration,
|
||||
private _extHostWorkspace: ExtHostWorkspace,
|
||||
private _extHostDocumentsAndEditors: ExtHostDocumentsAndEditors,
|
||||
private _logService: ILogService,
|
||||
private _logService: ILogService
|
||||
) {
|
||||
this._proxy = mainContext.getProxy(MainContext.MainThreadTerminalService);
|
||||
this.updateLastActiveWorkspace();
|
||||
this.updateVariableResolver();
|
||||
this.registerListeners();
|
||||
}
|
||||
|
||||
public createTerminal(name?: string, shellPath?: string, shellArgs?: string[] | string): vscode.Terminal {
|
||||
@@ -367,18 +371,21 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
|
||||
this._isWorkspaceShellAllowed,
|
||||
getSystemShell(platform.platform),
|
||||
process.env.hasOwnProperty('PROCESSOR_ARCHITEW6432'),
|
||||
process.env.windir
|
||||
process.env.windir,
|
||||
this._lastActiveWorkspace,
|
||||
this._variableResolver
|
||||
);
|
||||
}
|
||||
|
||||
private _getDefaultShellArgs(configProvider: ExtHostConfigProvider): string[] | string | undefined {
|
||||
private _getDefaultShellArgs(configProvider: ExtHostConfigProvider): string[] | string {
|
||||
const fetchSetting = (key: string) => {
|
||||
const setting = configProvider
|
||||
.getConfiguration(key.substr(0, key.lastIndexOf('.')))
|
||||
.inspect<string | string[]>(key.substr(key.lastIndexOf('.') + 1));
|
||||
return this._apiInspectConfigToPlain<string | string[]>(setting);
|
||||
};
|
||||
return terminalEnvironment.getDefaultShellArgs(fetchSetting, this._isWorkspaceShellAllowed);
|
||||
|
||||
return terminalEnvironment.getDefaultShellArgs(fetchSetting, this._isWorkspaceShellAllowed, this._lastActiveWorkspace, this._variableResolver);
|
||||
}
|
||||
|
||||
public async resolveTerminalRenderer(id: number): Promise<vscode.TerminalRenderer> {
|
||||
@@ -527,6 +534,24 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
|
||||
return env;
|
||||
}
|
||||
|
||||
private registerListeners(): void {
|
||||
this._extHostDocumentsAndEditors.onDidChangeActiveTextEditor(() => this.updateLastActiveWorkspace());
|
||||
this._extHostWorkspace.onDidChangeWorkspace(() => this.updateVariableResolver());
|
||||
}
|
||||
|
||||
private updateLastActiveWorkspace(): void {
|
||||
const activeEditor = this._extHostDocumentsAndEditors.activeEditor();
|
||||
if (activeEditor) {
|
||||
this._lastActiveWorkspace = this._extHostWorkspace.getWorkspaceFolder(activeEditor.document.uri) as IWorkspaceFolder;
|
||||
}
|
||||
}
|
||||
|
||||
private async updateVariableResolver(): Promise<void> {
|
||||
const configProvider = await this._extHostConfiguration.getConfigProvider();
|
||||
const workspaceFolders = await this._extHostWorkspace.getWorkspaceFolders2();
|
||||
this._variableResolver = new ExtHostVariableResolverService(workspaceFolders || [], this._extHostDocumentsAndEditors, configProvider);
|
||||
}
|
||||
|
||||
public async $createProcess(id: number, shellLaunchConfigDto: ShellLaunchConfigDto, activeWorkspaceRootUriComponents: UriComponents, cols: number, rows: number, isWorkspaceShellAllowed: boolean): Promise<void> {
|
||||
const shellLaunchConfig: IShellLaunchConfig = {
|
||||
name: shellLaunchConfigDto.name,
|
||||
@@ -542,6 +567,21 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
|
||||
if (!shellLaunchConfig.executable) {
|
||||
shellLaunchConfig.executable = this.getDefaultShell(configProvider);
|
||||
shellLaunchConfig.args = this._getDefaultShellArgs(configProvider);
|
||||
} else {
|
||||
if (this._variableResolver) {
|
||||
shellLaunchConfig.executable = this._variableResolver.resolve(this._lastActiveWorkspace, shellLaunchConfig.executable);
|
||||
if (shellLaunchConfig.args) {
|
||||
if (Array.isArray(shellLaunchConfig.args)) {
|
||||
const resolvedArgs: string[] = [];
|
||||
for (const arg of shellLaunchConfig.args) {
|
||||
resolvedArgs.push(this._variableResolver.resolve(this._lastActiveWorkspace, arg));
|
||||
}
|
||||
shellLaunchConfig.args = resolvedArgs;
|
||||
} else {
|
||||
shellLaunchConfig.args = this._variableResolver.resolve(this._lastActiveWorkspace, shellLaunchConfig.args);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get the initial cwd
|
||||
@@ -560,16 +600,12 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
|
||||
}
|
||||
} as IWorkspaceFolder : null;
|
||||
const envFromConfig = this._apiInspectConfigToPlain(configProvider.getConfiguration('terminal.integrated').inspect<ITerminalEnvironment>(`env.${platformKey}`));
|
||||
const workspaceFolders = await this._extHostWorkspace.getWorkspaceFolders2();
|
||||
// {{SQL CARBON EDIT}}
|
||||
// const variableResolver = workspaceFolders ? new ExtHostVariableResolverService(workspaceFolders, this._extHostDocumentsAndEditors, configProvider) : undefined;
|
||||
const variableResolver = undefined;
|
||||
const baseEnv = terminalConfig.get<boolean>('inheritEnv', true) ? process.env as platform.IProcessEnvironment : await this._getNonInheritedEnv();
|
||||
const env = terminalEnvironment.createTerminalEnvironment(
|
||||
shellLaunchConfig,
|
||||
lastActiveWorkspace,
|
||||
envFromConfig,
|
||||
variableResolver,
|
||||
this._variableResolver,
|
||||
isWorkspaceShellAllowed,
|
||||
pkg.version,
|
||||
terminalConfig.get<boolean>('setLocaleVariables', false),
|
||||
|
||||
@@ -1074,7 +1074,7 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
|
||||
toggleMaximizedPanel(): void {
|
||||
if (this.workbenchGrid instanceof Grid) {
|
||||
const curSize = this.workbenchGrid.getViewSize2(this.panelPartView);
|
||||
const curSize = this.workbenchGrid.getViewSize(this.panelPartView);
|
||||
const size = { ...curSize };
|
||||
|
||||
if (!this.isPanelMaximized()) {
|
||||
@@ -1106,9 +1106,9 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
try {
|
||||
// The panel is maximum when the editor is minimum
|
||||
if (this.state.panel.position === Position.BOTTOM) {
|
||||
return this.workbenchGrid.getViewSize2(this.editorPartView).height <= this.editorPartView.minimumHeight;
|
||||
return this.workbenchGrid.getViewSize(this.editorPartView).height <= this.editorPartView.minimumHeight;
|
||||
} else {
|
||||
return this.workbenchGrid.getViewSize2(this.editorPartView).width <= this.editorPartView.minimumWidth;
|
||||
return this.workbenchGrid.getViewSize(this.editorPartView).width <= this.editorPartView.minimumWidth;
|
||||
}
|
||||
} catch (e) {
|
||||
return false;
|
||||
|
||||
@@ -12,6 +12,7 @@ import { IDimension } from 'vs/platform/layout/browser/layoutService';
|
||||
import { ISerializableView, Orientation } from 'vs/base/browser/ui/grid/grid';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
|
||||
import { IViewSize } from 'vs/base/browser/ui/grid/gridview';
|
||||
|
||||
export interface IPartOptions {
|
||||
hasTitle?: boolean;
|
||||
@@ -117,8 +118,8 @@ export abstract class Part extends Component implements ISerializableView {
|
||||
|
||||
//#region ISerializableView
|
||||
|
||||
private _onDidChange = this._register(new Emitter<{ width: number; height: number; }>());
|
||||
get onDidChange(): Event<{ width: number, height: number }> { return this._onDidChange.event; }
|
||||
private _onDidChange = this._register(new Emitter<IViewSize | undefined>());
|
||||
get onDidChange(): Event<IViewSize | undefined> { return this._onDidChange.event; }
|
||||
|
||||
element: HTMLElement;
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ import { EditorDropTarget } from 'vs/workbench/browser/parts/editor/editorDropTa
|
||||
import { localize } from 'vs/nls';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
import { CenteredViewLayout } from 'vs/base/browser/ui/centered/centeredViewLayout';
|
||||
import { IView, orthogonal, LayoutPriority } from 'vs/base/browser/ui/grid/gridview';
|
||||
import { IView, orthogonal, LayoutPriority, IViewSize } from 'vs/base/browser/ui/grid/gridview';
|
||||
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { Parts, IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
|
||||
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
||||
@@ -564,7 +564,7 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro
|
||||
|
||||
// Maximize the group if it is currently minimized
|
||||
if (this.gridWidget) {
|
||||
const viewSize = this.gridWidget.getViewSize2(group);
|
||||
const viewSize = this.gridWidget.getViewSize(group);
|
||||
if (viewSize.width === group.minimumWidth || viewSize.height === group.minimumHeight) {
|
||||
this.arrangeGroups(GroupsArrangement.MINIMIZE_OTHERS);
|
||||
}
|
||||
@@ -756,13 +756,14 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro
|
||||
|
||||
//#region Part
|
||||
|
||||
readonly priority: LayoutPriority = LayoutPriority.High;
|
||||
|
||||
get minimumWidth(): number { return this.centeredLayoutWidget.minimumWidth; }
|
||||
get maximumWidth(): number { return this.centeredLayoutWidget.maximumWidth; }
|
||||
get minimumHeight(): number { return this.centeredLayoutWidget.minimumHeight; }
|
||||
get maximumHeight(): number { return this.centeredLayoutWidget.maximumHeight; }
|
||||
|
||||
get onDidChange(): Event<IViewSize | undefined> { return this.centeredLayoutWidget.onDidChange; }
|
||||
readonly priority: LayoutPriority = LayoutPriority.High;
|
||||
|
||||
get preferredSize(): Dimension {
|
||||
if (!this._preferredSize) {
|
||||
this._preferredSize = new Dimension(this.gridWidget.minimumWidth, this.gridWidget.minimumHeight);
|
||||
|
||||
@@ -919,7 +919,8 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe
|
||||
windowsPath = windowsPath.replace('%USERPROFILE%', process.env['USERPROFILE']!)
|
||||
.replace('%ProgramFiles(x86)%', process.env['ProgramFiles(x86)']!)
|
||||
.replace('%ProgramFiles%', process.env['ProgramFiles']!)
|
||||
.replace('%APPDATA%', process.env['APPDATA']!);
|
||||
.replace('%APPDATA%', process.env['APPDATA']!)
|
||||
.replace('%WINDIR%', process.env['WINDIR']!);
|
||||
promises.push(findExecutable(exeName, windowsPath));
|
||||
} else {
|
||||
promises.push(findExecutable(exeName, join('/usr/local/bin', exeName)));
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import { Action } from 'vs/base/common/actions';
|
||||
import { distinct } from 'vs/base/common/arrays';
|
||||
import { illegalArgument } from 'vs/base/common/errors';
|
||||
import { illegalArgument, onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
|
||||
import * as objects from 'vs/base/common/objects';
|
||||
import * as platform from 'vs/base/common/platform';
|
||||
@@ -38,7 +38,7 @@ import { Extensions as ActionExtensions, IWorkbenchActionRegistry } from 'vs/wor
|
||||
import { Extensions as WorkbenchExtensions, IWorkbenchContribution, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions';
|
||||
import { Extensions as ViewExtensions, IViewsRegistry } from 'vs/workbench/common/views';
|
||||
import { getMultiSelectedResources } from 'vs/workbench/contrib/files/browser/files';
|
||||
import { ExplorerFolderContext, ExplorerRootContext, FilesExplorerFocusCondition } from 'vs/workbench/contrib/files/common/files';
|
||||
import { ExplorerFolderContext, ExplorerRootContext, FilesExplorerFocusCondition, IExplorerService, VIEWLET_ID as VIEWLET_ID_FILES } from 'vs/workbench/contrib/files/common/files';
|
||||
import { OpenAnythingHandler } from 'vs/workbench/contrib/search/browser/openAnythingHandler';
|
||||
import { OpenSymbolHandler } from 'vs/workbench/contrib/search/browser/openSymbolHandler';
|
||||
import { registerContributions as replaceContributions } from 'vs/workbench/contrib/search/browser/replaceContributions';
|
||||
@@ -50,11 +50,13 @@ import { registerContributions as searchWidgetContributions } from 'vs/workbench
|
||||
import * as Constants from 'vs/workbench/contrib/search/common/constants';
|
||||
import { getWorkspaceSymbols } from 'vs/workbench/contrib/search/common/search';
|
||||
import { ISearchHistoryService, SearchHistoryService } from 'vs/workbench/contrib/search/common/searchHistoryService';
|
||||
import { FileMatchOrMatch, ISearchWorkbenchService, RenderableMatch, SearchWorkbenchService } from 'vs/workbench/contrib/search/common/searchModel';
|
||||
import { FileMatchOrMatch, ISearchWorkbenchService, RenderableMatch, SearchWorkbenchService, FileMatch } from 'vs/workbench/contrib/search/common/searchModel';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { IPanelService } from 'vs/workbench/services/panel/common/panelService';
|
||||
import { ISearchConfiguration, ISearchConfigurationProperties, PANEL_ID, VIEWLET_ID, VIEW_CONTAINER, VIEW_ID } from 'vs/workbench/services/search/common/search';
|
||||
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
|
||||
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||
import { ExplorerViewlet } from 'vs/workbench/contrib/files/browser/explorerViewlet';
|
||||
|
||||
registerSingleton(ISearchWorkbenchService, SearchWorkbenchService, true);
|
||||
registerSingleton(ISearchHistoryService, SearchHistoryService, true);
|
||||
@@ -211,6 +213,37 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
}
|
||||
});
|
||||
|
||||
CommandsRegistry.registerCommand({
|
||||
id: Constants.RevealInSideBarForSearchResults,
|
||||
handler: (accessor, fileMatch: FileMatch) => {
|
||||
const viewletService = accessor.get(IViewletService);
|
||||
const explorerService = accessor.get(IExplorerService);
|
||||
const contextService = accessor.get(IWorkspaceContextService);
|
||||
const uri = fileMatch.resource();
|
||||
|
||||
viewletService.openViewlet(VIEWLET_ID_FILES, false).then((viewlet: ExplorerViewlet) => {
|
||||
if (uri && contextService.isInsideWorkspace(uri)) {
|
||||
const explorerView = viewlet.getExplorerView();
|
||||
if (explorerView) {
|
||||
explorerView.setExpanded(true);
|
||||
explorerService.select(uri, true).then(() => explorerView.focus(), onUnexpectedError);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const RevealInSideBarForSearchResultsCommand: ICommandAction = {
|
||||
id: Constants.RevealInSideBarForSearchResults,
|
||||
title: nls.localize('revealInSideBar', "Reveal in Explorer")
|
||||
};
|
||||
|
||||
MenuRegistry.appendMenuItem(MenuId.SearchContext, {
|
||||
command: RevealInSideBarForSearchResultsCommand,
|
||||
when: ContextKeyExpr.and(Constants.FileFocusKey, Constants.HasSearchResults),
|
||||
group: '2_files',
|
||||
});
|
||||
|
||||
MenuRegistry.appendMenuItem(MenuId.SearchContext, {
|
||||
command: {
|
||||
id: Constants.ReplaceActionId,
|
||||
|
||||
@@ -24,6 +24,7 @@ export const CloseReplaceWidgetActionId = 'closeReplaceInFilesWidget';
|
||||
export const ToggleCaseSensitiveCommandId = 'toggleSearchCaseSensitive';
|
||||
export const ToggleWholeWordCommandId = 'toggleSearchWholeWord';
|
||||
export const ToggleRegexCommandId = 'toggleSearchRegex';
|
||||
export const RevealInSideBarForSearchResults = 'search.action.revealInSideBar';
|
||||
|
||||
export const ToggleSearchViewPositionCommandId = 'search.action.toggleSearchViewPosition';
|
||||
|
||||
|
||||
@@ -8,12 +8,15 @@ import * as platform from 'vs/base/common/platform';
|
||||
import { EDITOR_FONT_DEFAULTS, IEditorOptions } from 'vs/editor/common/config/editorOptions';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { ITerminalConfiguration, ITerminalFont, IS_WORKSPACE_SHELL_ALLOWED_STORAGE_KEY, TERMINAL_CONFIG_SECTION, DEFAULT_LETTER_SPACING, DEFAULT_LINE_HEIGHT, MINIMUM_LETTER_SPACING, LinuxDistro } from 'vs/workbench/contrib/terminal/common/terminal';
|
||||
import { ITerminalConfiguration, ITerminalFont, IS_WORKSPACE_SHELL_ALLOWED_STORAGE_KEY, TERMINAL_CONFIG_SECTION, DEFAULT_LETTER_SPACING, DEFAULT_LINE_HEIGHT, MINIMUM_LETTER_SPACING, LinuxDistro, IShellLaunchConfig } from 'vs/workbench/contrib/terminal/common/terminal';
|
||||
import Severity from 'vs/base/common/severity';
|
||||
import { Terminal as XTermTerminal } from 'xterm';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { IBrowserTerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminal';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { basename } from 'vs/base/common/path';
|
||||
import { IExtensionManagementService } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { ExtensionType } from 'vs/platform/extensions/common/extensions';
|
||||
|
||||
const MINIMUM_FONT_SIZE = 6;
|
||||
const MAXIMUM_FONT_SIZE = 25;
|
||||
@@ -35,7 +38,7 @@ export class TerminalConfigHelper implements IBrowserTerminalConfigHelper {
|
||||
public constructor(
|
||||
private readonly _linuxDistro: LinuxDistro,
|
||||
@IConfigurationService private readonly _configurationService: IConfigurationService,
|
||||
@IConfigurationService private readonly _workspaceConfigurationService: IConfigurationService,
|
||||
@IExtensionManagementService private readonly _extensionManagementService: IExtensionManagementService,
|
||||
@INotificationService private readonly _notificationService: INotificationService,
|
||||
@IStorageService private readonly _storageService: IStorageService
|
||||
) {
|
||||
@@ -174,9 +177,9 @@ export class TerminalConfigHelper implements IBrowserTerminalConfigHelper {
|
||||
public checkWorkspaceShellPermissions(osOverride: platform.OperatingSystem = platform.OS): boolean {
|
||||
// Check whether there is a workspace setting
|
||||
const platformKey = osOverride === platform.OperatingSystem.Windows ? 'windows' : osOverride === platform.OperatingSystem.Macintosh ? 'osx' : 'linux';
|
||||
const shellConfigValue = this._workspaceConfigurationService.inspect<string>(`terminal.integrated.shell.${platformKey}`);
|
||||
const shellArgsConfigValue = this._workspaceConfigurationService.inspect<string[]>(`terminal.integrated.shellArgs.${platformKey}`);
|
||||
const envConfigValue = this._workspaceConfigurationService.inspect<{ [key: string]: string }>(`terminal.integrated.env.${platformKey}`);
|
||||
const shellConfigValue = this._configurationService.inspect<string>(`terminal.integrated.shell.${platformKey}`);
|
||||
const shellArgsConfigValue = this._configurationService.inspect<string[]>(`terminal.integrated.shellArgs.${platformKey}`);
|
||||
const envConfigValue = this._configurationService.inspect<{ [key: string]: string }>(`terminal.integrated.env.${platformKey}`);
|
||||
|
||||
// Check if workspace setting exists and whether it's whitelisted
|
||||
let isWorkspaceShellAllowed: boolean | undefined = false;
|
||||
@@ -244,4 +247,48 @@ export class TerminalConfigHelper implements IBrowserTerminalConfigHelper {
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
private readonly NO_RECOMMENDATIONS_KEY = 'terminalConfigHelper/launchRecommendationsIgnore';
|
||||
private recommendationsShown = false;
|
||||
|
||||
public async showRecommendations(shellLaunchConfig: IShellLaunchConfig): Promise<void> {
|
||||
if (this.recommendationsShown) {
|
||||
return;
|
||||
}
|
||||
this.recommendationsShown = true;
|
||||
|
||||
if (platform.isWindows && shellLaunchConfig.executable && basename(shellLaunchConfig.executable).toLowerCase() === 'wsl.exe') {
|
||||
if (this._storageService.getBoolean(this.NO_RECOMMENDATIONS_KEY, StorageScope.WORKSPACE, false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (! await this.isExtensionInstalled('ms-vscode-remote.remote-wsl')) {
|
||||
this._notificationService.prompt(
|
||||
Severity.Info,
|
||||
nls.localize(
|
||||
'useWslExtension.title',
|
||||
"Check out the 'Visual Studio Code Remote - WSL' extension for a great development experience in WSL. Click [here]({0}) to learn more.",
|
||||
'https://go.microsoft.com/fwlink/?linkid=2097212'
|
||||
),
|
||||
[
|
||||
{
|
||||
label: nls.localize('doNotShowAgain', "Don't Show Again"),
|
||||
run: () => {
|
||||
this._storageService.store(this.NO_RECOMMENDATIONS_KEY, true, StorageScope.WORKSPACE);
|
||||
}
|
||||
}
|
||||
],
|
||||
{
|
||||
sticky: true
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private isExtensionInstalled(id: string): Promise<boolean> {
|
||||
return this._extensionManagementService.getInstalled(ExtensionType.User).then(extensions => {
|
||||
return extensions.some(e => e.identifier.id === id);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,19 +184,32 @@ export class TerminalProcessManager implements ITerminalProcessManager {
|
||||
rows: number,
|
||||
isScreenReaderModeEnabled: boolean
|
||||
): Promise<ITerminalChildProcess> {
|
||||
const activeWorkspaceRootUri = this._historyService.getLastActiveWorkspaceRoot(Schemas.file);
|
||||
const platformKey = platform.isWindows ? 'windows' : (platform.isMacintosh ? 'osx' : 'linux');
|
||||
const lastActiveWorkspace = activeWorkspaceRootUri ? this._workspaceContextService.getWorkspaceFolder(activeWorkspaceRootUri) : null;
|
||||
if (!shellLaunchConfig.executable) {
|
||||
const defaultConfig = await this._terminalInstanceService.getDefaultShellAndArgs();
|
||||
shellLaunchConfig.executable = defaultConfig.shell;
|
||||
shellLaunchConfig.args = defaultConfig.args;
|
||||
} else {
|
||||
shellLaunchConfig.executable = this._configurationResolverService.resolve(lastActiveWorkspace === null ? undefined : lastActiveWorkspace, shellLaunchConfig.executable);
|
||||
if (shellLaunchConfig.args) {
|
||||
if (Array.isArray(shellLaunchConfig.args)) {
|
||||
const resolvedArgs: string[] = [];
|
||||
for (const arg of shellLaunchConfig.args) {
|
||||
resolvedArgs.push(this._configurationResolverService.resolve(lastActiveWorkspace === null ? undefined : lastActiveWorkspace, arg));
|
||||
}
|
||||
shellLaunchConfig.args = resolvedArgs;
|
||||
} else {
|
||||
shellLaunchConfig.args = this._configurationResolverService.resolve(lastActiveWorkspace === null ? undefined : lastActiveWorkspace, shellLaunchConfig.args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const activeWorkspaceRootUri = this._historyService.getLastActiveWorkspaceRoot(Schemas.file);
|
||||
const initialCwd = terminalEnvironment.getCwd(shellLaunchConfig, this._environmentService.userHome, activeWorkspaceRootUri, this._configHelper.config.cwd);
|
||||
|
||||
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();
|
||||
this._configHelper.showRecommendations(shellLaunchConfig);
|
||||
const baseEnv = this._configHelper.config.inheritEnv ? process.env as platform.IProcessEnvironment : await this._terminalInstanceService.getMainProcessParentEnv();
|
||||
const env = terminalEnvironment.createTerminalEnvironment(shellLaunchConfig, lastActiveWorkspace, envFromConfigValue, this._configurationResolverService, isWorkspaceShellAllowed, this._productService.version, this._configHelper.config.setLocaleVariables, baseEnv);
|
||||
|
||||
|
||||
@@ -122,6 +122,7 @@ export interface ITerminalConfigHelper {
|
||||
/** Sets whether a workspace shell configuration is allowed or not */
|
||||
setWorkspaceShellAllowed(isAllowed: boolean): void;
|
||||
checkWorkspaceShellPermissions(osOverride?: OperatingSystem): boolean;
|
||||
showRecommendations(shellLaunchConfig: IShellLaunchConfig): void;
|
||||
}
|
||||
|
||||
export interface ITerminalFont {
|
||||
|
||||
@@ -169,7 +169,9 @@ export function getDefaultShell(
|
||||
defaultShell: string,
|
||||
isWoW64: boolean,
|
||||
windir: string | undefined,
|
||||
platformOverride: platform.Platform = platform.platform
|
||||
lastActiveWorkspace: IWorkspaceFolder | undefined,
|
||||
configurationResolverService: IConfigurationResolverService | undefined,
|
||||
platformOverride: platform.Platform = platform.platform,
|
||||
): string {
|
||||
const platformKey = platformOverride === platform.Platform.Windows ? 'windows' : platformOverride === platform.Platform.Mac ? 'osx' : 'linux';
|
||||
const shellConfigValue = fetchSetting(`terminal.integrated.shell.${platformKey}`);
|
||||
@@ -190,17 +192,33 @@ export function getDefaultShell(
|
||||
executable = executable.replace(/\//g, '\\');
|
||||
}
|
||||
|
||||
if (configurationResolverService) {
|
||||
executable = configurationResolverService.resolve(lastActiveWorkspace, executable);
|
||||
}
|
||||
|
||||
return executable;
|
||||
}
|
||||
|
||||
export function getDefaultShellArgs(
|
||||
fetchSetting: (key: string) => { user: string | string[] | undefined, value: string | string[] | undefined, default: string | string[] | undefined },
|
||||
isWorkspaceShellAllowed: boolean,
|
||||
platformOverride: platform.Platform = platform.platform
|
||||
): string[] {
|
||||
lastActiveWorkspace: IWorkspaceFolder | undefined,
|
||||
configurationResolverService: IConfigurationResolverService | undefined,
|
||||
platformOverride: platform.Platform = platform.platform,
|
||||
): string | string[] {
|
||||
const platformKey = platformOverride === platform.Platform.Windows ? 'windows' : platformOverride === platform.Platform.Mac ? 'osx' : 'linux';
|
||||
const shellArgsConfigValue = fetchSetting(`terminal.integrated.shellArgs.${platformKey}`);
|
||||
const args = (isWorkspaceShellAllowed ? <string[]>shellArgsConfigValue.value : <string[]>shellArgsConfigValue.user) || <string[]>shellArgsConfigValue.default;
|
||||
let args = <string[] | string>((isWorkspaceShellAllowed ? shellArgsConfigValue.value : shellArgsConfigValue.user) || shellArgsConfigValue.default);
|
||||
if (typeof args === 'string' && platformOverride === platform.Platform.Windows) {
|
||||
return configurationResolverService ? configurationResolverService.resolve(lastActiveWorkspace, args) : args;
|
||||
}
|
||||
if (configurationResolverService) {
|
||||
const resolvedArgs: string[] = [];
|
||||
for (const arg of args) {
|
||||
resolvedArgs.push(configurationResolverService.resolve(lastActiveWorkspace, arg));
|
||||
}
|
||||
args = resolvedArgs;
|
||||
}
|
||||
return args;
|
||||
}
|
||||
|
||||
@@ -237,14 +255,14 @@ export function createTerminalEnvironment(
|
||||
}
|
||||
}
|
||||
|
||||
// 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');
|
||||
|
||||
// Merge config (settings) and ShellLaunchConfig environments
|
||||
mergeEnvironments(env, allowedEnvFromConfig);
|
||||
mergeEnvironments(env, shellLaunchConfig.env);
|
||||
|
||||
// Adding other env keys necessary to create the process
|
||||
addTerminalEnvironmentKeys(env, version, platform.locale, setLocaleVariables);
|
||||
}
|
||||
|
||||
@@ -17,6 +17,9 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur
|
||||
import { getDefaultShell, getDefaultShellArgs } from 'vs/workbench/contrib/terminal/common/terminalEnvironment';
|
||||
import { StorageScope, IStorageService } from 'vs/platform/storage/common/storage';
|
||||
import { getMainProcessParentEnv } from 'vs/workbench/contrib/terminal/node/terminalEnvironment';
|
||||
import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver';
|
||||
import { IHistoryService } from 'vs/workbench/services/history/common/history';
|
||||
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||
|
||||
let Terminal: typeof XTermTerminal;
|
||||
let WebLinksAddon: typeof XTermWebLinksAddon;
|
||||
@@ -28,7 +31,10 @@ export class TerminalInstanceService implements ITerminalInstanceService {
|
||||
constructor(
|
||||
@IInstantiationService private readonly _instantiationService: IInstantiationService,
|
||||
@IConfigurationService private readonly _configurationService: IConfigurationService,
|
||||
@IStorageService private readonly _storageService: IStorageService
|
||||
@IStorageService private readonly _storageService: IStorageService,
|
||||
@IConfigurationResolverService private readonly _configurationResolverService: IConfigurationResolverService,
|
||||
@IWorkspaceContextService private readonly _workspaceContextService: IWorkspaceContextService,
|
||||
@IHistoryService private readonly _historyService: IHistoryService
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -65,19 +71,26 @@ export class TerminalInstanceService implements ITerminalInstanceService {
|
||||
return this._storageService.getBoolean(IS_WORKSPACE_SHELL_ALLOWED_STORAGE_KEY, StorageScope.WORKSPACE, false);
|
||||
}
|
||||
|
||||
public getDefaultShellAndArgs(platformOverride: Platform = platform): Promise<{ shell: string, args: string[] | undefined }> {
|
||||
public getDefaultShellAndArgs(platformOverride: Platform = platform): Promise<{ shell: string, args: string | string[] }> {
|
||||
const isWorkspaceShellAllowed = this._isWorkspaceShellAllowed();
|
||||
const activeWorkspaceRootUri = this._historyService.getLastActiveWorkspaceRoot();
|
||||
let lastActiveWorkspace = activeWorkspaceRootUri ? this._workspaceContextService.getWorkspaceFolder(activeWorkspaceRootUri) : undefined;
|
||||
lastActiveWorkspace = lastActiveWorkspace === null ? undefined : lastActiveWorkspace;
|
||||
const shell = getDefaultShell(
|
||||
(key) => this._configurationService.inspect(key),
|
||||
isWorkspaceShellAllowed,
|
||||
getSystemShell(platformOverride),
|
||||
process.env.hasOwnProperty('PROCESSOR_ARCHITEW6432'),
|
||||
process.env.windir,
|
||||
lastActiveWorkspace,
|
||||
this._configurationResolverService,
|
||||
platformOverride
|
||||
);
|
||||
const args = getDefaultShellArgs(
|
||||
(key) => this._configurationService.inspect(key),
|
||||
isWorkspaceShellAllowed,
|
||||
lastActiveWorkspace,
|
||||
this._configurationResolverService,
|
||||
platformOverride
|
||||
);
|
||||
return Promise.resolve({ shell, args });
|
||||
|
||||
@@ -51,7 +51,7 @@ export class ReleaseNotesManager {
|
||||
private _releaseNotesCache: { [version: string]: Promise<string>; } = Object.create(null);
|
||||
|
||||
private _currentReleaseNotes: WebviewEditorInput | undefined = undefined;
|
||||
private _lastText: string;
|
||||
private _lastText: string | undefined;
|
||||
|
||||
public constructor(
|
||||
@IEnvironmentService private readonly _environmentService: IEnvironmentService,
|
||||
|
||||
@@ -3,49 +3,59 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import { memoize } from 'vs/base/common/decorators';
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
import { DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IEditorModel } from 'vs/platform/editor/common/editor';
|
||||
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||
import { EditorInput, EditorModel, GroupIdentifier, IEditorInput } from 'vs/workbench/common/editor';
|
||||
import { Webview, WebviewOptions } from 'vs/workbench/contrib/webview/common/webview';
|
||||
import { IWorkbenchLayoutService, Parts } from 'vs/workbench/services/layout/browser/layoutService';
|
||||
import { WebviewEvents, WebviewInputOptions } from './webviewEditorService';
|
||||
import { Webview, WebviewOptions } from 'vs/workbench/contrib/webview/common/webview';
|
||||
|
||||
export class WebviewEditorInput<State = any> extends EditorInput {
|
||||
class WebviewIconsManager {
|
||||
private readonly _icons = new Map<string, { light: URI, dark: URI }>();
|
||||
|
||||
private static _styleElement?: HTMLStyleElement;
|
||||
@memoize
|
||||
private get _styleElement(): HTMLStyleElement {
|
||||
const element = dom.createStyleSheet();
|
||||
element.className = 'webview-icons';
|
||||
return element;
|
||||
}
|
||||
|
||||
private static _icons = new Map<string, { light: URI, dark: URI }>();
|
||||
|
||||
private static updateStyleElement(
|
||||
id: string,
|
||||
public setIcons(
|
||||
webviewId: string,
|
||||
iconPath: { light: URI, dark: URI } | undefined
|
||||
) {
|
||||
if (!this._styleElement) {
|
||||
this._styleElement = dom.createStyleSheet();
|
||||
this._styleElement.className = 'webview-icons';
|
||||
}
|
||||
|
||||
if (!iconPath) {
|
||||
this._icons.delete(id);
|
||||
if (iconPath) {
|
||||
this._icons.set(webviewId, iconPath);
|
||||
} else {
|
||||
this._icons.set(id, iconPath);
|
||||
this._icons.delete(webviewId);
|
||||
}
|
||||
|
||||
this.updateStyleSheet();
|
||||
}
|
||||
|
||||
private updateStyleSheet() {
|
||||
const cssRules: string[] = [];
|
||||
this._icons.forEach((value, key) => {
|
||||
const webviewSelector = `.show-file-icons .webview-${key}-name-file-icon::before`;
|
||||
if (URI.isUri(value)) {
|
||||
cssRules.push(`${webviewSelector} { content: ""; background-image: url(${dom.asDomUri(value).toString()}); }`);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
cssRules.push(`.vs ${webviewSelector} { content: ""; background-image: url(${dom.asDomUri(value.light).toString()}); }`);
|
||||
cssRules.push(`.vs-dark ${webviewSelector} { content: ""; background-image: url(${dom.asDomUri(value.dark).toString()}); }`);
|
||||
}
|
||||
});
|
||||
this._styleElement.innerHTML = cssRules.join('\n');
|
||||
}
|
||||
}
|
||||
|
||||
export class WebviewEditorInput<State = any> extends EditorInput {
|
||||
|
||||
private readonly iconsManager = new WebviewIconsManager();
|
||||
|
||||
public static readonly typeId = 'workbench.editors.webviewInput';
|
||||
|
||||
@@ -144,7 +154,7 @@ export class WebviewEditorInput<State = any> extends EditorInput {
|
||||
|
||||
public set iconPath(value: { light: URI, dark: URI } | undefined) {
|
||||
this._iconPath = value;
|
||||
WebviewEditorInput.updateStyleElement(this.id, value);
|
||||
this.iconsManager.setIcons(this.id, value);
|
||||
}
|
||||
|
||||
public matches(other: IEditorInput): boolean {
|
||||
|
||||
@@ -200,6 +200,8 @@ export class BrowserKeyboardMapperFactoryBase {
|
||||
}]
|
||||
);
|
||||
|
||||
console.warn('Active keymap/keyevent does not match current keyboard layout', JSON.stringify(keymap), this._activeKeymapInfo ? JSON.stringify(this._activeKeymapInfo.layout) : '');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user