Skip to content

Commit

Permalink
Allow terminal workspace settings again
Browse files Browse the repository at this point in the history
Fixes #19758
  • Loading branch information
Tyriar committed Mar 23, 2017
1 parent 1c432b9 commit 521a1f9
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 99 deletions.
1 change: 1 addition & 0 deletions src/vs/workbench/parts/terminal/common/terminal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export const KEYBINDING_CONTEXT_TERMINAL_TEXT_SELECTED = new RawContextKey<boole
/** A keybinding context key that is set when the integrated terminal does not have text selected. */
export const KEYBINDING_CONTEXT_TERMINAL_TEXT_NOT_SELECTED: ContextKeyExpr = KEYBINDING_CONTEXT_TERMINAL_TEXT_SELECTED.toNegated();

export const IS_WORKSPACE_SHELL_ALLOWED_STORAGE_KEY = 'terminal.integrated.isWorkspaceShellAllowed';
export const NEVER_SUGGEST_SELECT_WINDOWS_SHELL_STORAGE_KEY = 'terminal.integrated.neverSuggestSelectWindowsShell';

export const ITerminalService = createDecorator<ITerminalService>(TERMINAL_SERVICE_ID);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,23 +40,20 @@ configurationRegistry.registerConfiguration({
'terminal.integrated.shell.linux': {
'description': nls.localize('terminal.integrated.shell.linux', "The path of the shell that the terminal uses on Linux."),
'type': 'string',
'default': TERMINAL_DEFAULT_SHELL_LINUX,
'isExecutable': true
'default': TERMINAL_DEFAULT_SHELL_LINUX
},
'terminal.integrated.shellArgs.linux': {
'description': nls.localize('terminal.integrated.shellArgs.linux', "The command line arguments to use when on the Linux terminal."),
'type': 'array',
'items': {
'type': 'string'
},
'default': [],
'isExecutable': true
'default': []
},
'terminal.integrated.shell.osx': {
'description': nls.localize('terminal.integrated.shell.osx', "The path of the shell that the terminal uses on OS X."),
'type': 'string',
'default': TERMINAL_DEFAULT_SHELL_OSX,
'isExecutable': true
'default': TERMINAL_DEFAULT_SHELL_OSX
},
'terminal.integrated.shellArgs.osx': {
'description': nls.localize('terminal.integrated.shellArgs.osx', "The command line arguments to use when on the OS X terminal."),
Expand All @@ -67,23 +64,20 @@ configurationRegistry.registerConfiguration({
// Unlike on Linux, ~/.profile is not sourced when logging into a macOS session. This
// is the reason terminals on macOS typically run login shells by default which set up
// the environment. See http://unix.stackexchange.com/a/119675/115410
'default': ['-l'],
'isExecutable': true
'default': ['-l']
},
'terminal.integrated.shell.windows': {
'description': nls.localize('terminal.integrated.shell.windows', "The path of the shell that the terminal uses on Windows. When using shells shipped with Windows (cmd, PowerShell or Bash on Ubuntu), prefer C:\\Windows\\sysnative over C:\\Windows\\System32 to use the 64-bit versions."),
'type': 'string',
'default': TERMINAL_DEFAULT_SHELL_WINDOWS,
'isExecutable': true
'default': TERMINAL_DEFAULT_SHELL_WINDOWS
},
'terminal.integrated.shellArgs.windows': {
'description': nls.localize('terminal.integrated.shellArgs.windows', "The command line arguments to use when on the Windows terminal."),
'type': 'array',
'items': {
'type': 'string'
},
'default': [],
'isExecutable': true
'default': []
},
'terminal.integrated.rightClickCopyPaste': {
'description': nls.localize('terminal.integrated.rightClickCopyPaste', "When set, this will prevent the context menu from appearing when right clicking within the terminal, instead it will copy when there is a selection and paste when there is no selection."),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,16 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import * as nls from 'vs/nls';
import * as platform from 'vs/base/common/platform';
import { IConfiguration as IEditorConfiguration, DefaultConfig } from 'vs/editor/common/config/defaultConfig';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { ITerminalConfiguration, ITerminalConfigHelper, ITerminalFont, IShellLaunchConfig } from 'vs/workbench/parts/terminal/common/terminal';
import { Platform } from 'vs/base/common/platform';
import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration';
import { IChoiceService } from 'vs/platform/message/common/message';
import { IStorageService, StorageScope } from "vs/platform/storage/common/storage";
import { ITerminalConfiguration, ITerminalConfigHelper, ITerminalFont, IShellLaunchConfig, IS_WORKSPACE_SHELL_ALLOWED_STORAGE_KEY } from 'vs/workbench/parts/terminal/common/terminal';
import { Severity } from "vs/editor/common/standalone/standaloneBase";
import { TPromise } from 'vs/base/common/winjs.base';

interface IFullTerminalConfiguration {
terminal: {
Expand All @@ -27,8 +33,11 @@ export class TerminalConfigHelper implements ITerminalConfigHelper {
private _lastFontMeasurement: ITerminalFont;

public constructor(
private _platform: Platform,
@IConfigurationService private _configurationService: IConfigurationService) {
private _platform: platform.Platform,
@IConfigurationService private _configurationService: IConfigurationService,
@IWorkspaceConfigurationService private _workspaceConfigurationService: IWorkspaceConfigurationService,
@IChoiceService private _choiceService: IChoiceService,
@IStorageService private _storageService: IStorageService) {
}

public get config(): ITerminalConfiguration {
Expand Down Expand Up @@ -88,21 +97,57 @@ export class TerminalConfigHelper implements ITerminalConfigHelper {
}

public mergeDefaultShellPathAndArgs(shell: IShellLaunchConfig): void {
const config = this.config;
shell.executable = '';
shell.args = [];
if (config && config.shell && config.shellArgs) {
if (this._platform === Platform.Windows) {
shell.executable = config.shell.windows;
shell.args = config.shellArgs.windows;
} else if (this._platform === Platform.Mac) {
shell.executable = config.shell.osx;
shell.args = config.shellArgs.osx;
} else if (this._platform === Platform.Linux) {
shell.executable = config.shell.linux;
shell.args = config.shellArgs.linux;
// Check whether there is a workspace setting
const platformKey = platform.isWindows ? 'windows' : platform.isMacintosh ? 'osx' : 'linux';
const shellConfigValue = this._workspaceConfigurationService.lookup<string>(`terminal.integrated.shell.${platformKey}`);
const shellArgsConfigValue = this._workspaceConfigurationService.lookup<string[]>(`terminal.integrated.shellArgs.${platformKey}`);

// Check if workspace setting exists and whether it's whitelisted
let isWorkspaceShellAllowed = false;
if (shellConfigValue.workspace !== undefined || shellArgsConfigValue.workspace !== undefined) {
isWorkspaceShellAllowed = this._storageService.getBoolean(IS_WORKSPACE_SHELL_ALLOWED_STORAGE_KEY, StorageScope.WORKSPACE, undefined);
}

// Check if the value is neither blacklisted (false) or whitelisted (true) and ask for
// permission
if (isWorkspaceShellAllowed === undefined) {
let shellString: string;
if (shellConfigValue.workspace) {
shellString = `"${shellConfigValue.workspace}"`;
}
let argsString: string;
if (shellArgsConfigValue.workspace) {
argsString = `[${shellArgsConfigValue.workspace.map(v => '"' + v + '"').join(', ')}]`;
}
// Should not be localized as it's json-like syntax referencing settings keys
let changeString: string;
if (shellConfigValue.workspace !== undefined) {
if (shellArgsConfigValue.workspace !== undefined) {
changeString = `shell: ${shellString}, shellArgs: ${argsString}`;
} else {
changeString = `shell: ${shellString}`;
}
} else { // if (shellArgsConfigValue.workspace !== undefined)
changeString = `shellArgs: ${argsString}`;
}
const message = nls.localize('terminal.integrated.allowWorkspaceShell', "This workspace wants to customize the terminal shell, do you want to allow it? ({0})", changeString);
const options = [nls.localize('allow', "Allow"), nls.localize('cancel', "Cancel"), nls.localize('disallow', "Disallow")];
this._choiceService.choose(Severity.Info, message, options).then(choice => {
switch (choice) {
case 0:
this._storageService.store(IS_WORKSPACE_SHELL_ALLOWED_STORAGE_KEY, true, StorageScope.WORKSPACE);
case 1:
return TPromise.as(null);
case 2:
this._storageService.store(IS_WORKSPACE_SHELL_ALLOWED_STORAGE_KEY, false, StorageScope.WORKSPACE);
default:
return TPromise.as(null);
}
});
}

shell.executable = (isWorkspaceShellAllowed ? shellConfigValue.value : shellConfigValue.user) || shellConfigValue.default;
shell.args = (isWorkspaceShellAllowed ? shellArgsConfigValue.value : shellArgsConfigValue.user) || shellArgsConfigValue.default;
}

private _toInteger(source: any, minimum?: number): number {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { IConfigurationService, getConfigurationValue } from 'vs/platform/config
import { Platform } from 'vs/base/common/platform';
import { TPromise } from 'vs/base/common/winjs.base';
import { TerminalConfigHelper } from 'vs/workbench/parts/terminal/electron-browser/terminalConfigHelper';
import { IShellLaunchConfig } from 'vs/workbench/parts/terminal/common/terminal';
import { DefaultConfig } from 'vs/editor/common/config/defaultConfig';


Expand Down Expand Up @@ -45,7 +44,7 @@ suite('Workbench - TerminalConfigHelper', () => {
}
}
});
configHelper = new TerminalConfigHelper(Platform.Linux, configurationService);
configHelper = new TerminalConfigHelper(Platform.Linux, configurationService, null, null, null);
configHelper.panelContainer = fixture;
assert.equal(configHelper.getFont().fontFamily, 'bar', 'terminal.integrated.fontFamily should be selected over editor.fontFamily');

Expand All @@ -59,7 +58,7 @@ suite('Workbench - TerminalConfigHelper', () => {
}
}
});
configHelper = new TerminalConfigHelper(Platform.Linux, configurationService);
configHelper = new TerminalConfigHelper(Platform.Linux, configurationService, null, null, null);
configHelper.panelContainer = fixture;
assert.equal(configHelper.getFont().fontFamily, 'foo', 'editor.fontFamily should be the fallback when terminal.integrated.fontFamily not set');
});
Expand All @@ -80,7 +79,7 @@ suite('Workbench - TerminalConfigHelper', () => {
}
}
});
configHelper = new TerminalConfigHelper(Platform.Linux, configurationService);
configHelper = new TerminalConfigHelper(Platform.Linux, configurationService, null, null, null);
configHelper.panelContainer = fixture;
assert.equal(configHelper.getFont().fontSize, '2px', 'terminal.integrated.fontSize should be selected over editor.fontSize');

Expand All @@ -96,7 +95,7 @@ suite('Workbench - TerminalConfigHelper', () => {
}
}
});
configHelper = new TerminalConfigHelper(Platform.Linux, configurationService);
configHelper = new TerminalConfigHelper(Platform.Linux, configurationService, null, null, null);
configHelper.panelContainer = fixture;
assert.equal(configHelper.getFont().fontSize, `${DefaultConfig.editor.fontSize}px`, 'The default editor font size should be used when editor.fontSize is 0 and terminal.integrated.fontSize not set');

Expand All @@ -112,7 +111,7 @@ suite('Workbench - TerminalConfigHelper', () => {
}
}
});
configHelper = new TerminalConfigHelper(Platform.Linux, configurationService);
configHelper = new TerminalConfigHelper(Platform.Linux, configurationService, null, null, null);
configHelper.panelContainer = fixture;
assert.equal(configHelper.getFont().fontSize, `${DefaultConfig.editor.fontSize}px`, 'The default editor font size should be used when editor.fontSize is < 0 and terminal.integrated.fontSize not set');
});
Expand All @@ -133,7 +132,7 @@ suite('Workbench - TerminalConfigHelper', () => {
}
}
});
configHelper = new TerminalConfigHelper(Platform.Linux, configurationService);
configHelper = new TerminalConfigHelper(Platform.Linux, configurationService, null, null, null);
configHelper.panelContainer = fixture;
assert.equal(configHelper.getFont().lineHeight, 2, 'terminal.integrated.lineHeight should be selected over editor.lineHeight');

