Merge from vscode 709a07d51919d3266ca71699c6ddfb2d3547c0e1 (#6575)

This commit is contained in:
Chris LaFreniere
2019-08-02 21:06:44 -07:00
committed by GitHub
parent 402b50c03b
commit 62d2fb534d
103 changed files with 726 additions and 374 deletions

View File

@@ -46,6 +46,9 @@ steps:
- script: |
DISPLAY=:10 ./scripts/test.sh --tfs "Unit Tests"
displayName: Run Unit Tests
- script: |
DISPLAY=:10 ./scripts/test-integration.sh --tfs "Integration Tests"
displayName: Run Integration Tests
- task: PublishTestResults@2
displayName: Publish Tests Results
inputs:

View File

@@ -93,16 +93,23 @@ steps:
- script: |
set -e
yarn gulp "electron-x64"
# xvfb seems to be crashing often, let's make sure it's always up
service xvfb start
displayName: Start xvfb
condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false'))
- script: |
set -e
DISPLAY=:10 ./scripts/test.sh --build --tfs "Unit Tests"
# yarn smoketest -- --build "$(agent.builddirectory)/VSCode-linux-x64"
displayName: Run unit tests
condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false'))
- script: |
set -e
DISPLAY=:10 ./scripts/test-integration.sh --build --tfs "Integration Tests"
# yarn smoketest -- --build "$(agent.builddirectory)/VSCode-linux-x64"
displayName: Run integration tests
condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false'))
- script: |
set -e
AZURE_DOCUMENTDB_MASTERKEY="$(builds-docdb-key-readwrite)" \

View File

@@ -123,6 +123,7 @@ jobs:
- LinuxSnap
- LinuxArmhf
- LinuxAlpine
- LinuxWeb
- macOS
steps:
- template: sync-mooncake.yml
@@ -132,4 +133,4 @@ schedules:
displayName: Mon-Fri at 7:00
branches:
include:
- master
- master

View File

@@ -7,6 +7,9 @@ ROOT="$REPO/.."
WEB_BUILD_NAME="vscode-web"
WEB_TARBALL_FILENAME="vscode-web.tar.gz"
WEB_TARBALL_PATH="$ROOT/$WEB_TARBALL_FILENAME"
BUILD="$ROOT/$WEB_BUILD_NAME"
PACKAGEJSON="$BUILD/package.json"
VERSION=$(node -p "require(\"$PACKAGEJSON\").version")
rm -rf $ROOT/vscode-web.tar.*

View File

@@ -99,6 +99,7 @@ steps:
exec { yarn gulp "vscode-win32-$env:VSCODE_ARCH-min-ci" }
exec { yarn gulp "vscode-reh-win32-$env:VSCODE_ARCH-min-ci" }
exec { yarn gulp "vscode-reh-web-win32-$env:VSCODE_ARCH-min-ci" }
exec { yarn gulp "vscode-win32-$env:VSCODE_ARCH-code-helper" }
exec { yarn gulp "vscode-win32-$env:VSCODE_ARCH-inno-updater" }
displayName: Build

View File

@@ -136,12 +136,17 @@ function copyInnoUpdater(arch) {
};
}
function patchInnoUpdater(arch) {
function updateIcon(executablePath) {
return cb => {
const icon = path.join(repoPath, 'resources', 'win32', 'code.ico');
rcedit(path.join(buildPath(arch), 'tools', 'inno_updater.exe'), { icon }, cb);
rcedit(executablePath, { icon }, cb);
};
}
gulp.task(task.define('vscode-win32-ia32-inno-updater', task.series(copyInnoUpdater('ia32'), patchInnoUpdater('ia32'))));
gulp.task(task.define('vscode-win32-x64-inno-updater', task.series(copyInnoUpdater('x64'), patchInnoUpdater('x64'))));
gulp.task(task.define('vscode-win32-ia32-inno-updater', task.series(copyInnoUpdater('ia32'), updateIcon(path.join(buildPath('ia32'), 'tools', 'inno_updater.exe')))));
gulp.task(task.define('vscode-win32-x64-inno-updater', task.series(copyInnoUpdater('x64'), updateIcon(path.join(buildPath('x64'), 'tools', 'inno_updater.exe')))));
// CodeHelper.exe icon
gulp.task(task.define('vscode-win32-ia32-code-helper', task.series(updateIcon(path.join(buildPath('ia32'), 'resources', 'app', 'out', 'vs', 'platform', 'files', 'node', 'watcher', 'win32', 'CodeHelper.exe')))));
gulp.task(task.define('vscode-win32-x64-code-helper', task.series(updateIcon(path.join(buildPath('x64'), 'resources', 'app', 'out', 'vs', 'platform', 'files', 'node', 'watcher', 'win32', 'CodeHelper.exe')))));

View File

@@ -743,5 +743,31 @@
"OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN",
"THE SOFTWARE."
]
},
{
"name": "atob",
"licenseDetail": [
"The MIT License (MIT)",
"",
"Copyright (c) 2015 AJ ONeal",
"",
"Permission is hereby granted, free of charge, to any person obtaining a copy",
"of this software and associated documentation files (the \"Software\"), to deal",
"in the Software without restriction, including without limitation the rights",
"to use, copy, modify, merge, publish, distribute, sublicense, and/or sell",
"copies of the Software, and to permit persons to whom the Software is",
"furnished to do so, subject to the following conditions:",
"",
"The above copyright notice and this permission notice shall be included in all",
"copies or substantial portions of the Software.",
"",
"THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR",
"IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,",
"FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE",
"AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER",
"LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,",
"OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE",
"SOFTWARE."
]
}
]

View File

@@ -33,6 +33,14 @@
"sourceMaps": true,
"outFiles": ["${workspaceFolder}/server/out"]
}
],
"compounds": [
{
"name": "Launch Extension and Attach Language Server",
"configurations": [
"Launch Extension",
"Attach Language Server"
]
}
]
}

View File

@@ -14,7 +14,7 @@
"dependencies": {
"jsonc-parser": "^2.1.0",
"request-light": "^0.2.4",
"vscode-json-languageservice": "^3.3.0",
"vscode-json-languageservice": "^3.3.1",
"vscode-languageserver": "^5.3.0-next.8",
"vscode-nls": "^4.1.1",
"vscode-uri": "^2.0.3"

View File

@@ -73,15 +73,15 @@ request-light@^0.2.4:
https-proxy-agent "^2.2.1"
vscode-nls "^4.0.0"
vscode-json-languageservice@^3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.3.0.tgz#f80ec21c19fb8648c815220a2857f9f0b22e1094"
integrity sha512-upq1PhwDItazdtRJ/R7uU0Fgrf9iaYa1xLK4WFLExR0DgbPojd0YgMpfyknVyXGlxsg3fJQ0H7J++QeByXHh9w==
vscode-json-languageservice@^3.3.1:
version "3.3.1"
resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.3.1.tgz#4ad2c82db849a7bbe54fcbf5c9b3a2ed26dc8fee"
integrity sha512-Qyvlrftexu1acvwbMt+CDehVrDZtFV1GAJrKdOCHQL9bWNhzI06KEiSd4iXR0NUOuAdroG/uU4wBkH6e5CcTXg==
dependencies:
jsonc-parser "^2.1.0"
vscode-languageserver-types "^3.15.0-next.2"
vscode-nls "^4.1.1"
vscode-uri "^2.0.1"
vscode-uri "^2.0.3"
vscode-jsonrpc@^4.1.0-next.2:
version "4.1.0-next.2"
@@ -130,11 +130,6 @@ vscode-uri@^1.0.6:
resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-1.0.6.tgz#6b8f141b0bbc44ad7b07e94f82f168ac7608ad4d"
integrity sha512-sLI2L0uGov3wKVb9EB+vIQBl9tVP90nqRvxSoJ35vI3NjxE8jfsE5DSOhWgSunHSZmKS4OCi2jrtfxK7uyp2ww==
vscode-uri@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-2.0.1.tgz#5448e4f77d21d93ffa34b96f84c6c5e09e3f5a9b"
integrity sha512-s/k0zsYr6y+tsocFyxT/+G5aq8mEdpDZuph3LZ+UmCs7LNhx/xomiCy5kyP+jOAKC7RMCUvb6JbPD1/TgAvq0g==
vscode-uri@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-2.0.3.tgz#25e5f37f552fbee3cec7e5f80cef8469cefc6543"

View File

@@ -1627,7 +1627,7 @@
"bat": "_windows",
"clojure": "_clojure",
"coffeescript": "_coffee",
"jsonc": "_tsconfig",
"jsonc": "_json",
"c": "_c",
"cpp": "_cpp",
"csharp": "_c-sharp",
@@ -1896,7 +1896,7 @@
"bat": "_windows_light",
"clojure": "_clojure_light",
"coffeescript": "_coffee_light",
"jsonc": "_tsconfig_light",
"jsonc": "_json_light",
"c": "_c_light",
"cpp": "_cpp_light",
"csharp": "_c-sharp_light",
@@ -2012,4 +2012,4 @@
}
},
"version": "https://github.com/jesseweed/seti-ui/commit/904c16acced1134a81b31d71d60293288c31334b"
}
}

View File

@@ -76,7 +76,7 @@
"vscode-ripgrep": "^1.5.5",
"vscode-sqlite3": "4.0.8",
"vscode-textmate": "^4.2.2",
"xterm": "3.15.0-beta89",
"xterm": "3.15.0-beta90",
"xterm-addon-search": "0.2.0-beta3",
"xterm-addon-web-links": "0.1.0-beta10",
"yauzl": "^2.9.2",

View File

@@ -20,7 +20,7 @@
"vscode-proxy-agent": "0.4.0",
"vscode-ripgrep": "^1.5.5",
"vscode-textmate": "^4.2.2",
"xterm": "3.15.0-beta89",
"xterm": "3.15.0-beta90",
"xterm-addon-search": "0.2.0-beta3",
"xterm-addon-web-links": "0.1.0-beta10",
"yauzl": "^2.9.2",

View File

@@ -1159,10 +1159,10 @@ xterm-addon-web-links@0.1.0-beta10:
resolved "https://registry.yarnpkg.com/xterm-addon-web-links/-/xterm-addon-web-links-0.1.0-beta10.tgz#610fa9773a2a5ccd41c1c83ba0e2dd2c9eb66a23"
integrity sha512-xfpjy0V6bB4BR44qIgZQPoCMVakxb65gMscPkHpO//QxvUxKzabV3dxOsIbeZRFkUGsWTFlvz2OoaBLoNtv5gg==
xterm@3.15.0-beta89:
version "3.15.0-beta89"
resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.15.0-beta89.tgz#255962e2595deefb42b8c0043001256526163a3f"
integrity sha512-rNaoUamacPRg+ejbKDGRDNqR3SZ3Uf/pUW0mO+FF25/lIgdLq8x7RgZVBgFweCZ/dijPjxoyMcgfNDTH9h8LOg==
xterm@3.15.0-beta90:
version "3.15.0-beta90"
resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.15.0-beta90.tgz#e1732c2914584c86cffa797ba762c482f21ce182"
integrity sha512-eixIA5brfoez+Y8bJPCcIw8Q7LgOvxRX3cPBaGmo7ozUASx9IEGOmvIRQX1ozTUmxEiXPnAxOfl/isQ+yNlaww==
yauzl@^2.9.2:
version "2.10.0"

View File

