diff --git a/OSSREADME.json b/OSSREADME.json
index 5fe88517ee4..1c3d9cb2135 100644
--- a/OSSREADME.json
+++ b/OSSREADME.json
@@ -38,7 +38,7 @@
},
{
"name": "chromium",
- "version": "49.0.2623.75",
+ "version": "52.0.2743.82",
"repositoryURL": "http://www.chromium.org/Home",
"licenseDetail": [
"BSD License",
@@ -74,20 +74,20 @@
},
{
"name": "libchromiumcontent",
- "version": "49.0.2623.75",
+ "version": "52.0.2743.82",
"license": "MIT",
"repositoryURL": "https://github.com/electron/libchromiumcontent",
"isProd": true
},
{
"name": "nodejs",
- "version": "5.10.0",
+ "version": "6.3.0",
"repositoryURL": "https://github.com/nodejs/node",
"isProd": true
},
{
"name": "electron",
- "version": "0.37.6",
+ "version": "1.3.5",
"license": "MIT",
"repositoryURL": "https://github.com/electron/electron",
"isProd": true
diff --git a/appveyor.yml b/appveyor.yml
index 67d80cae24f..3632e51d974 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,5 +1,5 @@
environment:
- ATOM_SHELL_INTERNAL_RUN_AS_NODE: 1
+ ELECTRON_RUN_AS_NODE: 1
VSCODE_BUILD_VERBOSE: true
install:
diff --git a/build/gulpfile.vscode.js b/build/gulpfile.vscode.js
index 8df4cf8257b..1b6fda4d1de 100644
--- a/build/gulpfile.vscode.js
+++ b/build/gulpfile.vscode.js
@@ -230,6 +230,7 @@ function packageTask(platform, arch, opts) {
if (platform === 'win32') {
result = es.merge(result, gulp.src('resources/win32/bin/code.js', { base: 'resources/win32' }));
+ result = es.merge(result, gulp.src('resources/win32/bin/cat.exe', { base: 'resources/win32' }));
result = es.merge(result, gulp.src('resources/win32/bin/code.cmd', { base: 'resources/win32' })
.pipe(replace('@@NAME@@', product.nameShort))
diff --git a/build/lib/watch/index.js b/build/lib/watch/index.js
index 6c141221047..17cd6ab6646 100644
--- a/build/lib/watch/index.js
+++ b/build/lib/watch/index.js
@@ -3,11 +3,11 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
-var es = require('event-stream');
+const es = require('event-stream');
/** Ugly hack for gulp-tsb */
function handleDeletions() {
- return es.mapSync(function (f) {
+ return es.mapSync(f => {
if (/\.ts$/.test(f.relative) && !f.contents) {
f.contents = new Buffer('');
f.stat = { mtime: new Date() };
@@ -17,7 +17,9 @@ function handleDeletions() {
});
}
-var watch = process.platform === 'win32' ? require('./watch-win32') : require('gulp-watch');
+const watch = process.platform === 'win32'
+ ? require('./watch-win32')
+ : require('gulp-watch');
module.exports = function () {
return watch.apply(null, arguments)
diff --git a/build/lib/watch/package.json b/build/lib/watch/package.json
index 47bf00b77f1..0d031340153 100644
--- a/build/lib/watch/package.json
+++ b/build/lib/watch/package.json
@@ -1,10 +1,10 @@
{
- "name": "watch",
- "version": "1.0.0",
- "description": "",
- "author": "Microsoft ",
- "private": true,
- "devDependencies": {
- "gulp-watch": "^4.3.5"
- }
+ "name": "watch",
+ "version": "1.0.0",
+ "description": "",
+ "author": "Microsoft ",
+ "private": true,
+ "devDependencies": {
+ "gulp-watch": "^4.3.9"
+ }
}
diff --git a/build/npm/preinstall.js b/build/npm/preinstall.js
index 124013231d7..6a65998d3f6 100644
--- a/build/npm/preinstall.js
+++ b/build/npm/preinstall.js
@@ -3,11 +3,32 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
-var win = "Please run '.\\scripts\\npm.bat install' instead.";
-var nix = "Please run './scripts/npm.sh install' instead.";
+const path = require('path');
+const cp = require('child_process');
if (process.env['npm_config_disturl'] !== 'https://atom.io/download/atom-shell') {
console.error("You can't use plain npm to install Code's dependencies.");
- console.error(/^win/.test(process.platform) ? win : nix);
+ console.error(
+ /^win/.test(process.platform)
+ ? "Please run '.\\scripts\\npm.bat install' instead."
+ : "Please run './scripts/npm.sh install' instead."
+ );
+
process.exit(1);
}
+
+// make sure we install gulp watch for the system installed
+// node, since that is the driver of gulp
+if (process.platform !== 'win32') {
+ const env = Object.assign({}, process.env);
+
+ delete env['npm_config_disturl'];
+ delete env['npm_config_target'];
+ delete env['npm_config_runtime'];
+
+ cp.spawnSync('npm', ['install'], {
+ cwd: path.join(path.dirname(__dirname), 'lib', 'watch'),
+ stdio: 'inherit',
+ env
+ });
+}
\ No newline at end of file
diff --git a/extensions/node-debug/node-debug.azure.json b/extensions/node-debug/node-debug.azure.json
index 336a0c85e76..2a2679bd2eb 100644
--- a/extensions/node-debug/node-debug.azure.json
+++ b/extensions/node-debug/node-debug.azure.json
@@ -1,6 +1,6 @@
{
"account": "monacobuild",
"container": "debuggers",
- "zip": "d643199/node-debug.zip",
+ "zip": "9263600/node-debug.zip",
"output": ""
}
diff --git a/extensions/typescript/src/utils/electron.ts b/extensions/typescript/src/utils/electron.ts
index a4e08453f9f..c0bda301689 100644
--- a/extensions/typescript/src/utils/electron.ts
+++ b/extensions/typescript/src/utils/electron.ts
@@ -48,7 +48,7 @@ function generatePatchedEnv(env:any, stdInPipeName:string, stdOutPipeName:string
newEnv['STDIN_PIPE_NAME'] = stdInPipeName;
newEnv['STDOUT_PIPE_NAME'] = stdOutPipeName;
newEnv['STDERR_PIPE_NAME'] = stdErrPipeName;
- newEnv['ATOM_SHELL_INTERNAL_RUN_AS_NODE'] = '1';
+ newEnv['ELECTRON_RUN_AS_NODE'] = '1';
return newEnv;
}
diff --git a/extensions/typescript/src/utils/electronForkStart.ts b/extensions/typescript/src/utils/electronForkStart.ts
index 46a12506041..83f75724002 100644
--- a/extensions/typescript/src/utils/electronForkStart.ts
+++ b/extensions/typescript/src/utils/electronForkStart.ts
@@ -31,7 +31,7 @@ var stdErrPipeName = process.env['STDERR_PIPE_NAME'];
log('STDIN_PIPE_NAME: ' + stdInPipeName);
log('STDOUT_PIPE_NAME: ' + stdOutPipeName);
log('STDERR_PIPE_NAME: ' + stdErrPipeName);
-log('ATOM_SHELL_INTERNAL_RUN_AS_NODE: ' + process.env['ATOM_SHELL_INTERNAL_RUN_AS_NODE']);
+log('ELECTRON_RUN_AS_NODE: ' + process.env['ELECTRON_RUN_AS_NODE']);
// stdout redirection to named pipe
(function() {
@@ -147,7 +147,7 @@ log('ATOM_SHELL_INTERNAL_RUN_AS_NODE: ' + process.env['ATOM_SHELL_INTERNAL_RUN_A
delete process.env['STDIN_PIPE_NAME'];
delete process.env['STDOUT_PIPE_NAME'];
delete process.env['STDERR_PIPE_NAME'];
- delete process.env['ATOM_SHELL_INTERNAL_RUN_AS_NODE'];
+ delete process.env['ELECTRON_RUN_AS_NODE'];
require(program);
diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json
index 4266bd833e9..743ef15228f 100644
--- a/npm-shrinkwrap.json
+++ b/npm-shrinkwrap.json
@@ -414,7 +414,7 @@
"from": "vscode-textmate@2.1.1",
"resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-2.1.1.tgz"
},
- "windows-mutex": {
+ "windows-mutex": {
"version": "0.2.0",
"from": "windows-mutex@>=0.2.0 <0.3.0",
"resolved": "https://registry.npmjs.org/windows-mutex/-/windows-mutex-0.2.0.tgz"
diff --git a/package.json b/package.json
index 224945b0df9..ea947787c97 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "code-oss-dev",
"version": "1.6.0",
- "electronVersion": "0.37.6",
+ "electronVersion": "1.3.5",
"distro": "3d44b35db8d394d6d7b2bc224675735a0a8f2704",
"author": {
"name": "Microsoft Corporation"
@@ -69,7 +69,6 @@
"gulp-uglify": "^1.4.1",
"gulp-util": "^3.0.6",
"gulp-vinyl-zip": "^1.2.2",
- "gulp-watch": "4.3.6",
"innosetup-compiler": "^5.5.60",
"is": "^3.1.0",
"istanbul": "^0.3.17",
diff --git a/resources/darwin/bin/code.sh b/resources/darwin/bin/code.sh
index ac498810000..9dba3f8e378 100755
--- a/resources/darwin/bin/code.sh
+++ b/resources/darwin/bin/code.sh
@@ -7,5 +7,5 @@ function realpath() { /usr/bin/python -c "import os,sys; print os.path.realpath(
CONTENTS="$(dirname "$(dirname "$(dirname "$(dirname "$(realpath "$0")")")")")"
ELECTRON="$CONTENTS/MacOS/Electron"
CLI="$CONTENTS/Resources/app/out/cli.js"
-ATOM_SHELL_INTERNAL_RUN_AS_NODE=1 "$ELECTRON" "$CLI" "$@"
+ELECTRON_RUN_AS_NODE=1 "$ELECTRON" "$CLI" "$@"
exit $?
\ No newline at end of file
diff --git a/resources/linux/bin/code.sh b/resources/linux/bin/code.sh
index 77fa49722f7..f0877aa4c9f 100755
--- a/resources/linux/bin/code.sh
+++ b/resources/linux/bin/code.sh
@@ -33,5 +33,5 @@ fi
ELECTRON="$VSCODE_PATH/@@NAME@@"
CLI="$VSCODE_PATH/resources/app/out/cli.js"
-ATOM_SHELL_INTERNAL_RUN_AS_NODE=1 "$ELECTRON" "$CLI" "$@"
+ELECTRON_RUN_AS_NODE=1 "$ELECTRON" "$CLI" "$@"
exit $?
\ No newline at end of file
diff --git a/resources/win32/bin/cat.exe b/resources/win32/bin/cat.exe
new file mode 100644
index 00000000000..f564baa192a
Binary files /dev/null and b/resources/win32/bin/cat.exe differ
diff --git a/resources/win32/bin/code.cmd b/resources/win32/bin/code.cmd
index a975610eb31..2564a3234ba 100644
--- a/resources/win32/bin/code.cmd
+++ b/resources/win32/bin/code.cmd
@@ -1,6 +1,6 @@
@echo off
setlocal
set VSCODE_DEV=
-set ATOM_SHELL_INTERNAL_RUN_AS_NODE=1
-call "%~dp0..\@@NAME@@.exe" "%~dp0..\resources\\app\\out\\cli.js" %*
+set ELECTRON_RUN_AS_NODE=1
+call "%~dp0..\@@NAME@@.exe" "%~dp0..\resources\\app\\out\\cli.js" %* | cat
endlocal
\ No newline at end of file
diff --git a/resources/win32/bin/code.sh b/resources/win32/bin/code.sh
index 83f7bfea10c..49636eec1e2 100644
--- a/resources/win32/bin/code.sh
+++ b/resources/win32/bin/code.sh
@@ -11,5 +11,5 @@ if [ "$(expr substr $(uname -s) 1 9)" == "CYGWIN_NT" ]; then
else
CLI="$VSCODE_PATH/resources/app/out/cli.js"
fi
-ELECTRON_NO_ATTACH_CONSOLE=1 ATOM_SHELL_INTERNAL_RUN_AS_NODE=1 "$ELECTRON" "$CLI" "$@"
+ELECTRON_RUN_AS_NODE=1 "$ELECTRON" "$CLI" "$@" | cat
exit $?
diff --git a/scripts/code-cli.sh b/scripts/code-cli.sh
index 5823276e47f..9a4c03e31d4 100755
--- a/scripts/code-cli.sh
+++ b/scripts/code-cli.sh
@@ -30,7 +30,7 @@ function code() {
CLI="$ROOT/out/cli.js"
- ATOM_SHELL_INTERNAL_RUN_AS_NODE=1 \
+ ELECTRON_RUN_AS_NODE=1 \
NODE_ENV=development \
VSCODE_DEV=1 \
ELECTRON_ENABLE_LOGGING=1 \
diff --git a/scripts/test-integration.bat b/scripts/test-integration.bat
index 87dec89d1a1..16a617b5e11 100644
--- a/scripts/test-integration.bat
+++ b/scripts/test-integration.bat
@@ -1,10 +1,8 @@
@echo off
setlocal
-rem APPVEYOR Builds
if not "%APPVEYOR%" == "" (
- set ELECTRON_NO_ATTACH_CONSOLE=1
- set ATOM_SHELL_INTERNAL_RUN_AS_NODE=
+ set ELECTRON_RUN_AS_NODE=
)
:: Integration Tests
diff --git a/scripts/test.bat b/scripts/test.bat
index e55af32e6c0..bd7a7fe82cb 100644
--- a/scripts/test.bat
+++ b/scripts/test.bat
@@ -1,17 +1,7 @@
@echo off
setlocal
-set ATOM_SHELL_INTERNAL_RUN_AS_NODE=1
-
-rem TFS Builds
-if not "%BUILD_BUILDID%" == "" (
- set ELECTRON_NO_ATTACH_CONSOLE=1
-)
-
-rem APPVEYOR Builds
-if not "%APPVEYOR%" == "" (
- set ELECTRON_NO_ATTACH_CONSOLE=1
-)
+set ELECTRON_RUN_AS_NODE=1
pushd %~dp0\..
@@ -20,7 +10,15 @@ set NAMESHORT=%NAMESHORT: "=%
set NAMESHORT=%NAMESHORT:"=%.exe
set CODE=".build\electron\%NAMESHORT%"
-%CODE% .\node_modules\mocha\bin\_mocha %*
+rem TFS Builds
+if not "%BUILD_BUILDID%" == "" (
+ %CODE% .\node_modules\mocha\bin\_mocha %*
+)
+
+rem Otherwise
+if "%BUILD_BUILDID%" == "" (
+ %CODE% .\node_modules\mocha\bin\_mocha %* | .\resources\win32\bin\cat
+)
popd
endlocal
diff --git a/scripts/test.sh b/scripts/test.sh
index 5b6a7d2e39d..59bd5615b52 100755
--- a/scripts/test.sh
+++ b/scripts/test.sh
@@ -30,11 +30,11 @@ test -d out || ./node_modules/.bin/gulp compile
# Unit Tests
export VSCODE_DEV=1
if [[ "$OSTYPE" == "darwin"* ]]; then
- cd $ROOT ; ulimit -n 4096 ; ATOM_SHELL_INTERNAL_RUN_AS_NODE=1 \
+ cd $ROOT ; ulimit -n 4096 ; ELECTRON_RUN_AS_NODE=1 \
"$CODE" \
node_modules/mocha/bin/_mocha "$@"
else
- cd $ROOT ; ATOM_SHELL_INTERNAL_RUN_AS_NODE=1 \
+ cd $ROOT ; ELECTRON_RUN_AS_NODE=1 \
"$CODE" \
node_modules/mocha/bin/_mocha "$@"
fi
diff --git a/src/typings/electron.d.ts b/src/typings/electron.d.ts
index 938d88df290..cf4ce357304 100644
--- a/src/typings/electron.d.ts
+++ b/src/typings/electron.d.ts
@@ -1,4 +1,4 @@
-// Type definitions for Electron v1.2.5
+// Type definitions for Electron v1.3.4
// Project: http://electron.atom.io/
// Definitions by: jedmao , rhysd , Milan Burda
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
@@ -25,6 +25,23 @@ declare namespace Electron {
sender: EventEmitter;
}
+ type Point = {
+ x: number;
+ y: number;
+ }
+
+ type Size = {
+ width: number;
+ height: number;
+ }
+
+ type Rectangle = {
+ x: number;
+ y: number;
+ width: number;
+ height: number;
+ }
+
// https://github.com/electron/electron/blob/master/docs/api/app.md
/**
@@ -160,6 +177,12 @@ declare namespace Electron {
* Emitted when the gpu process crashes.
*/
on(event: 'gpu-process-crashed', listener: Function): this;
+ /**
+ * Emitted when Chrome's accessibility support changes.
+ *
+ * Note: This API is only available on macOS and Windows.
+ */
+ on(event: 'accessibility-support-changed', listener: (event: Event, accessibilitySupportEnabled: boolean) => void): this;
on(event: string, listener: Function): this;
/**
* Try to close all windows. The before-quit event will first be emitted.
@@ -273,28 +296,43 @@ declare namespace Electron {
* Once registered, all links with your-protocol:// will be opened with the current executable.
* The whole link, including protocol, will be passed to your application as a parameter.
*
+ * On Windows you can provide optional parameters path, the path to your executable,
+ * and args, an array of arguments to be passed to your executable when it launches.
+ *
+ * @param protocol The name of your protocol, without ://.
+ * @param path Defaults to process.execPath.
+ * @param args Defaults to an empty array.
+ *
* Note: This is only implemented on macOS and Windows.
* On macOS, you can only register protocols that have been added to your app's info.plist.
*/
- setAsDefaultProtocolClient(protocol: string): void;
+ setAsDefaultProtocolClient(protocol: string, path?: string, args?: string[]): boolean;
/**
* Removes the current executable as the default handler for a protocol (aka URI scheme).
*
+ * @param protocol The name of your protocol, without ://.
+ * @param path Defaults to process.execPath.
+ * @param args Defaults to an empty array.
+ *
* Note: This is only implemented on macOS and Windows.
*/
- removeAsDefaultProtocolClient(protocol: string): void;
+ removeAsDefaultProtocolClient(protocol: string, path?: string, args?: string[]): boolean;
/**
+ * @param protocol The name of your protocol, without ://.
+ * @param path Defaults to process.execPath.
+ * @param args Defaults to an empty array.
+ *
* @returns Whether the current executable is the default handler for a protocol (aka URI scheme).
*
* Note: This is only implemented on macOS and Windows.
*/
- isDefaultProtocolClient(protocol: string): boolean;
+ isDefaultProtocolClient(protocol: string, path?: string, args?: string[]): boolean;
/**
* Adds tasks to the Tasks category of JumpList on Windows.
*
* Note: This API is only available on Windows.
*/
- setUserTasks(tasks: Task[]): void;
+ setUserTasks(tasks: Task[]): boolean;
/**
* This method makes your application a Single Instance Application instead of allowing
* multiple instances of your app to run, this will ensure that only a single instance
@@ -326,6 +364,8 @@ declare namespace Electron {
getCurrentActivityType(): string;
/**
* Changes the Application User Model ID to id.
+ *
+ * Note: This is only implemented on Windows.
*/
setAppUserModelId(id: string): void;
/**
@@ -341,6 +381,33 @@ declare namespace Electron {
* This method can only be called before app is ready.
*/
disableHardwareAcceleration(): void;
+ /**
+ * @returns whether current desktop environment is Unity launcher. (Linux)
+ *
+ * Note: This API is only available on Linux.
+ */
+ isUnityRunning(): boolean;
+ /**
+ * Returns a Boolean, true if Chrome's accessibility support is enabled, false otherwise.
+ * This API will return true if the use of assistive technologies, such as screen readers,
+ * has been detected.
+ * See https://www.chromium.org/developers/design-documents/accessibility for more details.
+ *
+ * Note: This API is only available on macOS and Windows.
+ */
+ isAccessibilitySupportEnabled(): boolean;
+ /**
+ * @returns an Object with the login item settings of the app.
+ *
+ * Note: This API is only available on macOS and Windows.
+ */
+ getLoginItemSettings(): LoginItemSettings;
+ /**
+ * Set the app's login item settings.
+ *
+ * Note: This API is only available on macOS and Windows.
+ */
+ setLoginItemSettings(settings: LoginItemSettings): void;
commandLine: CommandLine;
/**
* Note: This API is only available on macOS.
@@ -348,7 +415,7 @@ declare namespace Electron {
dock: Dock;
}
- type AppPathName = 'home' | 'appData' | 'userData' | 'temp' | 'exe' | 'module' | 'desktop' | 'documents' | 'downloads' | 'music' | 'pictures' | 'videos' | 'pepperFlashSystemPlugin';
+ type AppPathName = 'home'|'appData'|'userData'|'temp'|'exe'|'module'|'desktop'|'documents'|'downloads'|'music'|'pictures'|'videos'|'pepperFlashSystemPlugin';
interface ImportCertificateOptions {
/**
@@ -368,7 +435,7 @@ declare namespace Electron {
* Note: This will not affect process.argv, and is mainly used by developers
* to control some low-level Chromium behaviors.
*/
- appendSwitch(_switch: string, value?: string | number): void;
+ appendSwitch(_switch: string, value?: string): void;
/**
* Append an argument to Chromium's command line. The argument will quoted properly.
*
@@ -414,6 +481,20 @@ declare namespace Electron {
* Note: This API is only available on macOS.
*/
getBadge(): string;
+ /**
+ * Sets the counter badge for current app. Setting the count to 0 will hide the badge.
+ *
+ * @returns True when the call succeeded, otherwise returns false.
+ *
+ * Note: This API is only available on macOS and Linux.
+ */
+ setBadgeCount(count: number): boolean;
+ /**
+ * @returns The current value displayed in the counter badge.
+ *
+ * Note: This API is only available on macOS and Linux.
+ */
+ getBadgeCount(): number;
/**
* Hides the dock icon.
*
@@ -426,6 +507,13 @@ declare namespace Electron {
* Note: This API is only available on macOS.
*/
show(): void;
+ /**
+ * @returns Whether the dock icon is visible.
+ * The app.dock.show() call is asynchronous so this method might not return true immediately after that call.
+ *
+ * Note: This API is only available on macOS.
+ */
+ isVisible(): boolean;
/**
* Sets the application dock menu.
*
@@ -472,6 +560,32 @@ declare namespace Electron {
iconIndex?: number;
}
+ interface LoginItemSettings {
+ /**
+ * True if the app is set to open at login.
+ */
+ openAtLogin: boolean;
+ /**
+ * True if the app is set to open as hidden at login. This setting is only supported on macOS.
+ */
+ openAsHidden: boolean;
+ /**
+ * True if the app was opened at login automatically. This setting is only supported on macOS.
+ */
+ wasOpenedAtLogin?: boolean;
+ /**
+ * True if the app was opened as a hidden login item. This indicates that the app should not
+ * open any windows at startup. This setting is only supported on macOS.
+ */
+ wasOpenedAsHidden?: boolean;
+ /**
+ * True if the app was opened as a login item that should restore the state from the previous session.
+ * This indicates that the app should restore the windows that were open the last time the app was closed.
+ * This setting is only supported on macOS.
+ */
+ restoreState?: boolean;
+ }
+
// https://github.com/electron/electron/blob/master/docs/api/auto-updater.md
/**
@@ -504,6 +618,10 @@ declare namespace Electron {
* Set the url and initialize the auto updater.
*/
setFeedURL(url: string, requestHeaders?: Headers): void;
+ /**
+ * @returns The current update feed URL.
+ */
+ getFeedURL(): string;
/**
* Ask the server whether there is an update, you have to call setFeedURL
* before using this API
@@ -527,7 +645,7 @@ declare namespace Electron {
* Emitted when the document changed its title,
* calling event.preventDefault() would prevent the native window’s title to change.
*/
- on(event: 'page-title-updated', listener: (event: Event) => void): this;
+ on(event: 'page-title-updated', listener: (event: Event, title: string) => void): this;
/**
* Emitted when the window is going to be closed. It’s emitted before the beforeunload
* and unload event of the DOM. Calling event.preventDefault() will cancel the close.
@@ -629,6 +747,9 @@ declare namespace Electron {
*/
on(event: 'swipe', listener: (event: Event, direction: SwipeDirection) => void): this;
on(event: string, listener: Function): this;
+ /**
+ * Creates a new BrowserWindow with native properties as set by the options.
+ */
constructor(options?: BrowserWindowOptions);
/**
* @returns All opened browser windows.
@@ -703,6 +824,10 @@ declare namespace Electron {
* @returns Whether the window is focused.
*/
isFocused(): boolean;
+ /**
+ * @returns Whether the window is destroyed.
+ */
+ isDestroyed(): boolean;
/**
* Shows and gives focus to the window.
*/
@@ -764,7 +889,7 @@ declare namespace Electron {
*
* Note: This API is available only on macOS.
*/
- setAspectRatio(aspectRatio: number, extraSize?: Dimension): void;
+ setAspectRatio(aspectRatio: number, extraSize?: Size): void;
/**
* Resizes and moves the window to width, height, x, y.
*/
@@ -773,6 +898,14 @@ declare namespace Electron {
* @returns The window's width, height, x and y values.
*/
getBounds(): Rectangle;
+ /**
+ * Resizes and moves the window's client area (e.g. the web page) to width, height, x, y.
+ */
+ setContentBounds(options: Rectangle, animate?: boolean): void;
+ /**
+ * @returns The window's client area (e.g. the web page) width, height, x and y values.
+ */
+ getContentBounds(): Rectangle;
/**
* Resizes the window to width and height.
*/
@@ -968,6 +1101,13 @@ declare namespace Electron {
* @param callback Supplies the image that stores data of the snapshot.
*/
capturePage(rect: Rectangle, callback: (image: NativeImage) => void): void;
+ /**
+ * Captures the snapshot of page within rect, upon completion the callback
+ * will be called. Omitting the rect would capture the whole visible page.
+ * Note: Be sure to read documents on remote buffer in remote if you are going
+ * to use this API in renderer process.
+ * @param callback Supplies the image that stores data of the snapshot.
+ */
capturePage(callback: (image: NativeImage) => void): void;
/**
* Same as webContents.loadURL(url).
@@ -990,7 +1130,13 @@ declare namespace Electron {
* @param progress Valid range is [0, 1.0]. If < 0, the progress bar is removed.
* If greater than 0, it becomes indeterminate.
*/
- setProgressBar(progress: number): void;
+ setProgressBar(progress: number, options?: {
+ /**
+ * Mode for the progress bar.
+ * Note: This is only implemented on Windows.
+ */
+ mode: 'none' | 'normal' | 'indeterminate' | 'error' | 'paused'
+ }): void;
/**
* Sets a 16px overlay onto the current Taskbar icon, usually used to convey
* some sort of application status or to passively notify the user.
@@ -1014,8 +1160,23 @@ declare namespace Electron {
* Add a thumbnail toolbar with a specified set of buttons to the thumbnail image
* of a window in a taskbar button layout.
* @returns Whether the thumbnail has been added successfully.
+ *
+ * Note: This API is available only on Windows.
*/
setThumbarButtons(buttons: ThumbarButton[]): boolean;
+ /**
+ * Sets the region of the window to show as the thumbnail image displayed when hovering
+ * over the window in the taskbar. You can reset the thumbnail to be the entire window
+ * by specifying an empty region: {x: 0, y: 0, width: 0, height: 0}.
+ *
+ * Note: This API is available only on Windows.
+ */
+ setThumbnailClip(region: Rectangle): boolean;
+ /**
+ * Sets the toolTip that is displayed when hovering over the window thumbnail in the taskbar.
+ * Note: This API is available only on Windows.
+ */
+ setThumbnailToolTip(toolTip: string): boolean;
/**
* Same as webContents.showDefinitionForSelection().
* Note: This API is available only on macOS.
@@ -1258,12 +1419,17 @@ declare namespace Electron {
defaultEncoding?: string;
/**
* Whether to throttle animations and timers when the page becomes background.
- * Default: true
+ * Default: true.
*/
backgroundThrottling?: boolean;
+ /**
+ * Whether to enable offscreen rendering for the browser window.
+ * Default: false.
+ */
+ offscreen?: boolean;
}
- interface BrowserWindowOptions extends Rectangle {
+ interface BrowserWindowOptions {
/**
* Window’s width in pixels.
* Default: 800.
@@ -1387,7 +1553,7 @@ declare namespace Electron {
/**
* The window icon, when omitted on Windows the executable’s icon would be used as window icon.
*/
- icon?: NativeImage | string;
+ icon?: NativeImage|string;
/**
* Whether window should be shown when created.
* Default: true.
@@ -1458,22 +1624,20 @@ declare namespace Electron {
* The style of window title bar.
*/
titleBarStyle?: 'default' | 'hidden' | 'hidden-inset';
+ /**
+ * Use WS_THICKFRAME style for frameless windows on Windows
+ */
+ thickFrame?: boolean;
/**
* Settings of web page’s features.
*/
webPreferences?: WebPreferences;
}
- type BrowserWindowType = BrowserWindowTypeLinux | BrowserWindowTypeMac;
+ type BrowserWindowType = BrowserWindowTypeLinux | BrowserWindowTypeMac | BrowserWindowTypeWindows;
type BrowserWindowTypeLinux = 'desktop' | 'dock' | 'toolbar' | 'splash' | 'notification';
type BrowserWindowTypeMac = 'desktop' | 'textured';
-
- interface Rectangle {
- x?: number;
- y?: number;
- width?: number;
- height?: number;
- }
+ type BrowserWindowTypeWindows = 'toolbar';
// https://github.com/electron/electron/blob/master/docs/api/clipboard.md
@@ -1541,10 +1705,27 @@ declare namespace Electron {
html?: string;
image?: NativeImage;
}, type?: ClipboardType): void;
+ /**
+ * @returns An Object containing title and url keys representing the bookmark in the clipboard.
+ *
+ * Note: This API is available on macOS and Windows.
+ */
+ readBookmark(): Bookmark;
+ /**
+ * Writes the title and url into the clipboard as a bookmark.
+ *
+ * Note: This API is available on macOS and Windows.
+ */
+ writeBookmark(title: string, url: string, type?: ClipboardType): void;
}
type ClipboardType = '' | 'selection';
+ interface Bookmark {
+ title: string;
+ url: string;
+ }
+
// https://github.com/electron/electron/blob/master/docs/api/content-tracing.md
/**
@@ -1701,7 +1882,7 @@ declare namespace Electron {
* An object you can define that will be sent along with the report.
* Only string properties are sent correctly, nested objects are not supported.
*/
- extra?: { [prop: string]: string };
+ extra?: {[prop: string]: string};
}
interface CrashReport {
@@ -1734,7 +1915,7 @@ declare namespace Electron {
* The suggested size that thumbnail should be scaled.
* Default: {width: 150, height: 150}
*/
- thumbnailSize?: Dimension;
+ thumbnailSize?: Size;
}
interface DesktopCapturerSource {
@@ -1836,7 +2017,7 @@ declare namespace Electron {
/**
* Contains which features the dialog should use.
*/
- properties?: ('openFile' | 'openDirectory' | 'multiSelections' | 'createDirectory')[];
+ properties?: ('openFile' | 'openDirectory' | 'multiSelections' | 'createDirectory' | 'showHiddenFiles')[];
}
interface SaveDialogOptions {
@@ -1920,6 +2101,11 @@ declare namespace Electron {
* routine to determine the save path (Usually prompts a save dialog).
*/
setSavePath(path: string): void;
+ /**
+ * @returns The save path of the download item.
+ * This will be either the path set via downloadItem.setSavePath(path) or the path selected from the shown save dialog.
+ */
+ getSavePath(): string;
/**
* Pauses the download.
*/
@@ -2125,8 +2311,8 @@ declare namespace Electron {
}
type MenuItemType = 'normal' | 'separator' | 'submenu' | 'checkbox' | 'radio';
- type MenuItemRole = 'undo' | 'redo' | 'cut' | 'copy' | 'paste' | 'pasteandmatchstyle' | 'selectall' | 'delete' | 'minimize' | 'close' | 'quit' | 'togglefullscreen';
- type MenuItemRoleMac = 'about' | 'hide' | 'hideothers' | 'unhide' | 'front' | 'zoom' | 'window' | 'help' | 'services';
+ type MenuItemRole = 'undo' | 'redo' | 'cut' | 'copy' | 'paste' | 'pasteandmatchstyle' | 'selectall' | 'delete' | 'minimize' | 'close' | 'quit' | 'togglefullscreen' | 'resetzoom' | 'zoomin' | 'zoomout';
+ type MenuItemRoleMac = 'about' | 'hide' | 'hideothers' | 'unhide' | 'startspeaking' | 'stopspeaking' | 'front' | 'zoom' | 'window' | 'help' | 'services';
interface MenuItemOptions {
/**
@@ -2192,7 +2378,7 @@ declare namespace Electron {
* In Electron for the APIs that take images, you can pass either file paths
* or NativeImage instances. When passing null, an empty image will be used.
*/
- icon?: NativeImage | string;
+ icon?: NativeImage|string;
/**
* If false, the menu item will be greyed out and unclickable.
*/
@@ -2209,7 +2395,7 @@ declare namespace Electron {
* Should be specified for submenu type menu item, when it's specified the
* type: 'submenu' can be omitted for the menu item
*/
- submenu?: Menu | MenuItemOptions[];
+ submenu?: Menu|MenuItemOptions[];
/**
* Unique within a single menu. If defined then it can be used as a reference
* to this item by the position attribute.
@@ -2270,7 +2456,7 @@ declare namespace Electron {
* @param x Horizontal coordinate where the menu will be placed.
* @param y Vertical coordinate where the menu will be placed.
*/
- popup(browserWindow?: BrowserWindow, x?: number, y?: number, select?: number): void;
+ popup(browserWindow?: BrowserWindow, x?: number, y?: number): void;
/**
* Appends the menuItem to the menu.
*/
@@ -2309,13 +2495,25 @@ declare namespace Electron {
*/
static createFromDataURL(dataURL: string): NativeImage;
/**
- * @returns Buffer Contains the image's PNG encoded data.
+ * @returns Buffer that contains the image's PNG encoded data.
*/
toPNG(): Buffer;
/**
- * @returns Buffer Contains the image's JPEG encoded data.
+ * @returns Buffer that contains the image's JPEG encoded data.
*/
toJPEG(quality: number): Buffer;
+ /**
+ * @returns Buffer that contains a copy of the image's raw bitmap pixel data.
+ */
+ toBitmap(): Buffer;
+ /**
+ * @returns Buffer that contains the image's raw bitmap pixel data.
+ *
+ * The difference between getBitmap() and toBitmap() is, getBitmap() does not copy the bitmap data,
+ * so you have to use the returned Buffer immediately in current event loop tick,
+ * otherwise the data might be changed or destroyed.
+ */
+ getBitmap(): Buffer;
/**
* @returns string The data URL of the image.
*/
@@ -2333,7 +2531,7 @@ declare namespace Electron {
/**
* @returns {} The size of the image.
*/
- getSize(): Dimension;
+ getSize(): Size;
/**
* Marks the image as template image.
*/
@@ -2556,10 +2754,10 @@ declare namespace Electron {
* Unique identifier associated with the display.
*/
id: number;
- bounds: Bounds;
- workArea: Bounds;
- size: Dimension;
- workAreaSize: Dimension;
+ bounds: Rectangle;
+ workArea: Rectangle;
+ size: Size;
+ workAreaSize: Size;
/**
* Output device’s pixel scale factor.
*/
@@ -2571,23 +2769,6 @@ declare namespace Electron {
touchSupport: 'available' | 'unavailable' | 'unknown';
}
- type Bounds = {
- x: number;
- y: number;
- width: number;
- height: number;
- }
-
- type Dimension = {
- width: number;
- height: number;
- }
-
- type Point = {
- x: number;
- y: number;
- }
-
type DisplayMetrics = 'bounds' | 'workArea' | 'scaleFactor' | 'rotation';
/**
@@ -2627,7 +2808,7 @@ declare namespace Electron {
/**
* @returns The display that most closely intersects the provided bounds.
*/
- getDisplayMatching(rect: Bounds): Display;
+ getDisplayMatching(rect: Rectangle): Display;
}
// https://github.com/electron/electron/blob/master/docs/api/session.md
@@ -2641,7 +2822,7 @@ declare namespace Electron {
/**
* @returns a new Session instance from partition string.
*/
- static fromPartition(partition: string): Session;
+ static fromPartition(partition: string, options?: FromPartitionOptions): Session;
/**
* @returns the default session object of the app.
*/
@@ -2680,7 +2861,7 @@ declare namespace Electron {
/**
* Sets the proxy settings.
*/
- setProxy(config: string, callback: Function): void;
+ setProxy(config: ProxyConfig, callback: Function): void;
/**
* Resolves the proxy information for url.
*/
@@ -2741,6 +2922,13 @@ declare namespace Electron {
type Permission = 'media' | 'geolocation' | 'notifications' | 'midiSysex' | 'pointerLock' | 'fullscreen' | 'openExternal';
+ interface FromPartitionOptions {
+ /**
+ * Whether to enable cache.
+ */
+ cache?: boolean;
+ }
+
interface ClearStorageDataOptions {
/**
* Should follow window.location.origin’s representation scheme://host:port.
@@ -2756,21 +2944,40 @@ declare namespace Electron {
quotas?: ('temporary' | 'persistent' | 'syncable')[];
}
+ interface ProxyConfig {
+ /**
+ * The URL associated with the PAC file.
+ */
+ pacScript: string;
+ /**
+ * Rules indicating which proxies to use.
+ */
+ proxyRules: string;
+ /**
+ * Rules indicating which URLs should bypass the proxy settings.
+ */
+ proxyBypassRules: string;
+ }
+
interface NetworkEmulationOptions {
/**
* Whether to emulate network outage.
+ * Default: false.
*/
offline?: boolean;
/**
* RTT in ms.
+ * Default: 0, which will disable latency throttling.
*/
latency?: number;
/**
* Download rate in Bps.
+ * Default: 0, which will disable download throttling.
*/
downloadThroughput?: number;
/**
* Upload rate in Bps.
+ * Default: 0, which will disable upload throttling.
*/
uploadThroughput?: number;
}
@@ -3116,6 +3323,62 @@ declare namespace Electron {
* Play the beep sound.
*/
beep(): void;
+ /**
+ * Creates or updates a shortcut link at shortcutPath.
+ *
+ * Note: This API is available only on Windows.
+ */
+ writeShortcutLink(shortcutPath: string, options: ShortcutLinkOptions): boolean;
+ /**
+ * Creates or updates a shortcut link at shortcutPath.
+ *
+ * Note: This API is available only on Windows.
+ */
+ writeShortcutLink(shortcutPath: string, operation: 'create' | 'update' | 'replace', options: ShortcutLinkOptions): boolean;
+ /**
+ * Resolves the shortcut link at shortcutPath.
+ * An exception will be thrown when any error happens.
+ *
+ * Note: This API is available only on Windows.
+ */
+ readShortcutLink(shortcutPath: string): ShortcutLinkOptions;
+ }
+
+ interface ShortcutLinkOptions {
+ /**
+ * The target to launch from this shortcut.
+ */
+ target: string;
+ /**
+ * The working directory.
+ * Default: empty.
+ */
+ cwd?: string;
+ /**
+ * The arguments to be applied to target when launching from this shortcut.
+ * Default: empty.
+ */
+ args?: string;
+ /**
+ * The description of the shortcut.
+ * Default: empty.
+ */
+ description?: string;
+ /**
+ * The path to the icon, can be a DLL or EXE. icon and iconIndex have to be set together.
+ * Default: empty, which uses the target's icon.
+ */
+ icon?: string;
+ /**
+ * The resource ID of icon when icon is a DLL or EXE.
+ * Default: 0.
+ */
+ iconIndex?: number;
+ /**
+ * The Application User Model ID.
+ * Default: empty.
+ */
+ appUserModelId?: string;
}
// https://github.com/electron/electron/blob/master/docs/api/system-preferences.md
@@ -3130,6 +3393,26 @@ declare namespace Electron {
* Note: This is only implemented on macOS.
*/
isDarkMode(): boolean;
+ /**
+ * @returns If the Swipe between pages setting is on.
+ *
+ * Note: This is only implemented on macOS.
+ */
+ isSwipeTrackingFromScrollEventsEnabled(): boolean;
+ /**
+ * Posts event as native notifications of macOS.
+ * The userInfo contains the user information dictionary sent along with the notification.
+ *
+ * Note: This is only implemented on macOS.
+ */
+ postNotification(event: string, userInfo: Object): void;
+ /**
+ * Posts event as native notifications of macOS.
+ * The userInfo contains the user information dictionary sent along with the notification.
+ *
+ * Note: This is only implemented on macOS.
+ */
+ postLocalNotification(event: string, userInfo: Object): void;
/**
* Subscribes to native notifications of macOS, callback will be called when the corresponding event happens.
* The id of the subscriber is returned, which can be used to unsubscribe the event.
@@ -3177,17 +3460,17 @@ declare namespace Electron {
* Emitted when the tray icon is clicked.
* Note: The bounds payload is only implemented on macOS and Windows.
*/
- on(event: 'click', listener: (modifiers: Modifiers, bounds: Bounds) => void): this;
+ on(event: 'click', listener: (modifiers: Modifiers, bounds: Rectangle) => void): this;
/**
* Emitted when the tray icon is right clicked.
* Note: This is only implemented on macOS and Windows.
*/
- on(event: 'right-click', listener: (modifiers: Modifiers, bounds: Bounds) => void): this;
+ on(event: 'right-click', listener: (modifiers: Modifiers, bounds: Rectangle) => void): this;
/**
* Emitted when the tray icon is double clicked.
* Note: This is only implemented on macOS and Windows.
*/
- on(event: 'double-click', listener: (modifiers: Modifiers, bounds: Bounds) => void): this;
+ on(event: 'double-click', listener: (modifiers: Modifiers, bounds: Rectangle) => void): this;
/**
* Emitted when the tray balloon shows.
* Note: This is only implemented on Windows.
@@ -3213,6 +3496,11 @@ declare namespace Electron {
* Note: This is only implemented on macOS
*/
on(event: 'drop-files', listener: (event: Event, files: string[]) => void): this;
+ /**
+ * Emitted when dragged text is dropped in the tray icon.
+ * Note: This is only implemented on macOS
+ */
+ on(event: 'drop-text', listener: (event: Event, text: string) => void): this;
/**
* Emitted when a drag operation enters the tray icon.
* Note: This is only implemented on macOS
@@ -3232,7 +3520,7 @@ declare namespace Electron {
/**
* Creates a new tray icon associated with the image.
*/
- new (image: NativeImage | string): Tray;
+ new(image: NativeImage|string): Tray;
/**
* Destroys the tray icon immediately.
*/
@@ -3240,7 +3528,7 @@ declare namespace Electron {
/**
* Sets the image associated with this tray icon.
*/
- setImage(image: NativeImage | string): void;
+ setImage(image: NativeImage|string): void;
/**
* Sets the image associated with this tray icon when pressed.
*/
@@ -3255,10 +3543,10 @@ declare namespace Electron {
*/
setTitle(title: string): void;
/**
- * Sets whether the tray icon is highlighted when it is clicked.
+ * Sets when the tray's icon background becomes highlighted.
* Note: This is only implemented on macOS.
*/
- setHighlightMode(highlight: boolean): void;
+ setHighlightMode(mode: 'selection' | 'always' | 'never'): void;
/**
* Displays a tray balloon.
* Note: This is only implemented on Windows.
@@ -3282,7 +3570,7 @@ declare namespace Electron {
/**
* @returns The bounds of this tray icon.
*/
- getBounds(): Bounds;
+ getBounds(): Rectangle;
}
interface Modifiers {
@@ -3292,8 +3580,31 @@ declare namespace Electron {
metaKey: boolean;
}
+ interface DragItem {
+ /**
+ * The absolute path of the file to be dragged
+ */
+ file: string;
+ /**
+ * The image showing under the cursor when dragging.
+ */
+ icon: NativeImage;
+ }
+
// https://github.com/electron/electron/blob/master/docs/api/web-contents.md
+ interface WebContentsStatic {
+ /**
+ * @returns An array of all web contents. This will contain web contents for all windows,
+ * webviews, opened devtools, and devtools extension background pages.
+ */
+ getAllWebContents(): WebContents[];
+ /**
+ * @returns The web contents that is focused in this application, otherwise returns null.
+ */
+ getFocusedWebContents(): WebContents;
+ }
+
/**
* A WebContents is responsible for rendering and controlling a web page.
*/
@@ -3395,7 +3706,7 @@ declare namespace Electron {
* navigation outside of the page. Examples of this occurring are when anchor links
* are clicked or when the DOM hashchange event is triggered.
*/
- on(event: 'did-navigate-in-page', listener: (event: Event, url: string) => void): this;
+ on(event: 'did-navigate-in-page', listener: (event: Event, url: string, isMainFrame: boolean) => void): this;
/**
* Emitted when the renderer process has crashed.
*/
@@ -3472,9 +3783,9 @@ declare namespace Electron {
/**
* Emitted when the cursor’s type changes.
* If the type parameter is custom, the image parameter will hold the custom cursor image
- * in a NativeImage, and the scale will hold scaling information for the image.
+ * in a NativeImage, and scale, size and hotspot will hold additional information about the custom cursor.
*/
- on(event: 'cursor-changed', listener: (event: Event, type: CursorType, image?: NativeImage, scale?: number) => void): this;
+ on(event: 'cursor-changed', listener: (event: Event, type: CursorType, image?: NativeImage, scale?: number, size?: Size, hotspot?: Point) => void): this;
/**
* Emitted when there is a new context menu that needs to be handled.
*/
@@ -3487,6 +3798,10 @@ declare namespace Electron {
* passing empty string to callback will cancel the request.
*/
on(event: 'select-bluetooth-device', listener: (event: Event, deviceList: BluetoothDevice[], callback: (deviceId: string) => void) => void): this;
+ /**
+ * Emitted when a new frame is generated. Only the dirty area is passed in the buffer.
+ */
+ on(event: 'paint', listener: (event: Event, dirtyRect: Rectangle, image: NativeImage) => void): this;
on(event: string, listener: Function): this;
/**
* Loads the url in the window.
@@ -3597,47 +3912,74 @@ declare namespace Electron {
*/
isAudioMuted(): boolean;
/**
- * Executes Edit -> Undo command in page.
+ * Changes the zoom factor to the specified factor.
+ * Zoom factor is zoom percent divided by 100, so 300% = 3.0.
+ */
+ setZoomFactor(factor: number): void;
+ /**
+ * Sends a request to get current zoom factor.
+ */
+ getZoomFactor(callback: (zoomFactor: number) => void): void;
+ /**
+ * Changes the zoom level to the specified level.
+ * The original size is 0 and each increment above or below represents
+ * zooming 20% larger or smaller to default limits of 300% and 50% of original size, respectively.
+ */
+ setZoomLevel(level: number): void;
+ /**
+ * Sends a request to get current zoom level.
+ */
+ getZoomLevel(callback: (zoomLevel: number) => void): void;
+ /**
+ * Sets the maximum and minimum zoom level.
+ */
+ setZoomLevelLimits(minimumLevel: number, maximumLevel: number): void;
+ /**
+ * Executes the editing command undo in web page.
*/
undo(): void;
/**
- * Executes Edit -> Redo command in page.
+ * Executes the editing command redo in web page.
*/
redo(): void;
/**
- * Executes Edit -> Cut command in page.
+ * Executes the editing command cut in web page.
*/
cut(): void;
/**
- * Executes Edit -> Copy command in page.
+ * Executes the editing command copy in web page.
*/
copy(): void;
/**
- * Executes Edit -> Paste command in page.
+ * Copy the image at the given position to the clipboard.
+ */
+ copyImageAt(x: number, y: number): void;
+ /**
+ * Executes the editing command paste in web page.
*/
paste(): void;
/**
- * Executes Edit -> Paste and Match Style in page.
+ * Executes the editing command pasteAndMatchStyle in web page.
*/
pasteAndMatchStyle(): void;
/**
- * Executes Edit -> Delete command in page.
+ * Executes the editing command delete in web page.
*/
delete(): void;
/**
- * Executes Edit -> Select All command in page.
+ * Executes the editing command selectAll in web page.
*/
selectAll(): void;
/**
- * Executes Edit -> Unselect command in page.
+ * Executes the editing command unselect in web page.
*/
unselect(): void;
/**
- * Executes Edit -> Replace command in page.
+ * Executes the editing command replace in web page.
*/
replace(text: string): void;
/**
- * Executes Edit -> Replace Misspelling command in page.
+ * Executes the editing command replaceMisspelling in web page.
*/
replaceMisspelling(text: string): void;
/**
@@ -3739,16 +4081,12 @@ declare namespace Electron {
* Begin subscribing for presentation events and captured frames,
* The callback will be called when there is a presentation event.
*/
- beginFrameSubscription(callback: (
- /**
- * The frameBuffer is a Buffer that contains raw pixel data.
- * On most machines, the pixel data is effectively stored in 32bit BGRA format,
- * but the actual representation depends on the endianness of the processor
- * (most modern processors are little-endian, on machines with big-endian
- * processors the data is in 32bit ARGB format).
- */
- frameBuffer: Buffer
- ) => void): void;
+ beginFrameSubscription(onlyDirty: boolean, callback: BeginFrameSubscriptionCallback): void;
+ /**
+ * Begin subscribing for presentation events and captured frames,
+ * The callback will be called when there is a presentation event.
+ */
+ beginFrameSubscription(callback: BeginFrameSubscriptionCallback): void;
/**
* End subscribing for frame presentation events.
*/
@@ -3762,6 +4100,43 @@ declare namespace Electron {
* Note: This API is available only on macOS.
*/
showDefinitionForSelection(): void;
+ /**
+ * @returns Whether offscreen rendering is enabled.
+ */
+ isOffscreen(): boolean;
+ /**
+ * If offscreen rendering is enabled and not painting, start painting.
+ */
+ startPainting(): void;
+ /**
+ * If offscreen rendering is enabled and painting, stop painting.
+ */
+ stopPainting(): void;
+ /**
+ * If offscreen rendering is enabled returns whether it is currently painting.
+ */
+ isPainting(): boolean;
+ /**
+ * If offscreen rendering is enabled sets the frame rate to the specified number.
+ * Only values between 1 and 60 are accepted.
+ */
+ setFrameRate(fps: number): void;
+ /**
+ * If offscreen rendering is enabled returns the current frame rate.
+ */
+ getFrameRate(): number;
+ /**
+ * Sets the item as dragging item for current drag-drop operation.
+ */
+ startDrag(item: DragItem): void;
+ /**
+ * Captures a snapshot of the page within rect.
+ */
+ capturePage(callback: (image: NativeImage) => void): void;
+ /**
+ * Captures a snapshot of the page within rect.
+ */
+ capturePage(rect: Rectangle, callback: (image: NativeImage) => void): void;
/**
* @returns The unique ID of this WebContents.
*/
@@ -3786,6 +4161,24 @@ declare namespace Electron {
debugger: Debugger;
}
+ interface BeginFrameSubscriptionCallback {
+ (
+ /**
+ * The frameBuffer is a Buffer that contains raw pixel data.
+ * On most machines, the pixel data is effectively stored in 32bit BGRA format,
+ * but the actual representation depends on the endianness of the processor
+ * (most modern processors are little-endian, on machines with big-endian
+ * processors the data is in 32bit ARGB format).
+ */
+ frameBuffer: Buffer,
+ /**
+ * The dirtyRect is an object with x, y, width, height properties that describes which part of the page was repainted.
+ * If onlyDirty is set to true, frameBuffer will only contain the repainted area. onlyDirty defaults to false.
+ */
+ dirtyRect?: Rectangle
+ ): void
+ }
+
interface ContextMenuParams {
/**
* x coordinate
@@ -3825,76 +4218,76 @@ declare namespace Electron {
*/
mediaFlags: {
/**
- * Wether the media element has crashed.
+ * Whether the media element has crashed.
*/
inError: boolean;
/**
- * Wether the media element is paused.
+ * Whether the media element is paused.
*/
isPaused: boolean;
/**
- * Wether the media element is muted.
+ * Whether the media element is muted.
*/
isMuted: boolean;
/**
- * Wether the media element has audio.
+ * Whether the media element has audio.
*/
hasAudio: boolean;
/**
- * Wether the media element is looping.
+ * Whether the media element is looping.
*/
isLooping: boolean;
/**
- * Wether the media element's controls are visible.
+ * Whether the media element's controls are visible.
*/
isControlsVisible: boolean;
/**
- * Wether the media element's controls are toggleable.
+ * Whether the media element's controls are toggleable.
*/
canToggleControls: boolean;
/**
- * Wether the media element can be rotated.
+ * Whether the media element can be rotated.
*/
canRotate: boolean;
}
/**
- * Wether the context menu was invoked on an image which has non-empty contents.
+ * Whether the context menu was invoked on an image which has non-empty contents.
*/
hasImageContents: boolean;
/**
- * Wether the context is editable.
+ * Whether the context is editable.
*/
isEditable: boolean;
/**
- * These flags indicate wether the renderer believes it is able to perform the corresponding action.
+ * These flags indicate whether the renderer believes it is able to perform the corresponding action.
*/
editFlags: {
/**
- * Wether the renderer believes it can undo.
+ * Whether the renderer believes it can undo.
*/
canUndo: boolean;
/**
- * Wether the renderer believes it can redo.
+ * Whether the renderer believes it can redo.
*/
canRedo: boolean;
/**
- * Wether the renderer believes it can cut.
+ * Whether the renderer believes it can cut.
*/
canCut: boolean;
/**
- * Wether the renderer believes it can copy
+ * Whether the renderer believes it can copy
*/
canCopy: boolean;
/**
- * Wether the renderer believes it can paste.
+ * Whether the renderer believes it can paste.
*/
canPaste: boolean;
/**
- * Wether the renderer believes it can delete.
+ * Whether the renderer believes it can delete.
*/
canDelete: boolean;
/**
- * Wether the renderer believes it can select all.
+ * Whether the renderer believes it can select all.
*/
canSelectAll: boolean;
}
@@ -3943,7 +4336,7 @@ declare namespace Electron {
*/
type StopFindInPageAtion = 'clearSelection' | 'keepSelection' | 'activateSelection';
- type CursorType = 'default' | 'crosshair' | 'pointer' | 'text' | 'wait' | 'help' | 'e-resize' | 'n-resize' | 'ne-resize' | 'nw-resize' | 's-resize' | 'se-resize' | 'sw-resize' | 'w-resize' | 'ns-resize' | 'ew-resize' | 'nesw-resize' | 'nwse-resize' | 'col-resize' | 'row-resize' | 'm-panning' | 'e-panning' | 'n-panning' | 'ne-panning' | 'nw-panning' | 's-panning' | 'se-panning' | 'sw-panning' | 'w-panning' | 'move' | 'vertical-text' | 'cell' | 'context-menu' | 'alias' | 'progress' | 'nodrop' | 'copy' | 'none' | 'not-allowed' | 'zoom-in' | 'zoom-out' | 'grab' | 'grabbing' | 'custom';
+ type CursorType = 'default' | 'crosshair' | 'pointer' | 'text' | 'wait' | 'help' | 'e-resize' | 'n-resize' | 'ne-resize' | 'nw-resize' | 's-resize' | 'se-resize' | 'sw-resize' | 'w-resize' | 'ns-resize' | 'ew-resize' | 'nesw-resize' | 'nwse-resize' | 'col-resize' | 'row-resize' | 'm-panning' | 'e-panning' | 'n-panning' | 'ne-panning' | 'nw-panning' | 's-panning' | 'se-panning' |'sw-panning' | 'w-panning' | 'move' | 'vertical-text' | 'cell' | 'context-menu' | 'alias' | 'progress' | 'nodrop' | 'copy' | 'none' | 'not-allowed' | 'zoom-in' | 'zoom-out' | 'grab' | 'grabbing' | 'custom';
interface LoadURLOptions {
/**
@@ -3986,7 +4379,7 @@ declare namespace Electron {
* Specify page size of the generated PDF.
* Default: A4.
*/
- pageSize?: 'A3' | 'A4' | 'A5' | 'Legal' | 'Letter' | 'Tabloid' | Dimension;
+ pageSize?: 'A3' | 'A4' | 'A5' | 'Legal' | 'Letter' | 'Tabloid' | Size;
/**
* Whether to print CSS backgrounds.
* Default: false.
@@ -4006,10 +4399,33 @@ declare namespace Electron {
interface Certificate {
/**
- * PEM encoded data
+ * PEM encoded data.
+ */
+ data: string;
+ /**
+ * Issuer's Common Name.
*/
- data: Buffer;
issuerName: string;
+ /**
+ * Subject's Common Name.
+ */
+ subjectName: string;
+ /**
+ * Hex value represented string.
+ */
+ serialNumber: string;
+ /**
+ * Start date of the certificate being valid in seconds.
+ */
+ validStart: number;
+ /**
+ * End date of the certificate being valid in seconds.
+ */
+ validExpiry: number;
+ /**
+ * Fingerprint of the certificate.
+ */
+ fingerprint: string;
}
interface LoginRequest {
@@ -4068,7 +4484,7 @@ declare namespace Electron {
/**
* Coordinates of first match region.
*/
- selectionArea?: Bounds;
+ selectionArea?: Rectangle;
}
interface DeviceEmulationParameters {
@@ -4080,7 +4496,7 @@ declare namespace Electron {
/**
* Set the emulated screen size (screenPosition == mobile)
*/
- screenSize?: Dimension;
+ screenSize?: Size;
/**
* Position the view on the screen (screenPosition == mobile)
* Default: {x: 0, y: 0}
@@ -4094,7 +4510,7 @@ declare namespace Electron {
/**
* Set the emulated view size (empty means no override).
*/
- viewSize?: Dimension;
+ viewSize?: Size;
/**
* Whether emulated view should be scaled down if necessary to fit into available space
* Default: false
@@ -4139,7 +4555,7 @@ declare namespace Electron {
wheelTicksY?: number;
accelerationRatioX?: number;
accelerationRatioY?: number;
- hasPreciseScrollingDeltas?: number;
+ hasPreciseScrollingDeltas?: boolean;
canScroll?: boolean;
}
@@ -4365,6 +4781,14 @@ declare namespace Electron {
* @returns The title of guest page.
*/
getTitle(): string;
+ /**
+ * @returns Whether the web page is destroyed.
+ */
+ isDestroyed(): boolean;
+ /**
+ * @returns Whether the web page is focused.
+ */
+ isFocused(): boolean;
/**
* @returns Whether guest page is still loading resources.
*/
@@ -4416,7 +4840,7 @@ declare namespace Electron {
/**
* Navigates to the specified offset from the "current entry".
*/
- goToOffset(offset: boolean): void;
+ goToOffset(offset: number): void;
/**
* @returns Whether the renderer process has crashed.
*/
@@ -4556,6 +4980,14 @@ declare namespace Electron {
* @returns The WebContents associated with this webview.
*/
getWebContents(): WebContents;
+ /**
+ * Captures a snapshot of the webview's page. Same as webContents.capturePage([rect, ]callback).
+ */
+ capturePage(callback: (image: NativeImage) => void): void;
+ /**
+ * Captures a snapshot of the webview's page. Same as webContents.capturePage([rect, ]callback).
+ */
+ capturePage(rect: Rectangle, callback: (image: NativeImage) => void): void;
/**
* Fired when a load has committed. This includes navigation within the current document
* as well as subframe document-level loads, but does not include asynchronous resource loads.
@@ -4634,14 +5066,14 @@ declare namespace Electron {
*
* Calling event.preventDefault() does NOT have any effect.
*/
- addEventListener(type: 'will-navigate', listener: (event: WebViewElement.NavigateEvent) => void, useCapture?: boolean): void;
+ addEventListener(type: 'will-navigate', listener: (event: WebViewElement.WillNavigateEvent) => void, useCapture?: boolean): void;
/**
* Emitted when a navigation is done.
*
* This event is not emitted for in-page navigations, such as clicking anchor links
* or updating the window.location.hash. Use did-navigate-in-page event for this purpose.
*/
- addEventListener(type: 'did-navigate', listener: (event: WebViewElement.NavigateEvent) => void, useCapture?: boolean): void;
+ addEventListener(type: 'did-navigate', listener: (event: WebViewElement.DidNavigateEvent) => void, useCapture?: boolean): void;
/**
* Emitted when an in-page navigation happened.
*
@@ -4649,7 +5081,7 @@ declare namespace Electron {
* navigation outside of the page. Examples of this occurring are when anchor links
* are clicked or when the DOM hashchange event is triggered.
*/
- addEventListener(type: 'did-navigate-in-page', listener: (event: WebViewElement.NavigateEvent) => void, useCapture?: boolean): void;
+ addEventListener(type: 'did-navigate-in-page', listener: (event: WebViewElement.DidNavigateInPageEvent) => void, useCapture?: boolean): void;
/**
* Fired when the guest page attempts to close itself.
*/
@@ -4709,23 +5141,23 @@ declare namespace Electron {
namespace WebViewElement {
type Event = ElectronPrivate.GlobalEvent;
- interface LoadCommitEvent extends Event {
+ interface LoadCommitEvent extends Event {
url: string;
isMainFrame: boolean;
}
- interface DidFailLoadEvent extends Event {
+ interface DidFailLoadEvent extends Event {
errorCode: number;
errorDescription: string;
validatedURL: string;
isMainFrame: boolean;
}
- interface DidFrameFinishLoadEvent extends Event {
+ interface DidFrameFinishLoadEvent extends Event {
isMainFrame: boolean;
}
- interface DidGetResponseDetails extends Event {
+ interface DidGetResponseDetails extends Event {
status: boolean;
newURL: string;
originalURL: string;
@@ -4773,10 +5205,19 @@ declare namespace Electron {
options: BrowserWindowOptions;
}
- interface NavigateEvent extends Event {
+ interface WillNavigateEvent extends Event {
url: string;
}
+ interface DidNavigateEvent extends Event {
+ url: string;
+ }
+
+ interface DidNavigateInPageEvent extends Event {
+ url: string;
+ isMainFrame: boolean;
+ }
+
interface IpcMessageEvent extends Event {
channel: string;
args: any[];
@@ -4856,7 +5297,7 @@ declare namespace Electron {
session: typeof Electron.Session;
systemPreferences: Electron.SystemPreferences;
Tray: Electron.Tray;
- hideInternalModules(): void;
+ webContents: Electron.WebContentsStatic;
}
interface ElectronMainAndRenderer extends CommonElectron {
@@ -4896,6 +5337,18 @@ interface File {
// https://github.com/electron/electron/blob/master/docs/api/process.md
declare namespace NodeJS {
+
+ interface ProcessVersions {
+ /**
+ * Electron's version string.
+ */
+ electron: string;
+ /**
+ * Chrome's version string.
+ */
+ chrome: string;
+ }
+
interface Process {
/**
* Setting this to true can disable the support for asar archives in Node's built-in modules.
diff --git a/src/vs/base/common/labels.ts b/src/vs/base/common/labels.ts
index 96a51f345b1..3c37260ff8e 100644
--- a/src/vs/base/common/labels.ts
+++ b/src/vs/base/common/labels.ts
@@ -36,9 +36,13 @@ export class PathLabelProvider implements ILabelProvider {
}
}
-export function getPathLabel(arg1: URI | string, arg2?: URI | string | IWorkspaceProvider): string {
- let basepath = arg2 && getPath(arg2);
- let absolutePath = getPath(arg1);
+export function getPathLabel(resource: URI | string, basePathProvider?: URI | string | IWorkspaceProvider): string {
+ const absolutePath = getPath(resource);
+ if (!absolutePath) {
+ return null;
+ }
+
+ const basepath = basePathProvider && getPath(basePathProvider);
if (basepath && paths.isEqualOrParent(absolutePath, basepath)) {
if (basepath === absolutePath) {
@@ -48,7 +52,7 @@ export function getPathLabel(arg1: URI | string, arg2?: URI | string | IWorkspac
return paths.normalize(strings.ltrim(absolutePath.substr(basepath.length), paths.nativeSep), true);
}
- if (platform.isWindows && absolutePath[1] === ':') {
+ if (platform.isWindows && absolutePath && absolutePath[1] === ':') {
return paths.normalize(absolutePath.charAt(0).toUpperCase() + absolutePath.slice(1), true);
}
@@ -65,7 +69,7 @@ function getPath(arg1: URI | string | IWorkspaceProvider): string {
}
if (types.isFunction((arg1).getWorkspace)) {
- let ws = (arg1).getWorkspace();
+ const ws = (arg1).getWorkspace();
return ws ? ws.resource.fsPath : void 0;
}
diff --git a/src/vs/base/node/stdFork.ts b/src/vs/base/node/stdFork.ts
index 3f5a4a3f7f3..4e20df2187e 100644
--- a/src/vs/base/node/stdFork.ts
+++ b/src/vs/base/node/stdFork.ts
@@ -49,7 +49,7 @@ function generatePatchedEnv(env:any, stdInPipeName:string, stdOutPipeName:string
newEnv['STDIN_PIPE_NAME'] = stdInPipeName;
newEnv['STDOUT_PIPE_NAME'] = stdOutPipeName;
newEnv['STDERR_PIPE_NAME'] = stdErrPipeName;
- newEnv['ATOM_SHELL_INTERNAL_RUN_AS_NODE'] = '1';
+ newEnv['ELECTRON_RUN_AS_NODE'] = '1';
return newEnv;
}
diff --git a/src/vs/base/node/stdForkStart.js b/src/vs/base/node/stdForkStart.js
index 0b1e7382fe5..92024acf6b8 100644
--- a/src/vs/base/node/stdForkStart.js
+++ b/src/vs/base/node/stdForkStart.js
@@ -33,7 +33,7 @@ var stdErrPipeName = process.env['STDERR_PIPE_NAME'];
log('STDIN_PIPE_NAME: ' + stdInPipeName);
log('STDOUT_PIPE_NAME: ' + stdOutPipeName);
log('STDERR_PIPE_NAME: ' + stdErrPipeName);
-log('ATOM_SHELL_INTERNAL_RUN_AS_NODE: ' + process.env['ATOM_SHELL_INTERNAL_RUN_AS_NODE']);
+log('ELECTRON_RUN_AS_NODE: ' + process.env['ELECTRON_RUN_AS_NODE']);
// stdout redirection to named pipe
(function() {
@@ -149,7 +149,7 @@ log('ATOM_SHELL_INTERNAL_RUN_AS_NODE: ' + process.env['ATOM_SHELL_INTERNAL_RUN_A
delete process.env['STDIN_PIPE_NAME'];
delete process.env['STDOUT_PIPE_NAME'];
delete process.env['STDERR_PIPE_NAME'];
- delete process.env['ATOM_SHELL_INTERNAL_RUN_AS_NODE'];
+ delete process.env['ELECTRON_RUN_AS_NODE'];
require(program);
diff --git a/src/vs/code/electron-main/main.ts b/src/vs/code/electron-main/main.ts
index 0d0b3e365f0..e75241ab340 100644
--- a/src/vs/code/electron-main/main.ts
+++ b/src/vs/code/electron-main/main.ts
@@ -273,13 +273,13 @@ interface IEnv {
function getUnixShellEnvironment(): TPromise {
const promise = new TPromise((c, e) => {
- const runAsNode = process.env['ATOM_SHELL_INTERNAL_RUN_AS_NODE'];
+ const runAsNode = process.env['ELECTRON_RUN_AS_NODE'];
const noAttach = process.env['ELECTRON_NO_ATTACH_CONSOLE'];
const mark = generateUuid().replace(/-/g, '').substr(0, 12);
const regex = new RegExp(mark + '(.*)' + mark);
const env = assign({}, process.env, {
- ATOM_SHELL_INTERNAL_RUN_AS_NODE: '1',
+ ELECTRON_RUN_AS_NODE: '1',
ELECTRON_NO_ATTACH_CONSOLE: '1'
});
@@ -307,9 +307,9 @@ function getUnixShellEnvironment(): TPromise {
const env = JSON.parse(rawStripped);
if (runAsNode) {
- env['ATOM_SHELL_INTERNAL_RUN_AS_NODE'] = runAsNode;
+ env['ELECTRON_RUN_AS_NODE'] = runAsNode;
} else {
- delete env['ATOM_SHELL_INTERNAL_RUN_AS_NODE'];
+ delete env['ELECTRON_RUN_AS_NODE'];
}
if (noAttach) {
diff --git a/src/vs/code/electron-main/window.ts b/src/vs/code/electron-main/window.ts
index b8bbfc60312..800d5554362 100644
--- a/src/vs/code/electron-main/window.ts
+++ b/src/vs/code/electron-main/window.ts
@@ -568,7 +568,7 @@ export class VSCodeWindow {
return null;
}
- public getBounds(): Electron.Bounds {
+ public getBounds(): Electron.Rectangle {
const pos = this.win.getPosition();
const dimension = this.win.getSize();
diff --git a/src/vs/code/node/cli.ts b/src/vs/code/node/cli.ts
index 3a506b9d96a..18e6d60018c 100644
--- a/src/vs/code/node/cli.ts
+++ b/src/vs/code/node/cli.ts
@@ -31,7 +31,7 @@ export function main(argv: string[]): TPromise {
if (args.help) {
console.log(buildHelpMessage(product.nameLong, product.applicationName, pkg.version));
} else if (args.version) {
- console.log(`${ pkg.version } (${ product.commit })`);
+ console.log(`${ pkg.version }\n${ product.commit }`);
} else if (shouldSpawnCliProcess(args)) {
const mainCli = new TPromise(c => require(['vs/code/node/cliProcessMain'], c));
return mainCli.then(cli => cli.main(args));
@@ -41,7 +41,7 @@ export function main(argv: string[]): TPromise {
'VSCODE_CLI': '1',
'ELECTRON_NO_ATTACH_CONSOLE': '1'
});
- delete env['ATOM_SHELL_INTERNAL_RUN_AS_NODE'];
+ delete env['ELECTRON_RUN_AS_NODE'];
let options = {
detached: true,
diff --git a/src/vs/editor/browser/viewParts/lineNumbers/lineNumbers.css b/src/vs/editor/browser/viewParts/lineNumbers/lineNumbers.css
index 272e8c6fd1f..8bf1d15303d 100644
--- a/src/vs/editor/browser/viewParts/lineNumbers/lineNumbers.css
+++ b/src/vs/editor/browser/viewParts/lineNumbers/lineNumbers.css
@@ -12,7 +12,8 @@
cursor: default;
}
-.monaco-workbench .monaco-editor .margin-view-overlays .line-numbers {
+/* disable until https://github.com/Microsoft/vscode/issues/8708 is fixed */
+/*.monaco-workbench .monaco-editor .margin-view-overlays .line-numbers {
cursor: -webkit-image-set(
url('flipped-cursor.svg') 1x,
url('flipped-cursor-2x.svg') 2x
@@ -24,7 +25,7 @@
url('flipped-cursor-mac.svg') 1x,
url('flipped-cursor-mac-2x.svg') 2x
) 24 3, default;
-}
+}*/
.monaco-editor .margin-view-overlays .line-numbers.lh-odd {
margin-top: 1px;
diff --git a/src/vs/editor/contrib/find/browser/find.ts b/src/vs/editor/contrib/find/browser/find.ts
index 6924b1dc3cf..06ddc371a85 100644
--- a/src/vs/editor/contrib/find/browser/find.ts
+++ b/src/vs/editor/contrib/find/browser/find.ts
@@ -25,7 +25,7 @@ class FindController extends CommonFindController implements IFindController {
) {
super(editor, contextKeyService);
- this._widget = this._register(new FindWidget(editor, this, this._state, contextViewService, keybindingService));
+ this._widget = this._register(new FindWidget(editor, this, this._state, contextViewService, keybindingService, contextKeyService));
}
protected _start(opts:IFindStartOptions): void {
diff --git a/src/vs/editor/contrib/find/browser/findWidget.ts b/src/vs/editor/contrib/find/browser/findWidget.ts
index ed0825ff8d9..bd692ce101e 100644
--- a/src/vs/editor/contrib/find/browser/findWidget.ts
+++ b/src/vs/editor/contrib/find/browser/findWidget.ts
@@ -22,6 +22,8 @@ import {ICodeEditor, IOverlayWidget, IOverlayWidgetPosition, OverlayWidgetPositi
import {FIND_IDS, MATCHES_LIMIT} from 'vs/editor/contrib/find/common/findModel';
import {FindReplaceState, FindReplaceStateChangedEvent} from 'vs/editor/contrib/find/common/findState';
import {Range} from 'vs/editor/common/core/range';
+import {IContextKeyService, IContextKey} from 'vs/platform/contextkey/common/contextkey';
+import {CONTEXT_FIND_INPUT_FOCUSSED} from 'vs/editor/contrib/find/common/findController';
export interface IFindController {
replace(): void;
@@ -75,13 +77,15 @@ export class FindWidget extends Widget implements IOverlayWidget {
private _isReplaceVisible: boolean;
private _focusTracker: dom.IFocusTracker;
+ private _findInputFocussed: IContextKey;
constructor(
codeEditor: ICodeEditor,
controller: IFindController,
state: FindReplaceState,
contextViewProvider: IContextViewProvider,
- keybindingService: IKeybindingService
+ keybindingService: IKeybindingService,
+ contextKeyService: IContextKeyService
) {
super();
this._codeEditor = codeEditor;
@@ -112,8 +116,10 @@ export class FindWidget extends Widget implements IOverlayWidget {
this._updateToggleSelectionFindButton();
}
}));
+ this._findInputFocussed = CONTEXT_FIND_INPUT_FOCUSSED.bindTo(contextKeyService);
this._focusTracker = this._register(dom.trackFocus(this._findInput.inputBox.inputElement));
this._focusTracker.addFocusListener(() => {
+ this._findInputFocussed.set(true);
let selection = this._codeEditor.getSelection();
let currentMatch = this._state.currentMatch;
if (selection.startLineNumber !== selection.endLineNumber) {
@@ -123,6 +129,9 @@ export class FindWidget extends Widget implements IOverlayWidget {
}
}
});
+ this._focusTracker.addBlurListener(() => {
+ this._findInputFocussed.set(false);
+ });
this._codeEditor.addOverlayWidget(this);
}
diff --git a/src/vs/editor/contrib/find/common/findController.ts b/src/vs/editor/contrib/find/common/findController.ts
index 8d0bd01fab0..4f3319fc4f3 100644
--- a/src/vs/editor/contrib/find/common/findController.ts
+++ b/src/vs/editor/contrib/find/common/findController.ts
@@ -14,7 +14,7 @@ import {Selection} from 'vs/editor/common/core/selection';
import * as strings from 'vs/base/common/strings';
import * as editorCommon from 'vs/editor/common/editorCommon';
import {editorAction, commonEditorContribution, ServicesAccessor, EditorAction, EditorCommand, CommonEditorRegistry} from 'vs/editor/common/editorCommonExtensions';
-import {FIND_IDS, FindModelBoundToEditorModel} from 'vs/editor/contrib/find/common/findModel';
+import {FIND_IDS, FindModelBoundToEditorModel, ToggleCaseSensitiveKeybinding, ToggleRegexKeybinding, ToggleWholeWordKeybinding, ShowPreviousFindTermKeybinding, ShowNextFindTermKeybinding} from 'vs/editor/contrib/find/common/findModel';
import {FindReplaceState, FindReplaceStateChangedEvent, INewFindReplaceState} from 'vs/editor/contrib/find/common/findState';
import {DocumentHighlightProviderRegistry} from 'vs/editor/common/modes';
import {RunOnceScheduler, Delayer} from 'vs/base/common/async';
@@ -36,6 +36,7 @@ export interface IFindStartOptions {
export const CONTEXT_FIND_WIDGET_VISIBLE = new RawContextKey('findWidgetVisible', false);
export const CONTEXT_FIND_WIDGET_NOT_VISIBLE: ContextKeyExpr = CONTEXT_FIND_WIDGET_VISIBLE.toNegated();
+export const CONTEXT_FIND_INPUT_FOCUSSED = new RawContextKey('findInputFocussed', false);
export class CommonFindController extends Disposable implements editorCommon.IEditorContribution {
@@ -920,8 +921,10 @@ CommonEditorRegistry.registerEditorCommand(new FindCommand({
kbOpts: {
weight: CommonEditorRegistry.commandWeight(5),
kbExpr: EditorContextKeys.Focus,
- primary: KeyMod.Alt | KeyCode.KEY_C,
- mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_C }
+ primary: ToggleCaseSensitiveKeybinding.primary,
+ mac: ToggleCaseSensitiveKeybinding.mac,
+ win: ToggleCaseSensitiveKeybinding.win,
+ linux: ToggleCaseSensitiveKeybinding.linux
}
}));
@@ -932,8 +935,10 @@ CommonEditorRegistry.registerEditorCommand(new FindCommand({
kbOpts: {
weight: CommonEditorRegistry.commandWeight(5),
kbExpr: EditorContextKeys.Focus,
- primary: KeyMod.Alt | KeyCode.KEY_W,
- mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_W }
+ primary: ToggleWholeWordKeybinding.primary,
+ mac: ToggleWholeWordKeybinding.mac,
+ win: ToggleWholeWordKeybinding.win,
+ linux: ToggleWholeWordKeybinding.linux
}
}));
@@ -944,8 +949,10 @@ CommonEditorRegistry.registerEditorCommand(new FindCommand({
kbOpts: {
weight: CommonEditorRegistry.commandWeight(5),
kbExpr: EditorContextKeys.Focus,
- primary: KeyMod.Alt | KeyCode.KEY_R,
- mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_R }
+ primary: ToggleRegexKeybinding.primary,
+ mac: ToggleRegexKeybinding.mac,
+ win: ToggleRegexKeybinding.win,
+ linux: ToggleRegexKeybinding.linux
}
}));
@@ -988,8 +995,11 @@ CommonEditorRegistry.registerEditorCommand(new FindCommand({
handler: x => x.showPreviousFindTerm(),
kbOpts: {
weight: CommonEditorRegistry.commandWeight(5),
- kbExpr: EditorContextKeys.Focus,
- primary: KeyMod.Alt | KeyCode.UpArrow
+ kbExpr: ContextKeyExpr.and(CONTEXT_FIND_INPUT_FOCUSSED, EditorContextKeys.Focus),
+ primary: ShowPreviousFindTermKeybinding.primary,
+ mac: ShowPreviousFindTermKeybinding.mac,
+ win: ShowPreviousFindTermKeybinding.win,
+ linux: ShowPreviousFindTermKeybinding.linux
}
}));
@@ -999,7 +1009,10 @@ CommonEditorRegistry.registerEditorCommand(new FindCommand({
handler: x => x.showNextFindTerm(),
kbOpts: {
weight: CommonEditorRegistry.commandWeight(5),
- kbExpr: EditorContextKeys.Focus,
- primary: KeyMod.Alt | KeyCode.DownArrow
+ kbExpr: ContextKeyExpr.and(CONTEXT_FIND_INPUT_FOCUSSED, EditorContextKeys.Focus),
+ primary: ShowNextFindTermKeybinding.primary,
+ mac: ShowNextFindTermKeybinding.mac,
+ win: ShowNextFindTermKeybinding.win,
+ linux: ShowNextFindTermKeybinding.linux
}
}));
diff --git a/src/vs/editor/contrib/find/common/findModel.ts b/src/vs/editor/contrib/find/common/findModel.ts
index 542e7c2234e..2a1e47da5ea 100644
--- a/src/vs/editor/contrib/find/common/findModel.ts
+++ b/src/vs/editor/contrib/find/common/findModel.ts
@@ -16,6 +16,27 @@ import {FindDecorations} from './findDecorations';
import {FindReplaceState, FindReplaceStateChangedEvent} from './findState';
import {ReplaceAllCommand} from './replaceAllCommand';
import {Selection} from 'vs/editor/common/core/selection';
+import {KeyCode, KeyMod} from 'vs/base/common/keyCodes';
+import {IKeybindings} from 'vs/platform/keybinding/common/keybinding';
+
+export const ToggleCaseSensitiveKeybinding: IKeybindings = {
+ primary: KeyMod.Alt | KeyCode.KEY_C,
+ mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_C }
+};
+export const ToggleWholeWordKeybinding: IKeybindings = {
+ primary: KeyMod.Alt | KeyCode.KEY_W,
+ mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_W }
+};
+export const ToggleRegexKeybinding: IKeybindings = {
+ primary: KeyMod.Alt | KeyCode.KEY_R,
+ mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_R }
+};
+export const ShowPreviousFindTermKeybinding: IKeybindings = {
+ primary: KeyMod.Alt | KeyCode.UpArrow
+};
+export const ShowNextFindTermKeybinding: IKeybindings = {
+ primary: KeyMod.Alt | KeyCode.DownArrow
+};
export const FIND_IDS = {
StartFindAction: 'actions.find',
@@ -43,16 +64,16 @@ export const MATCHES_LIMIT = 999;
export class FindModelBoundToEditorModel {
- private _editor:editorCommon.ICommonCodeEditor;
- private _state:FindReplaceState;
- private _toDispose:IDisposable[];
+ private _editor: editorCommon.ICommonCodeEditor;
+ private _state: FindReplaceState;
+ private _toDispose: IDisposable[];
private _decorations: FindDecorations;
- private _ignoreModelContentChanged:boolean;
+ private _ignoreModelContentChanged: boolean;
- private _updateDecorationsScheduler:RunOnceScheduler;
+ private _updateDecorationsScheduler: RunOnceScheduler;
private _isDisposed: boolean;
- constructor(editor:editorCommon.ICommonCodeEditor, state:FindReplaceState) {
+ constructor(editor: editorCommon.ICommonCodeEditor, state: FindReplaceState) {
this._editor = editor;
this._state = state;
this._toDispose = [];
@@ -64,7 +85,7 @@ export class FindModelBoundToEditorModel {
this._updateDecorationsScheduler = new RunOnceScheduler(() => this.research(false), 100);
this._toDispose.push(this._updateDecorationsScheduler);
- this._toDispose.push(this._editor.onDidChangeCursorPosition((e:editorCommon.ICursorPositionChangedEvent) => {
+ this._toDispose.push(this._editor.onDidChangeCursorPosition((e: editorCommon.ICursorPositionChangedEvent) => {
if (
e.reason === editorCommon.CursorChangeReason.Explicit
|| e.reason === editorCommon.CursorChangeReason.Undo
@@ -75,7 +96,7 @@ export class FindModelBoundToEditorModel {
}));
this._ignoreModelContentChanged = false;
- this._toDispose.push(this._editor.onDidChangeModelRawContent((e:editorCommon.IModelContentChangedEvent) => {
+ this._toDispose.push(this._editor.onDidChangeModelRawContent((e: editorCommon.IModelContentChangedEvent) => {
if (this._ignoreModelContentChanged) {
return;
}
@@ -97,7 +118,7 @@ export class FindModelBoundToEditorModel {
this._toDispose = dispose(this._toDispose);
}
- private _onStateChanged(e:FindReplaceStateChangedEvent): void {
+ private _onStateChanged(e: FindReplaceStateChangedEvent): void {
if (this._isDisposed) {
// The find model is disposed during a find state changed event
return;
@@ -111,8 +132,8 @@ export class FindModelBoundToEditorModel {
}
}
- private static _getSearchRange(model:editorCommon.IModel, searchOnlyEditableRange:boolean, findScope:Range): Range {
- let searchRange:Range;
+ private static _getSearchRange(model: editorCommon.IModel, searchOnlyEditableRange: boolean, findScope: Range): Range {
+ let searchRange: Range;
if (searchOnlyEditableRange) {
searchRange = model.getEditableRange();
@@ -128,7 +149,7 @@ export class FindModelBoundToEditorModel {
return searchRange;
}
- private research(moveCursor:boolean, newFindScope?:Range): void {
+ private research(moveCursor: boolean, newFindScope?: Range): void {
let findScope: Range = null;
if (typeof newFindScope !== 'undefined') {
findScope = newFindScope;
@@ -169,7 +190,7 @@ export class FindModelBoundToEditorModel {
return false;
}
- private _setCurrentFindMatch(match:Range): void {
+ private _setCurrentFindMatch(match: Range): void {
let matchesPosition = this._decorations.setCurrentFindMatch(match);
this._state.changeMatchInfo(
matchesPosition,
@@ -181,7 +202,7 @@ export class FindModelBoundToEditorModel {
this._editor.revealRangeInCenterIfOutsideViewport(match);
}
- private _moveToPrevMatch(before:Position, isRecursed:boolean = false): void {
+ private _moveToPrevMatch(before: Position, isRecursed: boolean = false): void {
if (this._cannotFind()) {
return;
}
@@ -199,7 +220,7 @@ export class FindModelBoundToEditorModel {
before = searchRange.getEndPosition();
}
- let {lineNumber,column} = before;
+ let {lineNumber, column} = before;
let model = this._editor.getModel();
let position = new Position(lineNumber, column);
@@ -245,8 +266,8 @@ export class FindModelBoundToEditorModel {
this._moveToPrevMatch(this._editor.getSelection().getStartPosition());
}
- private _moveToNextMatch(nextMatch:Range): void
- private _moveToNextMatch(after:Position): void
+ private _moveToNextMatch(nextMatch: Range): void
+ private _moveToNextMatch(after: Position): void
private _moveToNextMatch(arg: any): void {
let nextMatch = Range.isIRange(arg) ? arg : Position.isIPosition(arg) ? this._getNextMatch(arg) : null;
if (nextMatch) {
@@ -254,7 +275,7 @@ export class FindModelBoundToEditorModel {
}
}
- private _getNextMatch(after:Position, isRecursed:boolean = false): Range {
+ private _getNextMatch(after: Position, isRecursed: boolean = false): Range {
if (this._cannotFind()) {
return null;
}
@@ -272,7 +293,7 @@ export class FindModelBoundToEditorModel {
after = searchRange.getStartPosition();
}
- let {lineNumber,column} = after;
+ let {lineNumber, column} = after;
let model = this._editor.getModel();
let position = new Position(lineNumber, column);
@@ -370,7 +391,7 @@ export class FindModelBoundToEditorModel {
}
}
- private _findMatches(findScope: Range, limitResultCount:number): Range[] {
+ private _findMatches(findScope: Range, limitResultCount: number): Range[] {
let searchRange = FindModelBoundToEditorModel._getSearchRange(this._editor.getModel(), this._state.isReplaceRevealed, findScope);
return this._editor.getModel().findMatches(this._state.searchString, searchRange, this._state.isRegex, this._state.matchCase, this._state.wholeWord, limitResultCount);
}
@@ -385,7 +406,7 @@ export class FindModelBoundToEditorModel {
// Get all the ranges (even more than the highlighted ones)
let ranges = this._findMatches(findScope, Number.MAX_VALUE);
- let replaceStrings:string[] = [];
+ let replaceStrings: string[] = [];
for (let i = 0, len = ranges.length; i < len; i++) {
replaceStrings.push(this.getReplaceString(ranges[i]));
}
@@ -409,7 +430,7 @@ export class FindModelBoundToEditorModel {
this._editor.setSelections(ranges.map(r => new Selection(r.startLineNumber, r.startColumn, r.endLineNumber, r.endColumn)));
}
- private _executeEditorCommand(source:string, command:editorCommon.ICommand): void {
+ private _executeEditorCommand(source: string, command: editorCommon.ICommand): void {
try {
this._ignoreModelContentChanged = true;
this._editor.executeCommand(source, command);
diff --git a/src/vs/vscode.d.ts b/src/vs/vscode.d.ts
index 33044f955f6..6ac61419bc9 100644
--- a/src/vs/vscode.d.ts
+++ b/src/vs/vscode.d.ts
@@ -3498,9 +3498,10 @@ declare namespace vscode {
*
* @param name Optional human-readable string which will be used to represent the terminal in the UI.
* @param shellPath Optional path to a custom shell executable to be used in the terminal.
+ * @param shellArgs Optional args for the custom shell executable, this does not work on Windows (see #8429)
* @return A new Terminal.
*/
- export function createTerminal(name?: string, shellPath?: string): Terminal;
+ export function createTerminal(name?: string, shellPath?: string, shellArgs?: string[]): Terminal;
}
/**
diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts
index 0533d77c825..8190d313b37 100644
--- a/src/vs/workbench/api/node/extHost.api.impl.ts
+++ b/src/vs/workbench/api/node/extHost.api.impl.ts
@@ -260,8 +260,8 @@ export class ExtHostAPIImplementation {
createOutputChannel(name: string): vscode.OutputChannel {
return extHostOutputService.createOutputChannel(name);
},
- createTerminal(name?: string, shellPath?: string): vscode.Terminal {
- return extHostTerminalService.createTerminal(name, shellPath);
+ createTerminal(name?: string, shellPath?: string, shellArgs?: string[]): vscode.Terminal {
+ return extHostTerminalService.createTerminal(name, shellPath, shellArgs);
}
};
diff --git a/src/vs/workbench/api/node/extHost.protocol.ts b/src/vs/workbench/api/node/extHost.protocol.ts
index 287936c1410..1e10df02db2 100644
--- a/src/vs/workbench/api/node/extHost.protocol.ts
+++ b/src/vs/workbench/api/node/extHost.protocol.ts
@@ -153,7 +153,7 @@ export abstract class MainThreadOutputServiceShape {
}
export abstract class MainThreadTerminalServiceShape {
- $createTerminal(name?: string, shellPath?: string): number { throw ni(); }
+ $createTerminal(name?: string, shellPath?: string, shellArgs?: string[]): TPromise { throw ni(); }
$dispose(terminalId: number): void { throw ni(); }
$hide(terminalId: number): void { throw ni(); }
$sendText(terminalId: number, text: string, addNewLine: boolean): void { throw ni(); }
diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts
index 74d0de54efa..2253748554b 100644
--- a/src/vs/workbench/api/node/extHostTerminalService.ts
+++ b/src/vs/workbench/api/node/extHostTerminalService.ts
@@ -10,18 +10,21 @@ import {MainContext, MainThreadTerminalServiceShape} from './extHost.protocol';
export class ExtHostTerminal implements vscode.Terminal {
- public _name: string;
- public _shellPath: string;
-
+ private _name: string;
private _id: number;
private _proxy: MainThreadTerminalServiceShape;
private _disposed: boolean;
+ private _queuedRequests: ApiRequest[] = [];
- constructor(proxy: MainThreadTerminalServiceShape, id: number, name?: string, shellPath?: string) {
+ constructor(proxy: MainThreadTerminalServiceShape, name?: string, shellPath?: string, shellArgs?: string[]) {
this._name = name;
- this._shellPath = shellPath;
this._proxy = proxy;
- this._id = this._proxy.$createTerminal(name, shellPath);
+ this._proxy.$createTerminal(name, shellPath, shellArgs).then((id) => {
+ this._id = id;
+ this._queuedRequests.forEach((r) => {
+ r.run(this._proxy, this._id);
+ });
+ });
}
public get name(): string {
@@ -31,26 +34,35 @@ export class ExtHostTerminal implements vscode.Terminal {
public sendText(text: string, addNewLine: boolean = true): void {
this._checkDisposed();
- this._proxy.$sendText(this._id, text, addNewLine);
+ this._queueApiRequest(this._proxy.$sendText, [text, addNewLine]);
}
public show(preserveFocus: boolean): void {
this._checkDisposed();
- this._proxy.$show(this._id, preserveFocus);
+ this._queueApiRequest(this._proxy.$show, [preserveFocus]);
}
public hide(): void {
this._checkDisposed();
- this._proxy.$hide(this._id);
+ this._queueApiRequest(this._proxy.$hide, []);
}
public dispose(): void {
if (!this._disposed) {
this._disposed = true;
- this._proxy.$dispose(this._id);
+ this._queueApiRequest(this._proxy.$dispose, []);
}
}
+ private _queueApiRequest(callback: (...args: any[]) => void, args: any[]) {
+ let request: ApiRequest = new ApiRequest(callback, args);
+ if (!this._id) {
+ this._queuedRequests.push(request);
+ return;
+ }
+ request.run(this._proxy, this._id);
+ }
+
private _checkDisposed() {
if (this._disposed) {
throw new Error('Terminal has already been disposed');
@@ -66,7 +78,21 @@ export class ExtHostTerminalService {
this._proxy = threadService.get(MainContext.MainThreadTerminalService);
}
- public createTerminal(name?: string, shellPath?: string): vscode.Terminal {
- return new ExtHostTerminal(this._proxy, -1, name, shellPath);
+ public createTerminal(name?: string, shellPath?: string, shellArgs?: string[]): vscode.Terminal {
+ return new ExtHostTerminal(this._proxy, name, shellPath, shellArgs);
}
}
+
+class ApiRequest {
+ private _callback: (...args: any[]) => void;
+ private _args: any[];
+
+ constructor(callback: (...args: any[]) => void, args: any[]) {
+ this._callback = callback;
+ this._args = args;
+ }
+
+ public run(proxy: MainThreadTerminalServiceShape, id: number) {
+ this._callback.apply(proxy, [id].concat(this._args));
+ }
+}
\ No newline at end of file
diff --git a/src/vs/workbench/api/node/mainThreadTerminalService.ts b/src/vs/workbench/api/node/mainThreadTerminalService.ts
index 94d11f0aa92..6c9a57262ab 100644
--- a/src/vs/workbench/api/node/mainThreadTerminalService.ts
+++ b/src/vs/workbench/api/node/mainThreadTerminalService.ts
@@ -8,6 +8,7 @@ import {ITerminalService} from 'vs/workbench/parts/terminal/electron-browser/ter
import {IPanelService} from 'vs/workbench/services/panel/common/panelService';
import {IPartService} from 'vs/workbench/services/part/common/partService';
import {MainThreadTerminalServiceShape} from './extHost.protocol';
+import {TPromise} from 'vs/base/common/winjs.base';
export class MainThreadTerminalService extends MainThreadTerminalServiceShape {
@@ -19,8 +20,8 @@ export class MainThreadTerminalService extends MainThreadTerminalServiceShape {
super();
}
- public $createTerminal(name?: string, shellPath?: string): number {
- return this.terminalService.createInstance(name, shellPath).id;
+ public $createTerminal(name?: string, shellPath?: string, shellArgs?: string[]): TPromise {
+ return TPromise.as(this.terminalService.createInstance(name, shellPath, shellArgs).id);
}
public $show(terminalId: number, preserveFocus: boolean): void {
diff --git a/src/vs/workbench/browser/parts/editor/editorStatus.ts b/src/vs/workbench/browser/parts/editor/editorStatus.ts
index 0324fd61340..a61faa1779b 100644
--- a/src/vs/workbench/browser/parts/editor/editorStatus.ts
+++ b/src/vs/workbench/browser/parts/editor/editorStatus.ts
@@ -662,9 +662,12 @@ export class ChangeModeAction extends Action {
// All languages are valid picks
const picks: IPickOpenEntry[] = languages.sort().map((lang, index) => {
- return {
+ const languageModeId = this.modeService.getModeIdForLanguageName(lang.toLowerCase());
+ const configureLabel = nls.localize('configuredLanguage', "Configured Language");
+
+ return {
label: lang,
- description: currentModeId === lang ? nls.localize('configuredLanguage', "Configured Language") : void 0
+ description: currentModeId === lang ? `${languageModeId} (${configureLabel})` : languageModeId
};
});
picks[0].separator = { border: true, label: nls.localize('languagesPicks', "languages") };
diff --git a/src/vs/workbench/parts/debug/electron-browser/debugService.ts b/src/vs/workbench/parts/debug/electron-browser/debugService.ts
index d7f264091d7..2fc38e6fa79 100644
--- a/src/vs/workbench/parts/debug/electron-browser/debugService.ts
+++ b/src/vs/workbench/parts/debug/electron-browser/debugService.ts
@@ -607,7 +607,7 @@ export class DebugService implements debug.IDebugService {
timeout: 1000 * 60 * 5,
args: [`${ publisher }.${ type }`, JSON.stringify(data), aiKey],
env: {
- ATOM_SHELL_INTERNAL_RUN_AS_NODE: 1,
+ ELECTRON_RUN_AS_NODE: 1,
PIPE_LOGGING: 'true',
AMD_ENTRYPOINT: 'vs/workbench/parts/debug/node/telemetryApp'
}
diff --git a/src/vs/workbench/parts/debug/electron-browser/rawDebugSession.ts b/src/vs/workbench/parts/debug/electron-browser/rawDebugSession.ts
index 1c19f36b60e..1786d1e0a9e 100644
--- a/src/vs/workbench/parts/debug/electron-browser/rawDebugSession.ts
+++ b/src/vs/workbench/parts/debug/electron-browser/rawDebugSession.ts
@@ -25,6 +25,7 @@ import v8 = require('vs/workbench/parts/debug/node/v8Protocol');
import {IOutputService} from 'vs/workbench/parts/output/common/output';
import {ExtensionsChannelId} from 'vs/platform/extensionManagement/common/extensionManagement';
import {TerminalSupport} from 'vs/workbench/parts/debug/electron-browser/terminalSupport';
+import {IConfigurationService} from 'vs/platform/configuration/common/configuration';
import {shell} from 'electron';
@@ -75,7 +76,8 @@ export class RawDebugSession extends v8.V8Protocol implements debug.IRawDebugSes
@ITelemetryService private telemetryService: ITelemetryService,
@IOutputService private outputService: IOutputService,
@ITerminalService private terminalService: ITerminalService,
- @IExternalTerminalService private nativeTerminalService: IExternalTerminalService
+ @IExternalTerminalService private nativeTerminalService: IExternalTerminalService,
+ @IConfigurationService private configurationService: IConfigurationService
) {
super();
this.emittedStopped = false;
@@ -348,7 +350,7 @@ export class RawDebugSession extends v8.V8Protocol implements debug.IRawDebugSes
if (request.command === 'runInTerminal') {
- TerminalSupport.runInTerminal(this.terminalService, this.nativeTerminalService, request.arguments, response).then(() => {
+ TerminalSupport.runInTerminal(this.terminalService, this.nativeTerminalService, this.configurationService, request.arguments, response).then(() => {
this.sendResponse(response);
}, e => {
response.success = false;
diff --git a/src/vs/workbench/parts/debug/electron-browser/terminalSupport.ts b/src/vs/workbench/parts/debug/electron-browser/terminalSupport.ts
index 0abf4baf819..b8474a0018f 100644
--- a/src/vs/workbench/parts/debug/electron-browser/terminalSupport.ts
+++ b/src/vs/workbench/parts/debug/electron-browser/terminalSupport.ts
@@ -8,33 +8,40 @@ import platform = require('vs/base/common/platform');
import {TPromise} from 'vs/base/common/winjs.base';
import {ITerminalService, ITerminalInstance} from 'vs/workbench/parts/terminal/electron-browser/terminal';
import {ITerminalService as IExternalTerminalService} from 'vs/workbench/parts/execution/common/execution';
+import {IConfigurationService} from 'vs/platform/configuration/common/configuration';
+export interface IIntegratedTerminalConfiguration {
+ terminal: {
+ integrated: {
+ shell: {
+ windows: string
+ }
+ }
+ };
+}
+
export class TerminalSupport {
private static integratedTerminalInstance: ITerminalInstance;
- public static runInTerminal(terminalService: ITerminalService, nativeTerminalService: IExternalTerminalService, args: DebugProtocol.RunInTerminalRequestArguments, response: DebugProtocol.RunInTerminalResponse): TPromise {
+ public static runInTerminal(terminalService: ITerminalService, nativeTerminalService: IExternalTerminalService, configurationService: IConfigurationService, args: DebugProtocol.RunInTerminalRequestArguments, response: DebugProtocol.RunInTerminalResponse): TPromise {
if (args.kind === 'external') {
return nativeTerminalService.runInTerminal(args.title, args.cwd, args.args, args.env);
}
- return this.runInIntegratedTerminal(terminalService, args);
- }
-
- private static runInIntegratedTerminal(terminalService: ITerminalService, args: DebugProtocol.RunInTerminalRequestArguments): TPromise {
if (!TerminalSupport.integratedTerminalInstance) {
TerminalSupport.integratedTerminalInstance = terminalService.createInstance(args.title || nls.localize('debuggee', "debuggee"));
}
terminalService.setActiveInstance(TerminalSupport.integratedTerminalInstance);
terminalService.showPanel(true);
- const command = this.prepareCommand(args);
+ const command = this.prepareCommand(args, configurationService);
TerminalSupport.integratedTerminalInstance.sendText(command, true);
return TPromise.as(void 0);
}
- private static prepareCommand(args: DebugProtocol.RunInTerminalRequestArguments): string {
+ private static prepareCommand(args: DebugProtocol.RunInTerminalRequestArguments, configurationService: IConfigurationService): string {
let command = '';
if (platform.isWindows) {
@@ -44,21 +51,41 @@ export class TerminalSupport {
return (s.indexOf(' ') >= 0 || s.indexOf('"') >= 0) ? `"${s}"` : s;
};
- if (args.cwd) {
- command += `cd ${quote(args.cwd)} && `;
+ const conf = configurationService.getConfiguration();
+
+ let isPowerShell = false;
+ if (conf.terminal && conf.terminal.integrated && conf.terminal.integrated.shell && conf.terminal.integrated.shell.windows) {
+ isPowerShell = conf.terminal.integrated.shell.windows.indexOf('PowerShell') >= 0;
}
- if (args.env) {
- command += 'cmd /C "';
- for (let key in args.env) {
- command += `set "${key}=${args.env[key]}" && `;
+
+ if (isPowerShell) {
+
+ if (args.cwd) {
+ command += `cd ${quote(args.cwd)}; `;
+ }
+ for (let a of args.args) {
+ command += `${quote(a)} `;
+ }
+
+ } else {
+
+ if (args.cwd) {
+ command += `cd ${quote(args.cwd)} && `;
+ }
+ if (args.env) {
+ command += 'cmd /C "';
+ for (let key in args.env) {
+ command += `set "${key}=${args.env[key]}" && `;
+ }
+ }
+ for (let a of args.args) {
+ command += `${quote(a)} `;
+ }
+ if (args.env) {
+ command += '"';
}
}
- for (let a of args.args) {
- command += `${quote(a)} `;
- }
- if (args.env) {
- command += '"';
- }
+
} else {
const quote = (s: string) => {
s = s.replace(/\"/g, '\\"');
diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionEditor.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionEditor.ts
index 195c970b017..ab5fab917dd 100644
--- a/src/vs/workbench/parts/extensions/electron-browser/extensionEditor.ts
+++ b/src/vs/workbench/parts/extensions/electron-browser/extensionEditor.ts
@@ -42,6 +42,7 @@ import { Keybinding } from 'vs/base/common/keyCodes';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { DomScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement';
import { IMessageService } from 'vs/platform/message/common/message';
+import { IOpenerService } from 'vs/platform/opener/common/opener';
function renderBody(body: string): string {
return `
@@ -140,7 +141,8 @@ export class ExtensionEditor extends BaseEditor {
@IThemeService private themeService: IThemeService,
@IWorkbenchEditorService private editorService: IWorkbenchEditorService,
@IKeybindingService private keybindingService: IKeybindingService,
- @IMessageService private messageService: IMessageService
+ @IMessageService private messageService: IMessageService,
+ @IOpenerService private openerService: IOpenerService
) {
super(ExtensionEditor.ID, telemetryService);
this._highlight = null;
@@ -276,9 +278,9 @@ export class ExtensionEditor extends BaseEditor {
webview.style(this.themeService.getColorTheme());
webview.contents = [body];
- const linkListener = webview.onDidClickLink(link => shell.openExternal(link.toString(true)));
- const themeListener = this.themeService.onDidColorThemeChange(themeId => webview.style(themeId));
- this.contentDisposables.push(webview, linkListener, themeListener);
+ webview.onDidClickLink(link => this.openerService.open(link), null, this.contentDisposables);
+ this.themeService.onDidColorThemeChange(themeId => webview.style(themeId), null, this.contentDisposables);
+ this.contentDisposables.push(webview);
})
.then(null, () => {
const p = append(this.content, $('p'));
diff --git a/src/vs/workbench/parts/files/browser/media/explorerviewlet.css b/src/vs/workbench/parts/files/browser/media/explorerviewlet.css
index 5dbaac7ee5e..e0f99c3f6cd 100644
--- a/src/vs/workbench/parts/files/browser/media/explorerviewlet.css
+++ b/src/vs/workbench/parts/files/browser/media/explorerviewlet.css
@@ -15,6 +15,11 @@
line-height: 22px;
}
+.explorer-viewlet .explorer-item {
+ display: flex; /* this helps showing the overflow ellipsis (...) even though we use display:inline-block for the labels */
+ flex-wrap: nowrap;
+}
+
.explorer-viewlet .explorer-item-label,
.explorer-viewlet .open-editor,
.explorer-viewlet .editor-group {
@@ -25,6 +30,7 @@
.explorer-viewlet .explorer-item-label,
.explorer-viewlet .explorer-item .monaco-inputbox {
display: inline-block; /* required for icons support :before rule */
+ flex: 1;
}
.explorer-viewlet .explorer-open-editors .monaco-tree .monaco-tree-row > .content {
diff --git a/src/vs/workbench/parts/files/browser/views/explorerViewer.ts b/src/vs/workbench/parts/files/browser/views/explorerViewer.ts
index 70e41699ed8..e80253e0029 100644
--- a/src/vs/workbench/parts/files/browser/views/explorerViewer.ts
+++ b/src/vs/workbench/parts/files/browser/views/explorerViewer.ts
@@ -398,19 +398,19 @@ export class FileRenderer extends ActionsRenderer implements IRenderer {
const name = dotSegments[0]; // file.txt => "file", .dockerfile => "", file.some.txt => "file"
if (name) {
- classes.push(`${name.toLowerCase()}-name-file-icon`);
+ classes.push(`${this.cssEscape(name.toLowerCase())}-name-file-icon`);
}
const extensions = dotSegments.splice(1);
if (extensions.length > 0) {
for (let i = 0; i < extensions.length; i++) {
- classes.push(`${extensions.slice(i).join('.').toLowerCase()}-ext-file-icon`); // add each combination of all found extensions if more than one
+ classes.push(`${this.cssEscape(extensions.slice(i).join('.').toLowerCase())}-ext-file-icon`); // add each combination of all found extensions if more than one
}
}
const langId = this.modeService.getModeIdByFilenameOrFirstLine(fsPath);
if (langId) {
- classes.push(`${langId}-lang-file-icon`);
+ classes.push(`${this.cssEscape(langId)}-lang-file-icon`);
}
return classes;
@@ -422,11 +422,15 @@ export class FileRenderer extends ActionsRenderer implements IRenderer {
const classes = ['folder-icon'];
if (basename) {
- classes.push(`${basename.toLowerCase()}-name-folder-icon`);
+ classes.push(`${this.cssEscape(basename.toLowerCase())}-name-folder-icon`);
}
return classes;
}
+
+ private cssEscape(val: string): string {
+ return val.replace(/\s/g, '\\$&'); // make sure to not introduce CSS classes from files that contain whitespace
+ }
}
// Explorer Accessibility Provider
diff --git a/src/vs/workbench/parts/git/electron-browser/electronGitService.ts b/src/vs/workbench/parts/git/electron-browser/electronGitService.ts
index 59e84d0d967..fa51cb29a32 100644
--- a/src/vs/workbench/parts/git/electron-browser/electronGitService.ts
+++ b/src/vs/workbench/parts/git/electron-browser/electronGitService.ts
@@ -158,7 +158,7 @@ function createRemoteRawGitService(gitPath: string, execPath: string, workspaceR
timeout: 1000 * 60,
args: [path, workspaceRoot, encoding, execPath, version],
env: {
- ATOM_SHELL_INTERNAL_RUN_AS_NODE: 1,
+ ELECTRON_RUN_AS_NODE: 1,
PIPE_LOGGING: 'true',
AMD_ENTRYPOINT: 'vs/workbench/parts/git/node/gitApp',
VERBOSE_LOGGING: String(verbose)
diff --git a/src/vs/workbench/parts/search/browser/search.contribution.ts b/src/vs/workbench/parts/search/browser/search.contribution.ts
index e5215a75ab6..9819545ae25 100644
--- a/src/vs/workbench/parts/search/browser/search.contribution.ts
+++ b/src/vs/workbench/parts/search/browser/search.contribution.ts
@@ -25,11 +25,12 @@ import {IKeybindings} from 'vs/platform/keybinding/common/keybinding';
import {IQuickOpenService} from 'vs/workbench/services/quickopen/common/quickOpenService';
import {IViewletService} from 'vs/workbench/services/viewlet/common/viewletService';
import {KeyMod, KeyCode} from 'vs/base/common/keyCodes';
-import {OpenSearchViewletAction, ReplaceInFilesAction, ShowNextSearchTermAction, ShowPreviousSearchTermAction, FocusNextInputAction, FocusPreviousInputAction} from 'vs/workbench/parts/search/browser/searchActions';
+import * as searchActions from 'vs/workbench/parts/search/browser/searchActions';
import * as Constants from 'vs/workbench/parts/search/common/constants';
import { registerContributions as replaceContributions } from 'vs/workbench/parts/search/browser/replaceContributions';
import { registerContributions as searchWidgetContributions } from 'vs/workbench/parts/search/browser/searchWidget';
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
+import { ToggleCaseSensitiveKeybinding, ToggleRegexKeybinding, ToggleWholeWordKeybinding, ShowPreviousFindTermKeybinding, ShowNextFindTermKeybinding } from 'vs/editor/contrib/find/common/findModel';
replaceContributions();
searchWidgetContributions();
@@ -118,13 +119,13 @@ const openSearchViewletKb: IKeybindings = {
};
(Registry.as(ActionExtensions.WorkbenchActions)).registerWorkbenchAction(
- new SyncActionDescriptor(OpenSearchViewletAction, OpenSearchViewletAction.ID, OpenSearchViewletAction.LABEL, openSearchViewletKb),
+ new SyncActionDescriptor(searchActions.OpenSearchViewletAction, searchActions.OpenSearchViewletAction.ID, searchActions.OpenSearchViewletAction.LABEL, openSearchViewletKb),
'View: Show Search',
nls.localize('view', "View")
);
(Registry.as(ActionExtensions.WorkbenchActions)).registerWorkbenchAction(
- new SyncActionDescriptor(ReplaceInFilesAction, ReplaceInFilesAction.ID, ReplaceInFilesAction.LABEL, {
+ new SyncActionDescriptor(searchActions.ReplaceInFilesAction, searchActions.ReplaceInFilesAction.ID, searchActions.ReplaceInFilesAction.LABEL, {
primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_H
}),
'Replace in Files'
@@ -165,22 +166,22 @@ registry.registerWorkbenchAction(new SyncActionDescriptor(ShowAllSymbolsAction,
primary: KeyMod.CtrlCmd | KeyCode.KEY_T
}), 'Show All Symbols');
-registry.registerWorkbenchAction(new SyncActionDescriptor(ShowNextSearchTermAction, ShowNextSearchTermAction.ID, ShowNextSearchTermAction.LABEL, {
- primary: KeyMod.Alt | KeyCode.DownArrow
-}, ContextKeyExpr.and(Constants.SearchViewletVisibleKey, Constants.SearchInputBoxFocussedKey)), '');
+registry.registerWorkbenchAction(new SyncActionDescriptor(searchActions.ShowNextSearchTermAction, searchActions.ShowNextSearchTermAction.ID, searchActions.ShowNextSearchTermAction.LABEL, ShowNextFindTermKeybinding, ContextKeyExpr.and(Constants.SearchViewletVisibleKey, Constants.SearchInputBoxFocussedKey)), '');
-registry.registerWorkbenchAction(new SyncActionDescriptor(ShowPreviousSearchTermAction, ShowPreviousSearchTermAction.ID, ShowPreviousSearchTermAction.LABEL, {
- primary: KeyMod.Alt | KeyCode.UpArrow
-}, ContextKeyExpr.and(Constants.SearchViewletVisibleKey, Constants.SearchInputBoxFocussedKey)), '');
+registry.registerWorkbenchAction(new SyncActionDescriptor(searchActions.ShowPreviousSearchTermAction, searchActions.ShowPreviousSearchTermAction.ID, searchActions.ShowPreviousSearchTermAction.LABEL, ShowPreviousFindTermKeybinding, ContextKeyExpr.and(Constants.SearchViewletVisibleKey, Constants.SearchInputBoxFocussedKey)), '');
-registry.registerWorkbenchAction(new SyncActionDescriptor(FocusNextInputAction, FocusNextInputAction.ID, FocusNextInputAction.LABEL, {
+registry.registerWorkbenchAction(new SyncActionDescriptor(searchActions.FocusNextInputAction, searchActions.FocusNextInputAction.ID, searchActions.FocusNextInputAction.LABEL, {
primary: KeyCode.DownArrow
}, ContextKeyExpr.and(Constants.SearchViewletVisibleKey, Constants.InputBoxFocussedKey)), '');
-registry.registerWorkbenchAction(new SyncActionDescriptor(FocusPreviousInputAction, FocusPreviousInputAction.ID, FocusPreviousInputAction.LABEL, {
+registry.registerWorkbenchAction(new SyncActionDescriptor(searchActions.FocusPreviousInputAction, searchActions.FocusPreviousInputAction.ID, searchActions.FocusPreviousInputAction.LABEL, {
primary: KeyCode.UpArrow
}, ContextKeyExpr.and(Constants.SearchViewletVisibleKey, Constants.InputBoxFocussedKey, Constants.SearchInputBoxFocussedKey.toNegated())), '');
+registry.registerWorkbenchAction(new SyncActionDescriptor(searchActions.ToggleCaseSensitiveAction, Constants.ToggleCaseSensitiveActionId, '', ToggleCaseSensitiveKeybinding, ContextKeyExpr.and(Constants.SearchViewletVisibleKey, Constants.SearchInputBoxFocussedKey)), '');
+registry.registerWorkbenchAction(new SyncActionDescriptor(searchActions.ToggleWholeWordAction, Constants.ToggleWholeWordActionId, '', ToggleWholeWordKeybinding, ContextKeyExpr.and(Constants.SearchViewletVisibleKey, Constants.SearchInputBoxFocussedKey)), '');
+registry.registerWorkbenchAction(new SyncActionDescriptor(searchActions.ToggleRegexAction, Constants.ToggleRegexActionId, '', ToggleRegexKeybinding, ContextKeyExpr.and(Constants.SearchViewletVisibleKey, Constants.SearchInputBoxFocussedKey)), '');
+
// Configuration
const configurationRegistry = Registry.as(ConfigurationExtensions.Configuration);
configurationRegistry.registerConfiguration({
diff --git a/src/vs/workbench/parts/search/browser/searchActions.ts b/src/vs/workbench/parts/search/browser/searchActions.ts
index a0660b81c59..ec7c97d3bb3 100644
--- a/src/vs/workbench/parts/search/browser/searchActions.ts
+++ b/src/vs/workbench/parts/search/browser/searchActions.ts
@@ -39,6 +39,45 @@ export function appendKeyBindingLabel(label: string, keyBinding: any, keyBinding
return label + ' (' + keyBindingService2.getLabelFor(keyBinding) + ')';
}
+export class ToggleCaseSensitiveAction extends Action {
+
+ constructor(id: string, label: string, @IViewletService private viewletService: IViewletService) {
+ super(id, label);
+ }
+
+ public run(): TPromise {
+ let searchViewlet = this.viewletService.getActiveViewlet();
+ searchViewlet.toggleCaseSensitive();
+ return TPromise.as(null);
+ }
+}
+
+export class ToggleWholeWordAction extends Action {
+
+ constructor(id: string, label: string, @IViewletService private viewletService: IViewletService) {
+ super(id, label);
+ }
+
+ public run(): TPromise {
+ let searchViewlet = this.viewletService.getActiveViewlet();
+ searchViewlet.toggleWholeWords();
+ return TPromise.as(null);
+ }
+}
+
+export class ToggleRegexAction extends Action {
+
+ constructor(id: string, label: string, @IViewletService private viewletService: IViewletService) {
+ super(id, label);
+ }
+
+ public run(): TPromise {
+ let searchViewlet = this.viewletService.getActiveViewlet();
+ searchViewlet.toggleRegex();
+ return TPromise.as(null);
+ }
+}
+
export class ShowNextSearchTermAction extends Action {
public static ID = 'search.history.showNext';
diff --git a/src/vs/workbench/parts/search/browser/searchViewlet.ts b/src/vs/workbench/parts/search/browser/searchViewlet.ts
index d33bd665e66..9f251cce6af 100644
--- a/src/vs/workbench/parts/search/browser/searchViewlet.ts
+++ b/src/vs/workbench/parts/search/browser/searchViewlet.ts
@@ -617,6 +617,21 @@ export class SearchViewlet extends Viewlet {
return dom.hasClass(this.queryDetails, 'more');
}
+ public toggleCaseSensitive(): void {
+ this.searchWidget.searchInput.setCaseSensitive(!this.searchWidget.searchInput.getCaseSensitive());
+ this.onQueryChanged(true, true);
+ }
+
+ public toggleWholeWords(): void {
+ this.searchWidget.searchInput.setWholeWords(!this.searchWidget.searchInput.getWholeWords());
+ this.onQueryChanged(true, true);
+ }
+
+ public toggleRegex(): void {
+ this.searchWidget.searchInput.setRegex(!this.searchWidget.searchInput.getRegex());
+ this.onQueryChanged(true, true);
+ }
+
public toggleFileTypes(moveFocus?: boolean, show?: boolean, skipLayout?: boolean, reverse?: boolean): void {
let cls = 'more';
show = typeof show === 'undefined' ? !dom.hasClass(this.queryDetails, cls) : Boolean(show);
diff --git a/src/vs/workbench/parts/search/browser/searchWidget.ts b/src/vs/workbench/parts/search/browser/searchWidget.ts
index b6827643e92..3b66bedd7b6 100644
--- a/src/vs/workbench/parts/search/browser/searchWidget.ts
+++ b/src/vs/workbench/parts/search/browser/searchWidget.ts
@@ -201,7 +201,10 @@ export class SearchWidget extends Widget {
let inputOptions: IFindInputOptions = {
label: nls.localize('label.Search', 'Search: Type Search Term and press Enter to search or Escape to cancel'),
validation: (value: string) => this.validatSearchInput(value),
- placeholder: nls.localize('search.placeHolder', "Search")
+ placeholder: nls.localize('search.placeHolder', "Search"),
+ appendCaseSensitiveLabel: appendKeyBindingLabel('', this.keyBindingService2.lookupKeybindings(Constants.ToggleCaseSensitiveActionId)[0], this.keyBindingService2),
+ appendWholeWordsLabel: appendKeyBindingLabel('', this.keyBindingService2.lookupKeybindings(Constants.ToggleWholeWordActionId)[0], this.keyBindingService2),
+ appendRegexLabel: appendKeyBindingLabel('', this.keyBindingService2.lookupKeybindings(Constants.ToggleRegexActionId)[0], this.keyBindingService2)
};
let searchInputContainer= dom.append(parent, dom.$('.search-container.input-box'));
@@ -350,7 +353,7 @@ export class SearchWidget extends Widget {
export function registerContributions() {
KeybindingsRegistry.registerCommandAndKeybindingRule({id: ReplaceAllAction.ID,
weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
- when: ContextKeyExpr.and(ContextKeyExpr.has('searchViewletVisible'), Constants.ReplaceActiveKey, CONTEXT_FIND_WIDGET_NOT_VISIBLE),
+ when: ContextKeyExpr.and(Constants.SearchViewletVisibleKey, Constants.ReplaceActiveKey, CONTEXT_FIND_WIDGET_NOT_VISIBLE),
primary: KeyMod.Alt | KeyMod.CtrlCmd | KeyCode.Enter,
handler: accessor => {
if (isSearchViewletFocussed(accessor.get(IViewletService))) {
diff --git a/src/vs/workbench/parts/search/common/constants.ts b/src/vs/workbench/parts/search/common/constants.ts
index 94d8751d55f..678d59c02dd 100644
--- a/src/vs/workbench/parts/search/common/constants.ts
+++ b/src/vs/workbench/parts/search/common/constants.ts
@@ -7,6 +7,11 @@ import {RawContextKey} from 'vs/platform/contextkey/common/contextkey';
export const VIEWLET_ID = 'workbench.view.search';
+export const ToggleCaseSensitiveActionId = 'toggleSearchCaseSensitive';
+export const ToggleWholeWordActionId = 'toggleSearchWholeWord';
+export const ToggleRegexActionId = 'toggleSearchRegex';
+
+
export const SearchViewletVisibleKey = new RawContextKey('searchViewletVisible', true);
export const InputBoxFocussedKey = new RawContextKey('inputBoxFocus', false);
export const SearchInputBoxFocussedKey = new RawContextKey('searchInputBoxFocus', false);
diff --git a/src/vs/workbench/parts/terminal/electron-browser/media/terminal.css b/src/vs/workbench/parts/terminal/electron-browser/media/terminal.css
index 132831e836b..35c4f0f5188 100644
--- a/src/vs/workbench/parts/terminal/electron-browser/media/terminal.css
+++ b/src/vs/workbench/parts/terminal/electron-browser/media/terminal.css
@@ -22,6 +22,7 @@
display: flex;
padding: 0 20px;
flex-grow: 1;
+ width: 100%;
}
.monaco-workbench .panel.integrated-terminal .terminal-wrapper {
diff --git a/src/vs/workbench/parts/terminal/electron-browser/terminal.ts b/src/vs/workbench/parts/terminal/electron-browser/terminal.ts
index 794b7a2ce95..1c558a60f49 100644
--- a/src/vs/workbench/parts/terminal/electron-browser/terminal.ts
+++ b/src/vs/workbench/parts/terminal/electron-browser/terminal.ts
@@ -62,7 +62,7 @@ export interface ITerminalService {
onInstanceTitleChanged: Event;
terminalInstances: ITerminalInstance[];
- createInstance(name?: string, shellPath?: string): ITerminalInstance;
+ createInstance(name?: string, shellPath?: string, shellArgs?: string[]): ITerminalInstance;
getInstanceFromId(terminalId: number): ITerminalInstance;
getInstanceLabels(): string[];
getActiveInstance(): ITerminalInstance;
diff --git a/src/vs/workbench/parts/terminal/electron-browser/terminalActions.ts b/src/vs/workbench/parts/terminal/electron-browser/terminalActions.ts
index 9f622245cae..1db5b02b6c5 100644
--- a/src/vs/workbench/parts/terminal/electron-browser/terminalActions.ts
+++ b/src/vs/workbench/parts/terminal/electron-browser/terminalActions.ts
@@ -47,6 +47,9 @@ export class KillTerminalAction extends Action {
let terminalInstance = this.terminalService.getActiveInstance();
if (terminalInstance) {
this.terminalService.getActiveInstance().dispose();
+ if (this.terminalService.terminalInstances.length > 0) {
+ this.terminalService.showPanel(true);
+ }
}
return TPromise.as(void 0);
}
diff --git a/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts b/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts
index f895e8ee838..47e7ac5cc06 100644
--- a/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts
+++ b/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts
@@ -38,6 +38,7 @@ export class TerminalInstance implements ITerminalInstance {
public get onTitleChanged(): Event { return this._onTitleChanged.event; }
private isExiting: boolean = false;
+ private isVisible: boolean = false;
private toDispose: lifecycle.IDisposable[] = [];
private skipTerminalKeybindings: Keybinding[] = [];
private process: cp.ChildProcess;
@@ -52,13 +53,13 @@ export class TerminalInstance implements ITerminalInstance {
private container: HTMLElement,
private workspace: IWorkspace,
name: string,
- shellPath: string,
+ shell: IShell,
@IKeybindingService private keybindingService: IKeybindingService,
@IMessageService private messageService: IMessageService
) {
this._id = TerminalInstance.ID_COUNTER++;
this._onTitleChanged = new Emitter();
- this.createProcess(workspace, name, shellPath);
+ this.createProcess(workspace, name, shell);
if (container) {
this.attachToElement(container);
@@ -74,6 +75,7 @@ export class TerminalInstance implements ITerminalInstance {
throw new Error('The terminal instance has already been attached to a container');
}
+ this.container = container;
this.wrapperElement = document.createElement('div');
DOM.addClass(this.wrapperElement, 'terminal-wrapper');
this.xtermElement = document.createElement('div');
@@ -139,6 +141,7 @@ export class TerminalInstance implements ITerminalInstance {
this.container.appendChild(this.wrapperElement);
this.layout(new Dimension(this.container.offsetWidth, this.container.offsetHeight));
+ this.setVisible(this.isVisible);
}
public copySelection(): void {
@@ -195,7 +198,10 @@ export class TerminalInstance implements ITerminalInstance {
}
public setVisible(visible: boolean): void {
- DOM.toggleClass(this.wrapperElement, 'active', visible);
+ this.isVisible = visible;
+ if (this.wrapperElement) {
+ DOM.toggleClass(this.wrapperElement, 'active', visible);
+ }
}
public scrollDown(): void {
@@ -210,9 +216,11 @@ export class TerminalInstance implements ITerminalInstance {
return typeof data === 'string' ? data.replace(TerminalInstance.EOL_REGEX, os.EOL) : data;
}
- private createProcess(workspace: IWorkspace, name?: string, shellPath?: string) {
+ private createProcess(workspace: IWorkspace, name: string, shell: IShell) {
let locale = this.configHelper.isSetLocaleVariables() ? platform.locale : undefined;
- let shell = shellPath ? { executable: shellPath, args: [] } : this.configHelper.getShell();
+ if (!shell.executable) {
+ shell = this.configHelper.getShell();
+ }
let env = TerminalInstance.createTerminalEnv(process.env, shell, workspace, locale);
this._title = name ? name : '';
this.process = cp.fork('./terminalProcess', [], {
@@ -244,9 +252,11 @@ export class TerminalInstance implements ITerminalInstance {
let env = TerminalInstance.cloneEnv(parentEnv);
env['PTYPID'] = process.pid.toString();
env['PTYSHELL'] = shell.executable;
- shell.args.forEach((arg, i) => {
- env[`PTYSHELLARG${i}`] = arg;
- });
+ if (shell.args) {
+ shell.args.forEach((arg, i) => {
+ env[`PTYSHELLARG${i}`] = arg;
+ });
+ }
env['PTYCWD'] = TerminalInstance.sanitizeCwd(workspace ? workspace.resource.fsPath : os.homedir());
if (locale) {
env['LANG'] = TerminalInstance.getLangEnvVariable(locale);
diff --git a/src/vs/workbench/parts/terminal/electron-browser/terminalPanel.ts b/src/vs/workbench/parts/terminal/electron-browser/terminalPanel.ts
index 5a6b61185ad..333101d492d 100644
--- a/src/vs/workbench/parts/terminal/electron-browser/terminalPanel.ts
+++ b/src/vs/workbench/parts/terminal/electron-browser/terminalPanel.ts
@@ -72,6 +72,8 @@ export class TerminalPanel extends Panel {
this.updateTheme();
this.updateConfig();
+ // Force another layout (first is setContainers) since config has changed
+ this.layout(new Dimension(this.terminalContainer.offsetWidth, this.terminalContainer.offsetHeight));
return TPromise.as(void 0);
}
diff --git a/src/vs/workbench/parts/terminal/electron-browser/terminalProcess.js b/src/vs/workbench/parts/terminal/electron-browser/terminalProcess.js
index 5b383f8f17b..9b38c52dd7f 100644
--- a/src/vs/workbench/parts/terminal/electron-browser/terminalProcess.js
+++ b/src/vs/workbench/parts/terminal/electron-browser/terminalProcess.js
@@ -65,7 +65,7 @@ function getArgs() {
function cleanEnv() {
var keys = [
- 'ATOM_SHELL_INTERNAL_RUN_AS_NODE',
+ 'ELECTRON_RUN_AS_NODE',
'PTYCWD',
'PTYPID',
'PTYSHELL'
diff --git a/src/vs/workbench/parts/terminal/electron-browser/terminalService.ts b/src/vs/workbench/parts/terminal/electron-browser/terminalService.ts
index b9bc29f817d..5c91bb1ff06 100644
--- a/src/vs/workbench/parts/terminal/electron-browser/terminalService.ts
+++ b/src/vs/workbench/parts/terminal/electron-browser/terminalService.ts
@@ -14,7 +14,7 @@ import { IPartService } from 'vs/workbench/services/part/common/partService';
import { ITerminalInstance, ITerminalService, KEYBINDING_CONTEXT_TERMINAL_FOCUS, TERMINAL_PANEL_ID } from 'vs/workbench/parts/terminal/electron-browser/terminal';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { TPromise } from 'vs/base/common/winjs.base';
-import { TerminalConfigHelper } from 'vs/workbench/parts/terminal/electron-browser/terminalConfigHelper';
+import { TerminalConfigHelper, IShell } from 'vs/workbench/parts/terminal/electron-browser/terminalConfigHelper';
import { TerminalInstance } from 'vs/workbench/parts/terminal/electron-browser/terminalInstance';
export class TerminalService implements ITerminalService {
@@ -51,7 +51,11 @@ export class TerminalService implements ITerminalService {
this._configHelper = this.instantiationService.createInstance(TerminalConfigHelper, platform.platform);
}
- public createInstance(name?: string, shellPath?: string): ITerminalInstance {
+ public createInstance(name?: string, shellPath?: string, shellArgs?: string[]): ITerminalInstance {
+ let shell: IShell = {
+ executable: shellPath,
+ args: shellArgs
+ };
let terminalInstance = this.instantiationService.createInstance(TerminalInstance,
this.terminalFocusContextKey,
this.onTerminalInstanceDispose.bind(this),
@@ -59,7 +63,7 @@ export class TerminalService implements ITerminalService {
this.terminalContainer,
this.workspaceContextService.getWorkspace(),
name,
- shellPath);
+ shell);
terminalInstance.addDisposable(terminalInstance.onTitleChanged(this._onInstanceTitleChanged.fire, this._onInstanceTitleChanged));
this.terminalInstances.push(terminalInstance);
if (this.terminalInstances.length === 1) {
@@ -139,11 +143,11 @@ export class TerminalService implements ITerminalService {
}
public setContainers(panelContainer: Builder, terminalContainer: HTMLElement): void {
+ this._configHelper.panelContainer = panelContainer;
this.terminalContainer = terminalContainer;
this._terminalInstances.forEach(terminalInstance => {
terminalInstance.attachToElement(this.terminalContainer);
});
- this._configHelper.panelContainer = panelContainer;
}
public showPanel(focus?: boolean): TPromise {
@@ -151,7 +155,6 @@ export class TerminalService implements ITerminalService {
let panel = this.panelService.getActivePanel();
if (!panel || panel.getId() !== TERMINAL_PANEL_ID) {
return this.panelService.openPanel(TERMINAL_PANEL_ID, focus).then(() => {
- panel = this.panelService.getActivePanel();
if (focus) {
this.getActiveInstance().focus(true);
}
diff --git a/src/vs/workbench/services/contextview/electron-browser/contextmenuService.ts b/src/vs/workbench/services/contextview/electron-browser/contextmenuService.ts
index a5956e04643..d6a9ab0da6c 100644
--- a/src/vs/workbench/services/contextview/electron-browser/contextmenuService.ts
+++ b/src/vs/workbench/services/contextview/electron-browser/contextmenuService.ts
@@ -54,7 +54,7 @@ export class ContextMenuService implements IContextMenuService {
x *= zoom;
y *= zoom;
- menu.popup(remote.getCurrentWindow(), Math.floor(x), Math.floor(y), -1 /* no item selected by default */);
+ menu.popup(remote.getCurrentWindow(), Math.floor(x), Math.floor(y));
if (delegate.onHide) {
delegate.onHide(undefined);
}