Expand All @@ -149,70 +148,8 @@ suite('Workbench - TerminalConfigHelper', () => {
}
}
});
configHelper = new TerminalConfigHelper(Platform.Linux, configurationService);
configHelper = new TerminalConfigHelper(Platform.Linux, configurationService, null, null, null);
configHelper.panelContainer = fixture;
assert.equal(configHelper.getFont().lineHeight, 1.2, 'editor.lineHeight should be 1.2 when terminal.integrated.lineHeight not set');
});

test('TerminalConfigHelper - getShell', function () {
let configurationService: IConfigurationService;
let configHelper: TerminalConfigHelper;
let shellConfig: IShellLaunchConfig;

configurationService = new MockConfigurationService({
terminal: {
integrated: {
shell: {
linux: 'foo'
},
shellArgs: {
linux: []
}
}
}
});
configHelper = new TerminalConfigHelper(Platform.Linux, configurationService);
configHelper.panelContainer = fixture;
shellConfig = { executable: null, args: [] };
configHelper.mergeDefaultShellPathAndArgs(shellConfig);
assert.equal(shellConfig.executable, 'foo', 'terminal.integrated.shell.linux should be selected on Linux');

configurationService = new MockConfigurationService({
terminal: {
integrated: {
shell: {
osx: 'foo'
},
shellArgs: {
osx: []
}
}
}
});
configHelper = new TerminalConfigHelper(Platform.Mac, configurationService);
configHelper.panelContainer = fixture;
shellConfig = { executable: null, args: [] };
configHelper.mergeDefaultShellPathAndArgs(shellConfig);
assert.equal(shellConfig.executable, 'foo', 'terminal.integrated.shell.osx should be selected on OS X');

configurationService = new MockConfigurationService({
terminal: {
integrated: {
shell: {
windows: 'foo'
},
shellArgs: {
windows: []
}
}
}
});
configHelper = new TerminalConfigHelper(Platform.Windows, configurationService);
configHelper.panelContainer = fixture;
shellConfig = { executable: null, args: [] };
configHelper.mergeDefaultShellPathAndArgs(shellConfig);
assert.equal(shellConfig.executable, 'foo', 'terminal.integrated.shell.windows should be selected on Windows');
});


});

0 comments on commit 521a1f9

Please sign in to comment.