@@ -34,8 +34,7 @@ if grep -qi Microsoft /proc/version; then
if [ -n "$WSL_EXT_WLOC" ]; then
# replace \r\n with \n in WSL_EXT_WLOC
WSL_CODE=$(wslpath -u "${WSL_EXT_WLOC%%[[:cntrl:]]}")/scripts/wslCode.sh
WIN_CODE_CMD=$(wslpath -w "$VSCODE_PATH/bin/$APP_NAME.cmd")
"$WSL_CODE" "$COMMIT" "$QUALITY" "$WIN_CODE_CMD" "$APP_NAME" "$DATAFOLDER" "$@"
"$WSL_CODE" "$COMMIT" "$QUALITY" "$ELECTRON" "$APP_NAME" "$DATAFOLDER" "$@"
exit $?
fi
else

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env bash
set -ex
set -e
if [[ "$OSTYPE" == "darwin"* ]]; then
realpath() { [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"; }

View File

@@ -79,8 +79,8 @@ export class CustomTreeViewPanel extends ViewletPanel {
this.treeView.show(container);
}
layoutBody(size: number): void {
this.treeView.layout(size);
layoutBody(height: number, width: number): void {
this.treeView.layout(height, width);
}
getActions(): IAction[] {

View File

@@ -195,6 +195,7 @@ export class Dialog extends Disposable {
this.applyStyles();
this.element.setAttribute('aria-label', this.message);
show(this.element);
// Focus first element

View File

@@ -647,12 +647,15 @@ export class MouseController<T> implements IDisposable {
}
const newSelection = disjunction(rangeSelection, relativeComplement(selection, contiguousRange));
this.list.setFocus([focus]);
this.list.setSelection(newSelection, e.browserEvent);
} else if (this.isSelectionSingleChangeEvent(e)) {
const selection = this.list.getSelection();
const newSelection = selection.filter(i => i !== focus);
this.list.setFocus([focus]);
if (selection.length === newSelection.length) {
this.list.setSelection([...newSelection, focus], e.browserEvent);
} else {

View File

@@ -626,8 +626,11 @@ class SubmenuMenuActionViewItem extends BaseMenuActionViewItem {
this._register(addDisposableListener(this.element, EventType.KEY_DOWN, e => {
let event = new StandardKeyboardEvent(e);
if (event.equals(KeyCode.RightArrow) || event.equals(KeyCode.Enter)) {
EventHelper.stop(e, true);
if (document.activeElement === this.item) {
if (event.equals(KeyCode.RightArrow) || event.equals(KeyCode.Enter)) {
EventHelper.stop(e, true);
}
}
}));
@@ -802,4 +805,4 @@ export function cleanMnemonic(label: string): string {
const mnemonicInText = matches[0].charAt(0) === '&';
return label.replace(regex, mnemonicInText ? '$2' : '').trim();
}
}

View File

@@ -244,7 +244,7 @@ class TreeRenderer<T, TFilterData, TTemplateData> implements IListRenderer<ITree
private _renderIndentGuides: RenderIndentGuides = RenderIndentGuides.None;
private renderedIndentGuides = new SetMap<ITreeNode<T, TFilterData>, HTMLDivElement>();
private activeParentNodes = new Set<ITreeNode<T, TFilterData>>();
private activeIndentNodes = new Set<ITreeNode<T, TFilterData>>();
private indentGuidesDisposable: IDisposable = Disposable.None;
private disposables: IDisposable[] = [];
@@ -353,6 +353,7 @@ class TreeRenderer<T, TFilterData, TTemplateData> implements IListRenderer<ITree
}
this.renderTwistie(node, data.templateData);
this._onDidChangeActiveNodes(this.activeNodes.elements);
this.renderIndentGuides(node, data.templateData);
}
@@ -386,7 +387,7 @@ class TreeRenderer<T, TFilterData, TTemplateData> implements IListRenderer<ITree
const parent = node.parent;
const guide = $<HTMLDivElement>('.indent-guide', { style: `width: ${this.indent}px` });
if (this.activeParentNodes.has(parent)) {
if (this.activeIndentNodes.has(parent)) {
addClass(guide, 'active');
}
@@ -413,24 +414,26 @@ class TreeRenderer<T, TFilterData, TTemplateData> implements IListRenderer<ITree
const set = new Set<ITreeNode<T, TFilterData>>();
nodes.forEach(node => {
if (node.parent) {
if (node.collapsible && node.children.length > 0 && !node.collapsed) {
set.add(node);
} else if (node.parent) {
set.add(node.parent);
}
});
this.activeParentNodes.forEach(node => {
this.activeIndentNodes.forEach(node => {
if (!set.has(node)) {
this.renderedIndentGuides.forEach(node, line => removeClass(line, 'active'));
}
});
set.forEach(node => {
if (!this.activeParentNodes.has(node)) {
if (!this.activeIndentNodes.has(node)) {
this.renderedIndentGuides.forEach(node, line => addClass(line, 'active'));
}
});
this.activeParentNodes = set;
this.activeIndentNodes = set;
}
dispose(): void {

View File

@@ -477,7 +477,7 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
// View
rerender(element?: T): void {
if (element === undefined) {
if (element === undefined || element === this.root.element) {
this.tree.rerender();
return;
}
@@ -602,9 +602,9 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
return nodes.map(n => n!.element as T);
}
open(elements: T[]): void {
open(elements: T[], browserEvent?: UIEvent): void {
const nodes = elements.map(e => this.getDataNode(e));
this.tree.open(nodes);
this.tree.open(nodes, browserEvent);
}
reveal(element: T, relativeTop?: number): void {

View File

@@ -268,7 +268,9 @@ export class ChannelServer<TContext = string> implements IChannelServer<TContext
registerChannel(channelName: string, channel: IServerChannel<TContext>): void {
this.channels.set(channelName, channel);
this.flushPendingRequests(channelName);
// https://github.com/microsoft/vscode/issues/72531
setTimeout(() => this.flushPendingRequests(channelName), 0);
}
private sendResponse(response: IRawResponse): void {

View File

@@ -697,8 +697,6 @@ export class CodeApplication extends Disposable {
private handleRemoteAuthorities(): void {
const connectionPool: Map<string, ActiveConnection> = new Map<string, ActiveConnection>();
const isBuilt = this.environmentService.isBuilt;
class ActiveConnection {
private readonly _authority: string;
private readonly _connection: Promise<ManagementPersistentConnection>;
@@ -708,7 +706,6 @@ export class CodeApplication extends Disposable {
this._authority = authority;
const options: IConnectionOptions = {
isBuilt,
commit: product.commit,
socketFactory: nodeSocketFactory,
addressProvider: {

View File

@@ -23,7 +23,7 @@ import { ILogService, ConsoleLogMainService, MultiplexLogService, getLogLevel }
import { StateService } from 'vs/platform/state/node/stateService';
import { IStateService } from 'vs/platform/state/common/state';
import { IEnvironmentService, ParsedArgs } from 'vs/platform/environment/common/environment';
import { EnvironmentService } from 'vs/platform/environment/node/environmentService';
import { EnvironmentService, xdgRuntimeDir } from 'vs/platform/environment/node/environmentService';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { ConfigurationService } from 'vs/platform/configuration/node/configurationService';
import { IRequestService } from 'vs/platform/request/common/request';
@@ -332,11 +332,19 @@ class CodeMain {
private handleStartupDataDirError(environmentService: IEnvironmentService, error: NodeJS.ErrnoException): void {
if (error.code === 'EACCES' || error.code === 'EPERM') {
const directories = [environmentService.userDataPath];
if (environmentService.extensionsPath) {
directories.push(environmentService.extensionsPath);
}
if (xdgRuntimeDir) {
directories.push(xdgRuntimeDir);
}
this.showStartupWarningDialog(
localize('startupDataDirError', "Unable to write program user data."),
environmentService.extensionsPath
? localize('startupUserDataAndExtensionsDirErrorDetail', "Please make sure the directories {0} and {1} are writeable.", environmentService.userDataPath, environmentService.extensionsPath)
: localize('startupUserDataDirErrorDetail', "Please make sure the directory {0} is writeable.", environmentService.userDataPath)
localize('startupUserDataAndExtensionsDirErrorDetail', "Please make sure the following directories are writeable:\n\n{0}", directories.join('\n'))
);
}
}
@@ -394,4 +402,4 @@ class CodeMain {
// Main Startup
const code = new CodeMain();
code.main();
code.main();

View File

@@ -112,7 +112,13 @@ export class Main {
private async listExtensions(showVersions: boolean, category?: string): Promise<void> {
let extensions = await this.extensionManagementService.getInstalled(ExtensionType.User);
if (category) {
// TODO: we should save this array in a common place so that the command and extensionQuery can use it that way changing it is easier
const categories = ['"programming languages"', 'snippets', 'linters', 'themes', 'debuggers', 'formatters', 'keymaps', '"scm providers"', 'other', '"extension packs"', '"language packs"'];
if (category && category !== '') {
if (categories.indexOf(category.toLowerCase()) < 0) {
console.log('Invalid category please enter a valid category. To list valid categories run --category without a category specified');
return;
}
extensions = extensions.filter(e => {
if (e.manifest.categories) {
const lowerCaseCategories: string[] = e.manifest.categories.map(c => c.toLowerCase());
@@ -120,6 +126,12 @@ export class Main {
}
return false;
});
} else if (category === '') {
console.log('Possible Categories: ');
categories.forEach(category => {
console.log(category);
});
return;
}
extensions.forEach(e => console.log(getId(e.manifest, showVersions)));
}
@@ -369,4 +381,4 @@ export async function main(argv: ParsedArgs): Promise<void> {
disposables.dispose();
}
});
}
}

View File

@@ -39,7 +39,7 @@ import { ModelDecorationOptions } from 'vs/editor/common/model/textModel';
import { IModelContentChangedEvent, IModelDecorationsChangedEvent, IModelLanguageChangedEvent, IModelLanguageConfigurationChangedEvent, IModelOptionsChangedEvent } from 'vs/editor/common/model/textModelEvents';
import * as modes from 'vs/editor/common/modes';
import { editorUnnecessaryCodeBorder, editorUnnecessaryCodeOpacity } from 'vs/editor/common/view/editorColorRegistry';
import { editorErrorBorder, editorErrorForeground, editorHintBorder, editorHintForeground, editorInfoBorder, editorInfoForeground, editorWarningBorder, editorWarningForeground } from 'vs/platform/theme/common/colorRegistry';
import { editorErrorBorder, editorErrorForeground, editorHintBorder, editorHintForeground, editorInfoBorder, editorInfoForeground, editorWarningBorder, editorWarningForeground, editorForeground } from 'vs/platform/theme/common/colorRegistry';
import { VerticalRevealType } from 'vs/editor/common/view/viewEvents';
import { IEditorWhitespace } from 'vs/editor/common/viewLayout/whitespaceComputer';
import { ViewModel } from 'vs/editor/common/viewModel/viewModelImpl';
@@ -1849,5 +1849,6 @@ registerThemingParticipant((theme, collector) => {
collector.addRule(`.${SHOW_UNUSED_ENABLED_CLASS} .monaco-editor .${ClassName.EditorUnnecessaryDecoration} { border-bottom: 2px dashed ${unnecessaryBorder}; }`);
}
collector.addRule(`.monaco-editor .${ClassName.EditorDeprecatedInlineDecoration} { text-decoration: line-through; }`);
const deprecatedForeground = theme.getColor(editorForeground) || 'inherit';
collector.addRule(`.monaco-editor .${ClassName.EditorDeprecatedInlineDecoration} { text-decoration: line-through; text-decoration-color: ${deprecatedForeground}}`);
});

View File

@@ -6,7 +6,7 @@
import { Color } from 'vs/base/common/color';
import { IDisposable } from 'vs/base/common/lifecycle';
import * as strings from 'vs/base/common/strings';
import { IConfigurationChangedEvent } from 'vs/editor/common/config/editorOptions';
import { IConfigurationChangedEvent, EDITOR_FONT_DEFAULTS } from 'vs/editor/common/config/editorOptions';
import { IPosition, Position } from 'vs/editor/common/core/position';
import { IRange, Range } from 'vs/editor/common/core/range';
import * as editorCommon from 'vs/editor/common/editorCommon';
@@ -668,12 +668,13 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel
const fontInfo = this.configuration.editor.fontInfo;
const colorMap = this._getColorMap();
const fontFamily = fontInfo.fontFamily === EDITOR_FONT_DEFAULTS.fontFamily ? fontInfo.fontFamily : `'${fontInfo.fontFamily}', ${EDITOR_FONT_DEFAULTS.fontFamily}`;
return (
`<div style="`
+ `color: ${colorMap[ColorId.DefaultForeground]};`
+ `background-color: ${colorMap[ColorId.DefaultBackground]};`
+ `font-family: ${fontInfo.fontFamily};`
+ `font-family: ${fontFamily};`
+ `font-weight: ${fontInfo.fontWeight};`
+ `font-size: ${fontInfo.fontSize}px;`
+ `line-height: ${fontInfo.lineHeight}px;`

View File

@@ -74,7 +74,7 @@ export class LightBulbWidget extends Disposable implements IContentWidget {
// Make sure that focus / cursor location is not lost when clicking widget icon
this._editor.focus();
dom.EventHelper.stop(e, true);
e.preventDefault();
// a bit of extra work to make sure the menu
// doesn't cover the line-text
const { top, height } = dom.getDomNodePagePosition(this._domNode);

View File

@@ -468,7 +468,7 @@ export class SimpleConfigurationService implements IConfigurationService {
defaults: emptyModel,
user: emptyModel,
workspace: emptyModel,
folders: {}
folders: []
};
}
}

View File

@@ -6,8 +6,8 @@
import * as assert from 'assert';
import { StandardTokenType } from 'vs/editor/common/modes';
import * as fs from 'fs';
import { getPathFromAmdModule } from 'vs/base/common/amd';
import { parse } from 'vs/editor/common/modes/tokenization/typescript';
// import { getPathFromAmdModule } from 'vs/base/common/amd';
// import { parse } from 'vs/editor/common/modes/tokenization/typescript';
import { toStandardTokenType } from 'vs/editor/common/modes/supports/tokenization';
interface IParseFunc {
@@ -107,6 +107,7 @@ function parseTest(fileName: string): ITest {
return { content, assertions };
}
// @ts-ignore
function executeTest(fileName: string, parseFunc: IParseFunc): void {
const { content, assertions } = parseTest(fileName);
const actual = parseFunc(content);
@@ -134,6 +135,6 @@ function executeTest(fileName: string, parseFunc: IParseFunc): void {
suite('Classification', () => {
test('TypeScript', () => {
executeTest(getPathFromAmdModule(require, 'vs/editor/test/node/classification/typescript-test.ts').replace(/\bout\b/, 'src'), parse);
// executeTest(getPathFromAmdModule(require, 'vs/editor/test/node/classification/typescript-test.ts').replace(/\bout\b/, 'src'), parse);
});
});

View File

@@ -235,6 +235,17 @@ var AMDLoader;
*--------------------------------------------------------------------------------------------*/
var AMDLoader;
(function (AMDLoader) {
function ensureError(err) {
if (err instanceof Error) {
return err;
}
var result = new Error(err.message || String(err) || 'Unknown Error');
if (err.stack) {
result.stack = err.stack;
}
return result;
}
AMDLoader.ensureError = ensureError;
;
var ConfigurationOptionsUtil = /** @class */ (function () {
function ConfigurationOptionsUtil() {
@@ -244,22 +255,16 @@ var AMDLoader;
*/
ConfigurationOptionsUtil.validateConfigurationOptions = function (options) {
function defaultOnError(err) {
if (err.errorCode === 'load') {
if (err.phase === 'loading') {
console.error('Loading "' + err.moduleId + '" failed');
console.error('Detail: ', err.detail);
if (err.detail && err.detail.stack) {
console.error(err.detail.stack);
}
console.error(err);
console.error('Here are the modules that depend on it:');
console.error(err.neededBy);
return;
}
if (err.errorCode === 'factory') {
if (err.phase === 'factory') {
console.error('The factory method of "' + err.moduleId + '" has thrown an exception');
console.error(err.detail);
if (err.detail && err.detail.stack) {
console.error(err.detail.stack);
}
console.error(err);
return;
}
}
@@ -302,7 +307,7 @@ var AMDLoader;
if (!Array.isArray(options.nodeModules)) {
options.nodeModules = [];
}
if (typeof options.nodeCachedData === 'object') {
if (options.nodeCachedData && typeof options.nodeCachedData === 'object') {
if (typeof options.nodeCachedData.seed !== 'string') {
options.nodeCachedData.seed = 'seed';
}
@@ -310,7 +315,9 @@ var AMDLoader;
options.nodeCachedData.writeDelay = 1000 * 7;
}
if (!options.nodeCachedData.path || typeof options.nodeCachedData.path !== 'string') {
options.onError('INVALID cached data configuration, \'path\' MUST be set');
var err = ensureError(new Error('INVALID cached data configuration, \'path\' MUST be set'));
err.phase = 'configuration';
options.onError(err);
options.nodeCachedData = undefined;
}
}
@@ -956,6 +963,7 @@ var AMDLoader;
this._errorback = errorback;
this.moduleIdResolver = moduleIdResolver;
this.exports = {};
this.error = null;
this.exportsPassedIn = false;
this.unresolvedDependenciesCount = this.dependencies.length;
this._isComplete = false;
@@ -1007,11 +1015,11 @@ var AMDLoader;
}
}
if (producedError) {
config.onError({
errorCode: 'factory',
moduleId: this.strId,
detail: producedError
});
var err = AMDLoader.ensureError(producedError);
err.phase = 'factory';
err.moduleId = this.strId;
this.error = err;
config.onError(err);
}
this.dependencies = null;
this._callback = null;
@@ -1022,6 +1030,8 @@ var AMDLoader;
* One of the direct dependencies or a transitive dependency has failed to load.
*/
Module.prototype.onDependencyError = function (err) {
this._isComplete = true;
this.error = err;
if (this._errorback) {
this._errorback(err);
return true;
@@ -1272,6 +1282,9 @@ var AMDLoader;
if (!m.isComplete()) {
throw new Error('Check dependency list! Synchronous require cannot resolve module \'' + _strModuleId + '\'. This module has not been resolved completely yet.');
}
if (m.error) {
throw m.error;
}
return m.exports;
};
ModuleManager.prototype.configure = function (params, shouldOverwrite) {
@@ -1301,16 +1314,15 @@ var AMDLoader;
this.defineModule(this._moduleIdProvider.getStrModuleId(moduleId), defineCall.dependencies, defineCall.callback, null, defineCall.stack);
}
};
ModuleManager.prototype._createLoadError = function (moduleId, err) {
ModuleManager.prototype._createLoadError = function (moduleId, _err) {
var _this = this;
var strModuleId = this._moduleIdProvider.getStrModuleId(moduleId);
var neededBy = (this._inverseDependencies2[moduleId] || []).map(function (intModuleId) { return _this._moduleIdProvider.getStrModuleId(intModuleId); });
return {
errorCode: 'load',
moduleId: strModuleId,
neededBy: neededBy,
detail: err
};
var err = AMDLoader.ensureError(_err);
err.phase = 'loading';
err.moduleId = strModuleId;
err.neededBy = neededBy;
return err;
};
/**
* Callback from the scriptLoader when a module hasn't been loaded.
@@ -1318,6 +1330,9 @@ var AMDLoader;
*/
ModuleManager.prototype._onLoadError = function (moduleId, err) {
var error = this._createLoadError(moduleId, err);
if (!this._modules2[moduleId]) {
this._modules2[moduleId] = new Module(moduleId, this._moduleIdProvider.getStrModuleId(moduleId), [], function () { }, function () { }, null);
}
// Find any 'local' error handlers, walk the entire chain of inverse dependencies if necessary.
var seenModuleId = [];
for (var i = 0, len = this._moduleIdProvider.getMaxModuleId(); i < len; i++) {
@@ -1525,6 +1540,10 @@ var AMDLoader;
}
var dependencyModule = this._modules2[dependency.id];
if (dependencyModule && dependencyModule.isComplete()) {
if (dependencyModule.error) {
module.onDependencyError(dependencyModule.error);
return;
}
module.unresolvedDependenciesCount--;
continue;
}

View File

@@ -5,7 +5,7 @@
import * as objects from 'vs/base/common/objects';
import * as types from 'vs/base/common/types';
import { URI } from 'vs/base/common/uri';
import { URI, UriComponents } from 'vs/base/common/uri';
import { Event } from 'vs/base/common/event';
import { Registry } from 'vs/platform/registry/common/platform';
import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
@@ -124,7 +124,7 @@ export interface IConfigurationData {
defaults: IConfigurationModel;
user: IConfigurationModel;
workspace: IConfigurationModel;
folders: { [folder: string]: IConfigurationModel };
folders: [UriComponents, IConfigurationModel][];
}
export function compare(from: IConfigurationModel, to: IConfigurationModel): { added: string[], removed: string[], updated: string[] } {

View File

@@ -8,7 +8,7 @@ import { ResourceMap } from 'vs/base/common/map';
import * as arrays from 'vs/base/common/arrays';
import * as types from 'vs/base/common/types';
import * as objects from 'vs/base/common/objects';
import { URI } from 'vs/base/common/uri';
import { URI, UriComponents } from 'vs/base/common/uri';
import { OVERRIDE_PROPERTY_PATTERN, ConfigurationScope, IConfigurationRegistry, Extensions, IConfigurationPropertySchema } from 'vs/platform/configuration/common/configurationRegistry';
import { IOverrides, overrideIdentifierFromKey, addToValueTree, toValuesTree, IConfigurationModel, getConfigurationValue, IConfigurationOverrides, IConfigurationData, getDefaultValues, getConfigurationKeys, IConfigurationChangeEvent, ConfigurationTarget, removeFromValueTree, toOverrides } from 'vs/platform/configuration/common/configuration';
import { Workspace } from 'vs/platform/workspace/common/workspace';
@@ -546,11 +546,11 @@ export class Configuration {
overrides: this._workspaceConfiguration.overrides,
keys: this._workspaceConfiguration.keys
},
folders: this._folderConfigurations.keys().reduce((result, folder) => {
folders: this._folderConfigurations.keys().reduce<[UriComponents, IConfigurationModel][]>((result, folder) => {
const { contents, overrides, keys } = this._folderConfigurations.get(folder)!;
result[folder.toString()] = { contents, overrides, keys };
result.push([folder, { contents, overrides, keys }]);
return result;
}, Object.create({}))
}, [])
};
}

View File

@@ -85,6 +85,10 @@ export class ContextMenuHandler {
menu.onDidBlur(() => this.contextViewService.hideContextView(true), null, menuDisposables);
domEvent(window, EventType.BLUR)(() => { this.contextViewService.hideContextView(true); }, null, menuDisposables);
domEvent(window, EventType.MOUSE_DOWN)((e: MouseEvent) => {
if (e.defaultPrevented) {
return;
}
let event = new StandardMouseEvent(e);
let element: HTMLElement | null = event.target;

View File

@@ -19,7 +19,7 @@ import { URI } from 'vs/base/common/uri';
// Read this before there's any chance it is overwritten
// Related to https://github.com/Microsoft/vscode/issues/30624
const xdgRuntimeDir = process.env['XDG_RUNTIME_DIR'];
export const xdgRuntimeDir = process.env['XDG_RUNTIME_DIR'];
function getNixIPCHandle(userDataPath: string, type: string): string {
const vscodePortable = process.env['VSCODE_PORTABLE'];

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@@ -559,7 +559,7 @@ export class Menubar {
})];
case StateType.CheckingForUpdates:
return [new MenuItem({ label: nls.localize('miCheckingForUpdates', "Checking For Updates..."), enabled: false })];
return [new MenuItem({ label: nls.localize('miCheckingForUpdates', "Checking for Updates..."), enabled: false })];
case StateType.AvailableForDownload:
return [new MenuItem({

View File

@@ -35,7 +35,6 @@ export interface ConnectionTypeRequest {
signedData?: string;
desiredConnectionType?: ConnectionType;
args?: any;
isBuilt: boolean;
}
export interface ErrorMessage {
@@ -51,7 +50,6 @@ export type HandshakeMessage = AuthRequest | SignRequest | ConnectionTypeRequest
interface ISimpleConnectionOptions {
isBuilt: boolean;
commit: string | undefined;
host: string;
port: number;
@@ -110,8 +108,7 @@ async function connectToRemoteExtensionHostAgent(options: ISimpleConnectionOptio
type: 'connectionType',
commit: options.commit,
signedData: signed,
desiredConnectionType: connectionType,
isBuilt: options.isBuilt
desiredConnectionType: connectionType
};
if (args) {
connTypeRequest.args = args;
@@ -200,7 +197,6 @@ async function doConnectRemoteAgentTunnel(options: ISimpleConnectionOptions, sta
}
export interface IConnectionOptions {
isBuilt: boolean;
commit: string | undefined;
socketFactory: ISocketFactory;
addressProvider: IAddressProvider;
@@ -210,7 +206,6 @@ export interface IConnectionOptions {
async function resolveConnectionOptions(options: IConnectionOptions, reconnectionToken: string, reconnectionProtocol: PersistentProtocol | null): Promise<ISimpleConnectionOptions> {
const { host, port } = await options.addressProvider.getAddress();
return {
isBuilt: options.isBuilt,
commit: options.commit,
host: host,
port: port,

View File

@@ -13,22 +13,7 @@ export class SignService implements ISignService {
private readonly _tkn: string | null;
constructor(token: string | undefined) {
if (typeof token !== 'undefined') {
this._tkn = token;
} else {
this._tkn = SignService._readTokenFromURL();
}
}
private static _readTokenFromURL(): string | null {
if (!document.location.hash) {
return null;
}
const m = document.location.hash.match(/[#&]tkn=([^&]+)/);
if (!m) {
return null;
}
return m[1];
this._tkn = token || null;
}
async sign(value: string): Promise<string> {

View File

@@ -444,6 +444,7 @@ export interface IWindowConfiguration extends ParsedArgs {
filesToDiff?: IPath[];
filesToWait?: IPathsToWaitFor;
termProgram?: string;
connectionToken?: string;
}
export interface IRunActionInWindowRequest {

2
src/vs/vscode.d.ts vendored
View File

@@ -5454,7 +5454,7 @@ declare module 'vscode' {
* from `tasks.json` files as well as tasks from task providers
* contributed through extensions.
*
* @param filter a filter to filter the return tasks.
* @param filter Optional filter to select tasks of a certain type or version.
*/
export function fetchTasks(filter?: TaskFilter): Thenable<Task[]>;

View File

@@ -983,19 +983,19 @@ declare module 'vscode' {
/**
* An event that when fired allows overriding the [dimensions](#Terminal.dimensions) of the
* terminal. Note that when set the overridden dimensions will only take effect when they
* terminal. Note that when set, the overridden dimensions will only take effect when they
* are lower than the actual dimensions of the terminal (ie. there will never be a scroll
* bar). Set to `undefined` for the terminal to go back to the regular dimensions (fit to
* the size of the panel).
*
* **Example:** Override the dimensions of a terminal to 20 columns and 10 rows
* ```typescript
* const dimensionsEmitter = new vscode.EventEmitter<string>();
* const dimensionsEmitter = new vscode.EventEmitter<vscode.TerminalDimensions>();
* const pty: vscode.Pseudoterminal = {
* onDidWrite: writeEmitter.event,
* onDidOverrideDimensions: dimensionsEmitter.event,
* open: () => {
* dimensionsEmitter.fire({
* dimensionsEmitter.fire({
* columns: 20,
* rows: 10
* });
@@ -1013,17 +1013,17 @@ declare module 'vscode' {
* **Example:** Exit the terminal when "y" is pressed, otherwise show a notification.
* ```typescript
* const writeEmitter = new vscode.EventEmitter<string>();
* const closeEmitter = new vscode.EventEmitter<number>();
* const closeEmitter = new vscode.EventEmitter<vscode.TerminalDimensions>();
* const pty: vscode.Pseudoterminal = {
* onDidWrite: writeEmitter.event,
* onDidClose: closeEmitter.event,
* open: () => writeEmitter.fire('Press y to exit successfully'),
* close: () => {}
* handleInput: {
* handleInput: data => {
* if (data !== 'y') {
* vscode.window.showInformationMessage('Something went wrong');
* }
* data => closeEmitter.fire();
* closeEmitter.fire();
* }
* };
* vscode.window.createTerminal({ name: 'Exit example', pty });
@@ -1071,6 +1071,11 @@ declare module 'vscode' {
* state of a terminal's dimensions should be treated as `undefined` until this is triggered
* as the size of a terminal isn't know until it shows up in the user interface.
*
* When dimensions are overridden by
* [onDidOverrideDimensions](#Pseudoterminal.onDidOverrideDimensions), `setDimensions` will
* continue to be called with the regular panel dimensions, allowing the extension continue
* to react dimension changes.
*
* @param dimensions The new dimensions.
*/
setDimensions?(dimensions: TerminalDimensions): void;

View File

@@ -880,6 +880,7 @@ export interface ExtHostExtensionServiceShape {
$startExtensionHost(enabledExtensionIds: ExtensionIdentifier[]): Promise<void>;
$activateByEvent(activationEvent: string): Promise<void>;
$activate(extensionId: ExtensionIdentifier, activationEvent: string): Promise<boolean>;
$setRemoteEnvironment(env: { [key: string]: string | null }): Promise<void>;
$deltaExtensions(toAdd: IExtensionDescription[], toRemove: ExtensionIdentifier[]): Promise<void>;

View File

@@ -128,7 +128,9 @@ export class ExtHostCommands implements ExtHostCommandsShape {
if (this._commands.has(id)) {
// we stay inside the extension host and support
// to pass any kind of parameters around
return this._executeContributedCommand<T>(id, args);
const res = this._executeContributedCommand<T>(id, args);
this._onDidExecuteCommand.fire({ command: id, arguments: args });
return res;
} else {
// automagically convert some argument types
@@ -170,7 +172,6 @@ export class ExtHostCommands implements ExtHostCommandsShape {
try {
const result = callback.apply(thisArg, args);
this._onDidExecuteCommand.fire({ command: id, arguments: args });
return Promise.resolve(result);
} catch (err) {
this._logService.error(err, id);

View File

@@ -263,8 +263,8 @@ export class ExtHostConfigProvider {
const defaultConfiguration = ExtHostConfigProvider.parseConfigurationModel(data.defaults);
const userConfiguration = ExtHostConfigProvider.parseConfigurationModel(data.user);
const workspaceConfiguration = ExtHostConfigProvider.parseConfigurationModel(data.workspace);
const folders: ResourceMap<ConfigurationModel> = Object.keys(data.folders).reduce((result, key) => {
result.set(URI.parse(key), ExtHostConfigProvider.parseConfigurationModel(data.folders[key]));
const folders: ResourceMap<ConfigurationModel> = data.folders.reduce((result, value) => {
result.set(URI.revive(value[0]), ExtHostConfigProvider.parseConfigurationModel(value[1]));
return result;
}, new ResourceMap<ConfigurationModel>());
return new Configuration(defaultConfiguration, userConfiguration, new ConfigurationModel(), workspaceConfiguration, folders, new ConfigurationModel(), new ResourceMap<ConfigurationModel>(), false);

View File

@@ -767,6 +767,20 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
return buff;
}
public async $setRemoteEnvironment(env: { [key: string]: string | null }): Promise<void> {
if (!this._initData.remote.isRemote) {
return;
}
for (const key in env) {
const value = env[key];
if (value === null) {
delete process.env[key];
} else {
process.env[key] = value;
}
}
}
}
function loadCommonJSModule<T>(logService: ILogService, modulePath: string, activationTimesBuilder: ExtensionActivationTimesBuilder): Promise<T> {

View File

@@ -743,12 +743,16 @@ export class ExtHostTask implements ExtHostTaskShape {
throw new Error('Unexpected: Task cannot be resolved.');
}
if (resolvedTask.definition !== task.definition) {
throw new Error('Unexpected: The resolved task definition must be the same object as the original task definition. The task definition cannot be changed.');
}
if (CustomExecutionDTO.is(resolvedTaskDTO.execution)) {
await this.addCustomExecution(taskDTO, <vscode.Task2>task);
await this.addCustomExecution(resolvedTaskDTO, <vscode.Task2>resolvedTask);
}
if (CustomExecution2DTO.is(resolvedTaskDTO.execution)) {
await this.addCustomExecution2(taskDTO, <vscode.Task2>task);
await this.addCustomExecution2(resolvedTaskDTO, <vscode.Task2>resolvedTask);
}
return resolvedTaskDTO;*/

View File

@@ -371,7 +371,8 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
process.env.hasOwnProperty('PROCESSOR_ARCHITEW6432'),
process.env.windir,
this._lastActiveWorkspace,
this._variableResolver
this._variableResolver,
this._logService
);
}
@@ -383,7 +384,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
return this._apiInspectConfigToPlain<string | string[]>(setting);
};
return terminalEnvironment.getDefaultShellArgs(fetchSetting, this._isWorkspaceShellAllowed, this._lastActiveWorkspace, this._variableResolver);
return terminalEnvironment.getDefaultShellArgs(fetchSetting, this._isWorkspaceShellAllowed, this._lastActiveWorkspace, this._variableResolver, this._logService);
}
public async resolveTerminalRenderer(id: number): Promise<vscode.TerminalRenderer> {

View File

@@ -587,7 +587,7 @@ export class CustomMenubarControl extends MenubarControl {
this.updateService.checkForUpdates({ windowId }));
case StateType.CheckingForUpdates:
return new Action('update.checking', nls.localize('checkingForUpdates', "Checking For Updates..."), undefined, false);
return new Action('update.checking', nls.localize('checkingForUpdates', "Checking for Updates..."), undefined, false);
case StateType.AvailableForDownload:
return new Action('update.downloadNow', nls.localize({ key: 'download now', comment: ['&& denotes a mnemonic'] }, "D&&ownload Now"), undefined, true, () =>

View File

@@ -76,8 +76,8 @@ export class CustomTreeViewPanel extends ViewletPanel {
this.treeView.show(container);
}
layoutBody(size: number): void {
this.treeView.layout(size);
layoutBody(height: number, width: number): void {
this.treeView.layout(height, width);
}
getActions(): IAction[] {
@@ -329,11 +329,11 @@ export class CustomTreeView extends Disposable implements ITreeView {
this._onDidChangeVisibility.fire(this.isVisible);
}
focus(): void {
focus(reveal: boolean = true): void {
if (this.tree && this.root.children && this.root.children.length > 0) {
// Make sure the current selected element is revealed
const selectedElement = this.tree.getSelection()[0];
if (selectedElement) {
if (selectedElement && reveal) {
this.tree.reveal(selectedElement, 0.5);
}
@@ -384,7 +384,8 @@ export class CustomTreeView extends Disposable implements ITreeView {
expandOnlyOnTwistieClick: (e: ITreeItem) => !!e.command,
collapseByDefault: (e: ITreeItem): boolean => {
return e.collapsibleState !== TreeItemCollapsibleState.Expanded;
}
},
multipleSelectionSupport: false
}));
aligner.tree = this.tree;
@@ -480,14 +481,14 @@ export class CustomTreeView extends Disposable implements ITreeView {
this.markdownResult = this.markdownRenderer.render(this._messageValue);
DOM.append(this.messageElement, this.markdownResult.element);
}
this.layout(this._size);
this.layout(this._height, this._width);
}
}
private hideMessage(): void {
this.resetMessageElement();
DOM.addClass(this.messageElement, 'hide');
this.layout(this._size);
this.layout(this._height, this._width);
}
private resetMessageElement(): void {
@@ -498,14 +499,16 @@ export class CustomTreeView extends Disposable implements ITreeView {
DOM.clearNode(this.messageElement);
}
private _size: number;
layout(size: number) {
if (size) {
this._size = size;
const treeSize = size - DOM.getTotalHeight(this.messageElement);
this.treeContainer.style.height = treeSize + 'px';
private _height: number;
private _width: number;
layout(height: number, width: number) {
if (height && width) {
this._height = height;
this._width = width;
const treeHeight = height - DOM.getTotalHeight(this.messageElement);
this.treeContainer.style.height = treeHeight + 'px';
if (this.tree) {
this.tree.layout(treeSize);
this.tree.layout(treeHeight, width);
}
}
}
@@ -595,10 +598,11 @@ export class CustomTreeView extends Disposable implements ITreeView {
if (this.tree) {
this.refreshing = true;
await Promise.all(elements.map(element => this.tree.updateChildren(element, true)));
elements.map(element => this.tree.rerender(element));
this.refreshing = false;
this.updateContentAreas();
if (this.focused) {
this.focus();
this.focus(false);
}
}
}

View File

@@ -104,6 +104,7 @@
.customview-tree .monaco-list .monaco-list-row {
padding-right: 12px;
padding-left: 0px;
}
.customview-tree .monaco-list .monaco-list-row .custom-view-tree-node-item {

View File

@@ -556,7 +556,8 @@ export class PersistentContributableViewsModel extends ContributableViewsModel {
visibleGlobal: undefined,
visibleWorkspace: isUndefined(workspaceViewState.isHidden) ? undefined : !workspaceViewState.isHidden,
collapsed: workspaceViewState.collapsed,
order: workspaceViewState.order
order: workspaceViewState.order,
size: workspaceViewState.size
});
}

View File

@@ -118,7 +118,8 @@ class CodeRendererMain extends Disposable {
const environmentService = new BrowserWorkbenchEnvironmentService({
workspaceId: payload.id,
remoteAuthority: this.configuration.remoteAuthority,
webviewEndpoint: this.configuration.webviewEndpoint
webviewEndpoint: this.configuration.webviewEndpoint,
connectionToken: this.configuration.connectionToken
});
serviceCollection.set(IWorkbenchEnvironmentService, environmentService);
@@ -131,7 +132,7 @@ class CodeRendererMain extends Disposable {
serviceCollection.set(IRemoteAuthorityResolverService, remoteAuthorityResolverService);
// Signing
const signService = new SignService(this.configuration.connectionToken);
const signService = new SignService(environmentService.configuration.connectionToken);
serviceCollection.set(ISignService, signService);
// Remote Agent

View File

@@ -37,6 +37,7 @@ import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteA
// tslint:disable-next-line: import-patterns
import { IExperimentService, IExperiment, ExperimentActionType, ExperimentState } from 'vs/workbench/contrib/experiments/common/experimentService';
import { ExtensionHostDebugChannelClient, ExtensionHostDebugBroadcastChannel } from 'vs/platform/debug/common/extensionHostDebugIpc';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
//#region Extension Tips
@@ -303,7 +304,8 @@ export class SimpleWindowService extends Disposable implements IWindowService {
@IConfigurationService private readonly configurationService: IConfigurationService,
@IStorageService private readonly storageService: IStorageService,
@IWorkspaceContextService private readonly workspaceService: IWorkspaceContextService,
@ILogService private readonly logService: ILogService
@ILogService private readonly logService: ILogService,
@IWorkbenchEnvironmentService private readonly workbenchEnvironmentService: IWorkbenchEnvironmentService
) {
super();
@@ -499,7 +501,7 @@ export class SimpleWindowService extends Disposable implements IWindowService {
for (let i = 0; i < _uris.length; i++) {
const uri = _uris[i];
if ('folderUri' in uri) {
const newAddress = `${document.location.origin}/?folder=${uri.folderUri.path}`;
const newAddress = `${document.location.origin}/?folder=${uri.folderUri.path}${this.workbenchEnvironmentService.configuration.connectionToken ? `&tkn=${this.workbenchEnvironmentService.configuration.connectionToken}` : ''}`;
if (openFolderInNewWindow) {
window.open(newAddress);
} else {
@@ -618,6 +620,10 @@ export class SimpleWindowsService implements IWindowsService {
readonly onWindowUnmaximize: Event<number> = Event.None;
readonly onRecentlyOpenedChange: Event<void> = Event.None;
constructor(
@IWorkbenchEnvironmentService private readonly workbenchEnvironmentService: IWorkbenchEnvironmentService
) {
}
isFocused(_windowId: number): Promise<boolean> {
return Promise.resolve(true);
}
@@ -788,6 +794,9 @@ export class SimpleWindowsService implements IWindowsService {
newAddress += `&ibe=${encodeURIComponent(ibe)}`;
}
// add connection token
newAddress += `${this.workbenchEnvironmentService.configuration.connectionToken ? `tkn=${this.workbenchEnvironmentService.configuration.connectionToken}` : ''}`;
window.open(newAddress);
return Promise.resolve();

View File

@@ -237,7 +237,7 @@ import { isMacintosh, isWindows, isLinux, isWeb } from 'vs/base/common/platform'
'workbench.useExperimentalGridLayout': {
'type': 'boolean',
'description': nls.localize('workbench.useExperimentalGridLayout', "Enables the grid layout for the workbench. This setting may enable additional layout options for workbench components."),
'default': true,
'default': false,
'scope': ConfigurationScope.APPLICATION
}
}
@@ -360,4 +360,4 @@ import { isMacintosh, isWindows, isLinux, isWeb } from 'vs/base/common/platform'
}
}
});
})();
})();

View File

@@ -79,11 +79,25 @@ export class Workbench extends Layout {
setUnexpectedErrorHandler(error => this.handleUnexpectedError(error, logService));
// Inform user about loading issues from the loader
interface AnnotatedLoadingError extends Error {
phase: 'loading';
moduleId: string;
neededBy: string[];
}
interface AnnotatedFactoryError extends Error {
phase: 'factory';
moduleId: string;
}
interface AnnotatedValidationError extends Error {
phase: 'configuration';
}
type AnnotatedError = AnnotatedLoadingError | AnnotatedFactoryError | AnnotatedValidationError;
(<any>window).require.config({
onError: (err: { errorCode: string; }) => {
if (err.errorCode === 'load') {
onError: (err: AnnotatedError) => {
if (err.phase === 'loading') {
onUnexpectedError(new Error(localize('loaderErrorNative', "Failed to load a required file. Please restart the application to try again. Details: {0}", JSON.stringify(err))));
}
console.error(err);
}
});
}

View File

@@ -325,7 +325,7 @@ export interface ITreeView extends IDisposable {
focus(): void;
layout(height: number): void;
layout(height: number, width: number): void;
show(container: HTMLElement): void;

View File

@@ -36,6 +36,7 @@ import { ICommentInfo, ICommentService } from 'vs/workbench/contrib/comments/bro
import { COMMENTEDITOR_DECORATION_KEY, ReviewZoneWidget } from 'vs/workbench/contrib/comments/browser/commentThreadWidget';
import { ctxCommentEditorFocused, SimpleCommentEditor } from 'vs/workbench/contrib/comments/browser/simpleCommentEditor';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { EmbeddedCodeEditorWidget } from 'vs/editor/browser/widget/embeddedCodeEditorWidget';
export const ID = 'editor.contrib.review';
@@ -173,7 +174,6 @@ export class ReviewController implements IEditorContribution {
@IContextMenuService readonly contextMenuService: IContextMenuService,
@IQuickInputService private readonly quickInputService: IQuickInputService
) {
this.editor = editor;
this.globalToDispose = [];
this.localToDispose = [];
this._commentInfos = [];
@@ -181,6 +181,12 @@ export class ReviewController implements IEditorContribution {
this._pendingCommentCache = {};
this._computePromise = null;
if (editor instanceof EmbeddedCodeEditorWidget) {
return;
}
this.editor = editor;
this._commentingRangeDecorator = new CommentingRangeDecorator();
this.globalToDispose.push(this.commentService.onDidDeleteDataProvider(ownerId => {

View File

@@ -433,6 +433,10 @@
z-index: 10;
}
div.preview.inline .monaco-editor .comment-range-glyph {
display: none !important;
}
.monaco-editor .comment-range-glyph:before {
position: absolute;
content: "";

View File

@@ -184,7 +184,7 @@ export function registerCommands(): void {
id: STEP_INTO_ID,
weight: KeybindingWeight.WorkbenchContrib + 10, // Have a stronger weight to have priority over full screen when debugging
primary: KeyCode.F11,
when: CONTEXT_DEBUG_STATE.isEqualTo('stopped'),
when: CONTEXT_IN_DEBUG_MODE,
handler: (accessor: ServicesAccessor, _: string, thread: IThread | undefined) => {
getThreadAndRun(accessor, thread, thread => thread.stepIn());
}

View File

@@ -358,7 +358,7 @@ export class RemoteInstallAction extends InstallInOtherServerAction {
}
protected getInstallLabel(): string {
return this.extensionManagementServerService.remoteExtensionManagementServer ? localize('Install on Server', "Install on {0}", this.extensionManagementServerService.remoteExtensionManagementServer.label) : InstallInOtherServerAction.INSTALL_LABEL;
return this.extensionManagementServerService.remoteExtensionManagementServer ? localize('Install on Server', "Install in {0}", this.extensionManagementServerService.remoteExtensionManagementServer.label) : InstallInOtherServerAction.INSTALL_LABEL;
}
}
@@ -712,7 +712,13 @@ export class ManageExtensionAction extends ExtensionDropDownAction {
]);
groups.push([this.instantiationService.createInstance(UninstallAction)]);
groups.push([this.instantiationService.createInstance(InstallAnotherVersionAction)]);
groups.push([this.instantiationService.createInstance(ExtensionInfoAction), this.instantiationService.createInstance(ExtensionSettingsAction)]);
const extensionActions: ExtensionAction[] = [this.instantiationService.createInstance(ExtensionInfoAction)];
if (this.extension.local && this.extension.local.manifest.contributes && this.extension.local.manifest.contributes.configuration) {
extensionActions.push(this.instantiationService.createInstance(ExtensionSettingsAction));
}
groups.push(extensionActions);
groups.forEach(group => group.forEach(extensionAction => extensionAction.extension = this.extension));
@@ -3089,7 +3095,7 @@ interface IExtensionPickItem extends IQuickPickItem {
extension?: IExtension;
}
export class InstallLocalExtensionsOnRemoteAction extends Action {
export class InstallLocalExtensionsInRemoteAction extends Action {
constructor(
@IExtensionsWorkbenchService private readonly extensionsWorkbenchService: IExtensionsWorkbenchService,
@@ -3101,14 +3107,14 @@ export class InstallLocalExtensionsOnRemoteAction extends Action {
@IProgressService private readonly progressService: IProgressService,
@IInstantiationService private readonly instantiationService: IInstantiationService
) {
super('workbench.extensions.actions.installLocalExtensionsOnRemote');
super('workbench.extensions.actions.installLocalExtensionsInRemote');
this.update();
this._register(this.extensionsWorkbenchService.onChange(() => this.update()));
}
get label(): string {
return this.extensionManagementServerService.remoteExtensionManagementServer ?
localize('install local extensions', "Install Local Extensions on {0}", this.extensionManagementServerService.remoteExtensionManagementServer.label) : '';
localize('install local extensions', "Install Local Extensions in {0}...", this.extensionManagementServerService.remoteExtensionManagementServer.label) : '';
}
private update(): void {
@@ -3141,6 +3147,7 @@ export class InstallLocalExtensionsOnRemoteAction extends Action {
const localExtensionsToInstall = this.getLocalExtensionsToInstall();
quickPick.busy = false;
if (localExtensionsToInstall.length) {
quickPick.title = localize('install local extensions title', "Install Local Extensions in {0}", this.extensionManagementServerService.remoteExtensionManagementServer!.label);
quickPick.placeholder = localize('select extensions to install', "Select extensions to install");
quickPick.canSelectMany = true;
localExtensionsToInstall.sort((e1, e2) => e1.displayName.localeCompare(e2.displayName));
@@ -3189,9 +3196,9 @@ export class InstallLocalExtensionsOnRemoteAction extends Action {
this.notificationService.notify({
severity: Severity.Info,
message: localize('finished installing', "Completed installing the extensions. Please reload the window now."),
message: localize('finished installing', "Successfully installed extensions in {0}. Please reload the window to enable them.", this.extensionManagementServerService.remoteExtensionManagementServer!.label),
actions: {
primary: [new Action('realod', localize('reload', "Realod Window"), '', true,
primary: [new Action('realod', localize('reload', "Reload Window"), '', true,
() => this.windowService.reloadWindow())]
}
});

View File

@@ -68,7 +68,7 @@ export class ExtensionDependencyChecker extends Disposable implements IWorkbench
severity: Severity.Info,
message: localize('finished installing missing deps', "Finished installing missing dependencies. Please reload the window now."),
actions: {
primary: [new Action('realod', localize('reload', "Realod Window"), '', true,
primary: [new Action('realod', localize('reload', "Reload Window"), '', true,
() => this.windowService.reloadWindow())]
}
});

View File

@@ -22,7 +22,7 @@ import { IExtensionsWorkbenchService, IExtensionsViewlet, VIEWLET_ID, AutoUpdate
import {
ShowEnabledExtensionsAction, ShowInstalledExtensionsAction, ShowRecommendedExtensionsAction, ShowPopularExtensionsAction, ShowDisabledExtensionsAction,
ShowOutdatedExtensionsAction, ClearExtensionsInputAction, ChangeSortAction, UpdateAllAction, CheckForUpdatesAction, DisableAllAction, EnableAllAction,
EnableAutoUpdateAction, DisableAutoUpdateAction, ShowBuiltInExtensionsAction, InstallVSIXAction, InstallLocalExtensionsOnRemoteAction
EnableAutoUpdateAction, DisableAutoUpdateAction, ShowBuiltInExtensionsAction, InstallVSIXAction, InstallLocalExtensionsInRemoteAction
} from 'vs/workbench/contrib/extensions/browser/extensionsActions';
import { IExtensionManagementService } from 'vs/platform/extensionManagement/common/extensionManagement';
import { IExtensionEnablementService, IExtensionManagementServerService, IExtensionManagementServer } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
@@ -409,7 +409,7 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio
triggerCharacters: ['@'],
sortKey: (item: string) => {
if (item.indexOf(':') === -1) { return 'a'; }
else if (/ext:/.test(item) || /tag:/.test(item)) { return 'b'; }
else if (/ext:/.test(item) || /id:/.test(item) || /tag:/.test(item)) { return 'b'; }
else if (/sort:/.test(item)) { return 'c'; }
else { return 'd'; }
},
@@ -484,7 +484,7 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio
this.instantiationService.createInstance(CheckForUpdatesAction, CheckForUpdatesAction.ID, CheckForUpdatesAction.LABEL),
...(this.configurationService.getValue(AutoUpdateConfigurationKey) ? [this.instantiationService.createInstance(DisableAutoUpdateAction, DisableAutoUpdateAction.ID, DisableAutoUpdateAction.LABEL)] : [this.instantiationService.createInstance(UpdateAllAction, UpdateAllAction.ID, UpdateAllAction.LABEL), this.instantiationService.createInstance(EnableAutoUpdateAction, EnableAutoUpdateAction.ID, EnableAutoUpdateAction.LABEL)]),
this.instantiationService.createInstance(InstallVSIXAction, InstallVSIXAction.ID, InstallVSIXAction.LABEL),
...(this.extensionManagementServerService.localExtensionManagementServer && this.extensionManagementServerService.remoteExtensionManagementServer ? [this.instantiationService.createInstance(InstallLocalExtensionsOnRemoteAction)] : []),
...(this.extensionManagementServerService.localExtensionManagementServer && this.extensionManagementServerService.remoteExtensionManagementServer ? [this.instantiationService.createInstance(InstallLocalExtensionsInRemoteAction)] : []),
new Separator(),
this.instantiationService.createInstance(DisableAllAction, DisableAllAction.ID, DisableAllAction.LABEL),
this.instantiationService.createInstance(EnableAllAction, EnableAllAction.ID, EnableAllAction.LABEL)

View File

@@ -1,10 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8 14C11.3137 14 14 11.3137 14 8C14 4.68629 11.3137 2 8 2C4.68629 2 2 4.68629 2 8C2 11.3137 4.68629 14 8 14ZM11.9139 8C11.9139 10.1616 10.1616 11.9139 8 11.9139C5.83839 11.9139 4.08606 10.1616 4.08606 8C4.08606 5.83839 5.83839 4.08606 8 4.08606C10.1616 4.08606 11.9139 5.83839 11.9139 8ZM8 3.86919C10.2814 3.86919 12.1308 5.71862 12.1308 8C12.1308 8.00001 12.1308 8 12.1308 8C12.1308 5.71862 10.2814 3.86919 8 3.86919Z" fill="#848484"/>
</g>
<defs>
<clipPath id="clip0">
<rect width="16" height="16" fill="white"/>
</clipPath>
</defs>
<circle cx="8" cy="8" r="5.5" stroke="#C5C5C5"/>
<circle cx="8" cy="8" r="2" fill="#C5C5C5"/>
</svg>

Before

Width:  |  Height:  |  Size: 715 B

After

Width:  |  Height:  |  Size: 197 B

View File

@@ -1,10 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8 14C11.3137 14 14 11.3137 14 8C14 4.68629 11.3137 2 8 2C4.68629 2 2 4.68629 2 8C2 11.3137 4.68629 14 8 14ZM11.9139 8C11.9139 10.1616 10.1616 11.9139 8 11.9139C5.83839 11.9139 4.08606 10.1616 4.08606 8C4.08606 5.83839 5.83839 4.08606 8 4.08606C10.1616 4.08606 11.9139 5.83839 11.9139 8ZM8 3.86919C10.2814 3.86919 12.1308 5.71862 12.1308 8C12.1308 8.00001 12.1308 8 12.1308 8C12.1308 5.71862 10.2814 3.86919 8 3.86919Z" fill="#848484"/>
</g>
<defs>
<clipPath id="clip0">
<rect width="16" height="16" fill="white"/>
</clipPath>
</defs>
<circle cx="8" cy="8" r="5.5" stroke="#424242"/>
<circle cx="8" cy="8" r="2" fill="#424242"/>
</svg>

Before

Width:  |  Height:  |  Size: 715 B

After

Width:  |  Height:  |  Size: 197 B

View File

@@ -1,3 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.99977 14V2.18091L12.9998 8.06215L3.99977 14ZM5.5 4.99997L10.3145 8.06215L5.5 11.1809L5.5 4.99997Z" fill="#89D185"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M4 2V14.4805L12.9146 8.24024L4 2ZM11.1809 8.24024L4.995 12.5684V3.91209L11.1809 8.24024Z" fill="#C5C5C5"/>
</svg>

Before

Width:  |  Height:  |  Size: 271 B

After

Width:  |  Height:  |  Size: 259 B

View File

@@ -1,3 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.99977 14V2.18091L12.9998 8.06215L3.99977 14ZM5.5 4.99997L10.3145 8.06215L5.5 11.1809L5.5 4.99997Z" fill="#388A34"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M4 2V14.4805L12.9146 8.24024L4 2ZM11.1809 8.24024L4.995 12.5684V3.91209L11.1809 8.24024Z" fill="#424242"/>
</svg>

Before

Width:  |  Height:  |  Size: 271 B

After

Width:  |  Height:  |  Size: 259 B

View File

@@ -11,7 +11,7 @@ import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
import { IExtensionManagementServerService } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { ILabelService } from 'vs/platform/label/common/label';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { InstallLocalExtensionsOnRemoteAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions';
import { InstallLocalExtensionsInRemoteAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions';
export class RemoteExtensionsInstaller extends Disposable implements IWorkbenchContribution {
@@ -22,16 +22,16 @@ export class RemoteExtensionsInstaller extends Disposable implements IWorkbenchC
) {
super();
if (this.extensionManagementServerService.localExtensionManagementServer && this.extensionManagementServerService.remoteExtensionManagementServer) {
const installLocalExtensionsOnRemoteAction = instantiationService.createInstance(InstallLocalExtensionsOnRemoteAction);
CommandsRegistry.registerCommand('workbench.extensions.installLocalExtensions', () => installLocalExtensionsOnRemoteAction.run());
const installLocalExtensionsInRemoteAction = instantiationService.createInstance(InstallLocalExtensionsInRemoteAction);
CommandsRegistry.registerCommand('workbench.extensions.installLocalExtensions', () => installLocalExtensionsInRemoteAction.run());
let disposable = Disposable.None;
const appendMenuItem = () => {
disposable.dispose();
disposable = MenuRegistry.appendMenuItem(MenuId.CommandPalette, {
command: {
id: 'workbench.extensions.installLocalExtensions',
category: localize('extensions', "Extensions"),
title: installLocalExtensionsOnRemoteAction.label
category: localize('remote', "Remote"),
title: installLocalExtensionsInRemoteAction.label
}
});
};
@@ -41,4 +41,4 @@ export class RemoteExtensionsInstaller extends Disposable implements IWorkbenchC
}
}
}
}

View File

@@ -1518,7 +1518,7 @@ suite('ExtensionsActions Test', () => {
await workbenchService.queryGallery(CancellationToken.None);
testObject.extension = extensions[0];
assert.ok(testObject.enabled);
assert.equal('Install on remote', testObject.label);
assert.equal('Install in remote', testObject.label);
assert.equal('extension-action prominent install', testObject.class);
});
@@ -1544,7 +1544,7 @@ suite('ExtensionsActions Test', () => {
await workbenchService.queryGallery(CancellationToken.None);
testObject.extension = extensions[0];
assert.ok(testObject.enabled);
assert.equal('Install on remote', testObject.label);
assert.equal('Install in remote', testObject.label);
assert.equal('extension-action prominent install', testObject.class);
onInstallExtension.fire({ identifier: localWorkspaceExtension.identifier, gallery });
@@ -1577,7 +1577,7 @@ suite('ExtensionsActions Test', () => {
await workbenchService.queryGallery(CancellationToken.None);
testObject.extension = extensions[0];
assert.ok(testObject.enabled);
assert.equal('Install on remote', testObject.label);
assert.equal('Install in remote', testObject.label);
assert.equal('extension-action prominent install', testObject.class);
onInstallExtension.fire({ identifier: localWorkspaceExtension.identifier, gallery });
@@ -1608,7 +1608,7 @@ suite('ExtensionsActions Test', () => {
await workbenchService.queryGallery(CancellationToken.None);
testObject.extension = extensions[0];
assert.ok(testObject.enabled);
assert.equal('Install on remote', testObject.label);
assert.equal('Install in remote', testObject.label);
assert.equal('extension-action prominent install', testObject.class);
});
@@ -1704,7 +1704,7 @@ suite('ExtensionsActions Test', () => {
await workbenchService.queryGallery(CancellationToken.None);
testObject.extension = extensions[0];
assert.ok(testObject.enabled);
assert.equal('Install on remote', testObject.label);
assert.equal('Install in remote', testObject.label);
uninstallEvent.fire(localWorkspaceExtension.identifier);
assert.ok(!testObject.enabled);
@@ -1825,7 +1825,7 @@ suite('ExtensionsActions Test', () => {
await workbenchService.queryGallery(CancellationToken.None);
testObject.extension = extensions[0];
assert.ok(testObject.enabled);
assert.equal('Install on remote', testObject.label);
assert.equal('Install in remote', testObject.label);
assert.equal('extension-action prominent install', testObject.class);
});
@@ -1848,7 +1848,7 @@ suite('ExtensionsActions Test', () => {
await workbenchService.queryGallery(CancellationToken.None);
testObject.extension = extensions[0];
assert.ok(testObject.enabled);
assert.equal('Install on remote', testObject.label);
assert.equal('Install in remote', testObject.label);
uninstallEvent.fire(languagePackExtension.identifier);
assert.ok(!testObject.enabled);

View File

@@ -258,7 +258,7 @@ class MarkerWidget extends Disposable {
}));
this.icon = dom.append(parent, dom.$(''));
this.multilineActionbar = this._register(new ActionBar(dom.append(parent, dom.$('.multiline-actions'))));
this.messageAndDetailsContainer = dom.append(parent, dom.$('.marker-message-details'));
this.messageAndDetailsContainer = dom.append(parent, dom.$('.marker-message-details-container'));
}
render(element: Marker, filterData: MarkerFilterData | undefined): void {
@@ -312,33 +312,32 @@ class MarkerWidget extends Disposable {
const viewState = this.markersViewModel.getViewModel(element);
const multiline = !viewState || viewState.multiline;
const lineMatches = filterData && filterData.lineMatches || [];
const messageContainer = dom.append(this.messageAndDetailsContainer, dom.$('.marker-message'));
dom.toggleClass(messageContainer, 'multiline', multiline);
let lastLineElement = messageContainer;
let lastLineElement: HTMLElement | undefined = undefined;
for (let index = 0; index < (multiline ? lines.length : 1); index++) {
lastLineElement = dom.append(messageContainer, dom.$('.marker-message-line'));
const highlightedLabel = new HighlightedLabel(lastLineElement, false);
highlightedLabel.set(lines[index], lineMatches[index]);
lastLineElement = dom.append(this.messageAndDetailsContainer, dom.$('.marker-message-line'));
const messageElement = dom.append(lastLineElement, dom.$('.marker-message'));
const highlightedLabel = new HighlightedLabel(messageElement, false);
highlightedLabel.set(lines[index].length > 1000 ? `${lines[index].substring(0, 1000)}...` : lines[index], lineMatches[index]);
if (lines[index] === '') {
lastLineElement.style.height = `${VirtualDelegate.LINE_HEIGHT}px`;
}
}
this.renderDetails(marker, filterData, multiline ? lastLineElement : this.messageAndDetailsContainer);
this.renderDetails(marker, filterData, lastLineElement || dom.append(this.messageAndDetailsContainer, dom.$('.marker-message-line')));
}
private renderDetails(marker: IMarker, filterData: MarkerFilterData | undefined, parent: HTMLElement): void {
dom.addClass(parent, 'details-container');
const sourceMatches = filterData && filterData.sourceMatches || [];
const codeMatches = filterData && filterData.codeMatches || [];
const source = new HighlightedLabel(dom.append(parent, dom.$('')), false);
source.set(marker.source, sourceMatches);
dom.toggleClass(source.element, 'marker-source', !!marker.source);
if (marker.source || marker.code) {
const source = new HighlightedLabel(dom.append(parent, dom.$('.marker-source')), false);
const sourceMatches = filterData && filterData.sourceMatches || [];
source.set(marker.source, sourceMatches);
const code = new HighlightedLabel(dom.append(parent, dom.$('')), false);
code.set(marker.code, codeMatches);
dom.toggleClass(code.element, 'marker-code', !!marker.code);
const code = new HighlightedLabel(dom.append(parent, dom.$('.marker-code')), false);
const codeMatches = filterData && filterData.codeMatches || [];
code.set(marker.code, codeMatches);
}
const lnCol = dom.append(parent, dom.$('span.marker-line'));
lnCol.textContent = Messages.MARKERS_PANEL_AT_LINE_COL_NUMBER(marker.startLineNumber, marker.startColumn);

View File

@@ -97,6 +97,7 @@
.markers-panel .markers-panel-container .tree-container .monaco-tl-contents {
display: flex;
line-height: 22px;
padding-right: 10px;
}
.hc-black .markers-panel .markers-panel-container .tree-container .monaco-tl-contents {
@@ -112,23 +113,22 @@
margin-left: 10px;
}
.markers-panel .markers-panel-container .tree-container .monaco-tl-contents .marker-message-details,
.markers-panel .markers-panel-container .tree-container .monaco-tl-contents .marker-message:not(.multiline) {
display: flex;
.markers-panel .markers-panel-container .tree-container .monaco-tl-contents .marker-message-details-container {
flex: 1;
overflow: hidden;
}
.markers-panel .markers-panel-container .tree-container .monaco-tl-contents .marker-message.multiline {
white-space: pre;
flex: 1;
.markers-panel .markers-panel-container .tree-container .monaco-tl-contents .marker-message-details-container > .marker-message-line {
overflow: hidden;
}
.markers-panel .markers-panel-container .tree-container .monaco-tl-contents .marker-message:not(.multiline) .marker-message-line {
.markers-panel .markers-panel-container .tree-container .monaco-tl-contents .marker-message-details-container > .marker-message-line > .marker-message {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.markers-panel .markers-panel-container .tree-container .monaco-tl-contents .marker-message .details-container {
.markers-panel .markers-panel-container .tree-container .monaco-tl-contents .marker-message-details-container > .marker-message-line.details-container {
display: flex;
}
@@ -222,4 +222,4 @@
.markers-panel .monaco-tl-contents .multiline-actions .action-item.disabled,
.markers-panel .monaco-tl-contents .actions .action-item.disabled {
display: none;
}
}

View File

@@ -12,10 +12,29 @@
margin-left: 2px;
}
/* Deal with overflow */
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-widget .setting-list-value,
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-widget .setting-list-sibling {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-widget .setting-list-value {
max-width: 90%;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-widget .setting-list-sibling {
max-width: 10%;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-value,
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-sibling {
display: inline-block;
line-height: 22px;
}
/* Use monospace to display glob patterns in exclude widget */
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-exclude-widget .setting-list-value,
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-exclude-widget .setting-list-sibling {
font-family: var(--monaco-monospace-font);
}
@@ -35,6 +54,7 @@
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-row {
position: relative;
max-height: 22px;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-row:focus {
@@ -102,6 +122,8 @@
margin-right: 10px;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-widget {
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-widget,
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-exclude-widget {
margin-bottom: 1px;
padding: 1px;
}

View File

@@ -978,8 +978,15 @@ export class SettingsEditor2 extends BaseEditor {
// If a single setting is being refreshed, it's ok to refresh now if that is not the focused setting
if (key) {
const focusedKey = focusedSetting.getAttribute(AbstractSettingRenderer.SETTING_KEY_ATTR);
if (focusedKey === key &&
!DOM.hasClass(focusedSetting, 'setting-item-list')) { // update `list`s live, as they have a separate "submit edit" step built in before this
/**
* Update `list`s live if focused item is whole list or list item,
* as they have a separate "submit edit" step built in before this
*/
if (
focusedKey === key &&
!DOM.hasClass(focusedSetting, 'setting-item-list') &&
!DOM.hasClass(focusedSetting, 'setting-item-contents')
) {
this.updateModifiedLabelForKey(key);
this.scheduleRefresh(focusedSetting, key);

View File

@@ -698,32 +698,46 @@ export class SettingArrayRenderer extends AbstractSettingRenderer implements ITr
private onDidChangeList(template: ISettingListItemTemplate, e: IListChangeEvent): void {
if (template.context) {
const newValue: any[] | undefined = isArray(template.context.scopeValue)
? [...template.context.scopeValue]
: [...template.context.value];
let newValue: any[] = [];
if (isArray(template.context.scopeValue)) {
newValue = [...template.context.scopeValue];
} else if (isArray(template.context.value)) {
newValue = [...template.context.value];
}
// Delete value
if (e.removeIndex) {
if (!e.value && e.originalValue && e.removeIndex > -1) {
newValue.splice(e.removeIndex, 1);
if (e.targetIndex !== undefined) {
// Delete value
if (!e.value && e.originalValue && e.targetIndex > -1) {
newValue.splice(e.targetIndex, 1);
}
}
// Add value
else if (e.value && !e.originalValue) {
newValue.push(e.value);
}
// Update value
else if (e.value && e.originalValue) {
const valueIndex = newValue.indexOf(e.originalValue);
if (valueIndex > -1) {
newValue[valueIndex] = e.value;
// Update value
else if (e.value && e.originalValue) {
if (e.targetIndex > -1) {
newValue[e.targetIndex] = e.value;
}
// For some reason, we are updating and cannot find original value
// Just append the value in this case
else {
newValue.push(e.value);
}
}
// For some reason, we are updating and cannot find original value
// Just append the value in this case
else {
// Add value
else if (e.value && !e.originalValue && e.targetIndex >= newValue.length) {
newValue.push(e.value);
}
}
if (
template.context.defaultValue &&
isArray(template.context.defaultValue) &&
template.context.defaultValue.length === newValue.length &&
template.context.defaultValue.join() === newValue.join()
) {
return this._onDidChangeSetting.fire({
key: template.context.setting.key,
value: undefined, // reset setting
type: template.context.valueType
});
}
this._onDidChangeSetting.fire({
key: template.context.setting.key,

View File

@@ -20,6 +20,7 @@ import { foreground, inputBackground, inputBorder, inputForeground, listActiveSe
import { attachButtonStyler, attachInputBoxStyler } from 'vs/platform/theme/common/styler';
import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
import { disposableTimeout } from 'vs/base/common/async';
import { isUndefinedOrNull } from 'vs/base/common/types';
const $ = DOM.$;
export const settingsHeaderForeground = registerColor('settings.headerForeground', { light: '#444444', dark: '#e7e7e7', hc: '#ffffff' }, localize('headerForeground', "(For settings editor preview) The foreground color for a section header or active title."));
@@ -131,14 +132,16 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
}
});
type EditKey = 'none' | 'create' | number;
export class ListSettingListModel {
private _dataItems: IListDataItem[] = [];
private _editKey: string | null;
private _editKey: EditKey;
private _selectedIdx: number | null;
get items(): IListViewItem[] {
const items = this._dataItems.map((item, i) => {
const editing = item.value === this._editKey;
const editing = typeof this._editKey === 'number' && this._editKey === i;
return <IListViewItem>{
...item,
editing,
@@ -146,7 +149,7 @@ export class ListSettingListModel {
};
});
if (this._editKey === '') {
if (this._editKey === 'create') {
items.push({
editing: true,
selected: true,
@@ -158,7 +161,7 @@ export class ListSettingListModel {
return items;
}
setEditKey(key: string | null): void {
setEditKey(key: EditKey): void {
this._editKey = key;
}
@@ -195,7 +198,7 @@ export interface IListChangeEvent {
originalValue: string;
value?: string;
sibling?: string;
removeIndex?: number;
targetIndex?: number;
}
export class ListSettingWidget extends Disposable {
@@ -218,7 +221,8 @@ export class ListSettingWidget extends Disposable {
) {
super();
this.listElement = DOM.append(container, $('.setting-list-widget'));
this.listElement = DOM.append(container, $('div'));
this.getContainerClasses().forEach(c => this.listElement.classList.add(c));
this.listElement.setAttribute('tabindex', '0');
DOM.append(container, this.renderAddButton());
this.renderList();
@@ -228,13 +232,19 @@ export class ListSettingWidget extends Disposable {
this._register(DOM.addStandardDisposableListener(this.listElement, 'keydown', (e: KeyboardEvent) => {
if (e.keyCode === KeyCode.UpArrow) {
const selectedIndex = this.model.getSelected();
this.model.selectPrevious();
this.renderList();
if (this.model.getSelected() !== selectedIndex) {
this.renderList();
}
e.preventDefault();
e.stopPropagation();
} else if (e.keyCode === KeyCode.DownArrow) {
const selectedIndex = this.model.getSelected();
this.model.selectNext();
this.renderList();
if (this.model.getSelected() !== selectedIndex) {
this.renderList();
}
e.preventDefault();
e.stopPropagation();
}
@@ -259,6 +269,10 @@ export class ListSettingWidget extends Disposable {
};
}
protected getContainerClasses() {
return ['setting-list-widget'];
}
setValue(listData: IListDataItem[]): void {
this.model.setValue(listData);
this.renderList();
@@ -288,7 +302,7 @@ export class ListSettingWidget extends Disposable {
const item = this.model.items[targetIdx];
if (item) {
this.editSetting(item.value);
this.editSetting(targetIdx);
e.preventDefault();
e.stopPropagation();
}
@@ -342,30 +356,30 @@ export class ListSettingWidget extends Disposable {
enabled: true,
id: 'workbench.action.removeListItem',
tooltip: this.getLocalizedStrings().deleteActionTooltip,
run: () => this._onDidChangeList.fire({ originalValue: key, value: undefined, removeIndex: idx })
run: () => this._onDidChangeList.fire({ originalValue: key, value: undefined, targetIndex: idx })
};
}
private createEditAction(key: string): IAction {
private createEditAction(idx: number): IAction {
return <IAction>{
class: 'setting-listAction-edit',
enabled: true,
id: 'workbench.action.editListItem',
tooltip: this.getLocalizedStrings().editActionTooltip,
run: () => {
this.editSetting(key);
this.editSetting(idx);
}
};
}
private editSetting(key: string): void {
this.model.setEditKey(key);
private editSetting(idx: number): void {
this.model.setEditKey(idx);
this.renderList();
}
private renderItem(item: IListViewItem, idx: number, listFocused: boolean): HTMLElement {
return item.editing ?
this.renderEditItem(item) :
this.renderEditItem(item, idx) :
this.renderDataItem(item, idx, listFocused);
}
@@ -384,7 +398,7 @@ export class ListSettingWidget extends Disposable {
siblingElement.textContent = item.sibling ? ('when: ' + item.sibling) : null;
actionBar.push([
this.createEditAction(item.value),
this.createEditAction(idx),
this.createDeleteAction(item.value, idx)
], { icon: true, label: false });
@@ -412,24 +426,25 @@ export class ListSettingWidget extends Disposable {
this._register(attachButtonStyler(startAddButton, this.themeService));
this._register(startAddButton.onDidClick(() => {
this.model.setEditKey('');
this.model.setEditKey('create');
this.renderList();
}));
return rowElement;
}
private renderEditItem(item: IListViewItem): HTMLElement {
private renderEditItem(item: IListViewItem, idx: number): HTMLElement {
const rowElement = $('.setting-list-edit-row');
const onSubmit = (edited: boolean) => {
this.model.setEditKey(null);
this.model.setEditKey('none');
const value = valueInput.value.trim();
if (edited && value) {
if (edited && !isUndefinedOrNull(value)) {
this._onDidChangeList.fire({
originalValue: item.value,
value: value,
sibling: siblingInput && siblingInput.value.trim()
sibling: siblingInput && siblingInput.value.trim(),
targetIndex: idx
});
}
this.renderList();
@@ -514,6 +529,10 @@ export class ExcludeSettingWidget extends ListSettingWidget {
settingListRowSiblingHintLabel: localize('excludeSiblingHintLabel', "Exclude files matching `{0}`, only when a file matching `{1}` is present", pattern, sibling)
};
}
protected getContainerClasses() {
return ['setting-list-exclude-widget'];
}
}
export interface IListDataItem {

View File

@@ -284,6 +284,26 @@ class ProgressReporter {
}
}
class RemoteExtensionHostEnvironmentUpdater implements IWorkbenchContribution {
constructor(
@IRemoteAgentService remoteAgentService: IRemoteAgentService,
@IRemoteAuthorityResolverService remoteResolverService: IRemoteAuthorityResolverService,
@IExtensionService extensionService: IExtensionService
) {
const connection = remoteAgentService.getConnection();
if (connection) {
connection.onDidStateChange(async e => {
if (e.type === PersistentConnectionEventType.ConnectionGain) {
const resolveResult = await remoteResolverService.resolveAuthority(connection.remoteAuthority);
if (resolveResult.options && resolveResult.options.extensionHostEnv) {
await extensionService.setRemoteEnvironment(resolveResult.options.extensionHostEnv);
}
}
});
}
}
}
class RemoteAgentConnectionStatusListener implements IWorkbenchContribution {
constructor(
@IRemoteAgentService remoteAgentService: IRemoteAgentService,
@@ -440,6 +460,7 @@ const workbenchContributionsRegistry = Registry.as<IWorkbenchContributionsRegist
workbenchContributionsRegistry.registerWorkbenchContribution(RemoteChannelsContribution, LifecyclePhase.Starting);
workbenchContributionsRegistry.registerWorkbenchContribution(RemoteAgentDiagnosticListener, LifecyclePhase.Eventually);
workbenchContributionsRegistry.registerWorkbenchContribution(RemoteAgentConnectionStatusListener, LifecyclePhase.Eventually);
workbenchContributionsRegistry.registerWorkbenchContribution(RemoteExtensionHostEnvironmentUpdater, LifecyclePhase.Eventually);
workbenchContributionsRegistry.registerWorkbenchContribution(RemoteWindowActiveIndicator, LifecyclePhase.Starting);
workbenchContributionsRegistry.registerWorkbenchContribution(RemoteTelemetryEnablementUpdater, LifecyclePhase.Ready);
workbenchContributionsRegistry.registerWorkbenchContribution(RemoteEmptyWorkbenchPresentation, LifecyclePhase.Starting);

View File

@@ -213,37 +213,6 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({
}
});
CommandsRegistry.registerCommand({
id: Constants.RevealInSideBarForSearchResults,
handler: (accessor, fileMatch: FileMatch) => {
const viewletService = accessor.get(IViewletService);
const explorerService = accessor.get(IExplorerService);
const contextService = accessor.get(IWorkspaceContextService);
const uri = fileMatch.resource;
viewletService.openViewlet(VIEWLET_ID_FILES, false).then((viewlet: ExplorerViewlet) => {
if (uri && contextService.isInsideWorkspace(uri)) {
const explorerView = viewlet.getExplorerView();
if (explorerView) {
explorerView.setExpanded(true);
explorerService.select(uri, true).then(() => explorerView.focus(), onUnexpectedError);
}
}
});
}
});
const RevealInSideBarForSearchResultsCommand: ICommandAction = {
id: Constants.RevealInSideBarForSearchResults,
title: nls.localize('revealInSideBar', "Reveal in Explorer")
};
MenuRegistry.appendMenuItem(MenuId.SearchContext, {
command: RevealInSideBarForSearchResultsCommand,
when: ContextKeyExpr.and(Constants.FileFocusKey, Constants.HasSearchResults),
group: '2_files',
});
MenuRegistry.appendMenuItem(MenuId.SearchContext, {
command: {
id: Constants.ReplaceActionId,
@@ -343,6 +312,38 @@ CommandsRegistry.registerCommand({
handler: clearHistoryCommand
});
CommandsRegistry.registerCommand({
id: Constants.RevealInSideBarForSearchResults,
handler: (accessor, fileMatch: FileMatch) => {
const viewletService = accessor.get(IViewletService);
const explorerService = accessor.get(IExplorerService);
const contextService = accessor.get(IWorkspaceContextService);
const uri = fileMatch.resource;
viewletService.openViewlet(VIEWLET_ID_FILES, false).then((viewlet: ExplorerViewlet) => {
if (uri && contextService.isInsideWorkspace(uri)) {
const explorerView = viewlet.getExplorerView();
if (explorerView) {
explorerView.setExpanded(true);
explorerService.select(uri, true).then(() => explorerView.focus(), onUnexpectedError);
}
}
});
}
});
const RevealInSideBarForSearchResultsCommand: ICommandAction = {
id: Constants.RevealInSideBarForSearchResults,
title: nls.localize('revealInSideBar', "Reveal in Explorer")
};
MenuRegistry.appendMenuItem(MenuId.SearchContext, {
command: RevealInSideBarForSearchResultsCommand,
when: ContextKeyExpr.and(Constants.FileFocusKey, Constants.HasSearchResults),
group: 'search_3',
order: 1
});
const clearSearchHistoryLabel = nls.localize('clearSearchHistoryLabel', "Clear Search History");
const ClearSearchHistoryCommand: ICommandAction = {
id: Constants.ClearSearchHistoryCommandId,

View File

@@ -470,17 +470,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
return this._taskSystem.customExecutionComplete(task, result);
}
private isBadTsConfig(taskId: string | TaskIdentifier | undefined): taskId is string {
const badTsconfig = '\\tsconfig.json';
const tsc = 'tsc';
return typeof taskId === 'string' && (taskId.length > badTsconfig.length) && strings.equalsIgnoreCase(taskId.substring(taskId.length - badTsconfig.length, taskId.length), badTsconfig) && (taskId.substring(0, tsc.length) === tsc);
}
public getTask(folder: IWorkspaceFolder | string, identifier: string | TaskIdentifier, compareId: boolean = false): Promise<Task | undefined> {
if (this.isBadTsConfig(identifier)) {
return Promise.reject(new Error(nls.localize('badTsConfig', "Task '{0}' contains \"\\\\\". Typescript tasks must use \"/\"", identifier)));
}
const name = Types.isString(folder) ? folder : folder.name;
if (this.ignoredWorkspaceFolders.some(ignored => ignored.name === name)) {
return Promise.reject(new Error(nls.localize('TaskServer.folderIgnored', 'The folder {0} is ignored since it uses task version 0.1.0', name)));

View File

@@ -378,6 +378,9 @@ actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(RenameTerminalAc
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FocusTerminalFindWidgetAction, FocusTerminalFindWidgetAction.ID, FocusTerminalFindWidgetAction.LABEL, {
primary: KeyMod.CtrlCmd | KeyCode.KEY_F
}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Focus Find Widget', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FocusTerminalFindWidgetAction, FocusTerminalFindWidgetAction.ID, FocusTerminalFindWidgetAction.LABEL, {
primary: KeyMod.CtrlCmd | KeyCode.KEY_F
}, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_FOCUSED), 'Terminal: Focus Find Widget', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(HideTerminalFindWidgetAction, HideTerminalFindWidgetAction.ID, HideTerminalFindWidgetAction.LABEL, {
primary: KeyCode.Escape,
secondary: [KeyMod.Shift | KeyCode.Escape]

View File

@@ -38,6 +38,7 @@ const winLocalLinkClause = '((' + winPathPrefix + '|(' + winExcludedPathCharacte
replacing space with nonBreakningSpace or space ASCII code - 32. */
const lineAndColumnClause = [
'((\\S*)", line ((\\d+)( column (\\d+))?))', // "(file path)", line 45 [see #40468]
'((\\S*)",((\\d+)(:(\\d+))?))', // "(file path)",45 [see #78205]
'((\\S*) on line ((\\d+)(, column (\\d+))?))', // (file path) on line 8, column 13
'((\\S*):line ((\\d+)(, column (\\d+))?))', // (file path):line 8, column 13
'(([^\\s\\(\\)]*)(\\s?[\\(\\[](\\d+)(,\\s?(\\d+))?)[\\)\\]])', // (file path)(45), (file path) (45), (file path)(45,18), (file path) (45,18), (file path)(45, 18), (file path) (45, 18), also with []

View File

@@ -78,7 +78,11 @@ function resolveConfigurationVariables(configurationResolverService: IConfigurat
Object.keys(env).forEach((key) => {
const value = env[key];
if (typeof value === 'string' && lastActiveWorkspaceRoot !== null) {
env[key] = configurationResolverService.resolve(lastActiveWorkspaceRoot, value);
try {
env[key] = configurationResolverService.resolve(lastActiveWorkspaceRoot, value);
} catch (e) {
env[key] = value;
}
}
});
return env;
@@ -138,19 +142,19 @@ export function getCwd(
if (!shell.ignoreConfigurationCwd && customCwd) {
if (configurationResolverService) {
try {
cwd = configurationResolverService.resolve(lastActiveWorkspace, customCwd);
customCwd = configurationResolverService.resolve(lastActiveWorkspace, customCwd);
} catch (e) {
// There was an issue resolving a variable, just use the unresolved customCwd which
// which will fail, and log the error in the console.
cwd = customCwd;
if (logService) {
logService.error('Resolving terminal.integrated.cwd', e);
logService.error('Could not resolve terminal.integrated.cwd', e);
}
return customCwd;
}
}
if (path.isAbsolute(customCwd) && !cwd) {
if (path.isAbsolute(customCwd)) {
cwd = customCwd;
} else if (root && !cwd) {
} else if (root) {
cwd = path.join(root.fsPath, customCwd);
}
}
@@ -192,7 +196,8 @@ export function getDefaultShell(
windir: string | undefined,
lastActiveWorkspace: IWorkspaceFolder | undefined,
configurationResolverService: IConfigurationResolverService | undefined,
platformOverride: platform.Platform = platform.platform,
logService: ILogService,
platformOverride: platform.Platform = platform.platform
): string {
const platformKey = platformOverride === platform.Platform.Windows ? 'windows' : platformOverride === platform.Platform.Mac ? 'osx' : 'linux';
const shellConfigValue = fetchSetting(`terminal.integrated.shell.${platformKey}`);
@@ -214,7 +219,12 @@ export function getDefaultShell(
}
if (configurationResolverService) {
executable = configurationResolverService.resolve(lastActiveWorkspace, executable);
try {
executable = configurationResolverService.resolve(lastActiveWorkspace, executable);
} catch (e) {
logService.error(`Could not resolve terminal.integrated.shell.${platformKey}`, e);
executable = executable;
}
}
return executable;
@@ -225,6 +235,7 @@ export function getDefaultShellArgs(
isWorkspaceShellAllowed: boolean,
lastActiveWorkspace: IWorkspaceFolder | undefined,
configurationResolverService: IConfigurationResolverService | undefined,
logService: ILogService,
platformOverride: platform.Platform = platform.platform,
): string | string[] {
const platformKey = platformOverride === platform.Platform.Windows ? 'windows' : platformOverride === platform.Platform.Mac ? 'osx' : 'linux';
@@ -236,7 +247,12 @@ export function getDefaultShellArgs(
if (configurationResolverService) {
const resolvedArgs: string[] = [];
for (const arg of args) {
resolvedArgs.push(configurationResolverService.resolve(lastActiveWorkspace, arg));
try {
resolvedArgs.push(configurationResolverService.resolve(lastActiveWorkspace, arg));
} catch (e) {
logService.error(`Could not resolve terminal.integrated.shellArgs.${platformKey}`, e);
resolvedArgs.push(arg);
}
}
args = resolvedArgs;
}

View File

@@ -20,6 +20,7 @@ import { getMainProcessParentEnv } from 'vs/workbench/contrib/terminal/node/term
import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver';
import { IHistoryService } from 'vs/workbench/services/history/common/history';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { ILogService } from 'vs/platform/log/common/log';
let Terminal: typeof XTermTerminal;
let WebLinksAddon: typeof XTermWebLinksAddon;
@@ -34,7 +35,8 @@ export class TerminalInstanceService implements ITerminalInstanceService {
@IStorageService private readonly _storageService: IStorageService,
@IConfigurationResolverService private readonly _configurationResolverService: IConfigurationResolverService,
@IWorkspaceContextService private readonly _workspaceContextService: IWorkspaceContextService,
@IHistoryService private readonly _historyService: IHistoryService
@IHistoryService private readonly _historyService: IHistoryService,
@ILogService private readonly _logService: ILogService
) {
}
@@ -84,6 +86,7 @@ export class TerminalInstanceService implements ITerminalInstanceService {
process.env.windir,
lastActiveWorkspace,
this._configurationResolverService,
this._logService,
platformOverride
);
const args = getDefaultShellArgs(
@@ -91,6 +94,7 @@ export class TerminalInstanceService implements ITerminalInstanceService {
isWorkspaceShellAllowed,
lastActiveWorkspace,
this._configurationResolverService,
this._logService,
platformOverride
);
return Promise.resolve({ shell, args });
@@ -99,4 +103,4 @@ export class TerminalInstanceService implements ITerminalInstanceService {
public getMainProcessParentEnv(): Promise<IProcessEnvironment> {
return getMainProcessParentEnv();
}
}
}

View File

@@ -120,10 +120,11 @@ async function detectAvailableWindowsShells(): Promise<IShellDefinition[]> {
`${process.env['ProgramFiles']}\\Git\\usr\\bin\\bash.exe`,
`${process.env['LocalAppData']}\\Programs\\Git\\bin\\bash.exe`,
],
Cygwin: [
`${process.env['HOMEDRIVE']}\\cygwin64\\bin\\bash.exe`,
`${process.env['HOMEDRIVE']}\\cygwin\\bin\\bash.exe`
]
// See #75945
// Cygwin: [
// `${process.env['HOMEDRIVE']}\\cygwin64\\bin\\bash.exe`,
// `${process.env['HOMEDRIVE']}\\cygwin\\bin\\bash.exe`
// ]
};
const promises: PromiseLike<IShellDefinition | undefined>[] = [];
Object.keys(expectedLocations).forEach(key => promises.push(validateShellPaths(key, expectedLocations[key])));
@@ -170,4 +171,4 @@ async function getShellPathFromRegistry(shellName: string): Promise<string> {
} catch (error) {
return '';
}
}
}

View File

@@ -121,7 +121,8 @@ suite('Workbench - TerminalLinkHandler', () => {
{ urlFormat: '{0}[{1},{2}]', line: '5', column: '3' },
{ urlFormat: '{0} [{1},{2}]', line: '5', column: '3' },
{ urlFormat: '{0}[{1}, {2}]', line: '5', column: '3' },
{ urlFormat: '{0} [{1}, {2}]', line: '5', column: '3' }
{ urlFormat: '{0} [{1}, {2}]', line: '5', column: '3' },
{ urlFormat: '"{0}",{1}', line: '5' }
];
linkUrls.forEach(linkUrl => {
@@ -185,7 +186,8 @@ suite('Workbench - TerminalLinkHandler', () => {
{ urlFormat: '{0}[{1}]', line: '5' },
{ urlFormat: '{0} [{1}]', line: '5' },
{ urlFormat: '{0}[{1},{2}]', line: '5', column: '3' },
{ urlFormat: '{0} [{1},{2}]', line: '5', column: '3' }
{ urlFormat: '{0} [{1},{2}]', line: '5', column: '3' },
{ urlFormat: '"{0}",{1}', line: '5' }
];
linkUrls.forEach(linkUrl => {

View File

@@ -490,7 +490,7 @@ export class UpdateContribution extends Disposable implements IWorkbenchContribu
group: '5_update',
command: {
id: 'update.checking',
title: nls.localize('checkingForUpdates', "Checking For Updates..."),
title: nls.localize('checkingForUpdates', "Checking for Updates..."),
precondition: FalseContext
},
when: CONTEXT_UPDATE_STATE.isEqualTo(StateType.CheckingForUpdates)

View File

@@ -31,7 +31,7 @@ export function getWebviewThemeData(
}, {} as { [key: string]: string });
const styles = {
'vscode-font-family': '-apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "Ubuntu", "Droid Sans", ans-serif',
'vscode-font-family': '-apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "Ubuntu", "Droid Sans", sans-serif',
'vscode-font-weight': 'normal',
'vscode-font-size': '13px',
'vscode-editor-font-family': editorFontFamily,
@@ -60,4 +60,4 @@ namespace ApiThemeClassName {
return ApiThemeClassName.highContrast;
}
}
}
}

View File

@@ -61,6 +61,7 @@ export interface IBrowserWindowConfiguration {
workspaceId: string;
remoteAuthority?: string;
webviewEndpoint?: string;
connectionToken?: string;
}
export class BrowserWorkbenchEnvironmentService implements IEnvironmentService {
@@ -81,6 +82,7 @@ export class BrowserWorkbenchEnvironmentService implements IEnvironmentService {
this.localeResource = joinPath(this.userRoamingDataHome, 'locale.json');
this.backupHome = joinPath(this.userRoamingDataHome, BACKUPS);
this.configuration.backupWorkspaceResource = joinPath(this.backupHome, configuration.workspaceId);
this.configuration.connectionToken = configuration.connectionToken || this.getConnectionTokenFromLocation();
this.logsPath = '/web/logs';
@@ -182,4 +184,21 @@ export class BrowserWorkbenchEnvironmentService implements IEnvironmentService {
get webviewCspSource(): string {
return this.webviewEndpoint ? this.webviewEndpoint : 'vscode-resource:';
}
private getConnectionTokenFromLocation(): string | undefined {
// TODO: Check with @alexd where the token will be: search or hash?
let connectionToken: string | undefined = undefined;
if (document.location.search) {
connectionToken = this.getConnectionToken(document.location.search);
}
if (!connectionToken && document.location.hash) {
connectionToken = this.getConnectionToken(document.location.hash);
}
return connectionToken;
}
private getConnectionToken(str: string): string | undefined {
const m = str.match(/[#&]tkn=([^&]+)/);
return m ? m[1] : undefined;
}
}

View File

@@ -263,6 +263,11 @@ export abstract class AbstractExtensionService extends Disposable implements IEx
return 0;
}
public async setRemoteEnvironment(env: { [key: string]: string | null }): Promise<void> {
await this._extensionHostProcessManagers
.map(manager => manager.setRemoteEnvironment(env));
}
//#endregion
// --- impl

View File

@@ -290,6 +290,15 @@ export class ExtensionHostProcessManager extends Disposable {
}
return proxy.$deltaExtensions(toAdd, toRemove);
}
public async setRemoteEnvironment(env: { [key: string]: string | null }): Promise<void> {
const proxy = await this._getExtensionHostProcessProxy();
if (!proxy) {
return;
}
return proxy.$setRemoteEnvironment(env);
}
}
const colorTables = [

View File

@@ -229,6 +229,12 @@ export interface IExtensionService {
*/
stopExtensionHost(): void;
/**
* Modify the environment of the remote extension host
* @param env New properties for the remote extension host
*/
setRemoteEnvironment(env: { [key: string]: string | null }): Promise<void>;
_logOrShowMessage(severity: Severity, msg: string): void;
_activateById(extensionId: ExtensionIdentifier, activationEvent: string): Promise<void>;
_onWillActivateExtension(extensionId: ExtensionIdentifier): void;
@@ -278,6 +284,7 @@ export class NullExtensionService implements IExtensionService {
restartExtensionHost(): void { }
startExtensionHost(): void { }
stopExtensionHost(): void { }
async setRemoteEnvironment(_env: { [key: string]: string | null }): Promise<void> { }
canAddExtension(): boolean { return false; }
canRemoveExtension(): boolean { return false; }
_logOrShowMessage(_severity: Severity, _msg: string): void { }

View File

@@ -71,7 +71,6 @@ export class RemoteExtensionHostClient extends Disposable implements IExtensionH
public start(): Promise<IMessagePassingProtocol> {
const options: IConnectionOptions = {
isBuilt: this._environmentService.isBuilt,
commit: this._productService.commit,
socketFactory: this._socketFactory,
addressProvider: {

View File

@@ -68,7 +68,7 @@ const resourceLabelFormattersExtPoint = ExtensionsRegistry.registerExtensionPoin
});
const sepRegexp = /\//g;
const labelMatchingRegexp = /\$\{scheme\}|\$\{authority\}|\$\{path\}/g;
const labelMatchingRegexp = /\$\{(scheme|authority|path|(query)\.(.+?))\}/g;
function hasDriveLetter(path: string): boolean {
return !!(isWindows && path && path[2] === ':');
@@ -222,12 +222,23 @@ export class LabelService implements ILabelService {
}
private formatUri(resource: URI, formatting: ResourceLabelFormatting, forceNoTildify?: boolean): string {
let label = formatting.label.replace(labelMatchingRegexp, match => {
switch (match) {
case '${scheme}': return resource.scheme;
case '${authority}': return resource.authority;
case '${path}': return resource.path;
default: return '';
let label = formatting.label.replace(labelMatchingRegexp, (match, token, qsToken, qsValue) => {
switch (token) {
case 'scheme': return resource.scheme;
case 'authority': return resource.authority;
case 'path': return resource.path;
default: {
if (qsToken === 'query') {
const { query } = resource;
if (query && query[0] === '{' && query[query.length - 1] === '}') {
try {
return JSON.parse(query)[qsValue] || '';
}
catch { }
}
}
return '';
}
}
});
@@ -265,4 +276,4 @@ export class LabelService implements ILabelService {
}
}
registerSingleton(ILabelService, LabelService, true);
registerSingleton(ILabelService, LabelService, true);

View File

@@ -97,4 +97,64 @@ suite('URI Label', () => {
const uri1 = URI.parse('vscode://microsoft.com/1/2/3/4/5');
assert.equal(labelService.getUriLabel(uri1, { relative: false }), 'second');
});
test('custom query', function () {
labelService.registerFormatter({
scheme: 'vscode',
formatting: {
label: 'LABEL${query.prefix}: ${query.path}/END',
separator: '/',
tildify: true,
normalizeDriveLetter: true
}
});
const uri1 = URI.parse(`vscode://microsoft.com/1/2/3/4/5?${encodeURIComponent(JSON.stringify({ prefix: 'prefix', path: 'path' }))}`);
assert.equal(labelService.getUriLabel(uri1, { relative: false }), 'LABELprefix: path/END');
});
test('custom query without value', function () {
labelService.registerFormatter({
scheme: 'vscode',
formatting: {
label: 'LABEL${query.prefix}: ${query.path}/END',
separator: '/',
tildify: true,
normalizeDriveLetter: true
}
});
const uri1 = URI.parse(`vscode://microsoft.com/1/2/3/4/5?${encodeURIComponent(JSON.stringify({ path: 'path' }))}`);
assert.equal(labelService.getUriLabel(uri1, { relative: false }), 'LABEL: path/END');
});
test('custom query without query json', function () {
labelService.registerFormatter({
scheme: 'vscode',
formatting: {
label: 'LABEL${query.prefix}: ${query.path}/END',
separator: '/',
tildify: true,
normalizeDriveLetter: true
}
});
const uri1 = URI.parse('vscode://microsoft.com/1/2/3/4/5?path=foo');
assert.equal(labelService.getUriLabel(uri1, { relative: false }), 'LABEL: /END');
});
test('custom query without query', function () {
labelService.registerFormatter({
scheme: 'vscode',
formatting: {
label: 'LABEL${query.prefix}: ${query.path}/END',
separator: '/',
tildify: true,
normalizeDriveLetter: true
}
});
const uri1 = URI.parse('vscode://microsoft.com/1/2/3/4/5');
assert.equal(labelService.getUriLabel(uri1, { relative: false }), 'LABEL: /END');
});
});

View File

@@ -28,7 +28,7 @@ export class RemoteAgentService extends AbstractRemoteAgentService implements IR
super(environmentService);
this.socketFactory = new BrowserSocketFactory(webSocketFactory);
this._connection = this._register(new RemoteAgentConnection(environmentService.configuration.remoteAuthority!, productService.commit, this.socketFactory, environmentService, remoteAuthorityResolverService, signService));
this._connection = this._register(new RemoteAgentConnection(environmentService.configuration.remoteAuthority!, productService.commit, this.socketFactory, remoteAuthorityResolverService, signService));
}
getConnection(): IRemoteAgentConnection | null {

View File

@@ -84,7 +84,6 @@ export class RemoteAgentConnection extends Disposable implements IRemoteAgentCon
remoteAuthority: string,
private readonly _commit: string | undefined,
private readonly _socketFactory: ISocketFactory,
private readonly _environmentService: IEnvironmentService,
private readonly _remoteAuthorityResolverService: IRemoteAuthorityResolverService,
private readonly _signService: ISignService
) {
@@ -111,7 +110,6 @@ export class RemoteAgentConnection extends Disposable implements IRemoteAgentCon
private async _createConnection(): Promise<Client<RemoteAgentConnectionContext>> {
let firstCall = true;
const options: IConnectionOptions = {
isBuilt: this._environmentService.isBuilt,
commit: this._commit,
socketFactory: this._socketFactory,
addressProvider: {

View File

@@ -27,7 +27,7 @@ export class RemoteAgentService extends AbstractRemoteAgentService implements IR
super(environmentService);
this.socketFactory = nodeSocketFactory;
if (remoteAuthority) {
this._connection = this._register(new RemoteAgentConnection(remoteAuthority, product.commit, nodeSocketFactory, environmentService, remoteAuthorityResolverService, signService));
this._connection = this._register(new RemoteAgentConnection(remoteAuthority, product.commit, nodeSocketFactory, remoteAuthorityResolverService, signService));
}
}

View File

@@ -100,7 +100,6 @@ export class TunnelService implements ITunnelService {
}
const options: IConnectionOptions = {
isBuilt: this.environmentService.isBuilt,
commit: product.commit,
socketFactory: nodeSocketFactory,
addressProvider: {

View File

@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { URI } from 'vs/base/common/uri';
import { URI, UriComponents } from 'vs/base/common/uri';
import { ExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace';
import { ExtHostConfigProvider } from 'vs/workbench/api/common/extHostConfiguration';
import { MainThreadConfigurationShape, IConfigurationInitData } from 'vs/workbench/api/common/extHost.protocol';
@@ -12,7 +12,7 @@ import { ConfigurationModel } from 'vs/platform/configuration/common/configurati
import { TestRPCProtocol } from './testRPCProtocol';
import { mock } from 'vs/workbench/test/electron-browser/api/mock';
import { IWorkspaceFolder, WorkspaceFolder } from 'vs/platform/workspace/common/workspace';
import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration';
import { ConfigurationTarget, IConfigurationModel } from 'vs/platform/configuration/common/configuration';
import { NullLogService } from 'vs/platform/log/common/log';
import { assign } from 'vs/base/common/objects';
import { Counter } from 'vs/base/common/numbers';
@@ -39,7 +39,7 @@ suite('ExtHostConfiguration', function () {
defaults: new ConfigurationModel(contents),
user: new ConfigurationModel(contents),
workspace: new ConfigurationModel(),
folders: Object.create(null),
folders: [],
configurationScopes: []
};
}
@@ -277,7 +277,7 @@ suite('ExtHostConfiguration', function () {
}
}, ['editor.wordWrap']),
workspace: new ConfigurationModel({}, []),
folders: Object.create(null),
folders: [],
configurationScopes: []
}
);
@@ -297,13 +297,13 @@ suite('ExtHostConfiguration', function () {
test('inspect in single root context', function () {
const workspaceUri = URI.file('foo');
const folders = Object.create(null);
const folders: [UriComponents, IConfigurationModel][] = [];
const workspace = new ConfigurationModel({
'editor': {
'wordWrap': 'bounded'
}
}, ['editor.wordWrap']);
folders[workspaceUri.toString()] = workspace;
folders.push([workspaceUri, workspace]);
const extHostWorkspace = new ExtHostWorkspace(new TestRPCProtocol(), new NullLogService(), new Counter());
extHostWorkspace.$initializeWorkspace({
'id': 'foo',
@@ -365,19 +365,19 @@ suite('ExtHostConfiguration', function () {
const firstRoot = URI.file('foo1');
const secondRoot = URI.file('foo2');
const thirdRoot = URI.file('foo3');
const folders = Object.create(null);
folders[firstRoot.toString()] = new ConfigurationModel({
const folders: [UriComponents, IConfigurationModel][] = [];
folders.push([firstRoot, new ConfigurationModel({
'editor': {
'wordWrap': 'off',
'lineNumbers': 'relative'
}
}, ['editor.wordWrap']);
folders[secondRoot.toString()] = new ConfigurationModel({
}, ['editor.wordWrap'])]);
folders.push([secondRoot, new ConfigurationModel({
'editor': {
'wordWrap': 'on'
}
}, ['editor.wordWrap']);
folders[thirdRoot.toString()] = new ConfigurationModel({}, []);
}, ['editor.wordWrap'])]);
folders.push([thirdRoot, new ConfigurationModel({}, [])]);
const extHostWorkspace = new ExtHostWorkspace(new TestRPCProtocol(), new NullLogService(), new Counter());
extHostWorkspace.$initializeWorkspace({

View File

@@ -60,9 +60,9 @@ export class StatusBar {
case StatusBarElement.LANGUAGE_STATUS:
return `${this.mainSelector} ${this.rightSelector}[title="Select Language Mode"]`;
case StatusBarElement.FEEDBACK_ICON:
return `${this.mainSelector} ${this.rightSelector} .monaco-dropdown.send-feedback`;
return `${this.mainSelector} .statusbar-item.right[id="status.feedback"]`;
default:
throw new Error(element);
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More