From 0eb0fe9e1afe28374627ceedf4169f13503cf188 Mon Sep 17 00:00:00 2001 From: Tony Xia Date: Thu, 11 Apr 2019 23:55:05 +1000 Subject: [PATCH 01/48] Update comment --- src/vs/base/browser/dnd.ts | 2 +- src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts | 2 +- src/vs/base/browser/ui/scrollbar/scrollableElement.ts | 2 +- src/vs/base/browser/ui/tree/tree.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vs/base/browser/dnd.ts b/src/vs/base/browser/dnd.ts index 76fa2957325..1a5d28e802e 100644 --- a/src/vs/base/browser/dnd.ts +++ b/src/vs/base/browser/dnd.ts @@ -68,7 +68,7 @@ export const DataTransfers = { FILES: 'Files', /** - * Typicaly transfer type for copy/paste transfers. + * Typically transfer type for copy/paste transfers. */ TEXT: 'text/plain' }; diff --git a/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts b/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts index 9910bf95f55..28658f3ee60 100644 --- a/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts +++ b/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts @@ -126,7 +126,7 @@ export class BreadcrumbsWidget { this._pendingLayout.dispose(); } if (dim) { - // only meaure + // only measure this._pendingLayout = this._updateDimensions(dim); } else { this._pendingLayout = this._updateScrollbar(); diff --git a/src/vs/base/browser/ui/scrollbar/scrollableElement.ts b/src/vs/base/browser/ui/scrollbar/scrollableElement.ts index 9b31c847f70..fbf8d5dcd13 100644 --- a/src/vs/base/browser/ui/scrollbar/scrollableElement.ts +++ b/src/vs/base/browser/ui/scrollbar/scrollableElement.ts @@ -523,7 +523,7 @@ export class DomScrollableElement extends ScrollableElement { } public scanDomNode(): void { - // widh, scrollLeft, scrollWidth, height, scrollTop, scrollHeight + // width, scrollLeft, scrollWidth, height, scrollTop, scrollHeight this.setScrollDimensions({ width: this._element.clientWidth, scrollWidth: this._element.scrollWidth, diff --git a/src/vs/base/browser/ui/tree/tree.ts b/src/vs/base/browser/ui/tree/tree.ts index 03bf0c095b8..cedb6fbd423 100644 --- a/src/vs/base/browser/ui/tree/tree.ts +++ b/src/vs/base/browser/ui/tree/tree.ts @@ -33,7 +33,7 @@ export const enum TreeVisibility { export interface ITreeFilterDataResult { /** - * Whether the node should be visibile. + * Whether the node should be visible. */ visibility: boolean | TreeVisibility; From bea104db7bf70f6a3461b923c30b809538b17018 Mon Sep 17 00:00:00 2001 From: Tony Xia Date: Thu, 11 Apr 2019 23:56:59 +1000 Subject: [PATCH 02/48] Update variable names --- src/vs/base/browser/touch.ts | 4 ++-- src/vs/base/browser/ui/list/listWidget.ts | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/vs/base/browser/touch.ts b/src/vs/base/browser/touch.ts index 77f94de61f8..2499d715f8f 100644 --- a/src/vs/base/browser/touch.ts +++ b/src/vs/base/browser/touch.ts @@ -214,10 +214,10 @@ export class Gesture extends Disposable { } } - private newGestureEvent(type: string, intialTarget?: EventTarget): GestureEvent { + private newGestureEvent(type: string, initialTarget?: EventTarget): GestureEvent { let event = (document.createEvent('CustomEvent')); event.initEvent(type, false, true); - event.initialTarget = intialTarget; + event.initialTarget = initialTarget; return event; } diff --git a/src/vs/base/browser/ui/list/listWidget.ts b/src/vs/base/browser/ui/list/listWidget.ts index 0869c52c0d2..5babdbf0d72 100644 --- a/src/vs/base/browser/ui/list/listWidget.ts +++ b/src/vs/base/browser/ui/list/listWidget.ts @@ -502,7 +502,7 @@ function isMouseRightClick(event: UIEvent): boolean { return event instanceof MouseEvent && event.button === 2; } -const DefaultMultipleSelectionContoller = { +const DefaultMultipleSelectionController = { isSelectionSingleChangeEvent, isSelectionRangeChangeEvent }; @@ -529,7 +529,7 @@ export class MouseController implements IDisposable { this.multipleSelectionSupport = !(list.options.multipleSelectionSupport === false); if (this.multipleSelectionSupport) { - this.multipleSelectionController = list.options.multipleSelectionController || DefaultMultipleSelectionContoller; + this.multipleSelectionController = list.options.multipleSelectionController || DefaultMultipleSelectionController; } this.openController = list.options.openController || DefaultOpenController; @@ -909,7 +909,7 @@ function getContiguousRangeContaining(range: number[], value: number): number[] /** * Given two sorted collections of numbers, returns the intersection - * betweem them (OR). + * between them (OR). */ function disjunction(one: number[], other: number[]): number[] { const result: number[] = []; From cf72b92c4c6888379b43c6905dec4cc383c42546 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Thu, 11 Apr 2019 15:57:34 +0200 Subject: [PATCH 03/48] extract build & publish scripts --- build/azure-pipelines/darwin/build.sh | 4 ++ .../darwin/product-build-darwin.yml | 29 +------- build/azure-pipelines/darwin/publish.sh | 22 +++++++ build/azure-pipelines/linux/build.sh | 3 + .../linux/product-build-linux.yml | 66 +++---------------- build/azure-pipelines/linux/publish.sh | 51 ++++++++++++++ build/azure-pipelines/win32/build.ps1 | 4 ++ .../win32/product-build-win32.yml | 46 ++++--------- build/azure-pipelines/win32/publish.ps1 | 28 ++++++++ 9 files changed, 137 insertions(+), 116 deletions(-) create mode 100755 build/azure-pipelines/darwin/build.sh create mode 100755 build/azure-pipelines/darwin/publish.sh create mode 100755 build/azure-pipelines/linux/build.sh create mode 100755 build/azure-pipelines/linux/publish.sh create mode 100644 build/azure-pipelines/win32/build.ps1 create mode 100644 build/azure-pipelines/win32/publish.ps1 diff --git a/build/azure-pipelines/darwin/build.sh b/build/azure-pipelines/darwin/build.sh new file mode 100755 index 00000000000..604e92e9396 --- /dev/null +++ b/build/azure-pipelines/darwin/build.sh @@ -0,0 +1,4 @@ +#!/bin/sh +set -e +yarn gulp -- vscode-darwin-min +yarn gulp -- upload-vscode-sourcemaps \ No newline at end of file diff --git a/build/azure-pipelines/darwin/product-build-darwin.yml b/build/azure-pipelines/darwin/product-build-darwin.yml index 4169bcd8784..5de6ad87891 100644 --- a/build/azure-pipelines/darwin/product-build-darwin.yml +++ b/build/azure-pipelines/darwin/product-build-darwin.yml @@ -30,10 +30,7 @@ steps: set -e VSCODE_MIXIN_PASSWORD="$(VSCODE_MIXIN_PASSWORD)" \ AZURE_STORAGE_ACCESS_KEY="$(AZURE_STORAGE_ACCESS_KEY)" \ - yarn gulp -- vscode-darwin-min - VSCODE_MIXIN_PASSWORD="$(VSCODE_MIXIN_PASSWORD)" \ - AZURE_STORAGE_ACCESS_KEY="$(AZURE_STORAGE_ACCESS_KEY)" \ - yarn gulp -- upload-vscode-sourcemaps + ./build/azure-pipelines/darwin/build.sh displayName: Build - script: | @@ -74,30 +71,10 @@ steps: - script: | set -e - - # remove pkg from archive - zip -d ../VSCode-darwin.zip "*.pkg" - - # publish the build - PACKAGEJSON=`ls ../VSCode-darwin/*.app/Contents/Resources/app/package.json` - VERSION=`node -p "require(\"$PACKAGEJSON\").version"` AZURE_DOCUMENTDB_MASTERKEY="$(AZURE_DOCUMENTDB_MASTERKEY)" \ AZURE_STORAGE_ACCESS_KEY_2="$(AZURE_STORAGE_ACCESS_KEY_2)" \ - node build/azure-pipelines/common/publish.js \ - "$(VSCODE_QUALITY)" \ - darwin \ - archive \ - "VSCode-darwin-$(VSCODE_QUALITY).zip" \ - $VERSION \ - true \ - ../VSCode-darwin.zip - - # publish hockeyapp symbols - node build/azure-pipelines/common/symbols.js "$(VSCODE_MIXIN_PASSWORD)" "$(VSCODE_HOCKEYAPP_TOKEN)" "$(VSCODE_ARCH)" "$(VSCODE_HOCKEYAPP_ID_MACOS)" - - # upload configuration - AZURE_STORAGE_ACCESS_KEY="$(AZURE_STORAGE_ACCESS_KEY)" \ - yarn gulp -- upload-vscode-configuration + VSCODE_HOCKEYAPP_TOKEN="$(VSCODE_HOCKEYAPP_TOKEN)" \ + ./build/azure-pipelines/darwin/publish.sh displayName: Publish - task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0 diff --git a/build/azure-pipelines/darwin/publish.sh b/build/azure-pipelines/darwin/publish.sh new file mode 100755 index 00000000000..ae1f26173bb --- /dev/null +++ b/build/azure-pipelines/darwin/publish.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +# remove pkg from archive +zip -d ../VSCode-darwin.zip "*.pkg" + +# publish the build +PACKAGEJSON=`ls ../VSCode-darwin/*.app/Contents/Resources/app/package.json` +VERSION=`node -p "require(\"$PACKAGEJSON\").version"` +node build/azure-pipelines/common/publish.js \ + "$VSCODE_QUALITY" \ + darwin \ + archive \ + "VSCode-darwin-$VSCODE_QUALITY.zip" \ + $VERSION \ + true \ + ../VSCode-darwin.zip + +# publish hockeyapp symbols +node build/azure-pipelines/common/symbols.js "$VSCODE_MIXIN_PASSWORD" "$VSCODE_HOCKEYAPP_TOKEN" "$VSCODE_ARCH" "$VSCODE_HOCKEYAPP_ID_MACOS" + +# upload configuration +yarn gulp -- upload-vscode-configuration diff --git a/build/azure-pipelines/linux/build.sh b/build/azure-pipelines/linux/build.sh new file mode 100755 index 00000000000..69a7216fb96 --- /dev/null +++ b/build/azure-pipelines/linux/build.sh @@ -0,0 +1,3 @@ +#!/bin/sh +set -e +npm run gulp -- "vscode-linux-$VSCODE_ARCH-min" \ No newline at end of file diff --git a/build/azure-pipelines/linux/product-build-linux.yml b/build/azure-pipelines/linux/product-build-linux.yml index 3cea6670f05..823707c2c5d 100644 --- a/build/azure-pipelines/linux/product-build-linux.yml +++ b/build/azure-pipelines/linux/product-build-linux.yml @@ -28,11 +28,13 @@ steps: npm run monaco-compile-check node build/azure-pipelines/common/installDistro.js node build/lib/builtInExtensions.js + displayName: Prepare build - script: | set -e - VSCODE_MIXIN_PASSWORD="$(VSCODE_MIXIN_PASSWORD)" npm run gulp -- vscode-linux-$(VSCODE_ARCH)-min - name: build + VSCODE_MIXIN_PASSWORD="$(VSCODE_MIXIN_PASSWORD)" \ + ./build/azure-pipelines/linux/build.sh + displayName: Build - script: | set -e @@ -43,66 +45,16 @@ steps: DISPLAY=:10 ./scripts/test.sh --build --tfs "Unit Tests" # yarn smoketest -- --build "$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH)" - name: test + displayName: Run unit tests - script: | set -e - REPO="$(pwd)" - ROOT="$REPO/.." - ARCH="$(VSCODE_ARCH)" - - # Publish tarball - PLATFORM_LINUX="linux-$(VSCODE_ARCH)" - [[ "$ARCH" == "ia32" ]] && DEB_ARCH="i386" || DEB_ARCH="amd64" - [[ "$ARCH" == "ia32" ]] && RPM_ARCH="i386" || RPM_ARCH="x86_64" - BUILDNAME="VSCode-$PLATFORM_LINUX" - BUILD="$ROOT/$BUILDNAME" - BUILD_VERSION="$(date +%s)" - [ -z "$VSCODE_QUALITY" ] && TARBALL_FILENAME="code-$BUILD_VERSION.tar.gz" || TARBALL_FILENAME="code-$VSCODE_QUALITY-$BUILD_VERSION.tar.gz" - TARBALL_PATH="$ROOT/$TARBALL_FILENAME" - PACKAGEJSON="$BUILD/resources/app/package.json" - VERSION=$(node -p "require(\"$PACKAGEJSON\").version") - - rm -rf $ROOT/code-*.tar.* - (cd $ROOT && tar -czf $TARBALL_PATH $BUILDNAME) - AZURE_DOCUMENTDB_MASTERKEY="$(AZURE_DOCUMENTDB_MASTERKEY)" \ AZURE_STORAGE_ACCESS_KEY_2="$(AZURE_STORAGE_ACCESS_KEY_2)" \ - node build/azure-pipelines/common/publish.js "$VSCODE_QUALITY" "$PLATFORM_LINUX" archive-unsigned "$TARBALL_FILENAME" "$VERSION" true "$TARBALL_PATH" - - # Publish hockeyapp symbols - node build/azure-pipelines/common/symbols.js "$(VSCODE_MIXIN_PASSWORD)" "$(VSCODE_HOCKEYAPP_TOKEN)" "$(VSCODE_ARCH)" "$(VSCODE_HOCKEYAPP_ID_LINUX64)" - - # Publish DEB - npm run gulp -- "vscode-linux-$(VSCODE_ARCH)-build-deb" - PLATFORM_DEB="linux-deb-$ARCH" - [[ "$ARCH" == "ia32" ]] && DEB_ARCH="i386" || DEB_ARCH="amd64" - DEB_FILENAME="$(ls $REPO/.build/linux/deb/$DEB_ARCH/deb/)" - DEB_PATH="$REPO/.build/linux/deb/$DEB_ARCH/deb/$DEB_FILENAME" - - AZURE_DOCUMENTDB_MASTERKEY="$(AZURE_DOCUMENTDB_MASTERKEY)" \ - AZURE_STORAGE_ACCESS_KEY_2="$(AZURE_STORAGE_ACCESS_KEY_2)" \ - node build/azure-pipelines/common/publish.js "$VSCODE_QUALITY" "$PLATFORM_DEB" package "$DEB_FILENAME" "$VERSION" true "$DEB_PATH" - - # Publish RPM - npm run gulp -- "vscode-linux-$(VSCODE_ARCH)-build-rpm" - PLATFORM_RPM="linux-rpm-$ARCH" - [[ "$ARCH" == "ia32" ]] && RPM_ARCH="i386" || RPM_ARCH="x86_64" - RPM_FILENAME="$(ls $REPO/.build/linux/rpm/$RPM_ARCH/ | grep .rpm)" - RPM_PATH="$REPO/.build/linux/rpm/$RPM_ARCH/$RPM_FILENAME" - - AZURE_DOCUMENTDB_MASTERKEY="$(AZURE_DOCUMENTDB_MASTERKEY)" \ - AZURE_STORAGE_ACCESS_KEY_2="$(AZURE_STORAGE_ACCESS_KEY_2)" \ - node build/azure-pipelines/common/publish.js "$VSCODE_QUALITY" "$PLATFORM_RPM" package "$RPM_FILENAME" "$VERSION" true "$RPM_PATH" - - # Publish Snap - npm run gulp -- "vscode-linux-$(VSCODE_ARCH)-prepare-snap" - - # Pack snap tarball artifact, in order to preserve file perms - mkdir -p $REPO/.build/linux/snap-tarball - SNAP_TARBALL_PATH="$REPO/.build/linux/snap-tarball/snap-$(VSCODE_ARCH).tar.gz" - rm -rf $SNAP_TARBALL_PATH - (cd .build/linux && tar -czf $SNAP_TARBALL_PATH snap) + VSCODE_MIXIN_PASSWORD="$(VSCODE_MIXIN_PASSWORD)" \ + VSCODE_HOCKEYAPP_TOKEN="$(VSCODE_HOCKEYAPP_TOKEN)" \ + ./build/azure-pipelines/linux/publish.sh + displayName: Publish - task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0 displayName: 'Component Detection' diff --git a/build/azure-pipelines/linux/publish.sh b/build/azure-pipelines/linux/publish.sh new file mode 100755 index 00000000000..43061723255 --- /dev/null +++ b/build/azure-pipelines/linux/publish.sh @@ -0,0 +1,51 @@ +#!/bin/sh +set -e +REPO="$(pwd)" +ROOT="$REPO/.." + +# Publish tarball +PLATFORM_LINUX="linux-$VSCODE_ARCH" +[[ "$VSCODE_ARCH" == "ia32" ]] && DEB_ARCH="i386" || DEB_ARCH="amd64" +[[ "$VSCODE_ARCH" == "ia32" ]] && RPM_ARCH="i386" || RPM_ARCH="x86_64" +BUILDNAME="VSCode-$PLATFORM_LINUX" +BUILD="$ROOT/$BUILDNAME" +BUILD_VERSION="$(date +%s)" +[ -z "$VSCODE_QUALITY" ] && TARBALL_FILENAME="code-$BUILD_VERSION.tar.gz" || TARBALL_FILENAME="code-$VSCODE_QUALITY-$BUILD_VERSION.tar.gz" +TARBALL_PATH="$ROOT/$TARBALL_FILENAME" +PACKAGEJSON="$BUILD/resources/app/package.json" +VERSION=$(node -p "require(\"$PACKAGEJSON\").version") + +rm -rf $ROOT/code-*.tar.* +(cd $ROOT && tar -czf $TARBALL_PATH $BUILDNAME) + +node build/azure-pipelines/common/publish.js "$VSCODE_QUALITY" "$PLATFORM_LINUX" archive-unsigned "$TARBALL_FILENAME" "$VERSION" true "$TARBALL_PATH" + +# Publish hockeyapp symbols +node build/azure-pipelines/common/symbols.js "$VSCODE_MIXIN_PASSWORD" "$VSCODE_HOCKEYAPP_TOKEN" "$VSCODE_ARCH" "$VSCODE_HOCKEYAPP_ID_LINUX64" + +# Publish DEB +npm run gulp -- "vscode-linux-$VSCODE_ARCH-build-deb" +PLATFORM_DEB="linux-deb-$VSCODE_ARCH" +[[ "$VSCODE_ARCH" == "ia32" ]] && DEB_ARCH="i386" || DEB_ARCH="amd64" +DEB_FILENAME="$(ls $REPO/.build/linux/deb/$DEB_ARCH/deb/)" +DEB_PATH="$REPO/.build/linux/deb/$DEB_ARCH/deb/$DEB_FILENAME" + +node build/azure-pipelines/common/publish.js "$VSCODE_QUALITY" "$PLATFORM_DEB" package "$DEB_FILENAME" "$VERSION" true "$DEB_PATH" + +# Publish RPM +npm run gulp -- "vscode-linux-$VSCODE_ARCH-build-rpm" +PLATFORM_RPM="linux-rpm-$VSCODE_ARCH" +[[ "$VSCODE_ARCH" == "ia32" ]] && RPM_ARCH="i386" || RPM_ARCH="x86_64" +RPM_FILENAME="$(ls $REPO/.build/linux/rpm/$RPM_ARCH/ | grep .rpm)" +RPM_PATH="$REPO/.build/linux/rpm/$RPM_ARCH/$RPM_FILENAME" + +node build/azure-pipelines/common/publish.js "$VSCODE_QUALITY" "$PLATFORM_RPM" package "$RPM_FILENAME" "$VERSION" true "$RPM_PATH" + +# Publish Snap +npm run gulp -- "vscode-linux-$VSCODE_ARCH-prepare-snap" + +# Pack snap tarball artifact, in order to preserve file perms +mkdir -p $REPO/.build/linux/snap-tarball +SNAP_TARBALL_PATH="$REPO/.build/linux/snap-tarball/snap-$VSCODE_ARCH.tar.gz" +rm -rf $SNAP_TARBALL_PATH +(cd .build/linux && tar -czf $SNAP_TARBALL_PATH snap) diff --git a/build/azure-pipelines/win32/build.ps1 b/build/azure-pipelines/win32/build.ps1 new file mode 100644 index 00000000000..2a6485ae8e2 --- /dev/null +++ b/build/azure-pipelines/win32/build.ps1 @@ -0,0 +1,4 @@ +. build/azure-pipelines/win32/exec.ps1 +$ErrorActionPreference = "Stop" +exec { yarn gulp "vscode-win32-$(VSCODE_ARCH)-min" } +exec { yarn gulp "vscode-win32-$(VSCODE_ARCH)-inno-updater" } \ No newline at end of file diff --git a/build/azure-pipelines/win32/product-build-win32.yml b/build/azure-pipelines/win32/product-build-win32.yml index 5af15cf6625..51865c8561a 100644 --- a/build/azure-pipelines/win32/product-build-win32.yml +++ b/build/azure-pipelines/win32/product-build-win32.yml @@ -20,34 +20,34 @@ steps: $env:CHILD_CONCURRENCY="1" $env:VSCODE_MIXIN_PASSWORD="$(VSCODE_MIXIN_PASSWORD)" exec { yarn } - exec { npm run gulp -- mixin } - exec { npm run gulp -- hygiene } - exec { npm run monaco-compile-check } + exec { yarn gulp mixin } + exec { yarn gulp hygiene } + exec { yarn monaco-compile-check } exec { node build/azure-pipelines/common/installDistro.js } exec { node build/lib/builtInExtensions.js } + displayName: Prepare build - powershell: | . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" $env:VSCODE_MIXIN_PASSWORD="$(VSCODE_MIXIN_PASSWORD)" - exec { npm run gulp -- "vscode-win32-$(VSCODE_ARCH)-min" } - exec { npm run gulp -- "vscode-win32-$(VSCODE_ARCH)-inno-updater" } - name: build + .\build\azure-pipelines\win32\build.ps1 + displayName: Build - powershell: | . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" - exec { npm run gulp -- "electron-$(VSCODE_ARCH)" } + exec { yarn gulp "electron-$(VSCODE_ARCH)" } exec { .\scripts\test.bat --build --tfs "Unit Tests" } # yarn smoketest -- --build "$(agent.builddirectory)\VSCode-win32-$(VSCODE_ARCH)" - displayName: Unit tests + displayName: Run unit tests - powershell: | . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" - exec { npm run gulp -- "electron-$(VSCODE_ARCH)" } + exec { yarn gulp "electron-$(VSCODE_ARCH)" } exec { .\scripts\test-integration.bat --build --tfs "Integration Tests" } - displayName: Integration tests + displayName: Run integration tests - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@1 inputs: @@ -126,31 +126,11 @@ steps: - powershell: | . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" - exec { npm run gulp -- "vscode-win32-$(VSCODE_ARCH)-archive" "vscode-win32-$(VSCODE_ARCH)-system-setup" "vscode-win32-$(VSCODE_ARCH)-user-setup" --sign } - - $Repo = "$(pwd)" - $Root = "$Repo\.." - $SystemExe = "$Repo\.build\win32-$(VSCODE_ARCH)\system-setup\VSCodeSetup.exe" - $UserExe = "$Repo\.build\win32-$(VSCODE_ARCH)\user-setup\VSCodeSetup.exe" - $Zip = "$Repo\.build\win32-$(VSCODE_ARCH)\archive\VSCode-win32-$(VSCODE_ARCH).zip" - $Build = "$Root\VSCode-win32-$(VSCODE_ARCH)" - - # get version - $PackageJson = Get-Content -Raw -Path "$Build\resources\app\package.json" | ConvertFrom-Json - $Version = $PackageJson.version - $Quality = "$env:VSCODE_QUALITY" $env:AZURE_STORAGE_ACCESS_KEY_2 = "$(AZURE_STORAGE_ACCESS_KEY_2)" $env:AZURE_DOCUMENTDB_MASTERKEY = "$(AZURE_DOCUMENTDB_MASTERKEY)" - - $assetPlatform = if ("$(VSCODE_ARCH)" -eq "ia32") { "win32" } else { "win32-x64" } - - exec { node build/azure-pipelines/common/publish.js $Quality "$global:assetPlatform-archive" archive "VSCode-win32-$(VSCODE_ARCH)-$Version.zip" $Version true $Zip } - exec { node build/azure-pipelines/common/publish.js $Quality "$global:assetPlatform" setup "VSCodeSetup-$(VSCODE_ARCH)-$Version.exe" $Version true $SystemExe } - exec { node build/azure-pipelines/common/publish.js $Quality "$global:assetPlatform-user" setup "VSCodeUserSetup-$(VSCODE_ARCH)-$Version.exe" $Version true $UserExe } - - # publish hockeyapp symbols - $hockeyAppId = if ("$(VSCODE_ARCH)" -eq "ia32") { "$(VSCODE_HOCKEYAPP_ID_WIN32)" } else { "$(VSCODE_HOCKEYAPP_ID_WIN64)" } - exec { node build/azure-pipelines/common/symbols.js "$(VSCODE_MIXIN_PASSWORD)" "$(VSCODE_HOCKEYAPP_TOKEN)" "$(VSCODE_ARCH)" $hockeyAppId } + $env:VSCODE_HOCKEYAPP_TOKEN = "$(VSCODE_HOCKEYAPP_TOKEN)" + .\build\azure-pipelines\win32\publish.ps1 + displayName: Publish - task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0 displayName: 'Component Detection' diff --git a/build/azure-pipelines/win32/publish.ps1 b/build/azure-pipelines/win32/publish.ps1 new file mode 100644 index 00000000000..02973bc17e1 --- /dev/null +++ b/build/azure-pipelines/win32/publish.ps1 @@ -0,0 +1,28 @@ +. build/azure-pipelines/win32/exec.ps1 +$ErrorActionPreference = "Stop" + +$Arch = "$env:VSCODE_ARCH" + +exec { yarn gulp "vscode-win32-$Arch-archive" "vscode-win32-$Arch-system-setup" "vscode-win32-$Arch-user-setup" --sign } + +$Repo = "$(pwd)" +$Root = "$Repo\.." +$SystemExe = "$Repo\.build\win32-$Arch\system-setup\VSCodeSetup.exe" +$UserExe = "$Repo\.build\win32-$Arch\user-setup\VSCodeSetup.exe" +$Zip = "$Repo\.build\win32-$Arch\archive\VSCode-win32-$Arch.zip" +$Build = "$Root\VSCode-win32-$Arch" + +# get version +$PackageJson = Get-Content -Raw -Path "$Build\resources\app\package.json" | ConvertFrom-Json +$Version = $PackageJson.version +$Quality = "$env:VSCODE_QUALITY" + +$assetPlatform = if ("$Arch" -eq "ia32") { "win32" } else { "win32-x64" } + +exec { node build/azure-pipelines/common/publish.js $Quality "$global:assetPlatform-archive" archive "VSCode-win32-$Arch-$Version.zip" $Version true $Zip } +exec { node build/azure-pipelines/common/publish.js $Quality "$global:assetPlatform" setup "VSCodeSetup-$Arch-$Version.exe" $Version true $SystemExe } +exec { node build/azure-pipelines/common/publish.js $Quality "$global:assetPlatform-user" setup "VSCodeUserSetup-$Arch-$Version.exe" $Version true $UserExe } + +# publish hockeyapp symbols +$hockeyAppId = if ("$Arch" -eq "ia32") { "$env:VSCODE_HOCKEYAPP_ID_WIN32" } else { "$env:VSCODE_HOCKEYAPP_ID_WIN64" } +exec { node build/azure-pipelines/common/symbols.js "$env:VSCODE_MIXIN_PASSWORD" "$env:VSCODE_HOCKEYAPP_TOKEN" "$Arch" $hockeyAppId } From f1bb8327bf03e875eb7ac6e04ded69569fd28e38 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Thu, 11 Apr 2019 16:12:29 +0200 Subject: [PATCH 04/48] fix windows build script --- build/azure-pipelines/win32/build.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/azure-pipelines/win32/build.ps1 b/build/azure-pipelines/win32/build.ps1 index 2a6485ae8e2..60325ba54ca 100644 --- a/build/azure-pipelines/win32/build.ps1 +++ b/build/azure-pipelines/win32/build.ps1 @@ -1,4 +1,4 @@ . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" -exec { yarn gulp "vscode-win32-$(VSCODE_ARCH)-min" } -exec { yarn gulp "vscode-win32-$(VSCODE_ARCH)-inno-updater" } \ No newline at end of file +exec { yarn gulp "vscode-win32-$env:VSCODE_ARCH-min" } +exec { yarn gulp "vscode-win32-$env:VSCODE_ARCH-inno-updater" } \ No newline at end of file From d9bb681c47858c21c086b4a1ca5d1ba28ffe1387 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Thu, 11 Apr 2019 16:20:26 +0200 Subject: [PATCH 05/48] fix builds --- build/azure-pipelines/darwin/build.sh | 2 +- build/azure-pipelines/darwin/publish.sh | 2 +- build/azure-pipelines/linux/build.sh | 2 +- build/azure-pipelines/linux/publish.sh | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/azure-pipelines/darwin/build.sh b/build/azure-pipelines/darwin/build.sh index 604e92e9396..e9ee9d2b3af 100755 --- a/build/azure-pipelines/darwin/build.sh +++ b/build/azure-pipelines/darwin/build.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/usr/bin/env bash set -e yarn gulp -- vscode-darwin-min yarn gulp -- upload-vscode-sourcemaps \ No newline at end of file diff --git a/build/azure-pipelines/darwin/publish.sh b/build/azure-pipelines/darwin/publish.sh index ae1f26173bb..1ec7aa9a98e 100755 --- a/build/azure-pipelines/darwin/publish.sh +++ b/build/azure-pipelines/darwin/publish.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/usr/bin/env bash # remove pkg from archive zip -d ../VSCode-darwin.zip "*.pkg" diff --git a/build/azure-pipelines/linux/build.sh b/build/azure-pipelines/linux/build.sh index 69a7216fb96..95e01ceab8c 100755 --- a/build/azure-pipelines/linux/build.sh +++ b/build/azure-pipelines/linux/build.sh @@ -1,3 +1,3 @@ -#!/bin/sh +#!/usr/bin/env bash set -e npm run gulp -- "vscode-linux-$VSCODE_ARCH-min" \ No newline at end of file diff --git a/build/azure-pipelines/linux/publish.sh b/build/azure-pipelines/linux/publish.sh index 43061723255..bdc9ac58930 100755 --- a/build/azure-pipelines/linux/publish.sh +++ b/build/azure-pipelines/linux/publish.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/usr/bin/env bash set -e REPO="$(pwd)" ROOT="$REPO/.." From 9a711944c266e2966bfb82d586e188f443d70fea Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Thu, 11 Apr 2019 17:04:06 +0200 Subject: [PATCH 06/48] fix windows builds --- build/azure-pipelines/win32/publish.ps1 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/build/azure-pipelines/win32/publish.ps1 b/build/azure-pipelines/win32/publish.ps1 index 02973bc17e1..8e6fa988adf 100644 --- a/build/azure-pipelines/win32/publish.ps1 +++ b/build/azure-pipelines/win32/publish.ps1 @@ -17,11 +17,11 @@ $PackageJson = Get-Content -Raw -Path "$Build\resources\app\package.json" | Conv $Version = $PackageJson.version $Quality = "$env:VSCODE_QUALITY" -$assetPlatform = if ("$Arch" -eq "ia32") { "win32" } else { "win32-x64" } +$AssetPlatform = if ("$Arch" -eq "ia32") { "win32" } else { "win32-x64" } -exec { node build/azure-pipelines/common/publish.js $Quality "$global:assetPlatform-archive" archive "VSCode-win32-$Arch-$Version.zip" $Version true $Zip } -exec { node build/azure-pipelines/common/publish.js $Quality "$global:assetPlatform" setup "VSCodeSetup-$Arch-$Version.exe" $Version true $SystemExe } -exec { node build/azure-pipelines/common/publish.js $Quality "$global:assetPlatform-user" setup "VSCodeUserSetup-$Arch-$Version.exe" $Version true $UserExe } +exec { node build/azure-pipelines/common/publish.js $Quality "$AssetPlatform-archive" archive "VSCode-win32-$Arch-$Version.zip" $Version true $Zip } +exec { node build/azure-pipelines/common/publish.js $Quality "$AssetPlatform" setup "VSCodeSetup-$Arch-$Version.exe" $Version true $SystemExe } +exec { node build/azure-pipelines/common/publish.js $Quality "$AssetPlatform-user" setup "VSCodeUserSetup-$Arch-$Version.exe" $Version true $UserExe } # publish hockeyapp symbols $hockeyAppId = if ("$Arch" -eq "ia32") { "$env:VSCODE_HOCKEYAPP_ID_WIN32" } else { "$env:VSCODE_HOCKEYAPP_ID_WIN64" } From 421cf5ba67632cada5d092decd5db3eea3a10bfd Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 11 Apr 2019 17:04:22 +0200 Subject: [PATCH 07/48] files - more encoding tests --- .../textfile/test/fixtures/some_big5.txt | 1 + .../textfile/test/fixtures/some_cp1252.txt | 3 + .../textfile/test/fixtures/some_cyrillic.txt | 1 + .../textfile/test/fixtures/some_gbk.txt | 1 + .../textfile/test/fixtures/some_shiftjs.txt | 1 + .../textfile/test/textFileService.io.test.ts | 82 +++++++++---------- 6 files changed, 44 insertions(+), 45 deletions(-) create mode 100644 src/vs/workbench/services/textfile/test/fixtures/some_big5.txt create mode 100644 src/vs/workbench/services/textfile/test/fixtures/some_cp1252.txt create mode 100644 src/vs/workbench/services/textfile/test/fixtures/some_cyrillic.txt create mode 100644 src/vs/workbench/services/textfile/test/fixtures/some_gbk.txt create mode 100644 src/vs/workbench/services/textfile/test/fixtures/some_shiftjs.txt diff --git a/src/vs/workbench/services/textfile/test/fixtures/some_big5.txt b/src/vs/workbench/services/textfile/test/fixtures/some_big5.txt new file mode 100644 index 00000000000..b9e2570fef9 --- /dev/null +++ b/src/vs/workbench/services/textfile/test/fixtures/some_big5.txt @@ -0,0 +1 @@ +abc \ No newline at end of file diff --git a/src/vs/workbench/services/textfile/test/fixtures/some_cp1252.txt b/src/vs/workbench/services/textfile/test/fixtures/some_cp1252.txt new file mode 100644 index 00000000000..2ea52dc709f --- /dev/null +++ b/src/vs/workbench/services/textfile/test/fixtures/some_cp1252.txt @@ -0,0 +1,3 @@ +ObjectCount = LoadObjects("ffentlicher Ordner"); + +Private = "Persnliche Information" diff --git a/src/vs/workbench/services/textfile/test/fixtures/some_cyrillic.txt b/src/vs/workbench/services/textfile/test/fixtures/some_cyrillic.txt new file mode 100644 index 00000000000..f8ee3066712 --- /dev/null +++ b/src/vs/workbench/services/textfile/test/fixtures/some_cyrillic.txt @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/vs/workbench/services/textfile/test/fixtures/some_gbk.txt b/src/vs/workbench/services/textfile/test/fixtures/some_gbk.txt new file mode 100644 index 00000000000..eab73d1951b --- /dev/null +++ b/src/vs/workbench/services/textfile/test/fixtures/some_gbk.txt @@ -0,0 +1 @@ +йabc \ No newline at end of file diff --git a/src/vs/workbench/services/textfile/test/fixtures/some_shiftjs.txt b/src/vs/workbench/services/textfile/test/fixtures/some_shiftjs.txt new file mode 100644 index 00000000000..efa955b3ecb --- /dev/null +++ b/src/vs/workbench/services/textfile/test/fixtures/some_shiftjs.txt @@ -0,0 +1 @@ +abc \ No newline at end of file diff --git a/src/vs/workbench/services/textfile/test/textFileService.io.test.ts b/src/vs/workbench/services/textfile/test/textFileService.io.test.ts index da7fc8d1c4e..a3fcb00d950 100644 --- a/src/vs/workbench/services/textfile/test/textFileService.io.test.ts +++ b/src/vs/workbench/services/textfile/test/textFileService.io.test.ts @@ -9,7 +9,7 @@ import { workbenchInstantiationService, TestLifecycleService, TestTextFileServic import { IWindowsService } from 'vs/platform/windows/common/windows'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService'; -import { IFileService, ITextSnapshot, snapshotToString, SUPPORTED_ENCODINGS } from 'vs/platform/files/common/files'; +import { IFileService, ITextSnapshot, snapshotToString } from 'vs/platform/files/common/files'; import { TextFileEditorModelManager } from 'vs/workbench/services/textfile/common/textFileEditorModelManager'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { IModelService } from 'vs/editor/common/services/modelService'; @@ -251,6 +251,42 @@ suite('Files - TextFileService i/o', () => { assert.equal(snapshotToString(resolved.value.create(DefaultEndOfLine.LF).createSnapshot(false)), expectedContent); } + test('write - use encoding (cp1252)', async () => { + await testEncodingKeepsData(URI.file(join(testDir, 'some_cp1252.txt')), 'cp1252', ['ObjectCount = LoadObjects("Öffentlicher Ordner");', '', 'Private = "Persönliche Information"', ''].join('\n')); + }); + + test('write - use encoding (shiftjis)', async () => { + await testEncodingKeepsData(URI.file(join(testDir, 'some_shiftjs.txt')), 'shiftjis', '中文abc'); + }); + + test('write - use encoding (gbk)', async () => { + await testEncodingKeepsData(URI.file(join(testDir, 'some_gbk.txt')), 'gbk', '中国abc'); + }); + + test('write - use encoding (cyrillic)', async () => { + await testEncodingKeepsData(URI.file(join(testDir, 'some_cyrillic.txt')), 'cp866', 'АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя'); + }); + + test('write - use encoding (big5)', async () => { + await testEncodingKeepsData(URI.file(join(testDir, 'some_big5.txt')), 'cp950', '中文abc'); + }); + + async function testEncodingKeepsData(resource: URI, encoding: string, expected: string) { + let resolved = await service.resolve(resource, { encoding }); + const content = snapshotToString(resolved.value.create(DefaultEndOfLine.LF).createSnapshot(false)); + assert.equal(content, expected); + + await service.write(resource, content, { encoding }); + + resolved = await service.resolve(resource, { encoding }); + assert.equal(snapshotToString(resolved.value.create(DefaultEndOfLine.LF).createSnapshot(false)), content); + + await service.write(resource, TextModel.createFromString(content).createSnapshot(), { encoding }); + + resolved = await service.resolve(resource, { encoding }); + assert.equal(snapshotToString(resolved.value.create(DefaultEndOfLine.LF).createSnapshot(false)), content); + } + test('write - no encoding - content as string', async () => { const resource = URI.file(join(testDir, 'small.txt')); @@ -358,50 +394,6 @@ suite('Files - TextFileService i/o', () => { assert.equal(detectedEncoding, UTF8); }); - test('write - CP1252 - content as string', async () => { - const resource = URI.file(join(testDir, 'small_umlaut.txt')); - - const content = (await readFile(resource.fsPath)).toString(); - - await service.write(resource, content, { encoding: 'cp1252' }); - - const resolved = await service.resolve(resource, { encoding: 'cp1252' }); - assert.equal(snapshotToString(resolved.value.create(DefaultEndOfLine.LF).createSnapshot(false)), content); - }); - - test('write - all encodings - large content as snapshot', async () => { - const resource = URI.file(join(testDir, 'lorem.txt')); - const content = (await readFile(resource.fsPath)).toString(); - - for (const encoding of Object.keys(SUPPORTED_ENCODINGS)) { - if (encoding === 'utf8bom') { - continue; // this is the only encoding that is not standard, so skip it - } - - await testEncoding2(resource, encoding, content); - } - }); - - test('write - all encodings - small content as snapshot', async () => { - const resource = URI.file(join(testDir, 'small.txt')); - const content = (await readFile(resource.fsPath)).toString(); - - for (const encoding of Object.keys(SUPPORTED_ENCODINGS)) { - if (encoding === 'utf8bom') { - continue; // this is the only encoding that is not standard, so skip it - } - - await testEncoding2(resource, encoding, content); - } - }); - - async function testEncoding2(resource: URI, encoding: string, content: string): Promise { - await service.write(resource, content, { encoding }); - - const resolved = await service.resolve(resource, { encoding }); - assert.equal(snapshotToString(resolved.value.create(DefaultEndOfLine.LF).createSnapshot(false)), content, 'Encoding used: ' + encoding); - } - test('write - ensure BOM in empty file - content as string', async () => { const resource = URI.file(join(testDir, 'small.txt')); From 2adfa4353ee9152703ef439e2f7c25d857be62d6 Mon Sep 17 00:00:00 2001 From: isidor Date: Thu, 11 Apr 2019 17:09:45 +0200 Subject: [PATCH 08/48] debug console: In order to keep scroll position we need to give a good approximation to the tree fixes #71737 --- src/vs/workbench/contrib/debug/browser/repl.ts | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/debug/browser/repl.ts b/src/vs/workbench/contrib/debug/browser/repl.ts index 44d6ecce76f..75b1edfd663 100644 --- a/src/vs/workbench/contrib/debug/browser/repl.ts +++ b/src/vs/workbench/contrib/debug/browser/repl.ts @@ -720,11 +720,25 @@ class ReplDelegate implements IListVirtualDelegate { getHeight(element: IReplElement): number { // Give approximate heights. Repl has dynamic height so the tree will measure the actual height on its own. const fontSize = this.configurationService.getValue('debug').console.fontSize; + const rowHeight = Math.ceil(1.4 * fontSize); if (element instanceof Expression && element.hasChildren) { - return Math.ceil(2 * 1.4 * fontSize); + return 2 * rowHeight; } - return Math.ceil(1.4 * fontSize); + // In order to keep scroll position we need to give a good approximation to the tree + if (element instanceof SimpleReplElement) { + // For every 150 characters increase the number of lines needed + let count = Math.ceil(element.value.length / 150); + for (let i = 0; i < element.value.length; i++) { + if (element.value[i] === '\n' || element.value[i] === '\r\n') { + count++; + } + } + + return Math.max(1, count) * rowHeight; + } + + return rowHeight; } getTemplateId(element: IReplElement): string { From efa670f7b9965141fca80af1cdf73980900e75a7 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 11 Apr 2019 18:04:23 +0200 Subject: [PATCH 09/48] fix tests --- .../textfile/test/textFileService.io.test.ts | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/vs/workbench/services/textfile/test/textFileService.io.test.ts b/src/vs/workbench/services/textfile/test/textFileService.io.test.ts index a3fcb00d950..65b968a90c3 100644 --- a/src/vs/workbench/services/textfile/test/textFileService.io.test.ts +++ b/src/vs/workbench/services/textfile/test/textFileService.io.test.ts @@ -31,6 +31,7 @@ import { NodeTextFileService, EncodingOracle, IEncodingOverride } from 'vs/workb import { LegacyFileService } from 'vs/workbench/services/files/node/fileService'; import { DefaultEndOfLine } from 'vs/editor/common/model'; import { TextModel } from 'vs/editor/common/model/textModel'; +import { isWindows } from 'vs/base/common/platform'; class ServiceAccessor { constructor( @@ -248,11 +249,11 @@ suite('Files - TextFileService i/o', () => { const resolved = await service.resolve(resource); assert.equal(resolved.encoding, encoding); - assert.equal(snapshotToString(resolved.value.create(DefaultEndOfLine.LF).createSnapshot(false)), expectedContent); + assert.equal(snapshotToString(resolved.value.create(isWindows ? DefaultEndOfLine.CRLF : DefaultEndOfLine.LF).createSnapshot(false)), expectedContent); } test('write - use encoding (cp1252)', async () => { - await testEncodingKeepsData(URI.file(join(testDir, 'some_cp1252.txt')), 'cp1252', ['ObjectCount = LoadObjects("Öffentlicher Ordner");', '', 'Private = "Persönliche Information"', ''].join('\n')); + await testEncodingKeepsData(URI.file(join(testDir, 'some_cp1252.txt')), 'cp1252', ['ObjectCount = LoadObjects("Öffentlicher Ordner");', '', 'Private = "Persönliche Information"', ''].join(isWindows ? '\r\n' : '\n')); }); test('write - use encoding (shiftjis)', async () => { @@ -273,18 +274,18 @@ suite('Files - TextFileService i/o', () => { async function testEncodingKeepsData(resource: URI, encoding: string, expected: string) { let resolved = await service.resolve(resource, { encoding }); - const content = snapshotToString(resolved.value.create(DefaultEndOfLine.LF).createSnapshot(false)); + const content = snapshotToString(resolved.value.create(isWindows ? DefaultEndOfLine.CRLF : DefaultEndOfLine.LF).createSnapshot(false)); assert.equal(content, expected); await service.write(resource, content, { encoding }); resolved = await service.resolve(resource, { encoding }); - assert.equal(snapshotToString(resolved.value.create(DefaultEndOfLine.LF).createSnapshot(false)), content); + assert.equal(snapshotToString(resolved.value.create(DefaultEndOfLine.CRLF).createSnapshot(false)), content); await service.write(resource, TextModel.createFromString(content).createSnapshot(), { encoding }); resolved = await service.resolve(resource, { encoding }); - assert.equal(snapshotToString(resolved.value.create(DefaultEndOfLine.LF).createSnapshot(false)), content); + assert.equal(snapshotToString(resolved.value.create(DefaultEndOfLine.CRLF).createSnapshot(false)), content); } test('write - no encoding - content as string', async () => { @@ -295,7 +296,7 @@ suite('Files - TextFileService i/o', () => { await service.write(resource, content); const resolved = await service.resolve(resource); - assert.equal(snapshotToString(resolved.value.create(DefaultEndOfLine.LF).createSnapshot(false)), content); + assert.equal(snapshotToString(resolved.value.create(isWindows ? DefaultEndOfLine.CRLF : DefaultEndOfLine.LF).createSnapshot(false)), content); }); test('write - no encoding - content as snapshot', async () => { @@ -306,7 +307,7 @@ suite('Files - TextFileService i/o', () => { await service.write(resource, TextModel.createFromString(content).createSnapshot()); const resolved = await service.resolve(resource); - assert.equal(snapshotToString(resolved.value.create(DefaultEndOfLine.LF).createSnapshot(false)), content); + assert.equal(snapshotToString(resolved.value.create(isWindows ? DefaultEndOfLine.CRLF : DefaultEndOfLine.LF).createSnapshot(false)), content); }); test('write - encoding preserved (UTF 16 LE) - content as string', async () => { From 64a37d601a8112bd5d44d1db28342aa9458d25b8 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 10 Apr 2019 15:25:40 -0700 Subject: [PATCH 10/48] Convert SizeUtils to a static class This makes it easier to track references to these methods --- src/vs/base/browser/dom.ts | 71 +++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 36 deletions(-) diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index ccce65e591c..90762e85ada 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -514,48 +514,47 @@ export function getClientArea(element: HTMLElement): Dimension { throw new Error('Unable to figure out browser width and height'); } -const sizeUtils = { +class SizeUtils { - getBorderLeftWidth: function (element: HTMLElement): number { + static getBorderLeftWidth(element: HTMLElement): number { return getDimension(element, 'border-left-width', 'borderLeftWidth'); - }, - getBorderRightWidth: function (element: HTMLElement): number { + } + static getBorderRightWidth(element: HTMLElement): number { return getDimension(element, 'border-right-width', 'borderRightWidth'); - }, - getBorderTopWidth: function (element: HTMLElement): number { + } + static getBorderTopWidth(element: HTMLElement): number { return getDimension(element, 'border-top-width', 'borderTopWidth'); - }, - getBorderBottomWidth: function (element: HTMLElement): number { + } + static getBorderBottomWidth(element: HTMLElement): number { return getDimension(element, 'border-bottom-width', 'borderBottomWidth'); - }, + } - getPaddingLeft: function (element: HTMLElement): number { + static getPaddingLeft(element: HTMLElement): number { return getDimension(element, 'padding-left', 'paddingLeft'); - }, - getPaddingRight: function (element: HTMLElement): number { + } + static getPaddingRight(element: HTMLElement): number { return getDimension(element, 'padding-right', 'paddingRight'); - }, - getPaddingTop: function (element: HTMLElement): number { + } + static getPaddingTop(element: HTMLElement): number { return getDimension(element, 'padding-top', 'paddingTop'); - }, - getPaddingBottom: function (element: HTMLElement): number { + } + static getPaddingBottom(element: HTMLElement): number { return getDimension(element, 'padding-bottom', 'paddingBottom'); - }, + } - getMarginLeft: function (element: HTMLElement): number { + static getMarginLeft(element: HTMLElement): number { return getDimension(element, 'margin-left', 'marginLeft'); - }, - getMarginTop: function (element: HTMLElement): number { + } + static getMarginTop(element: HTMLElement): number { return getDimension(element, 'margin-top', 'marginTop'); - }, - getMarginRight: function (element: HTMLElement): number { + } + static getMarginRight(element: HTMLElement): number { return getDimension(element, 'margin-right', 'marginRight'); - }, - getMarginBottom: function (element: HTMLElement): number { + } + static getMarginBottom(element: HTMLElement): number { return getDimension(element, 'margin-bottom', 'marginBottom'); - }, - __commaSentinel: false -}; + } +} // ---------------------------------------------------------------------------------------- // Position & Dimension @@ -594,8 +593,8 @@ export function getTopLeftOffset(element: HTMLElement): { left: number; top: num } if (element === offsetParent) { - left += sizeUtils.getBorderLeftWidth(element); - top += sizeUtils.getBorderTopWidth(element); + left += SizeUtils.getBorderLeftWidth(element); + top += SizeUtils.getBorderTopWidth(element); top += element.offsetTop; left += element.offsetLeft; offsetParent = element.offsetParent; @@ -686,33 +685,33 @@ export const StandardWindow: IStandardWindow = new class implements IStandardWin // Adapted from WinJS // Gets the width of the element, including margins. export function getTotalWidth(element: HTMLElement): number { - let margin = sizeUtils.getMarginLeft(element) + sizeUtils.getMarginRight(element); + let margin = SizeUtils.getMarginLeft(element) + SizeUtils.getMarginRight(element); return element.offsetWidth + margin; } export function getContentWidth(element: HTMLElement): number { - let border = sizeUtils.getBorderLeftWidth(element) + sizeUtils.getBorderRightWidth(element); - let padding = sizeUtils.getPaddingLeft(element) + sizeUtils.getPaddingRight(element); + let border = SizeUtils.getBorderLeftWidth(element) + SizeUtils.getBorderRightWidth(element); + let padding = SizeUtils.getPaddingLeft(element) + SizeUtils.getPaddingRight(element); return element.offsetWidth - border - padding; } export function getTotalScrollWidth(element: HTMLElement): number { - let margin = sizeUtils.getMarginLeft(element) + sizeUtils.getMarginRight(element); + let margin = SizeUtils.getMarginLeft(element) + SizeUtils.getMarginRight(element); return element.scrollWidth + margin; } // Adapted from WinJS // Gets the height of the content of the specified element. The content height does not include borders or padding. export function getContentHeight(element: HTMLElement): number { - let border = sizeUtils.getBorderTopWidth(element) + sizeUtils.getBorderBottomWidth(element); - let padding = sizeUtils.getPaddingTop(element) + sizeUtils.getPaddingBottom(element); + let border = SizeUtils.getBorderTopWidth(element) + SizeUtils.getBorderBottomWidth(element); + let padding = SizeUtils.getPaddingTop(element) + SizeUtils.getPaddingBottom(element); return element.offsetHeight - border - padding; } // Adapted from WinJS // Gets the height of the element, including its margins. export function getTotalHeight(element: HTMLElement): number { - let margin = sizeUtils.getMarginTop(element) + sizeUtils.getMarginBottom(element); + let margin = SizeUtils.getMarginTop(element) + SizeUtils.getMarginBottom(element); return element.offsetHeight + margin; } From e7e32aff371c8943eeb60648e3d4ed33f79d2bf4 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 10 Apr 2019 15:29:42 -0700 Subject: [PATCH 11/48] Move getDimension into SizeUtils --- src/vs/base/browser/dom.ts | 51 +++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index 90762e85ada..e07379d1834 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -475,20 +475,6 @@ const convertToPixels: (element: HTMLElement, value: string) => number = (functi }; })(); -function getDimension(element: HTMLElement, cssPropertyName: string, jsPropertyName: string): number { - let computedStyle: CSSStyleDeclaration = getComputedStyle(element); - let value = '0'; - if (computedStyle) { - if (computedStyle.getPropertyValue) { - value = computedStyle.getPropertyValue(cssPropertyName); - } else { - // IE8 - value = (computedStyle).getAttribute(jsPropertyName); - } - } - return convertToPixels(element, value); -} - export function getClientArea(element: HTMLElement): Dimension { // Try with DOM clientWidth / clientHeight @@ -515,44 +501,57 @@ export function getClientArea(element: HTMLElement): Dimension { } class SizeUtils { + private static getDimension(element: HTMLElement, cssPropertyName: string, jsPropertyName: string): number { + let computedStyle: CSSStyleDeclaration = getComputedStyle(element); + let value = '0'; + if (computedStyle) { + if (computedStyle.getPropertyValue) { + value = computedStyle.getPropertyValue(cssPropertyName); + } else { + // IE8 + value = (computedStyle).getAttribute(jsPropertyName); + } + } + return convertToPixels(element, value); + } static getBorderLeftWidth(element: HTMLElement): number { - return getDimension(element, 'border-left-width', 'borderLeftWidth'); + return SizeUtils.getDimension(element, 'border-left-width', 'borderLeftWidth'); } static getBorderRightWidth(element: HTMLElement): number { - return getDimension(element, 'border-right-width', 'borderRightWidth'); + return SizeUtils.getDimension(element, 'border-right-width', 'borderRightWidth'); } static getBorderTopWidth(element: HTMLElement): number { - return getDimension(element, 'border-top-width', 'borderTopWidth'); + return SizeUtils.getDimension(element, 'border-top-width', 'borderTopWidth'); } static getBorderBottomWidth(element: HTMLElement): number { - return getDimension(element, 'border-bottom-width', 'borderBottomWidth'); + return SizeUtils.getDimension(element, 'border-bottom-width', 'borderBottomWidth'); } static getPaddingLeft(element: HTMLElement): number { - return getDimension(element, 'padding-left', 'paddingLeft'); + return SizeUtils.getDimension(element, 'padding-left', 'paddingLeft'); } static getPaddingRight(element: HTMLElement): number { - return getDimension(element, 'padding-right', 'paddingRight'); + return SizeUtils.getDimension(element, 'padding-right', 'paddingRight'); } static getPaddingTop(element: HTMLElement): number { - return getDimension(element, 'padding-top', 'paddingTop'); + return SizeUtils.getDimension(element, 'padding-top', 'paddingTop'); } static getPaddingBottom(element: HTMLElement): number { - return getDimension(element, 'padding-bottom', 'paddingBottom'); + return SizeUtils.getDimension(element, 'padding-bottom', 'paddingBottom'); } static getMarginLeft(element: HTMLElement): number { - return getDimension(element, 'margin-left', 'marginLeft'); + return SizeUtils.getDimension(element, 'margin-left', 'marginLeft'); } static getMarginTop(element: HTMLElement): number { - return getDimension(element, 'margin-top', 'marginTop'); + return SizeUtils.getDimension(element, 'margin-top', 'marginTop'); } static getMarginRight(element: HTMLElement): number { - return getDimension(element, 'margin-right', 'marginRight'); + return SizeUtils.getDimension(element, 'margin-right', 'marginRight'); } static getMarginBottom(element: HTMLElement): number { - return getDimension(element, 'margin-bottom', 'marginBottom'); + return SizeUtils.getDimension(element, 'margin-bottom', 'marginBottom'); } } From 4151e3e1bb79cd5ef6c709626b79102a63930fb9 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 10 Apr 2019 15:34:21 -0700 Subject: [PATCH 12/48] Move convertToPixels into sizeUtils --- src/vs/base/browser/dom.ts | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index e07379d1834..85ce189ee98 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -467,14 +467,6 @@ export function getComputedStyle(el: HTMLElement): CSSStyleDeclaration { return document.defaultView!.getComputedStyle(el, null); } -// Adapted from WinJS -// Converts a CSS positioning string for the specified element to pixels. -const convertToPixels: (element: HTMLElement, value: string) => number = (function () { - return function (element: HTMLElement, value: string): number { - return parseFloat(value) || 0; - }; -})(); - export function getClientArea(element: HTMLElement): Dimension { // Try with DOM clientWidth / clientHeight @@ -501,6 +493,12 @@ export function getClientArea(element: HTMLElement): Dimension { } class SizeUtils { + // Adapted from WinJS + // Converts a CSS positioning string for the specified element to pixels. + private static convertToPixels(element: HTMLElement, value: string): number { + return parseFloat(value) || 0; + } + private static getDimension(element: HTMLElement, cssPropertyName: string, jsPropertyName: string): number { let computedStyle: CSSStyleDeclaration = getComputedStyle(element); let value = '0'; @@ -512,7 +510,7 @@ class SizeUtils { value = (computedStyle).getAttribute(jsPropertyName); } } - return convertToPixels(element, value); + return SizeUtils.convertToPixels(element, value); } static getBorderLeftWidth(element: HTMLElement): number { From 0ae3ecbf15c65d1acb4fbf77e349fb9d7a5864fe Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 11 Apr 2019 09:47:06 -0700 Subject: [PATCH 13/48] Fix multiline jsdoc type highlightingFixes #27777 --- .../syntaxes/JavaScript.tmLanguage.json | 4 - .../syntaxes/JavaScriptReact.tmLanguage.json | 4 - .../build/update-grammars.js | 22 +- extensions/typescript-basics/package.json | 14 +- ...downDocumentationInjection.tmLanguage.json | 29 - .../syntaxes/TypeScript.tmLanguage.json | 4 - .../syntaxes/TypeScriptReact.tmLanguage.json | 4 - ...e.json => jsdoc.injection.tmLanguage.json} | 25 +- .../colorize-fixtures/test-jsdoc-example.ts | 8 + .../colorize-fixtures/test-jsdoc-markdown.ts | 7 + .../test-jsdoc-multiline-type.ts | 22 + .../test-jsdoc-example_ts.json | 277 +++++++ .../test-jsdoc-markdown_ts.json | 310 ++++++++ .../test-jsdoc-multiline-type_ts.json | 684 ++++++++++++++++++ 14 files changed, 1351 insertions(+), 63 deletions(-) delete mode 100644 extensions/typescript-basics/syntaxes/MarkdownDocumentationInjection.tmLanguage.json rename extensions/typescript-basics/syntaxes/{ExampleJsDoc.injection.tmLanguage.json => jsdoc.injection.tmLanguage.json} (51%) create mode 100644 extensions/typescript-basics/test/colorize-fixtures/test-jsdoc-example.ts create mode 100644 extensions/typescript-basics/test/colorize-fixtures/test-jsdoc-markdown.ts create mode 100644 extensions/typescript-basics/test/colorize-fixtures/test-jsdoc-multiline-type.ts create mode 100644 extensions/typescript-basics/test/colorize-results/test-jsdoc-example_ts.json create mode 100644 extensions/typescript-basics/test/colorize-results/test-jsdoc-markdown_ts.json create mode 100644 extensions/typescript-basics/test/colorize-results/test-jsdoc-multiline-type_ts.json diff --git a/extensions/javascript/syntaxes/JavaScript.tmLanguage.json b/extensions/javascript/syntaxes/JavaScript.tmLanguage.json index cce1a6843eb..1ca17ec6059 100644 --- a/extensions/javascript/syntaxes/JavaScript.tmLanguage.json +++ b/extensions/javascript/syntaxes/JavaScript.tmLanguage.json @@ -5254,10 +5254,6 @@ }, "jsdoctype": { "patterns": [ - { - "name": "invalid.illegal.type.jsdoc", - "match": "\\G{(?:[^}*]|\\*[^/}])+$" - }, { "contentName": "entity.name.type.instance.jsdoc", "begin": "\\G({)", diff --git a/extensions/javascript/syntaxes/JavaScriptReact.tmLanguage.json b/extensions/javascript/syntaxes/JavaScriptReact.tmLanguage.json index 312e60b04a6..276b577ee0c 100644 --- a/extensions/javascript/syntaxes/JavaScriptReact.tmLanguage.json +++ b/extensions/javascript/syntaxes/JavaScriptReact.tmLanguage.json @@ -5254,10 +5254,6 @@ }, "jsdoctype": { "patterns": [ - { - "name": "invalid.illegal.type.jsdoc", - "match": "\\G{(?:[^}*]|\\*[^/}])+$" - }, { "contentName": "entity.name.type.instance.jsdoc", "begin": "\\G({)", diff --git a/extensions/typescript-basics/build/update-grammars.js b/extensions/typescript-basics/build/update-grammars.js index c41d9c335ca..527fa2c1d43 100644 --- a/extensions/typescript-basics/build/update-grammars.js +++ b/extensions/typescript-basics/build/update-grammars.js @@ -17,6 +17,20 @@ function removeDom(grammar) { return grammar; } +function patchJsdoctype(grammar) { + grammar.repository['jsdoctype'].patterns = grammar.repository['jsdoctype'].patterns.filter(pattern => { + if (pattern.name && pattern.name.indexOf('illegal') >= -1) { + return false; + } + return true; + }); + return grammar; +} + +function patchGrammar(grammar) { + return removeDom(patchJsdoctype(grammar)); +} + function adaptToJavaScript(grammar, replacementScope) { grammar.name = 'JavaScript (with React support)'; grammar.fileTypes = ['.js', '.jsx', '.es6', '.mjs']; @@ -44,7 +58,7 @@ function adaptToJavaScript(grammar, replacementScope) { } var tsGrammarRepo = 'Microsoft/TypeScript-TmLanguage'; -updateGrammar.update(tsGrammarRepo, 'TypeScript.tmLanguage', './syntaxes/TypeScript.tmLanguage.json', grammar => removeDom(grammar)); -updateGrammar.update(tsGrammarRepo, 'TypeScriptReact.tmLanguage', './syntaxes/TypeScriptReact.tmLanguage.json', grammar => removeDom(grammar)); -updateGrammar.update(tsGrammarRepo, 'TypeScriptReact.tmLanguage', '../javascript/syntaxes/JavaScript.tmLanguage.json', grammar => adaptToJavaScript(removeDom(grammar), '.js')); -updateGrammar.update(tsGrammarRepo, 'TypeScriptReact.tmLanguage', '../javascript/syntaxes/JavaScriptReact.tmLanguage.json', grammar => adaptToJavaScript(removeDom(grammar), '.js.jsx')); +updateGrammar.update(tsGrammarRepo, 'TypeScript.tmLanguage', './syntaxes/TypeScript.tmLanguage.json', grammar => patchGrammar(grammar)); +updateGrammar.update(tsGrammarRepo, 'TypeScriptReact.tmLanguage', './syntaxes/TypeScriptReact.tmLanguage.json', grammar => patchGrammar(grammar)); +updateGrammar.update(tsGrammarRepo, 'TypeScriptReact.tmLanguage', '../javascript/syntaxes/JavaScript.tmLanguage.json', grammar => adaptToJavaScript(patchGrammar(grammar), '.js')); +updateGrammar.update(tsGrammarRepo, 'TypeScriptReact.tmLanguage', '../javascript/syntaxes/JavaScriptReact.tmLanguage.json', grammar => adaptToJavaScript(patchGrammar(grammar), '.js.jsx')); diff --git a/extensions/typescript-basics/package.json b/extensions/typescript-basics/package.json index 3f697de5ced..f5532d15dd3 100644 --- a/extensions/typescript-basics/package.json +++ b/extensions/typescript-basics/package.json @@ -79,18 +79,8 @@ } }, { - "scopeName": "documentation.markdown.injection", - "path": "./syntaxes/MarkdownDocumentationInjection.tmLanguage.json", - "injectTo": [ - "source.ts", - "source.tsx", - "source.js", - "source.js.jsx" - ] - }, - { - "scopeName": "documentation.example.injection", - "path": "./syntaxes/ExampleJsDoc.injection.tmLanguage.json", + "scopeName": "documentation.injection", + "path": "./syntaxes/jsdoc.injection.tmLanguage.json", "injectTo": [ "source.ts", "source.tsx", diff --git a/extensions/typescript-basics/syntaxes/MarkdownDocumentationInjection.tmLanguage.json b/extensions/typescript-basics/syntaxes/MarkdownDocumentationInjection.tmLanguage.json deleted file mode 100644 index 4794b38e2e1..00000000000 --- a/extensions/typescript-basics/syntaxes/MarkdownDocumentationInjection.tmLanguage.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "injectionSelector": "L:comment.block.documentation", - "patterns": [ - { - "include": "#markdown-comment" - } - ], - "repository": { - "markdown-comment": { - "begin": "(?<=/\\*\\*)([^*]|\\*(?!/))*$", - "while": "(^|\\G)\\s*\\*(?!/)(?=([^*]|[*](?!/))*$)", - "patterns": [ - { - "include": "text.html.markdown#fenced_code_block" - }, - { - "include": "text.html.markdown#lists" - }, - { - "include": "source.ts#docblock" - }, - { - "include": "text.html.markdown#inline" - } - ] - } - }, - "scopeName": "documentation.markdown.injection" -} \ No newline at end of file diff --git a/extensions/typescript-basics/syntaxes/TypeScript.tmLanguage.json b/extensions/typescript-basics/syntaxes/TypeScript.tmLanguage.json index 9d153014bac..cdfe6fd83bf 100644 --- a/extensions/typescript-basics/syntaxes/TypeScript.tmLanguage.json +++ b/extensions/typescript-basics/syntaxes/TypeScript.tmLanguage.json @@ -5303,10 +5303,6 @@ }, "jsdoctype": { "patterns": [ - { - "name": "invalid.illegal.type.jsdoc", - "match": "\\G{(?:[^}*]|\\*[^/}])+$" - }, { "contentName": "entity.name.type.instance.jsdoc", "begin": "\\G({)", diff --git a/extensions/typescript-basics/syntaxes/TypeScriptReact.tmLanguage.json b/extensions/typescript-basics/syntaxes/TypeScriptReact.tmLanguage.json index 7dd0b2755fa..3d6f484970b 100644 --- a/extensions/typescript-basics/syntaxes/TypeScriptReact.tmLanguage.json +++ b/extensions/typescript-basics/syntaxes/TypeScriptReact.tmLanguage.json @@ -5254,10 +5254,6 @@ }, "jsdoctype": { "patterns": [ - { - "name": "invalid.illegal.type.jsdoc", - "match": "\\G{(?:[^}*]|\\*[^/}])+$" - }, { "contentName": "entity.name.type.instance.jsdoc", "begin": "\\G({)", diff --git a/extensions/typescript-basics/syntaxes/ExampleJsDoc.injection.tmLanguage.json b/extensions/typescript-basics/syntaxes/jsdoc.injection.tmLanguage.json similarity index 51% rename from extensions/typescript-basics/syntaxes/ExampleJsDoc.injection.tmLanguage.json rename to extensions/typescript-basics/syntaxes/jsdoc.injection.tmLanguage.json index 03c52cb97ff..b7b4db2d2a5 100644 --- a/extensions/typescript-basics/syntaxes/ExampleJsDoc.injection.tmLanguage.json +++ b/extensions/typescript-basics/syntaxes/jsdoc.injection.tmLanguage.json @@ -2,10 +2,31 @@ "injectionSelector": "L:comment.block.documentation", "patterns": [ { - "include": "#example" + "include": "#jsdocbody" } ], "repository": { + "jsdocbody": { + "begin": "(?<=/\\*\\*)([^*]|\\*(?!/))*$", + "while": "(^|\\G)\\s*\\*(?!/)(?=([^*]|[*](?!/))*$)", + "patterns": [ + { + "include": "text.html.markdown#fenced_code_block" + }, + { + "include": "text.html.markdown#lists" + }, + { + "include": "#example" + }, + { + "include": "source.ts#docblock" + }, + { + "include": "text.html.markdown#inline" + } + ] + }, "example": { "begin": "((@)example)\\s+(?=([^*]|[*](?!/))*$).*$", "while": "(^|\\G)\\s(?!@)(?=([^*]|[*](?!/))*$)", @@ -25,5 +46,5 @@ ] } }, - "scopeName": "documentation.example.injection" + "scopeName": "documentation.injection" } \ No newline at end of file diff --git a/extensions/typescript-basics/test/colorize-fixtures/test-jsdoc-example.ts b/extensions/typescript-basics/test/colorize-fixtures/test-jsdoc-example.ts new file mode 100644 index 00000000000..411f9bbede3 --- /dev/null +++ b/extensions/typescript-basics/test/colorize-fixtures/test-jsdoc-example.ts @@ -0,0 +1,8 @@ +/** + * @example + * 1 + 1 + * + * @other + * not colored + */ +const a = 1 \ No newline at end of file diff --git a/extensions/typescript-basics/test/colorize-fixtures/test-jsdoc-markdown.ts b/extensions/typescript-basics/test/colorize-fixtures/test-jsdoc-markdown.ts new file mode 100644 index 00000000000..136f8b1bafb --- /dev/null +++ b/extensions/typescript-basics/test/colorize-fixtures/test-jsdoc-markdown.ts @@ -0,0 +1,7 @@ +/** + * **Bold** + * ```js + * 1 + code + * ``` + */ +const a = 1 \ No newline at end of file diff --git a/extensions/typescript-basics/test/colorize-fixtures/test-jsdoc-multiline-type.ts b/extensions/typescript-basics/test/colorize-fixtures/test-jsdoc-multiline-type.ts new file mode 100644 index 00000000000..eda831efe02 --- /dev/null +++ b/extensions/typescript-basics/test/colorize-fixtures/test-jsdoc-multiline-type.ts @@ -0,0 +1,22 @@ +/** + * @typedef {{ + * id: number, + * fn: !Function, + * context: (!Object|undefined) + * }} + * @private + */ +goog.dom.animationFrame.Task_; + + +/** + * @typedef {{ + * measureTask: goog.dom.animationFrame.Task_, + * mutateTask: goog.dom.animationFrame.Task_, + * state: (!Object|undefined), + * args: (!Array|undefined), + * isScheduled: boolean + * }} + * @private + */ +goog.dom.animationFrame.TaskSet_; \ No newline at end of file diff --git a/extensions/typescript-basics/test/colorize-results/test-jsdoc-example_ts.json b/extensions/typescript-basics/test/colorize-results/test-jsdoc-example_ts.json new file mode 100644 index 00000000000..ea15234c214 --- /dev/null +++ b/extensions/typescript-basics/test/colorize-results/test-jsdoc-example_ts.json @@ -0,0 +1,277 @@ +[ + { + "c": "/**", + "t": "source.ts comment.block.documentation.ts punctuation.definition.comment.ts", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" + } + }, + { + "c": " * ", + "t": "source.ts comment.block.documentation.ts", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" + } + }, + { + "c": "@", + "t": "source.ts comment.block.documentation.ts storage.type.class.jsdoc punctuation.definition.block.tag.jsdoc", + "r": { + "dark_plus": "storage.type: #569CD6", + "light_plus": "storage.type: #0000FF", + "dark_vs": "storage.type: #569CD6", + "light_vs": "storage.type: #0000FF", + "hc_black": "storage.type: #569CD6" + } + }, + { + "c": "example", + "t": "source.ts comment.block.documentation.ts storage.type.class.jsdoc", + "r": { + "dark_plus": "storage.type: #569CD6", + "light_plus": "storage.type: #0000FF", + "dark_vs": "storage.type: #569CD6", + "light_vs": "storage.type: #0000FF", + "hc_black": "storage.type: #569CD6" + } + }, + { + "c": " *", + "t": "source.ts comment.block.documentation.ts", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" + } + }, + { + "c": " ", + "t": "source.ts comment.block.documentation.ts meta.embedded.block.example.source.ts", + "r": { + "dark_plus": "meta.embedded: #D4D4D4", + "light_plus": "meta.embedded: #000000", + "dark_vs": "meta.embedded: #D4D4D4", + "light_vs": "meta.embedded: #000000", + "hc_black": "meta.embedded: #FFFFFF" + } + }, + { + "c": "1", + "t": "source.ts comment.block.documentation.ts meta.embedded.block.example.source.ts constant.numeric.decimal.tsx", + "r": { + "dark_plus": "constant.numeric: #B5CEA8", + "light_plus": "constant.numeric: #09885A", + "dark_vs": "constant.numeric: #B5CEA8", + "light_vs": "constant.numeric: #09885A", + "hc_black": "constant.numeric: #B5CEA8" + } + }, + { + "c": " ", + "t": "source.ts comment.block.documentation.ts meta.embedded.block.example.source.ts", + "r": { + "dark_plus": "meta.embedded: #D4D4D4", + "light_plus": "meta.embedded: #000000", + "dark_vs": "meta.embedded: #D4D4D4", + "light_vs": "meta.embedded: #000000", + "hc_black": "meta.embedded: #FFFFFF" + } + }, + { + "c": "+", + "t": "source.ts comment.block.documentation.ts meta.embedded.block.example.source.ts keyword.operator.arithmetic.tsx", + "r": { + "dark_plus": "keyword.operator: #D4D4D4", + "light_plus": "keyword.operator: #000000", + "dark_vs": "keyword.operator: #D4D4D4", + "light_vs": "keyword.operator: #000000", + "hc_black": "keyword.operator: #D4D4D4" + } + }, + { + "c": " ", + "t": "source.ts comment.block.documentation.ts meta.embedded.block.example.source.ts", + "r": { + "dark_plus": "meta.embedded: #D4D4D4", + "light_plus": "meta.embedded: #000000", + "dark_vs": "meta.embedded: #D4D4D4", + "light_vs": "meta.embedded: #000000", + "hc_black": "meta.embedded: #FFFFFF" + } + }, + { + "c": "1", + "t": "source.ts comment.block.documentation.ts meta.embedded.block.example.source.ts constant.numeric.decimal.tsx", + "r": { + "dark_plus": "constant.numeric: #B5CEA8", + "light_plus": "constant.numeric: #09885A", + "dark_vs": "constant.numeric: #B5CEA8", + "light_vs": "constant.numeric: #09885A", + "hc_black": "constant.numeric: #B5CEA8" + } + }, + { + "c": " *", + "t": "source.ts comment.block.documentation.ts", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" + } + }, + { + "c": " * ", + "t": "source.ts comment.block.documentation.ts", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" + } + }, + { + "c": "@", + "t": "source.ts comment.block.documentation.ts storage.type.class.jsdoc punctuation.definition.block.tag.jsdoc", + "r": { + "dark_plus": "storage.type: #569CD6", + "light_plus": "storage.type: #0000FF", + "dark_vs": "storage.type: #569CD6", + "light_vs": "storage.type: #0000FF", + "hc_black": "storage.type: #569CD6" + } + }, + { + "c": "other", + "t": "source.ts comment.block.documentation.ts storage.type.class.jsdoc", + "r": { + "dark_plus": "storage.type: #569CD6", + "light_plus": "storage.type: #0000FF", + "dark_vs": "storage.type: #569CD6", + "light_vs": "storage.type: #0000FF", + "hc_black": "storage.type: #569CD6" + } + }, + { + "c": " * not colored", + "t": "source.ts comment.block.documentation.ts", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" + } + }, + { + "c": " ", + "t": "source.ts comment.block.documentation.ts", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" + } + }, + { + "c": "*/", + "t": "source.ts comment.block.documentation.ts punctuation.definition.comment.ts", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" + } + }, + { + "c": "const", + "t": "source.ts meta.var.expr.ts storage.type.ts", + "r": { + "dark_plus": "storage.type: #569CD6", + "light_plus": "storage.type: #0000FF", + "dark_vs": "storage.type: #569CD6", + "light_vs": "storage.type: #0000FF", + "hc_black": "storage.type: #569CD6" + } + }, + { + "c": " ", + "t": "source.ts meta.var.expr.ts", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "a", + "t": "source.ts meta.var.expr.ts meta.var-single-variable.expr.ts meta.definition.variable.ts variable.other.constant.ts", + "r": { + "dark_plus": "variable: #9CDCFE", + "light_plus": "variable: #001080", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "variable: #9CDCFE" + } + }, + { + "c": " ", + "t": "source.ts meta.var.expr.ts meta.var-single-variable.expr.ts", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "=", + "t": "source.ts meta.var.expr.ts keyword.operator.assignment.ts", + "r": { + "dark_plus": "keyword.operator: #D4D4D4", + "light_plus": "keyword.operator: #000000", + "dark_vs": "keyword.operator: #D4D4D4", + "light_vs": "keyword.operator: #000000", + "hc_black": "keyword.operator: #D4D4D4" + } + }, + { + "c": " ", + "t": "source.ts meta.var.expr.ts", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "1", + "t": "source.ts meta.var.expr.ts constant.numeric.decimal.ts", + "r": { + "dark_plus": "constant.numeric: #B5CEA8", + "light_plus": "constant.numeric: #09885A", + "dark_vs": "constant.numeric: #B5CEA8", + "light_vs": "constant.numeric: #09885A", + "hc_black": "constant.numeric: #B5CEA8" + } + } +] \ No newline at end of file diff --git a/extensions/typescript-basics/test/colorize-results/test-jsdoc-markdown_ts.json b/extensions/typescript-basics/test/colorize-results/test-jsdoc-markdown_ts.json new file mode 100644 index 00000000000..eea45a645eb --- /dev/null +++ b/extensions/typescript-basics/test/colorize-results/test-jsdoc-markdown_ts.json @@ -0,0 +1,310 @@ +[ + { + "c": "/**", + "t": "source.ts comment.block.documentation.ts punctuation.definition.comment.ts", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" + } + }, + { + "c": " * ", + "t": "source.ts comment.block.documentation.ts", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" + } + }, + { + "c": "**", + "t": "source.ts comment.block.documentation.ts markup.bold.markdown punctuation.definition.bold.markdown", + "r": { + "dark_plus": "markup.bold: #569CD6", + "light_plus": "markup.bold: #000080", + "dark_vs": "markup.bold: #569CD6", + "light_vs": "markup.bold: #000080", + "hc_black": "comment: #7CA668" + } + }, + { + "c": "Bold", + "t": "source.ts comment.block.documentation.ts markup.bold.markdown", + "r": { + "dark_plus": "markup.bold: #569CD6", + "light_plus": "markup.bold: #000080", + "dark_vs": "markup.bold: #569CD6", + "light_vs": "markup.bold: #000080", + "hc_black": "comment: #7CA668" + } + }, + { + "c": "**", + "t": "source.ts comment.block.documentation.ts markup.bold.markdown punctuation.definition.bold.markdown", + "r": { + "dark_plus": "markup.bold: #569CD6", + "light_plus": "markup.bold: #000080", + "dark_vs": "markup.bold: #569CD6", + "light_vs": "markup.bold: #000080", + "hc_black": "comment: #7CA668" + } + }, + { + "c": " *", + "t": "source.ts comment.block.documentation.ts", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" + } + }, + { + "c": " ", + "t": "source.ts comment.block.documentation.ts markup.fenced_code.block.markdown", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" + } + }, + { + "c": "```", + "t": "source.ts comment.block.documentation.ts markup.fenced_code.block.markdown punctuation.definition.markdown", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" + } + }, + { + "c": "js", + "t": "source.ts comment.block.documentation.ts markup.fenced_code.block.markdown", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" + } + }, + { + "c": " *", + "t": "source.ts comment.block.documentation.ts", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" + } + }, + { + "c": " ", + "t": "source.ts comment.block.documentation.ts markup.fenced_code.block.markdown meta.embedded.block.javascript", + "r": { + "dark_plus": "meta.embedded: #D4D4D4", + "light_plus": "meta.embedded: #000000", + "dark_vs": "meta.embedded: #D4D4D4", + "light_vs": "meta.embedded: #000000", + "hc_black": "meta.embedded: #FFFFFF" + } + }, + { + "c": "1", + "t": "source.ts comment.block.documentation.ts markup.fenced_code.block.markdown meta.embedded.block.javascript constant.numeric.decimal.js", + "r": { + "dark_plus": "constant.numeric: #B5CEA8", + "light_plus": "constant.numeric: #09885A", + "dark_vs": "constant.numeric: #B5CEA8", + "light_vs": "constant.numeric: #09885A", + "hc_black": "constant.numeric: #B5CEA8" + } + }, + { + "c": " ", + "t": "source.ts comment.block.documentation.ts markup.fenced_code.block.markdown meta.embedded.block.javascript", + "r": { + "dark_plus": "meta.embedded: #D4D4D4", + "light_plus": "meta.embedded: #000000", + "dark_vs": "meta.embedded: #D4D4D4", + "light_vs": "meta.embedded: #000000", + "hc_black": "meta.embedded: #FFFFFF" + } + }, + { + "c": "+", + "t": "source.ts comment.block.documentation.ts markup.fenced_code.block.markdown meta.embedded.block.javascript keyword.operator.arithmetic.js", + "r": { + "dark_plus": "keyword.operator: #D4D4D4", + "light_plus": "keyword.operator: #000000", + "dark_vs": "keyword.operator: #D4D4D4", + "light_vs": "keyword.operator: #000000", + "hc_black": "keyword.operator: #D4D4D4" + } + }, + { + "c": " ", + "t": "source.ts comment.block.documentation.ts markup.fenced_code.block.markdown meta.embedded.block.javascript", + "r": { + "dark_plus": "meta.embedded: #D4D4D4", + "light_plus": "meta.embedded: #000000", + "dark_vs": "meta.embedded: #D4D4D4", + "light_vs": "meta.embedded: #000000", + "hc_black": "meta.embedded: #FFFFFF" + } + }, + { + "c": "code", + "t": "source.ts comment.block.documentation.ts markup.fenced_code.block.markdown meta.embedded.block.javascript variable.other.readwrite.js", + "r": { + "dark_plus": "variable: #9CDCFE", + "light_plus": "variable: #001080", + "dark_vs": "meta.embedded: #D4D4D4", + "light_vs": "meta.embedded: #000000", + "hc_black": "variable: #9CDCFE" + } + }, + { + "c": " *", + "t": "source.ts comment.block.documentation.ts", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" + } + }, + { + "c": " ", + "t": "source.ts comment.block.documentation.ts markup.fenced_code.block.markdown", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" + } + }, + { + "c": "```", + "t": "source.ts comment.block.documentation.ts markup.fenced_code.block.markdown punctuation.definition.markdown", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" + } + }, + { + "c": " ", + "t": "source.ts comment.block.documentation.ts", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" + } + }, + { + "c": "*/", + "t": "source.ts comment.block.documentation.ts punctuation.definition.comment.ts", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" + } + }, + { + "c": "const", + "t": "source.ts meta.var.expr.ts storage.type.ts", + "r": { + "dark_plus": "storage.type: #569CD6", + "light_plus": "storage.type: #0000FF", + "dark_vs": "storage.type: #569CD6", + "light_vs": "storage.type: #0000FF", + "hc_black": "storage.type: #569CD6" + } + }, + { + "c": " ", + "t": "source.ts meta.var.expr.ts", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "a", + "t": "source.ts meta.var.expr.ts meta.var-single-variable.expr.ts meta.definition.variable.ts variable.other.constant.ts", + "r": { + "dark_plus": "variable: #9CDCFE", + "light_plus": "variable: #001080", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "variable: #9CDCFE" + } + }, + { + "c": " ", + "t": "source.ts meta.var.expr.ts meta.var-single-variable.expr.ts", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "=", + "t": "source.ts meta.var.expr.ts keyword.operator.assignment.ts", + "r": { + "dark_plus": "keyword.operator: #D4D4D4", + "light_plus": "keyword.operator: #000000", + "dark_vs": "keyword.operator: #D4D4D4", + "light_vs": "keyword.operator: #000000", + "hc_black": "keyword.operator: #D4D4D4" + } + }, + { + "c": " ", + "t": "source.ts meta.var.expr.ts", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "1", + "t": "source.ts meta.var.expr.ts constant.numeric.decimal.ts", + "r": { + "dark_plus": "constant.numeric: #B5CEA8", + "light_plus": "constant.numeric: #09885A", + "dark_vs": "constant.numeric: #B5CEA8", + "light_vs": "constant.numeric: #09885A", + "hc_black": "constant.numeric: #B5CEA8" + } + } +] \ No newline at end of file diff --git a/extensions/typescript-basics/test/colorize-results/test-jsdoc-multiline-type_ts.json b/extensions/typescript-basics/test/colorize-results/test-jsdoc-multiline-type_ts.json new file mode 100644 index 00000000000..cc1eba5f197 --- /dev/null +++ b/extensions/typescript-basics/test/colorize-results/test-jsdoc-multiline-type_ts.json @@ -0,0 +1,684 @@ +[ + { + "c": "/**", + "t": "source.ts comment.block.documentation.ts punctuation.definition.comment.ts", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" + } + }, + { + "c": " * ", + "t": "source.ts comment.block.documentation.ts", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" + } + }, + { + "c": "@", + "t": "source.ts comment.block.documentation.ts storage.type.class.jsdoc punctuation.definition.block.tag.jsdoc", + "r": { + "dark_plus": "storage.type: #569CD6", + "light_plus": "storage.type: #0000FF", + "dark_vs": "storage.type: #569CD6", + "light_vs": "storage.type: #0000FF", + "hc_black": "storage.type: #569CD6" + } + }, + { + "c": "typedef", + "t": "source.ts comment.block.documentation.ts storage.type.class.jsdoc", + "r": { + "dark_plus": "storage.type: #569CD6", + "light_plus": "storage.type: #0000FF", + "dark_vs": "storage.type: #569CD6", + "light_vs": "storage.type: #0000FF", + "hc_black": "storage.type: #569CD6" + } + }, + { + "c": " ", + "t": "source.ts comment.block.documentation.ts", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" + } + }, + { + "c": "{", + "t": "source.ts comment.block.documentation.ts entity.name.type.instance.jsdoc punctuation.definition.bracket.curly.begin.jsdoc", + "r": { + "dark_plus": "entity.name.type: #4EC9B0", + "light_plus": "entity.name.type: #267F99", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "entity.name.type: #4EC9B0" + } + }, + { + "c": "{", + "t": "source.ts comment.block.documentation.ts entity.name.type.instance.jsdoc", + "r": { + "dark_plus": "entity.name.type: #4EC9B0", + "light_plus": "entity.name.type: #267F99", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "entity.name.type: #4EC9B0" + } + }, + { + "c": " *", + "t": "source.ts comment.block.documentation.ts", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" + } + }, + { + "c": " id: number,", + "t": "source.ts comment.block.documentation.ts entity.name.type.instance.jsdoc", + "r": { + "dark_plus": "entity.name.type: #4EC9B0", + "light_plus": "entity.name.type: #267F99", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "entity.name.type: #4EC9B0" + } + }, + { + "c": " *", + "t": "source.ts comment.block.documentation.ts", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" + } + }, + { + "c": " fn: !Function,", + "t": "source.ts comment.block.documentation.ts entity.name.type.instance.jsdoc", + "r": { + "dark_plus": "entity.name.type: #4EC9B0", + "light_plus": "entity.name.type: #267F99", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "entity.name.type: #4EC9B0" + } + }, + { + "c": " *", + "t": "source.ts comment.block.documentation.ts", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" + } + }, + { + "c": " context: (!Object|undefined)", + "t": "source.ts comment.block.documentation.ts entity.name.type.instance.jsdoc", + "r": { + "dark_plus": "entity.name.type: #4EC9B0", + "light_plus": "entity.name.type: #267F99", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "entity.name.type: #4EC9B0" + } + }, + { + "c": " *", + "t": "source.ts comment.block.documentation.ts", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" + } + }, + { + "c": " }", + "t": "source.ts comment.block.documentation.ts entity.name.type.instance.jsdoc", + "r": { + "dark_plus": "entity.name.type: #4EC9B0", + "light_plus": "entity.name.type: #267F99", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "entity.name.type: #4EC9B0" + } + }, + { + "c": "}", + "t": "source.ts comment.block.documentation.ts entity.name.type.instance.jsdoc punctuation.definition.bracket.curly.end.jsdoc", + "r": { + "dark_plus": "entity.name.type: #4EC9B0", + "light_plus": "entity.name.type: #267F99", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "entity.name.type: #4EC9B0" + } + }, + { + "c": " * ", + "t": "source.ts comment.block.documentation.ts", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" + } + }, + { + "c": "@", + "t": "source.ts comment.block.documentation.ts storage.type.class.jsdoc punctuation.definition.block.tag.jsdoc", + "r": { + "dark_plus": "storage.type: #569CD6", + "light_plus": "storage.type: #0000FF", + "dark_vs": "storage.type: #569CD6", + "light_vs": "storage.type: #0000FF", + "hc_black": "storage.type: #569CD6" + } + }, + { + "c": "private", + "t": "source.ts comment.block.documentation.ts storage.type.class.jsdoc", + "r": { + "dark_plus": "storage.type: #569CD6", + "light_plus": "storage.type: #0000FF", + "dark_vs": "storage.type: #569CD6", + "light_vs": "storage.type: #0000FF", + "hc_black": "storage.type: #569CD6" + } + }, + { + "c": " ", + "t": "source.ts comment.block.documentation.ts", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" + } + }, + { + "c": "*/", + "t": "source.ts comment.block.documentation.ts punctuation.definition.comment.ts", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" + } + }, + { + "c": "goog", + "t": "source.ts variable.other.object.ts", + "r": { + "dark_plus": "variable: #9CDCFE", + "light_plus": "variable: #001080", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "variable: #9CDCFE" + } + }, + { + "c": ".", + "t": "source.ts punctuation.accessor.ts", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "dom", + "t": "source.ts variable.other.object.property.ts", + "r": { + "dark_plus": "variable: #9CDCFE", + "light_plus": "variable: #001080", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "variable: #9CDCFE" + } + }, + { + "c": ".", + "t": "source.ts punctuation.accessor.ts", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "animationFrame", + "t": "source.ts variable.other.object.property.ts", + "r": { + "dark_plus": "variable: #9CDCFE", + "light_plus": "variable: #001080", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "variable: #9CDCFE" + } + }, + { + "c": ".", + "t": "source.ts punctuation.accessor.ts", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "Task_", + "t": "source.ts variable.other.property.ts", + "r": { + "dark_plus": "variable: #9CDCFE", + "light_plus": "variable: #001080", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "variable: #9CDCFE" + } + }, + { + "c": ";", + "t": "source.ts punctuation.terminator.statement.ts", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "/**", + "t": "source.ts comment.block.documentation.ts punctuation.definition.comment.ts", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" + } + }, + { + "c": " * ", + "t": "source.ts comment.block.documentation.ts", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" + } + }, + { + "c": "@", + "t": "source.ts comment.block.documentation.ts storage.type.class.jsdoc punctuation.definition.block.tag.jsdoc", + "r": { + "dark_plus": "storage.type: #569CD6", + "light_plus": "storage.type: #0000FF", + "dark_vs": "storage.type: #569CD6", + "light_vs": "storage.type: #0000FF", + "hc_black": "storage.type: #569CD6" + } + }, + { + "c": "typedef", + "t": "source.ts comment.block.documentation.ts storage.type.class.jsdoc", + "r": { + "dark_plus": "storage.type: #569CD6", + "light_plus": "storage.type: #0000FF", + "dark_vs": "storage.type: #569CD6", + "light_vs": "storage.type: #0000FF", + "hc_black": "storage.type: #569CD6" + } + }, + { + "c": " ", + "t": "source.ts comment.block.documentation.ts", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" + } + }, + { + "c": "{", + "t": "source.ts comment.block.documentation.ts entity.name.type.instance.jsdoc punctuation.definition.bracket.curly.begin.jsdoc", + "r": { + "dark_plus": "entity.name.type: #4EC9B0", + "light_plus": "entity.name.type: #267F99", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "entity.name.type: #4EC9B0" + } + }, + { + "c": "{", + "t": "source.ts comment.block.documentation.ts entity.name.type.instance.jsdoc", + "r": { + "dark_plus": "entity.name.type: #4EC9B0", + "light_plus": "entity.name.type: #267F99", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "entity.name.type: #4EC9B0" + } + }, + { + "c": " *", + "t": "source.ts comment.block.documentation.ts", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" + } + }, + { + "c": " measureTask: goog.dom.animationFrame.Task_,", + "t": "source.ts comment.block.documentation.ts entity.name.type.instance.jsdoc", + "r": { + "dark_plus": "entity.name.type: #4EC9B0", + "light_plus": "entity.name.type: #267F99", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "entity.name.type: #4EC9B0" + } + }, + { + "c": " *", + "t": "source.ts comment.block.documentation.ts", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" + } + }, + { + "c": " mutateTask: goog.dom.animationFrame.Task_,", + "t": "source.ts comment.block.documentation.ts entity.name.type.instance.jsdoc", + "r": { + "dark_plus": "entity.name.type: #4EC9B0", + "light_plus": "entity.name.type: #267F99", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "entity.name.type: #4EC9B0" + } + }, + { + "c": " *", + "t": "source.ts comment.block.documentation.ts", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" + } + }, + { + "c": " state: (!Object|undefined),", + "t": "source.ts comment.block.documentation.ts entity.name.type.instance.jsdoc", + "r": { + "dark_plus": "entity.name.type: #4EC9B0", + "light_plus": "entity.name.type: #267F99", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "entity.name.type: #4EC9B0" + } + }, + { + "c": " *", + "t": "source.ts comment.block.documentation.ts", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" + } + }, + { + "c": " args: (!Array|undefined),", + "t": "source.ts comment.block.documentation.ts entity.name.type.instance.jsdoc", + "r": { + "dark_plus": "entity.name.type: #4EC9B0", + "light_plus": "entity.name.type: #267F99", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "entity.name.type: #4EC9B0" + } + }, + { + "c": " *", + "t": "source.ts comment.block.documentation.ts", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" + } + }, + { + "c": " isScheduled: boolean", + "t": "source.ts comment.block.documentation.ts entity.name.type.instance.jsdoc", + "r": { + "dark_plus": "entity.name.type: #4EC9B0", + "light_plus": "entity.name.type: #267F99", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "entity.name.type: #4EC9B0" + } + }, + { + "c": " *", + "t": "source.ts comment.block.documentation.ts", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" + } + }, + { + "c": " }", + "t": "source.ts comment.block.documentation.ts entity.name.type.instance.jsdoc", + "r": { + "dark_plus": "entity.name.type: #4EC9B0", + "light_plus": "entity.name.type: #267F99", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "entity.name.type: #4EC9B0" + } + }, + { + "c": "}", + "t": "source.ts comment.block.documentation.ts entity.name.type.instance.jsdoc punctuation.definition.bracket.curly.end.jsdoc", + "r": { + "dark_plus": "entity.name.type: #4EC9B0", + "light_plus": "entity.name.type: #267F99", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "entity.name.type: #4EC9B0" + } + }, + { + "c": " * ", + "t": "source.ts comment.block.documentation.ts", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" + } + }, + { + "c": "@", + "t": "source.ts comment.block.documentation.ts storage.type.class.jsdoc punctuation.definition.block.tag.jsdoc", + "r": { + "dark_plus": "storage.type: #569CD6", + "light_plus": "storage.type: #0000FF", + "dark_vs": "storage.type: #569CD6", + "light_vs": "storage.type: #0000FF", + "hc_black": "storage.type: #569CD6" + } + }, + { + "c": "private", + "t": "source.ts comment.block.documentation.ts storage.type.class.jsdoc", + "r": { + "dark_plus": "storage.type: #569CD6", + "light_plus": "storage.type: #0000FF", + "dark_vs": "storage.type: #569CD6", + "light_vs": "storage.type: #0000FF", + "hc_black": "storage.type: #569CD6" + } + }, + { + "c": " ", + "t": "source.ts comment.block.documentation.ts", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" + } + }, + { + "c": "*/", + "t": "source.ts comment.block.documentation.ts punctuation.definition.comment.ts", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" + } + }, + { + "c": "goog", + "t": "source.ts variable.other.object.ts", + "r": { + "dark_plus": "variable: #9CDCFE", + "light_plus": "variable: #001080", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "variable: #9CDCFE" + } + }, + { + "c": ".", + "t": "source.ts punctuation.accessor.ts", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "dom", + "t": "source.ts variable.other.object.property.ts", + "r": { + "dark_plus": "variable: #9CDCFE", + "light_plus": "variable: #001080", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "variable: #9CDCFE" + } + }, + { + "c": ".", + "t": "source.ts punctuation.accessor.ts", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "animationFrame", + "t": "source.ts variable.other.object.property.ts", + "r": { + "dark_plus": "variable: #9CDCFE", + "light_plus": "variable: #001080", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "variable: #9CDCFE" + } + }, + { + "c": ".", + "t": "source.ts punctuation.accessor.ts", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "TaskSet_", + "t": "source.ts variable.other.property.ts", + "r": { + "dark_plus": "variable: #9CDCFE", + "light_plus": "variable: #001080", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "variable: #9CDCFE" + } + }, + { + "c": ";", + "t": "source.ts punctuation.terminator.statement.ts", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + } +] \ No newline at end of file From 9d3683d68925eb2e81bdec602e81b6c857092473 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 11 Apr 2019 10:05:27 -0700 Subject: [PATCH 14/48] Use some instead of reduce --- .../contrib/extensions/electron-browser/extensionEditor.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/extensions/electron-browser/extensionEditor.ts b/src/vs/workbench/contrib/extensions/electron-browser/extensionEditor.ts index c213b10e122..7357cfa53cc 100644 --- a/src/vs/workbench/contrib/extensions/electron-browser/extensionEditor.ts +++ b/src/vs/workbench/contrib/extensions/electron-browser/extensionEditor.ts @@ -606,9 +606,9 @@ export class ExtensionEditor extends BaseEditor { this.renderLocalizations(content, manifest, layout) ]; - const isEmpty = !renders.reduce((v, r) => r || v, false); scrollableContent.scanDomNode(); + const isEmpty = !renders.some(x => x); if (isEmpty) { append(content, $('p.nocontent')).textContent = localize('noContributions', "No Contributions"); append(this.content, content); From 8a9326fbc10eeb75c08a598720bc67da62d636fe Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Thu, 11 Apr 2019 17:19:36 +0000 Subject: [PATCH 15/48] Add settings GUI tab --- .../preferences/browser/preferencesEditor.ts | 23 +++++---- .../preferences/browser/preferencesWidgets.ts | 51 ++++++++++++++----- .../preferences/browser/settingsTree.ts | 2 +- .../preferences/browser/settingsTreeModels.ts | 7 +-- .../electron-browser/settingsEditor2.ts | 27 ++++++---- .../preferences/browser/preferencesService.ts | 11 ++-- .../preferences/common/preferences.ts | 2 +- 7 files changed, 80 insertions(+), 43 deletions(-) diff --git a/src/vs/workbench/contrib/preferences/browser/preferencesEditor.ts b/src/vs/workbench/contrib/preferences/browser/preferencesEditor.ts index d8dc634f821..edc231b62a1 100644 --- a/src/vs/workbench/contrib/preferences/browser/preferencesEditor.ts +++ b/src/vs/workbench/contrib/preferences/browser/preferencesEditor.ts @@ -256,8 +256,8 @@ export class PreferencesEditor extends BaseEditor { } const promise: Promise = this.input && this.input.isDirty() ? this.input.save() : Promise.resolve(true); promise.then(() => { - if (target === ConfigurationTarget.USER) { - this.preferencesService.switchSettings(ConfigurationTarget.USER, this.preferencesService.userSettingsResource, true); + if (target === ConfigurationTarget.USER_LOCAL) { + this.preferencesService.switchSettings(ConfigurationTarget.USER_LOCAL, this.preferencesService.userSettingsResource, true); } else if (target === ConfigurationTarget.WORKSPACE) { this.preferencesService.switchSettings(ConfigurationTarget.WORKSPACE, this.preferencesService.workspaceSettingsResource!, true); } else if (target instanceof URI) { @@ -507,7 +507,7 @@ class PreferencesRenderersController extends Disposable { private searchAllSettingsTargets(query: string, searchProvider: ISearchProvider, groupId: string, groupLabel: string, groupOrder: number, token?: CancellationToken): Promise { const searchPs = [ this.searchSettingsTarget(query, searchProvider, ConfigurationTarget.WORKSPACE, groupId, groupLabel, groupOrder, token), - this.searchSettingsTarget(query, searchProvider, ConfigurationTarget.USER, groupId, groupLabel, groupOrder, token) + this.searchSettingsTarget(query, searchProvider, ConfigurationTarget.USER_LOCAL, groupId, groupLabel, groupOrder, token) ]; for (const folder of this.workspaceContextService.getWorkspace().folders) { @@ -541,9 +541,10 @@ class PreferencesRenderersController extends Disposable { } private async getPreferencesEditorModel(target: SettingsTarget | undefined): Promise { - const resource = target === ConfigurationTarget.USER ? this.preferencesService.userSettingsResource : - target === ConfigurationTarget.WORKSPACE ? this.preferencesService.workspaceSettingsResource : - target; + const resource = target === ConfigurationTarget.USER_LOCAL ? this.preferencesService.userSettingsResource : + target === ConfigurationTarget.USER_REMOTE ? this.preferencesService.userSettingsResource : + target === ConfigurationTarget.WORKSPACE ? this.preferencesService.workspaceSettingsResource : + target; if (!resource) { return undefined; @@ -821,7 +822,7 @@ class SideBySidePreferencesWidget extends Widget { this.editablePreferencesEditorContainer = DOM.$('.editable-preferences-editor-container'); const editablePreferencesHeaderContainer = DOM.append(this.editablePreferencesEditorContainer, DOM.$('.preferences-header-container')); - this.settingsTargetsWidget = this._register(this.instantiationService.createInstance(SettingsTargetsWidget, editablePreferencesHeaderContainer)); + this.settingsTargetsWidget = this._register(this.instantiationService.createInstance(SettingsTargetsWidget, editablePreferencesHeaderContainer, undefined)); this._register(this.settingsTargetsWidget.onDidTargetChange(target => this._onDidSettingsTargetChange.fire(target))); this._register(attachStylerCallback(this.themeService, { scrollbarShadow }, colors => { @@ -865,7 +866,7 @@ class SideBySidePreferencesWidget extends Widget { private getDefaultPreferencesHeaderText(target: ConfigurationTarget): string { switch (target) { - case ConfigurationTarget.USER: + case ConfigurationTarget.USER_LOCAL: return nls.localize('defaultUserSettings', "Default User Settings"); case ConfigurationTarget.WORKSPACE: return nls.localize('defaultWorkspaceSettings', "Default Workspace Settings"); @@ -942,7 +943,7 @@ class SideBySidePreferencesWidget extends Widget { private getSettingsTarget(resource: URI): SettingsTarget { if (this.preferencesService.userSettingsResource.toString() === resource.toString()) { - return ConfigurationTarget.USER; + return ConfigurationTarget.USER_LOCAL; } const workspaceSettingsResource = this.preferencesService.workspaceSettingsResource; @@ -955,7 +956,7 @@ class SideBySidePreferencesWidget extends Widget { return folder.uri; } - return ConfigurationTarget.USER; + return ConfigurationTarget.USER_LOCAL; } private disposeEditors(): void { @@ -1202,7 +1203,7 @@ class SettingsEditorContribution extends AbstractSettingsEditorContribution impl .then(settingsModel => { if (settingsModel instanceof SettingsEditorModel && this.editor.getModel()) { switch (settingsModel.configurationTarget) { - case ConfigurationTarget.USER: + case ConfigurationTarget.USER_LOCAL: return this.instantiationService.createInstance(UserSettingsRenderer, this.editor, settingsModel); case ConfigurationTarget.WORKSPACE: return this.instantiationService.createInstance(WorkspaceSettingsRenderer, this.editor, settingsModel); diff --git a/src/vs/workbench/contrib/preferences/browser/preferencesWidgets.ts b/src/vs/workbench/contrib/preferences/browser/preferencesWidgets.ts index b63bba31943..8faa20df1ce 100644 --- a/src/vs/workbench/contrib/preferences/browser/preferencesWidgets.ts +++ b/src/vs/workbench/contrib/preferences/browser/preferencesWidgets.ts @@ -24,11 +24,14 @@ import { ConfigurationTarget } from 'vs/platform/configuration/common/configurat import { IContextKey } from 'vs/platform/contextkey/common/contextkey'; import { IContextMenuService, IContextViewService } from 'vs/platform/contextview/browser/contextView'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { ILabelService } from 'vs/platform/label/common/label'; +import { REMOTE_HOST_SCHEME } from 'vs/platform/remote/common/remoteHosts'; import { activeContrastBorder, badgeBackground, badgeForeground, contrastBorder, focusBorder } from 'vs/platform/theme/common/colorRegistry'; import { attachInputBoxStyler, attachStylerCallback } from 'vs/platform/theme/common/styler'; import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { IWorkspaceContextService, IWorkspaceFolder, WorkbenchState } from 'vs/platform/workspace/common/workspace'; import { PANEL_ACTIVE_TITLE_BORDER, PANEL_ACTIVE_TITLE_FOREGROUND, PANEL_INACTIVE_TITLE_FOREGROUND } from 'vs/workbench/common/theme'; +import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { ISettingsGroup } from 'vs/workbench/services/preferences/common/preferences'; export class SettingsHeaderWidget extends Widget implements IViewZone { @@ -464,14 +467,20 @@ export class FolderSettingsActionItem extends BaseActionItem { } } -export type SettingsTarget = ConfigurationTarget.USER | ConfigurationTarget.WORKSPACE | URI; +export type SettingsTarget = ConfigurationTarget.USER_LOCAL | ConfigurationTarget.USER_REMOTE | ConfigurationTarget.WORKSPACE | URI; + +export interface ISettingsTargetsWidgetOptions { + enableRemoteSettings?: boolean; +} export class SettingsTargetsWidget extends Widget { private settingsSwitcherBar: ActionBar; - private userSettings: Action; + private userLocalSettings: Action; + private userRemoteSettings: Action; private workspaceSettings: Action; private folderSettings: FolderSettingsActionItem; + private options: ISettingsTargetsWidgetOptions; private _settingsTarget: SettingsTarget; @@ -480,10 +489,14 @@ export class SettingsTargetsWidget extends Widget { constructor( parent: HTMLElement, + options: ISettingsTargetsWidgetOptions | undefined, @IWorkspaceContextService private readonly contextService: IWorkspaceContextService, - @IInstantiationService private readonly instantiationService: IInstantiationService + @IInstantiationService private readonly instantiationService: IInstantiationService, + @IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService, + @ILabelService private readonly labelService: ILabelService ) { super(); + this.options = options || {}; this.create(parent); this._register(this.contextService.onDidChangeWorkbenchState(() => this.onWorkbenchStateChanged())); this._register(this.contextService.onDidChangeWorkspaceFolders(() => this.update())); @@ -498,18 +511,25 @@ export class SettingsTargetsWidget extends Widget { actionItemProvider: (action: Action) => action.id === 'folderSettings' ? this.folderSettings : undefined })); - this.userSettings = new Action('userSettings', localize('userSettings', "User Settings"), '.settings-tab', true, () => this.updateTarget(ConfigurationTarget.USER)); - this.userSettings.tooltip = this.userSettings.label; + this.userLocalSettings = new Action('userSettings', localize('userSettings', "User Settings"), '.settings-tab', true, () => this.updateTarget(ConfigurationTarget.USER_LOCAL)); + this.userLocalSettings.tooltip = this.userLocalSettings.label; + + const remoteAuthority = this.environmentService.configuration.remoteAuthority; + const hostLabel = remoteAuthority && this.labelService.getHostLabel(REMOTE_HOST_SCHEME, remoteAuthority); + const remoteSettingsLabel = localize('userSettingsRemote', "Remote Settings") + + (hostLabel ? ` (${hostLabel})` : ''); + this.userRemoteSettings = new Action('userSettingsRemote', remoteSettingsLabel, '.settings-tab', true, () => this.updateTarget(ConfigurationTarget.USER_REMOTE)); + this.userRemoteSettings.tooltip = this.userRemoteSettings.label; this.workspaceSettings = new Action('workspaceSettings', localize('workspaceSettings', "Workspace Settings"), '.settings-tab', false, () => this.updateTarget(ConfigurationTarget.WORKSPACE)); this.workspaceSettings.tooltip = this.workspaceSettings.label; - const folderSettingsAction = new Action('folderSettings', localize('folderSettings', "Folder Settings"), '.settings-tab', false, (folder: IWorkspaceFolder) => this.updateTarget(folder ? folder.uri : ConfigurationTarget.USER)); + const folderSettingsAction = new Action('folderSettings', localize('folderSettings', "Folder Settings"), '.settings-tab', false, (folder: IWorkspaceFolder) => this.updateTarget(folder.uri)); this.folderSettings = this.instantiationService.createInstance(FolderSettingsActionItem, folderSettingsAction); this.update(); - this.settingsSwitcherBar.push([this.userSettings, this.workspaceSettings, folderSettingsAction]); + this.settingsSwitcherBar.push([this.userLocalSettings, this.userRemoteSettings, this.workspaceSettings, folderSettingsAction]); } get settingsTarget(): SettingsTarget { @@ -518,7 +538,8 @@ export class SettingsTargetsWidget extends Widget { set settingsTarget(settingsTarget: SettingsTarget) { this._settingsTarget = settingsTarget; - this.userSettings.checked = ConfigurationTarget.USER === this.settingsTarget; + this.userLocalSettings.checked = ConfigurationTarget.USER_LOCAL === this.settingsTarget; + this.userRemoteSettings.checked = ConfigurationTarget.USER_REMOTE === this.settingsTarget; this.workspaceSettings.checked = ConfigurationTarget.WORKSPACE === this.settingsTarget; if (this.settingsTarget instanceof URI) { this.folderSettings.getAction().checked = true; @@ -536,13 +557,13 @@ export class SettingsTargetsWidget extends Widget { } this.workspaceSettings.label = label; - } else if (settingsTarget === ConfigurationTarget.USER) { + } else if (settingsTarget === ConfigurationTarget.USER_LOCAL) { let label = localize('userSettings', "User Settings"); if (count) { label += ` (${count})`; } - this.userSettings.label = label; + this.userLocalSettings.label = label; } else if (settingsTarget instanceof URI) { this.folderSettings.setCount(settingsTarget, count); } @@ -552,21 +573,27 @@ export class SettingsTargetsWidget extends Widget { this.folderSettings.folder = null; this.update(); if (this.settingsTarget === ConfigurationTarget.WORKSPACE && this.contextService.getWorkbenchState() === WorkbenchState.WORKSPACE) { - this.updateTarget(ConfigurationTarget.USER); + this.updateTarget(ConfigurationTarget.USER_LOCAL); } } updateTarget(settingsTarget: SettingsTarget): Promise { - const isSameTarget = this.settingsTarget === settingsTarget || settingsTarget instanceof URI && this.settingsTarget instanceof URI && this.settingsTarget.toString() === settingsTarget.toString(); + const isSameTarget = this.settingsTarget === settingsTarget || + settingsTarget instanceof URI && + this.settingsTarget instanceof URI && + this.settingsTarget.toString() === settingsTarget.toString(); + if (!isSameTarget) { this.settingsTarget = settingsTarget; this._onDidTargetChange.fire(this.settingsTarget); } + return Promise.resolve(undefined); } private update(): void { DOM.toggleClass(this.settingsSwitcherBar.domNode, 'empty-workbench', this.contextService.getWorkbenchState() === WorkbenchState.EMPTY); + this.userRemoteSettings.enabled = !!(this.options.enableRemoteSettings && this.environmentService.configuration.remoteAuthority); this.workspaceSettings.enabled = this.contextService.getWorkbenchState() !== WorkbenchState.EMPTY; this.folderSettings.getAction().enabled = this.contextService.getWorkbenchState() === WorkbenchState.WORKSPACE && this.contextService.getWorkspace().folders.length > 0; } diff --git a/src/vs/workbench/contrib/preferences/browser/settingsTree.ts b/src/vs/workbench/contrib/preferences/browser/settingsTree.ts index 69d65e71352..59a36d4f50b 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsTree.ts @@ -1174,7 +1174,7 @@ export class SettingsTreeFilter implements ITreeFilter { } // Non-user scope selected - if (element instanceof SettingsTreeSettingElement && this.viewState.settingsTarget !== ConfigurationTarget.USER) { + if (element instanceof SettingsTreeSettingElement && this.viewState.settingsTarget !== ConfigurationTarget.USER_LOCAL) { if (!element.matchesScope(this.viewState.settingsTarget)) { return false; } diff --git a/src/vs/workbench/contrib/preferences/browser/settingsTreeModels.ts b/src/vs/workbench/contrib/preferences/browser/settingsTreeModels.ts index c921692d541..d277272f4be 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsTreeModels.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsTreeModels.ts @@ -337,9 +337,10 @@ interface IInspectResult { function inspectSetting(key: string, target: SettingsTarget, configurationService: IConfigurationService): IInspectResult { const inspectOverrides = URI.isUri(target) ? { resource: target } : undefined; const inspected = configurationService.inspect(key, inspectOverrides); - const targetSelector = target === ConfigurationTarget.USER ? 'user' : - target === ConfigurationTarget.WORKSPACE ? 'workspace' : - 'workspaceFolder'; + const targetSelector = target === ConfigurationTarget.USER_LOCAL ? 'userLocal' : + target === ConfigurationTarget.USER_REMOTE ? 'userRemote' : + target === ConfigurationTarget.WORKSPACE ? 'workspace' : + 'workspaceFolder'; const isConfigured = typeof inspected[targetSelector] !== 'undefined'; return { isConfigured, inspected, targetSelector }; diff --git a/src/vs/workbench/contrib/preferences/electron-browser/settingsEditor2.ts b/src/vs/workbench/contrib/preferences/electron-browser/settingsEditor2.ts index 6b0de094ef0..1985393f0c4 100644 --- a/src/vs/workbench/contrib/preferences/electron-browser/settingsEditor2.ts +++ b/src/vs/workbench/contrib/preferences/electron-browser/settingsEditor2.ts @@ -149,7 +149,7 @@ export class SettingsEditor2 extends BaseEditor { this.delayedFilterLogging = new Delayer(1000); this.localSearchDelayer = new Delayer(300); this.remoteSearchThrottle = new ThrottledDelayer(200); - this.viewState = { settingsTarget: ConfigurationTarget.USER }; + this.viewState = { settingsTarget: ConfigurationTarget.USER_LOCAL }; this.settingFastUpdateDelayer = new Delayer(SettingsEditor2.SETTING_UPDATE_FAST_DEBOUNCE); this.settingSlowUpdateDelayer = new Delayer(SettingsEditor2.SETTING_UPDATE_SLOW_DEBOUNCE); @@ -212,10 +212,10 @@ export class SettingsEditor2 extends BaseEditor { if (!options) { if (!this.viewState.settingsTarget) { // Persist? - options = SettingsEditorOptions.create({ target: ConfigurationTarget.USER }); + options = SettingsEditorOptions.create({ target: ConfigurationTarget.USER_LOCAL }); } } else if (!options.target) { - options.target = ConfigurationTarget.USER; + options.target = ConfigurationTarget.USER_LOCAL; } this._setOptions(options); @@ -406,8 +406,8 @@ export class SettingsEditor2 extends BaseEditor { const headerControlsContainer = DOM.append(this.headerContainer, $('.settings-header-controls')); const targetWidgetContainer = DOM.append(headerControlsContainer, $('.settings-target-container')); - this.settingsTargetsWidget = this._register(this.instantiationService.createInstance(SettingsTargetsWidget, targetWidgetContainer)); - this.settingsTargetsWidget.settingsTarget = ConfigurationTarget.USER; + this.settingsTargetsWidget = this._register(this.instantiationService.createInstance(SettingsTargetsWidget, targetWidgetContainer, { enableRemoteSettings: true })); + this.settingsTargetsWidget.settingsTarget = ConfigurationTarget.USER_LOCAL; this.settingsTargetsWidget.onDidTargetChange(target => this.onDidSettingsTargetChange(target)); } @@ -458,8 +458,10 @@ export class SettingsEditor2 extends BaseEditor { const currentSettingsTarget = this.settingsTargetsWidget.settingsTarget; const options: ISettingsEditorOptions = { query }; - if (currentSettingsTarget === ConfigurationTarget.USER) { + if (currentSettingsTarget === ConfigurationTarget.USER_LOCAL) { return this.preferencesService.openGlobalSettings(true, options); + } else if (currentSettingsTarget === ConfigurationTarget.USER_REMOTE) { + return this.preferencesService.openRemoteSettings(); } else if (currentSettingsTarget === ConfigurationTarget.WORKSPACE) { return this.preferencesService.openWorkspaceSettings(true, options); } else { @@ -615,8 +617,10 @@ export class SettingsEditor2 extends BaseEditor { this._register(this.settingRenderers.onDidClickOverrideElement((element: ISettingOverrideClickEvent) => { if (ConfigurationTargetToString(ConfigurationTarget.WORKSPACE) === element.scope.toUpperCase()) { this.settingsTargetsWidget.updateTarget(ConfigurationTarget.WORKSPACE); - } else if (ConfigurationTargetToString(ConfigurationTarget.USER) === element.scope.toUpperCase()) { - this.settingsTargetsWidget.updateTarget(ConfigurationTarget.USER); + } else if (ConfigurationTargetToString(ConfigurationTarget.USER_LOCAL) === element.scope.toUpperCase()) { + this.settingsTargetsWidget.updateTarget(ConfigurationTarget.USER_LOCAL); + } else if (ConfigurationTargetToString(ConfigurationTarget.USER_REMOTE) === element.scope.toUpperCase()) { + this.settingsTargetsWidget.updateTarget(ConfigurationTarget.USER_REMOTE); } this.searchWidget.setValue(element.targetKey); @@ -792,9 +796,10 @@ export class SettingsEditor2 extends BaseEditor { } } - const reportedTarget = props.settingsTarget === ConfigurationTarget.USER ? 'user' : - props.settingsTarget === ConfigurationTarget.WORKSPACE ? 'workspace' : - 'folder'; + const reportedTarget = props.settingsTarget === ConfigurationTarget.USER_LOCAL ? 'user' : + props.settingsTarget === ConfigurationTarget.USER_REMOTE ? 'user_remote' : + props.settingsTarget === ConfigurationTarget.WORKSPACE ? 'workspace' : + 'folder'; const data = { key: props.key, diff --git a/src/vs/workbench/services/preferences/browser/preferencesService.ts b/src/vs/workbench/services/preferences/browser/preferencesService.ts index ff35157ee90..7546a8f0efe 100644 --- a/src/vs/workbench/services/preferences/browser/preferencesService.ts +++ b/src/vs/workbench/services/preferences/browser/preferencesService.ts @@ -215,10 +215,10 @@ export class PreferencesService extends Disposable implements IPreferencesServic } async openRemoteSettings(): Promise { - const environemnt = await this.remoteAgentService.getEnvironment(); - if (environemnt) { - await this.createIfNotExists(environemnt.settingsPath, emptyEditableSettingsContent); - return this.editorService.openEditor({ resource: environemnt.settingsPath, options: { pinned: true, revealIfOpened: true } }); + const environment = await this.remoteAgentService.getEnvironment(); + if (environment) { + await this.createIfNotExists(environment.settingsPath, emptyEditableSettingsContent); + return this.editorService.openEditor({ resource: environment.settingsPath, options: { pinned: true, revealIfOpened: true } }); } return null; } @@ -520,6 +520,9 @@ export class PreferencesService extends Disposable implements IPreferencesServic private getEditableSettingsURI(configurationTarget: ConfigurationTarget, resource?: URI): URI | null { switch (configurationTarget) { case ConfigurationTarget.USER: + case ConfigurationTarget.USER_LOCAL: + return URI.file(this.environmentService.appSettingsPath); + case ConfigurationTarget.USER_REMOTE: return URI.file(this.environmentService.appSettingsPath); case ConfigurationTarget.WORKSPACE: if (this.contextService.getWorkbenchState() === WorkbenchState.EMPTY) { diff --git a/src/vs/workbench/services/preferences/common/preferences.ts b/src/vs/workbench/services/preferences/common/preferences.ts index 7385ab31222..5c7b5e91166 100644 --- a/src/vs/workbench/services/preferences/common/preferences.ts +++ b/src/vs/workbench/services/preferences/common/preferences.ts @@ -213,7 +213,7 @@ export interface IPreferencesService { export function getSettingsTargetName(target: ConfigurationTarget, resource: URI, workspaceContextService: IWorkspaceContextService): string { switch (target) { - case ConfigurationTarget.USER: + case ConfigurationTarget.USER_LOCAL: return localize('userSettingsTarget', "User Settings"); case ConfigurationTarget.WORKSPACE: return localize('workspaceSettingsTarget', "Workspace Settings"); From 5c3681e27e5402a6d754537913856a4adfd98cb1 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Thu, 11 Apr 2019 19:27:55 +0200 Subject: [PATCH 16/48] fix mac build --- build/azure-pipelines/darwin/product-build-darwin.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/build/azure-pipelines/darwin/product-build-darwin.yml b/build/azure-pipelines/darwin/product-build-darwin.yml index ead740924fc..9c97a6a32a7 100644 --- a/build/azure-pipelines/darwin/product-build-darwin.yml +++ b/build/azure-pipelines/darwin/product-build-darwin.yml @@ -77,6 +77,7 @@ steps: - script: | set -e + VSCODE_MIXIN_PASSWORD="$(VSCODE_MIXIN_PASSWORD)" \ AZURE_DOCUMENTDB_MASTERKEY="$(AZURE_DOCUMENTDB_MASTERKEY)" \ AZURE_STORAGE_ACCESS_KEY_2="$(AZURE_STORAGE_ACCESS_KEY_2)" \ VSCODE_HOCKEYAPP_TOKEN="$(VSCODE_HOCKEYAPP_TOKEN)" \ From 06dd5823e8d122973462861674852a7b70c83686 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Thu, 11 Apr 2019 20:38:05 +0200 Subject: [PATCH 17/48] fix mac build --- build/azure-pipelines/darwin/product-build-darwin.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/build/azure-pipelines/darwin/product-build-darwin.yml b/build/azure-pipelines/darwin/product-build-darwin.yml index 9c97a6a32a7..f5d5ef626b1 100644 --- a/build/azure-pipelines/darwin/product-build-darwin.yml +++ b/build/azure-pipelines/darwin/product-build-darwin.yml @@ -79,6 +79,7 @@ steps: set -e VSCODE_MIXIN_PASSWORD="$(VSCODE_MIXIN_PASSWORD)" \ AZURE_DOCUMENTDB_MASTERKEY="$(AZURE_DOCUMENTDB_MASTERKEY)" \ + AZURE_STORAGE_ACCESS_KEY="$(AZURE_STORAGE_ACCESS_KEY)" \ AZURE_STORAGE_ACCESS_KEY_2="$(AZURE_STORAGE_ACCESS_KEY_2)" \ VSCODE_HOCKEYAPP_TOKEN="$(VSCODE_HOCKEYAPP_TOKEN)" \ ./build/azure-pipelines/darwin/publish.sh From b53be6efef511b47094f82917724bb2241939f79 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Thu, 11 Apr 2019 18:35:22 +0000 Subject: [PATCH 18/48] Refactor to support ErrorTelemetry in non-browser processes --- .../telemetry/browser/errorTelemetry.ts | 128 +---------------- .../telemetry/common/errorTelemetry.ts | 136 ++++++++++++++++++ .../platform/telemetry/node/errorTelemetry.ts | 44 ++++++ 3 files changed, 184 insertions(+), 124 deletions(-) create mode 100644 src/vs/platform/telemetry/common/errorTelemetry.ts create mode 100644 src/vs/platform/telemetry/node/errorTelemetry.ts diff --git a/src/vs/platform/telemetry/browser/errorTelemetry.ts b/src/vs/platform/telemetry/browser/errorTelemetry.ts index 0abfe60e009..26380fa6ef0 100644 --- a/src/vs/platform/telemetry/browser/errorTelemetry.ts +++ b/src/vs/platform/telemetry/browser/errorTelemetry.ts @@ -3,69 +3,12 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { binarySearch } from 'vs/base/common/arrays'; +import { toDisposable } from 'vs/base/common/lifecycle'; import { globals } from 'vs/base/common/platform'; -import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { IDisposable, toDisposable, dispose } from 'vs/base/common/lifecycle'; -import * as Errors from 'vs/base/common/errors'; -import { safeStringify } from 'vs/base/common/objects'; +import BaseErrorTelemetry, { ErrorEvent } from '../common/errorTelemetry'; -/* __GDPR__FRAGMENT__ - "ErrorEvent" : { - "stack": { "classification": "CustomerContent", "purpose": "PerformanceAndHealth" }, - "message" : { "classification": "CustomerContent", "purpose": "PerformanceAndHealth" }, - "filename" : { "classification": "CustomerContent", "purpose": "PerformanceAndHealth" }, - "callstack": { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth" }, - "msg" : { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth" }, - "file" : { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth" }, - "line": { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "column": { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "uncaught_error_name": { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth" }, - "uncaught_error_msg": { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth" }, - "count": { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth", "isMeasurement": true } - } - */ -interface ErrorEvent { - callstack: string; - msg?: string; - file?: string; - line?: number; - column?: number; - uncaught_error_name?: string; - uncaught_error_msg?: string; - count?: number; -} - -namespace ErrorEvent { - export function compare(a: ErrorEvent, b: ErrorEvent) { - if (a.callstack < b.callstack) { - return -1; - } else if (a.callstack > b.callstack) { - return 1; - } - return 0; - } -} - -export default class ErrorTelemetry { - - public static ERROR_FLUSH_TIMEOUT: number = 5 * 1000; - - private _telemetryService: ITelemetryService; - private _flushDelay: number; - private _flushHandle: any = -1; - private _buffer: ErrorEvent[] = []; - private _disposables: IDisposable[] = []; - - constructor(telemetryService: ITelemetryService, flushDelay = ErrorTelemetry.ERROR_FLUSH_TIMEOUT) { - this._telemetryService = telemetryService; - this._flushDelay = flushDelay; - - // (1) check for unexpected but handled errors - const unbind = Errors.errorHandler.addListener((err) => this._onErrorEvent(err)); - this._disposables.push(toDisposable(unbind)); - - // (2) check for uncaught global errors +export default class ErrorTelemetry extends BaseErrorTelemetry { + protected installErrorListeners(): void { let oldOnError: Function; let that = this; if (typeof globals.onerror === 'function') { @@ -84,37 +27,7 @@ export default class ErrorTelemetry { })); } - dispose() { - clearTimeout(this._flushHandle); - this._flushBuffer(); - this._disposables = dispose(this._disposables); - } - - private _onErrorEvent(err: any): void { - - if (!err) { - return; - } - - // unwrap nested errors from loader - if (err.detail && err.detail.stack) { - err = err.detail; - } - - // work around behavior in workerServer.ts that breaks up Error.stack - let callstack = Array.isArray(err.stack) ? err.stack.join('\n') : err.stack; - let msg = err.message ? err.message : safeStringify(err); - - // errors without a stack are not useful telemetry - if (!callstack) { - return; - } - - this._enqueue({ msg, callstack }); - } - private _onUncaughtError(msg: string, file: string, line: number, column?: number, err?: any): void { - let data: ErrorEvent = { callstack: msg, msg, @@ -138,37 +51,4 @@ export default class ErrorTelemetry { this._enqueue(data); } - - private _enqueue(e: ErrorEvent): void { - - const idx = binarySearch(this._buffer, e, ErrorEvent.compare); - if (idx < 0) { - e.count = 1; - this._buffer.splice(~idx, 0, e); - } else { - if (!this._buffer[idx].count) { - this._buffer[idx].count = 0; - } - this._buffer[idx].count! += 1; - } - - if (this._flushHandle === -1) { - this._flushHandle = setTimeout(() => { - this._flushBuffer(); - this._flushHandle = -1; - }, this._flushDelay); - } - } - - private _flushBuffer(): void { - for (let error of this._buffer) { - /* __GDPR__ - "UnhandledError" : { - "${include}": [ "${ErrorEvent}" ] - } - */ - this._telemetryService.publicLog('UnhandledError', error, true); - } - this._buffer.length = 0; - } } diff --git a/src/vs/platform/telemetry/common/errorTelemetry.ts b/src/vs/platform/telemetry/common/errorTelemetry.ts new file mode 100644 index 00000000000..37be63bfc31 --- /dev/null +++ b/src/vs/platform/telemetry/common/errorTelemetry.ts @@ -0,0 +1,136 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { binarySearch } from 'vs/base/common/arrays'; +import * as Errors from 'vs/base/common/errors'; +import { dispose, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; +import { safeStringify } from 'vs/base/common/objects'; +import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; + +/* __GDPR__FRAGMENT__ + "ErrorEvent" : { + "stack": { "classification": "CustomerContent", "purpose": "PerformanceAndHealth" }, + "message" : { "classification": "CustomerContent", "purpose": "PerformanceAndHealth" }, + "filename" : { "classification": "CustomerContent", "purpose": "PerformanceAndHealth" }, + "callstack": { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth" }, + "msg" : { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth" }, + "file" : { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth" }, + "line": { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "column": { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "uncaught_error_name": { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth" }, + "uncaught_error_msg": { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth" }, + "count": { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth", "isMeasurement": true } + } + */ +export interface ErrorEvent { + callstack: string; + msg?: string; + file?: string; + line?: number; + column?: number; + uncaught_error_name?: string; + uncaught_error_msg?: string; + count?: number; +} + +export namespace ErrorEvent { + export function compare(a: ErrorEvent, b: ErrorEvent) { + if (a.callstack < b.callstack) { + return -1; + } else if (a.callstack > b.callstack) { + return 1; + } + return 0; + } +} + +export default abstract class BaseErrorTelemetry { + + public static ERROR_FLUSH_TIMEOUT: number = 5 * 1000; + + private _telemetryService: ITelemetryService; + private _flushDelay: number; + private _flushHandle: any = -1; + private _buffer: ErrorEvent[] = []; + protected _disposables: IDisposable[] = []; + + constructor(telemetryService: ITelemetryService, flushDelay = BaseErrorTelemetry.ERROR_FLUSH_TIMEOUT) { + this._telemetryService = telemetryService; + this._flushDelay = flushDelay; + + // (1) check for unexpected but handled errors + const unbind = Errors.errorHandler.addListener((err) => this._onErrorEvent(err)); + this._disposables.push(toDisposable(unbind)); + + // (2) install implementation-specific error listeners + this.installErrorListeners(); + } + + dispose() { + clearTimeout(this._flushHandle); + this._flushBuffer(); + this._disposables = dispose(this._disposables); + } + + protected installErrorListeners(): void { + // to override + } + + private _onErrorEvent(err: any): void { + + if (!err) { + return; + } + + // unwrap nested errors from loader + if (err.detail && err.detail.stack) { + err = err.detail; + } + + // work around behavior in workerServer.ts that breaks up Error.stack + let callstack = Array.isArray(err.stack) ? err.stack.join('\n') : err.stack; + let msg = err.message ? err.message : safeStringify(err); + + // errors without a stack are not useful telemetry + if (!callstack) { + return; + } + + this._enqueue({ msg, callstack }); + } + + protected _enqueue(e: ErrorEvent): void { + + const idx = binarySearch(this._buffer, e, ErrorEvent.compare); + if (idx < 0) { + e.count = 1; + this._buffer.splice(~idx, 0, e); + } else { + if (!this._buffer[idx].count) { + this._buffer[idx].count = 0; + } + this._buffer[idx].count! += 1; + } + + if (this._flushHandle === -1) { + this._flushHandle = setTimeout(() => { + this._flushBuffer(); + this._flushHandle = -1; + }, this._flushDelay); + } + } + + private _flushBuffer(): void { + for (let error of this._buffer) { + /* __GDPR__ + "UnhandledError" : { + "${include}": [ "${ErrorEvent}" ] + } + */ + this._telemetryService.publicLog('UnhandledError', error, true); + } + this._buffer.length = 0; + } +} diff --git a/src/vs/platform/telemetry/node/errorTelemetry.ts b/src/vs/platform/telemetry/node/errorTelemetry.ts new file mode 100644 index 00000000000..9cf146e5f6e --- /dev/null +++ b/src/vs/platform/telemetry/node/errorTelemetry.ts @@ -0,0 +1,44 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { onUnexpectedError } from 'vs/base/common/errors'; +import BaseErrorTelemetry from '../common/errorTelemetry'; + +export default class ErrorTelemetry extends BaseErrorTelemetry { + protected installErrorListeners(): void { + // Print a console message when rejection isn't handled within N seconds. For details: + // see https://nodejs.org/api/process.html#process_event_unhandledrejection + // and https://nodejs.org/api/process.html#process_event_rejectionhandled + const unhandledPromises: Promise[] = []; + process.on('unhandledRejection', (reason: any, promise: Promise) => { + unhandledPromises.push(promise); + setTimeout(() => { + const idx = unhandledPromises.indexOf(promise); + if (idx >= 0) { + promise.catch(e => { + unhandledPromises.splice(idx, 1); + console.warn(`rejected promise not handled within 1 second: ${e}`); + if (e.stack) { + console.warn(`stack trace: ${e.stack}`); + } + onUnexpectedError(reason); + }); + } + }, 1000); + }); + + process.on('rejectionHandled', (promise: Promise) => { + const idx = unhandledPromises.indexOf(promise); + if (idx >= 0) { + unhandledPromises.splice(idx, 1); + } + }); + + // Print a console message when an exception isn't handled. + process.on('uncaughtException', (err: Error) => { + onUnexpectedError(err); + }); + } +} From ea7e2600d8e8e97fcf23cbd90ed0a3e4951d7acd Mon Sep 17 00:00:00 2001 From: Rachel Macfarlane Date: Thu, 11 Apr 2019 14:28:53 -0700 Subject: [PATCH 19/48] Expose vscode.openIssueReporter command that allows passing an extensionId to open the reporter with --- .../issue/issueReporterMain.ts | 19 +++++++++++--- src/vs/platform/issue/common/issue.ts | 1 + src/vs/workbench/api/common/apiCommands.ts | 7 ++++++ .../api/common/extHostApiCommands.ts | 9 ++++++- .../electron-browser/issue.contribution.ts | 25 ++++++++++++++++--- .../issue/electron-browser/issueActions.ts | 17 ------------- 6 files changed, 53 insertions(+), 25 deletions(-) diff --git a/src/vs/code/electron-browser/issue/issueReporterMain.ts b/src/vs/code/electron-browser/issue/issueReporterMain.ts index 65ed00a1eba..c26d967523b 100644 --- a/src/vs/code/electron-browser/issue/issueReporterMain.ts +++ b/src/vs/code/electron-browser/issue/issueReporterMain.ts @@ -88,6 +88,8 @@ export class IssueReporter extends Disposable { os: `${os.type()} ${os.arch()} ${os.release()}${isSnap ? ' snap' : ''}` }, extensionsDisabled: !!this.environmentService.disableExtensions, + fileOnExtension: configuration.data.extensionId ? true : undefined, + selectedExtension: configuration.data.extensionId ? configuration.data.enabledExtensions.filter(extension => extension.id === configuration.data.extensionId)[0] : undefined }); const issueReporterElement = this.getElementById('issue-reporter'); @@ -698,9 +700,13 @@ export class IssueReporter extends Disposable { private setSourceOptions(): void { const sourceSelect = this.getElementById('issue-source')! as HTMLSelectElement; - const selected = sourceSelect.selectedIndex; + const { issueType, fileOnExtension } = this.issueReporterModel.getData(); + let selected = sourceSelect.selectedIndex; + if (selected === -1 && fileOnExtension !== undefined) { + selected = fileOnExtension ? 2 : 1; + } + sourceSelect.innerHTML = ''; - const { issueType } = this.issueReporterModel.getData(); if (issueType === IssueType.FeatureRequest) { sourceSelect.append(...[ this.makeOption('', localize('selectSource', "Select source"), true), @@ -959,10 +965,15 @@ export class IssueReporter extends Disposable { return 0; }); - const makeOption = (extension: IOption) => ``; + const makeOption = (extension: IOption, selectedExtension?: IssueReporterExtensionData) => { + const selected = selectedExtension && extension.id === selectedExtension.id; + return ``; + }; + const extensionsSelector = this.getElementById('extension-selector'); if (extensionsSelector) { - extensionsSelector.innerHTML = '' + extensionOptions.map(makeOption).join('\n'); + const { selectedExtension } = this.issueReporterModel.getData(); + extensionsSelector.innerHTML = '' + extensionOptions.map(extension => makeOption(extension, selectedExtension)).join('\n'); this.addEventListener('extension-selector', 'change', (e: Event) => { const selectedExtensionId = (e.target).value; diff --git a/src/vs/platform/issue/common/issue.ts b/src/vs/platform/issue/common/issue.ts index 0058f556840..d9d0e1c4492 100644 --- a/src/vs/platform/issue/common/issue.ts +++ b/src/vs/platform/issue/common/issue.ts @@ -56,6 +56,7 @@ export interface IssueReporterData extends WindowData { styles: IssueReporterStyles; enabledExtensions: IssueReporterExtensionData[]; issueType?: IssueType; + extensionId?: string; } export interface ISettingSearchResult { diff --git a/src/vs/workbench/api/common/apiCommands.ts b/src/vs/workbench/api/common/apiCommands.ts index 05aebd151ea..c7f4f1972c6 100644 --- a/src/vs/workbench/api/common/apiCommands.ts +++ b/src/vs/workbench/api/common/apiCommands.ts @@ -144,6 +144,13 @@ export class RemoveFromRecentlyOpenedAPICommand { } CommandsRegistry.registerCommand(RemoveFromRecentlyOpenedAPICommand.ID, adjustHandler(RemoveFromRecentlyOpenedAPICommand.execute)); +export class OpenIssueReporter { + public static ID = 'vscode.openIssueReporter'; + public static execute(executor: ICommandsExecutor, extensionId: string): Promise { + return executor.executeCommand('workbench.action.openIssueReporter', [extensionId]); + } +} + interface RecentEntry { uri: URI; type: 'workspace' | 'folder' | 'file'; diff --git a/src/vs/workbench/api/common/extHostApiCommands.ts b/src/vs/workbench/api/common/extHostApiCommands.ts index 737a581ee51..d4f1eb5ba6d 100644 --- a/src/vs/workbench/api/common/extHostApiCommands.ts +++ b/src/vs/workbench/api/common/extHostApiCommands.ts @@ -15,7 +15,7 @@ import * as search from 'vs/workbench/contrib/search/common/search'; import { ICommandHandlerDescription } from 'vs/platform/commands/common/commands'; import { ExtHostCommands } from 'vs/workbench/api/common/extHostCommands'; import { CustomCodeAction } from 'vs/workbench/api/common/extHostLanguageFeatures'; -import { ICommandsExecutor, OpenFolderAPICommand, DiffAPICommand, OpenAPICommand, RemoveFromRecentlyOpenedAPICommand, SetEditorLayoutAPICommand } from './apiCommands'; +import { ICommandsExecutor, OpenFolderAPICommand, DiffAPICommand, OpenAPICommand, RemoveFromRecentlyOpenedAPICommand, SetEditorLayoutAPICommand, OpenIssueReporter } from './apiCommands'; import { EditorGroupLayout } from 'vs/workbench/services/editor/common/editorGroupsService'; import { isFalsyOrEmpty } from 'vs/base/common/arrays'; @@ -258,6 +258,13 @@ export class ExtHostApiCommands { { name: 'layout', description: 'The editor layout to set.', constraint: (value: EditorGroupLayout) => typeof value === 'object' && Array.isArray(value.groups) } ] }); + + this._register(OpenIssueReporter.ID, adjustHandler(OpenIssueReporter.execute), { + description: 'Opens the issue reporter with the provided extension id as the selected source', + args: [ + { name: 'extensionId', description: 'extensionId to report an issue on', constraint: (value: any) => typeof value === 'string' } + ] + }); } // --- command impl diff --git a/src/vs/workbench/contrib/issue/electron-browser/issue.contribution.ts b/src/vs/workbench/contrib/issue/electron-browser/issue.contribution.ts index e734abdc41b..cbb10f15a37 100644 --- a/src/vs/workbench/contrib/issue/electron-browser/issue.contribution.ts +++ b/src/vs/workbench/contrib/issue/electron-browser/issue.contribution.ts @@ -6,9 +6,9 @@ import { Registry } from 'vs/platform/registry/common/platform'; import * as nls from 'vs/nls'; import product from 'vs/platform/product/node/product'; -import { SyncActionDescriptor } from 'vs/platform/actions/common/actions'; +import { SyncActionDescriptor, ICommandAction, MenuRegistry, MenuId } from 'vs/platform/actions/common/actions'; import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actions'; -import { OpenIssueReporterAction, ReportPerformanceIssueUsingReporterAction, OpenProcessExplorer } from 'vs/workbench/contrib/issue/electron-browser/issueActions'; +import { ReportPerformanceIssueUsingReporterAction, OpenProcessExplorer } from 'vs/workbench/contrib/issue/electron-browser/issueActions'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { IWorkbenchIssueService } from 'vs/workbench/contrib/issue/electron-browser/issue'; import { WorkbenchIssueService } from 'vs/workbench/contrib/issue/electron-browser/issueService'; @@ -19,8 +19,27 @@ const helpCategory = nls.localize('help', "Help"); const workbenchActionsRegistry = Registry.as(Extensions.WorkbenchActions); if (!!product.reportIssueUrl) { - workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(OpenIssueReporterAction, OpenIssueReporterAction.ID, OpenIssueReporterAction.LABEL), 'Help: Open Issue Reporter', helpCategory); workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(ReportPerformanceIssueUsingReporterAction, ReportPerformanceIssueUsingReporterAction.ID, ReportPerformanceIssueUsingReporterAction.LABEL), 'Help: Report Performance Issue', helpCategory); + + const OpenIssueReporterActionId = 'workbench.action.openIssueReporter'; + const OpenIssueReporterActionLabel = nls.localize({ key: 'reportIssueInEnglish', comment: ['Translate this to "Report Issue in English" in all languages please!'] }, "Report Issue"); + + CommandsRegistry.registerCommand(OpenIssueReporterActionId, function (accessor, args?: [string]) { + let extensionId: string | undefined; + if (args && Array.isArray(args)) { + [extensionId] = args; + } + + return accessor.get(IWorkbenchIssueService).openReporter({ extensionId }); + }); + + const command: ICommandAction = { + id: OpenIssueReporterActionId, + title: { value: OpenIssueReporterActionLabel, original: 'Help: Open Issue Reporter' }, + category: helpCategory + }; + + MenuRegistry.appendMenuItem(MenuId.CommandPalette, { command }); } const developerCategory = nls.localize('developer', "Developer"); diff --git a/src/vs/workbench/contrib/issue/electron-browser/issueActions.ts b/src/vs/workbench/contrib/issue/electron-browser/issueActions.ts index 884189cbaeb..4eaaf7c3029 100644 --- a/src/vs/workbench/contrib/issue/electron-browser/issueActions.ts +++ b/src/vs/workbench/contrib/issue/electron-browser/issueActions.ts @@ -8,23 +8,6 @@ import * as nls from 'vs/nls'; import { IssueType } from 'vs/platform/issue/common/issue'; import { IWorkbenchIssueService } from 'vs/workbench/contrib/issue/electron-browser/issue'; -export class OpenIssueReporterAction extends Action { - static readonly ID = 'workbench.action.openIssueReporter'; - static readonly LABEL = nls.localize({ key: 'reportIssueInEnglish', comment: ['Translate this to "Report Issue in English" in all languages please!'] }, "Report Issue"); - - constructor( - id: string, - label: string, - @IWorkbenchIssueService private readonly issueService: IWorkbenchIssueService - ) { - super(id, label); - } - - run(): Promise { - return this.issueService.openReporter().then(() => true); - } -} - export class OpenProcessExplorer extends Action { static readonly ID = 'workbench.action.openProcessExplorer'; static readonly LABEL = nls.localize('openProcessExplorer', "Open Process Explorer"); From 27c30c8a998fba012439ed838456eef3c43785d5 Mon Sep 17 00:00:00 2001 From: SteVen Batten <6561887+sbatten@users.noreply.github.com> Date: Thu, 11 Apr 2019 15:49:55 -0700 Subject: [PATCH 20/48] adding overlayService (#72014) * adding overlayService * addressing feedback from UX meeting * relocating to progressService2 * remove overlayService and update progressService --- src/vs/base/browser/ui/dialog/dialog.css | 20 +++++++ src/vs/base/browser/ui/dialog/dialog.ts | 7 ++- .../base/browser/ui/dialog/pending-dark.svg | 31 +++++++++++ src/vs/base/browser/ui/dialog/pending-hc.svg | 31 +++++++++++ src/vs/base/browser/ui/dialog/pending.svg | 31 +++++++++++ src/vs/platform/progress/common/progress.ts | 3 +- .../progress/browser/progressService2.ts | 54 +++++++++++++++++++ 7 files changed, 174 insertions(+), 3 deletions(-) create mode 100644 src/vs/base/browser/ui/dialog/pending-dark.svg create mode 100644 src/vs/base/browser/ui/dialog/pending-hc.svg create mode 100644 src/vs/base/browser/ui/dialog/pending.svg diff --git a/src/vs/base/browser/ui/dialog/dialog.css b/src/vs/base/browser/ui/dialog/dialog.css index 8f5d835974d..f772e57fcc5 100644 --- a/src/vs/base/browser/ui/dialog/dialog.css +++ b/src/vs/base/browser/ui/dialog/dialog.css @@ -15,6 +15,10 @@ align-items: center; } +.monaco-workbench .dialog-modal-block.dimmed { + background: rgba(0, 0, 0, 0.3); +} + /** Dialog: Container */ .monaco-workbench .dialog-box { display: flex; @@ -66,6 +70,10 @@ background-repeat: no-repeat; } +.vs .monaco-workbench .dialog-box .dialog-message-row .dialog-icon.icon-pending { + background-image: url('pending.svg'); +} + .vs .monaco-workbench .dialog-box .dialog-message-row .dialog-icon.icon-info { background-image: url('info.svg'); } @@ -78,6 +86,10 @@ background-image: url('error.svg'); } +.vs-dark .monaco-workbench .dialog-box .dialog-message-row .dialog-icon.icon-pending { + background-image: url('pending-dark.svg'); +} + .vs-dark .monaco-workbench .dialog-box .dialog-message-row .dialog-icon.icon-info, .hc-black .monaco-workbench .dialog-box .dialog-message-row .dialog-icon.icon-info { background-image: url('info-inverse.svg'); @@ -93,6 +105,14 @@ background-image: url('error-inverse.svg'); } +.hc-black .monaco-workbench .dialog-box .dialog-message-row .dialog-icon.icon-pending { + background-image: url('pending-hc.svg'); +} + +.monaco-workbench .dialog-box .dialog-message-row .dialog-icon.icon-pending { + background-size: 30px; +} + /** Dialog: Message Container */ .monaco-workbench .dialog-box .dialog-message-row .dialog-message-container { display: flex; diff --git a/src/vs/base/browser/ui/dialog/dialog.ts b/src/vs/base/browser/ui/dialog/dialog.ts index 0ee6b1f6555..2116fb99164 100644 --- a/src/vs/base/browser/ui/dialog/dialog.ts +++ b/src/vs/base/browser/ui/dialog/dialog.ts @@ -19,7 +19,7 @@ import { mnemonicButtonLabel } from 'vs/base/common/labels'; export interface IDialogOptions { cancelId?: number; detail?: string; - type?: 'none' | 'info' | 'error' | 'question' | 'warning'; + type?: 'none' | 'info' | 'error' | 'question' | 'warning' | 'pending'; } export interface IDialogStyles extends IButtonStyles { @@ -40,7 +40,7 @@ export class Dialog extends Disposable { constructor(private container: HTMLElement, private message: string, private buttons: string[], private options: IDialogOptions) { super(); - this.modal = this.container.appendChild($('.dialog-modal-block')); + this.modal = this.container.appendChild($(`.dialog-modal-block${options.type === 'pending' ? '.dimmed' : ''}`)); this.element = this.modal.appendChild($('.dialog-box')); hide(this.element); @@ -129,6 +129,9 @@ export class Dialog extends Disposable { case 'warning': addClass(this.iconElement, 'icon-warning'); break; + case 'pending': + addClass(this.iconElement, 'icon-pending'); + break; case 'none': case 'info': case 'question': diff --git a/src/vs/base/browser/ui/dialog/pending-dark.svg b/src/vs/base/browser/ui/dialog/pending-dark.svg new file mode 100644 index 00000000000..bbf6e8d84cf --- /dev/null +++ b/src/vs/base/browser/ui/dialog/pending-dark.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + diff --git a/src/vs/base/browser/ui/dialog/pending-hc.svg b/src/vs/base/browser/ui/dialog/pending-hc.svg new file mode 100644 index 00000000000..4d0b2a10c79 --- /dev/null +++ b/src/vs/base/browser/ui/dialog/pending-hc.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + diff --git a/src/vs/base/browser/ui/dialog/pending.svg b/src/vs/base/browser/ui/dialog/pending.svg new file mode 100644 index 00000000000..596cfdd60cd --- /dev/null +++ b/src/vs/base/browser/ui/dialog/pending.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + diff --git a/src/vs/platform/progress/common/progress.ts b/src/vs/platform/progress/common/progress.ts index a82359bdaee..c3830290c6f 100644 --- a/src/vs/platform/progress/common/progress.ts +++ b/src/vs/platform/progress/common/progress.ts @@ -30,7 +30,8 @@ export const enum ProgressLocation { Scm = 3, Extensions = 5, Window = 10, - Notification = 15 + Notification = 15, + Dialog = 20 } export interface IProgressOptions { diff --git a/src/vs/workbench/services/progress/browser/progressService2.ts b/src/vs/workbench/services/progress/browser/progressService2.ts index 80b1631c225..8f3203c675e 100644 --- a/src/vs/workbench/services/progress/browser/progressService2.ts +++ b/src/vs/workbench/services/progress/browser/progressService2.ts @@ -16,6 +16,10 @@ import { INotificationService, Severity, INotificationHandle, INotificationActio import { Action } from 'vs/base/common/actions'; import { Event } from 'vs/base/common/event'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { ILayoutService } from 'vs/platform/layout/browser/layoutService'; +import { Dialog } from 'vs/base/browser/ui/dialog/dialog'; +import { attachDialogStyler } from 'vs/platform/theme/common/styler'; +import { IThemeService } from 'vs/platform/theme/common/themeService'; export class ProgressService2 implements IProgressService2 { @@ -29,6 +33,8 @@ export class ProgressService2 implements IProgressService2 { @IViewletService private readonly _viewletService: IViewletService, @INotificationService private readonly _notificationService: INotificationService, @IStatusbarService private readonly _statusbarService: IStatusbarService, + @ILayoutService private readonly _layoutService: ILayoutService, + @IThemeService private readonly _themeService: IThemeService ) { } withProgress(options: IProgressOptions, task: (progress: IProgress) => Promise, onDidCancel?: () => void): Promise { @@ -53,6 +59,8 @@ export class ProgressService2 implements IProgressService2 { return this._withViewletProgress('workbench.view.scm', task); case ProgressLocation.Extensions: return this._withViewletProgress('workbench.view.extensions', task); + case ProgressLocation.Dialog: + return this._withDialogProgress(options, task, onDidCancel); default: return Promise.reject(new Error(`Bad progress location: ${location}`)); } @@ -265,6 +273,52 @@ export class ProgressService2 implements IProgressService2 { promise.then(onDone, onDone); return promise; } + + private _withDialogProgress

, R = unknown>(options: IProgressOptions, task: (progress: IProgress<{ message?: string, increment?: number }>) => P, onDidCancel?: () => void): P { + const disposables: IDisposable[] = []; + + let dialog: Dialog; + + const createDialog = (message: string) => { + dialog = new Dialog( + this._layoutService.container, + message, + [options.cancellable ? localize('cancel', "Cancel") : localize('dismiss', "Dismiss")], + { type: 'pending' } + ); + + disposables.push(dialog); + disposables.push(attachDialogStyler(dialog, this._themeService)); + + dialog.show().then(() => { + if (options.cancellable && typeof onDidCancel === 'function') { + onDidCancel(); + } + + dispose(dialog); + }); + + return dialog; + }; + + const updateDialog = (message?: string) => { + if (message && !dialog) { + dialog = createDialog(message); + } + }; + + const p = task({ + report: progress => { + updateDialog(progress.message); + } + }); + + p.finally(() => { + dispose(disposables); + }); + + return p; + } } registerSingleton(IProgressService2, ProgressService2, true); From aaee57e128d36de03b4eb07c4b07257ea890424b Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 11 Apr 2019 15:57:31 -0700 Subject: [PATCH 21/48] vscode-xterm@3.13.0-beta3 Fixes #69603 --- package.json | 8 ++++---- yarn.lock | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index af7e321e6f2..2fae932a2b5 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ "vscode-ripgrep": "^1.2.5", "vscode-sqlite3": "4.0.7", "vscode-textmate": "^4.0.1", - "vscode-xterm": "3.13.0-beta2", + "vscode-xterm": "3.13.0-beta3", "yauzl": "^2.9.1", "yazl": "^2.4.3" }, @@ -85,12 +85,12 @@ "gulp-atom-electron": "^1.20.0", "gulp-azure-storage": "^0.10.0", "gulp-buffer": "0.0.2", - "gulp-gunzip": "^1.0.0", "gulp-concat": "^2.6.1", "gulp-cssnano": "^2.1.3", "gulp-eslint": "^5.0.0", "gulp-filter": "^5.1.0", "gulp-flatmap": "^1.0.2", + "gulp-gunzip": "^1.0.0", "gulp-json-editor": "^2.5.0", "gulp-plumber": "^1.2.0", "gulp-remote-src": "^0.4.4", @@ -146,10 +146,10 @@ "url": "https://github.com/Microsoft/vscode/issues" }, "optionalDependencies": { - "vscode-windows-registry": "1.0.1", "vscode-windows-ca-certs": "0.1.0", + "vscode-windows-registry": "1.0.1", "windows-foreground-love": "0.1.0", "windows-mutex": "0.2.1", "windows-process-tree": "0.2.3" } -} \ No newline at end of file +} diff --git a/yarn.lock b/yarn.lock index f92d2434817..86a0865607c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9541,10 +9541,10 @@ vscode-windows-registry@1.0.1: dependencies: nan "^2.12.1" -vscode-xterm@3.13.0-beta2: - version "3.13.0-beta2" - resolved "https://registry.yarnpkg.com/vscode-xterm/-/vscode-xterm-3.13.0-beta2.tgz#4517a96ef30d8a8d6f27c60bfc374a405811ee6e" - integrity sha512-9iu3oxpFbyUzsAPYeipMSaI7I/nY4WHlpq2kJXXzibZAO9l7pVFBxFR9H0gfDBVn1+fMJsLIzRWGX9lKC83lfQ== +vscode-xterm@3.13.0-beta3: + version "3.13.0-beta3" + resolved "https://registry.yarnpkg.com/vscode-xterm/-/vscode-xterm-3.13.0-beta3.tgz#ab642ed77df07c2adfca7b15ae39c18328db3fc6" + integrity sha512-XvgD/P6CCV0+79UYM7CEL6Ziv2RiDopI3Wa1hIm3Dm8InWxkl3QwykINlempMNub+r0gwVwLKSQYr+Q/jg1IAw== vso-node-api@6.1.2-preview: version "6.1.2-preview" From f635233740f2bb44d9e4663f4152f1980ce0bb2b Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 11 Apr 2019 15:24:03 -0700 Subject: [PATCH 22/48] Check in stubbed out smart select support for js/ts For https://github.com/Microsoft/TypeScript/issues/29071 This require upstream TS support. Check in experimental support so that TS team can test the ux of this feature --- .../src/features/smartSelect.ts | 57 +++++++++++++++++++ .../src/languageProvider.ts | 1 + .../src/typescriptService.ts | 12 ++++ .../src/utils/api.ts | 1 + 4 files changed, 71 insertions(+) create mode 100644 extensions/typescript-language-features/src/features/smartSelect.ts diff --git a/extensions/typescript-language-features/src/features/smartSelect.ts b/extensions/typescript-language-features/src/features/smartSelect.ts new file mode 100644 index 00000000000..a9a0370bee9 --- /dev/null +++ b/extensions/typescript-language-features/src/features/smartSelect.ts @@ -0,0 +1,57 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as vscode from 'vscode'; +import * as Proto from '../protocol'; +import { ITypeScriptServiceClient } from '../typescriptService'; +import API from '../utils/api'; +import { VersionDependentRegistration } from '../utils/dependentRegistration'; +import * as typeConverters from '../utils/typeConverters'; + +class SmartSelection implements vscode.SelectionRangeProvider { + public static readonly minVersion = API.v350; + + public constructor( + private readonly client: ITypeScriptServiceClient + ) { } + + public async provideSelectionRanges( + document: vscode.TextDocument, + positions: vscode.Position[], + token: vscode.CancellationToken, + ): Promise { + const file = this.client.toOpenedFilePath(document); + if (!file) { + return undefined; + } + + const args: Proto.FileRequestArgs & { locations: Proto.Location[] } = { + file, + locations: positions.map(typeConverters.Position.toLocation) + }; + const response = await this.client.execute('selectionRange', args, token); + if (response.type !== 'response' || !response.body) { + return undefined; + } + return response.body.map(SmartSelection.convertSelectionRange); + } + + private static convertSelectionRange( + selectionRange: Proto.SelectionRange + ): vscode.SelectionRange { + return new vscode.SelectionRange( + typeConverters.Range.fromTextSpan(selectionRange.textSpan), + selectionRange.parent ? SmartSelection.convertSelectionRange(selectionRange.parent) : undefined, + ); + } +} + +export function register( + selector: vscode.DocumentSelector, + client: ITypeScriptServiceClient, +) { + return new VersionDependentRegistration(client, SmartSelection.minVersion, () => + vscode.languages.registerSelectionRangeProvider(selector, new SmartSelection(client))); +} \ No newline at end of file diff --git a/extensions/typescript-language-features/src/languageProvider.ts b/extensions/typescript-language-features/src/languageProvider.ts index 84dbb8e946d..28deb8c67f0 100644 --- a/extensions/typescript-language-features/src/languageProvider.ts +++ b/extensions/typescript-language-features/src/languageProvider.ts @@ -73,6 +73,7 @@ export default class LanguageProvider extends Disposable { this._register((await import('./features/references')).register(selector, this.client)); this._register((await import('./features/referencesCodeLens')).register(selector, this.description.id, this.client, cachedResponse)); this._register((await import('./features/rename')).register(selector, this.client, this.fileConfigurationManager)); + this._register((await import('./features/smartSelect')).register(selector, this.client)); this._register((await import('./features/signatureHelp')).register(selector, this.client)); this._register((await import('./features/tagClosing')).register(selector, this.description.id, this.client)); this._register((await import('./features/typeDefinitions')).register(selector, this.client)); diff --git a/extensions/typescript-language-features/src/typescriptService.ts b/extensions/typescript-language-features/src/typescriptService.ts index 277d6e3f47c..32ed3a60060 100644 --- a/extensions/typescript-language-features/src/typescriptService.ts +++ b/extensions/typescript-language-features/src/typescriptService.ts @@ -11,6 +11,17 @@ import { TypeScriptServiceConfiguration } from './utils/configuration'; import Logger from './utils/logger'; import { PluginManager } from './utils/plugins'; +declare module './protocol' { + interface SelectionRange { + textSpan: Proto.TextSpan; + parent?: SelectionRange; + } + + interface SelectionRangeResponse extends Proto.Response { + body?: ReadonlyArray; + } +} + export namespace ServerResponse { export class Cancelled { @@ -54,6 +65,7 @@ export interface TypeScriptRequestTypes { 'quickinfo': [Proto.FileLocationRequestArgs, Proto.QuickInfoResponse]; 'references': [Proto.FileLocationRequestArgs, Proto.ReferencesResponse]; 'rename': [Proto.RenameRequestArgs, Proto.RenameResponse]; + 'selectionRange': [Proto.FileRequestArgs & { locations: Proto.Location[] }, Proto.SelectionRangeResponse]; 'signatureHelp': [Proto.SignatureHelpRequestArgs, Proto.SignatureHelpResponse]; 'typeDefinition': [Proto.FileLocationRequestArgs, Proto.TypeDefinitionResponse]; } diff --git a/extensions/typescript-language-features/src/utils/api.ts b/extensions/typescript-language-features/src/utils/api.ts index a48a9f78f1f..9dcd05013db 100644 --- a/extensions/typescript-language-features/src/utils/api.ts +++ b/extensions/typescript-language-features/src/utils/api.ts @@ -36,6 +36,7 @@ export default class API { public static readonly v330 = API.fromSimpleString('3.3.0'); public static readonly v333 = API.fromSimpleString('3.3.3'); public static readonly v340 = API.fromSimpleString('3.4.0'); + public static readonly v350 = API.fromSimpleString('3.5.0'); public static fromVersionString(versionString: string): API { From c6a9536ed7ba33d304dad8c8593861ac16717063 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 11 Apr 2019 15:31:23 -0700 Subject: [PATCH 23/48] Add telemetry for how long completions take in js/ts We'd like to know the average time that it takes to return js/ts completions so that we can identify performance regressions. The time includes both the queuing time and the actual time spent executing the command against TS server --- .../src/features/completions.ts | 32 ++++++++++++++++--- .../src/languageProvider.ts | 2 +- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/extensions/typescript-language-features/src/features/completions.ts b/extensions/typescript-language-features/src/features/completions.ts index d5822dede34..6d9cb0498c7 100644 --- a/extensions/typescript-language-features/src/features/completions.ts +++ b/extensions/typescript-language-features/src/features/completions.ts @@ -7,7 +7,7 @@ import * as vscode from 'vscode'; import * as nls from 'vscode-nls'; import * as Proto from '../protocol'; import * as PConst from '../protocol.const'; -import { ITypeScriptServiceClient } from '../typescriptService'; +import { ITypeScriptServiceClient, ServerResponse } from '../typescriptService'; import API from '../utils/api'; import { nulToken } from '../utils/cancellation'; import { applyCodeAction } from '../utils/codeAction'; @@ -15,10 +15,11 @@ import { Command, CommandManager } from '../utils/commandManager'; import { ConfigurationDependentRegistration } from '../utils/dependentRegistration'; import { memoize } from '../utils/memoize'; import * as Previewer from '../utils/previewer'; +import { snippetForFunctionCall } from '../utils/snippetForFunctionCall'; +import TelemetryReporter from '../utils/telemetry'; import * as typeConverters from '../utils/typeConverters'; import TypingsStatus from '../utils/typingsStatus'; import FileConfigurationManager from './fileConfigurationManager'; -import { snippetForFunctionCall } from '../utils/snippetForFunctionCall'; const localize = nls.loadMessageBundle(); @@ -333,6 +334,7 @@ class TypeScriptCompletionItemProvider implements vscode.CompletionItemProvider private readonly typingsStatus: TypingsStatus, private readonly fileConfigurationManager: FileConfigurationManager, commandManager: CommandManager, + private readonly telemetryReporter: TelemetryReporter, onCompletionAccepted: (item: vscode.CompletionItem) => void ) { commandManager.register(new ApplyCompletionCodeActionCommand(this.client)); @@ -385,7 +387,28 @@ class TypeScriptCompletionItemProvider implements vscode.CompletionItemProvider let entries: ReadonlyArray; let metadata: any | undefined; if (this.client.apiVersion.gte(API.v300)) { - const response = await this.client.interruptGetErr(() => this.client.execute('completionInfo', args, token)); + const startTime = Date.now(); + let response: ServerResponse.Response | undefined; + try { + response = await this.client.interruptGetErr(() => this.client.execute('completionInfo', args, token)); + } finally { + const duration: number = Date.now() - startTime; + + /* __GDPR__ + "completions.execute" : { + "duration" : { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" }, + "type" : { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" }, + "${include}": [ + "${TypeScriptCommonProperties}", + ] + } + */ + this.telemetryReporter.logTelemetry('completions.execute', { + duration: duration + '', + type: response ? response.type : 'unknown' + }); + } + if (response.type !== 'response' || !response.body) { return null; } @@ -677,10 +700,11 @@ export function register( typingsStatus: TypingsStatus, fileConfigurationManager: FileConfigurationManager, commandManager: CommandManager, + telemetryReporter: TelemetryReporter, onCompletionAccepted: (item: vscode.CompletionItem) => void ) { return new ConfigurationDependentRegistration(modeId, 'suggest.enabled', () => vscode.languages.registerCompletionItemProvider(selector, - new TypeScriptCompletionItemProvider(client, modeId, typingsStatus, fileConfigurationManager, commandManager, onCompletionAccepted), + new TypeScriptCompletionItemProvider(client, modeId, typingsStatus, fileConfigurationManager, commandManager, telemetryReporter, onCompletionAccepted), ...TypeScriptCompletionItemProvider.triggerCharacters)); } diff --git a/extensions/typescript-language-features/src/languageProvider.ts b/extensions/typescript-language-features/src/languageProvider.ts index 28deb8c67f0..4a615d31dad 100644 --- a/extensions/typescript-language-features/src/languageProvider.ts +++ b/extensions/typescript-language-features/src/languageProvider.ts @@ -55,7 +55,7 @@ export default class LanguageProvider extends Disposable { const cachedResponse = new CachedResponse(); - this._register((await import('./features/completions')).register(selector, this.description.id, this.client, this.typingsStatus, this.fileConfigurationManager, this.commandManager, this.onCompletionAccepted)); + this._register((await import('./features/completions')).register(selector, this.description.id, this.client, this.typingsStatus, this.fileConfigurationManager, this.commandManager, this.telemetryReporter, this.onCompletionAccepted)); this._register((await import('./features/definitions')).register(selector, this.client)); this._register((await import('./features/directiveCommentCompletions')).register(selector, this.client)); this._register((await import('./features/documentHighlight')).register(selector, this.client)); From 9d43bdac05d51cf4fd94407bdb01c5c4e4c19584 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 11 Apr 2019 15:57:49 -0700 Subject: [PATCH 24/48] Register features with Promise.all instead of sequentially --- .../src/languageProvider.ts | 46 ++++++++++--------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/extensions/typescript-language-features/src/languageProvider.ts b/extensions/typescript-language-features/src/languageProvider.ts index 4a615d31dad..4210ba2ba20 100644 --- a/extensions/typescript-language-features/src/languageProvider.ts +++ b/extensions/typescript-language-features/src/languageProvider.ts @@ -55,28 +55,30 @@ export default class LanguageProvider extends Disposable { const cachedResponse = new CachedResponse(); - this._register((await import('./features/completions')).register(selector, this.description.id, this.client, this.typingsStatus, this.fileConfigurationManager, this.commandManager, this.telemetryReporter, this.onCompletionAccepted)); - this._register((await import('./features/definitions')).register(selector, this.client)); - this._register((await import('./features/directiveCommentCompletions')).register(selector, this.client)); - this._register((await import('./features/documentHighlight')).register(selector, this.client)); - this._register((await import('./features/documentSymbol')).register(selector, this.client, cachedResponse)); - this._register((await import('./features/folding')).register(selector, this.client)); - this._register((await import('./features/formatting')).register(selector, this.description.id, this.client, this.fileConfigurationManager)); - this._register((await import('./features/hover')).register(selector, this.client)); - this._register((await import('./features/implementations')).register(selector, this.client)); - this._register((await import('./features/implementationsCodeLens')).register(selector, this.description.id, this.client, cachedResponse)); - this._register((await import('./features/jsDocCompletions')).register(selector, this.description.id, this.client)); - this._register((await import('./features/organizeImports')).register(selector, this.client, this.commandManager, this.fileConfigurationManager, this.telemetryReporter)); - this._register((await import('./features/quickFix')).register(selector, this.client, this.fileConfigurationManager, this.commandManager, this.client.diagnosticsManager, this.telemetryReporter)); - this._register((await import('./features/fixAll')).register(selector, this.client, this.fileConfigurationManager, this.client.diagnosticsManager)); - this._register((await import('./features/refactor')).register(selector, this.client, this.fileConfigurationManager, this.commandManager, this.telemetryReporter)); - this._register((await import('./features/references')).register(selector, this.client)); - this._register((await import('./features/referencesCodeLens')).register(selector, this.description.id, this.client, cachedResponse)); - this._register((await import('./features/rename')).register(selector, this.client, this.fileConfigurationManager)); - this._register((await import('./features/smartSelect')).register(selector, this.client)); - this._register((await import('./features/signatureHelp')).register(selector, this.client)); - this._register((await import('./features/tagClosing')).register(selector, this.description.id, this.client)); - this._register((await import('./features/typeDefinitions')).register(selector, this.client)); + await Promise.all([ + import('./features/completions').then(provider => this._register(provider.register(selector, this.description.id, this.client, this.typingsStatus, this.fileConfigurationManager, this.commandManager, this.telemetryReporter, this.onCompletionAccepted))), + import('./features/definitions').then(provider => this._register(provider.register(selector, this.client))), + import('./features/directiveCommentCompletions').then(provider => this._register(provider.register(selector, this.client))), + import('./features/documentHighlight').then(provider => this._register(provider.register(selector, this.client))), + import('./features/documentSymbol').then(provider => this._register(provider.register(selector, this.client, cachedResponse))), + import('./features/folding').then(provider => this._register(provider.register(selector, this.client))), + import('./features/formatting').then(provider => this._register(provider.register(selector, this.description.id, this.client, this.fileConfigurationManager))), + import('./features/hover').then(provider => this._register(provider.register(selector, this.client))), + import('./features/implementations').then(provider => this._register(provider.register(selector, this.client))), + import('./features/implementationsCodeLens').then(provider => this._register(provider.register(selector, this.description.id, this.client, cachedResponse))), + import('./features/jsDocCompletions').then(provider => this._register(provider.register(selector, this.description.id, this.client))), + import('./features/organizeImports').then(provider => this._register(provider.register(selector, this.client, this.commandManager, this.fileConfigurationManager, this.telemetryReporter))), + import('./features/quickFix').then(provider => this._register(provider.register(selector, this.client, this.fileConfigurationManager, this.commandManager, this.client.diagnosticsManager, this.telemetryReporter))), + import('./features/fixAll').then(provider => this._register(provider.register(selector, this.client, this.fileConfigurationManager, this.client.diagnosticsManager))), + import('./features/refactor').then(provider => this._register(provider.register(selector, this.client, this.fileConfigurationManager, this.commandManager, this.telemetryReporter))), + import('./features/references').then(provider => this._register(provider.register(selector, this.client))), + import('./features/referencesCodeLens').then(provider => this._register(provider.register(selector, this.description.id, this.client, cachedResponse))), + import('./features/rename').then(provider => this._register(provider.register(selector, this.client, this.fileConfigurationManager))), + import('./features/smartSelect').then(provider => this._register(provider.register(selector, this.client))), + import('./features/signatureHelp').then(provider => this._register(provider.register(selector, this.client))), + import('./features/tagClosing').then(provider => this._register(provider.register(selector, this.description.id, this.client))), + import('./features/typeDefinitions').then(provider => this._register(provider.register(selector, this.client))), + ]); } private configurationChanged(): void { From 222e2798ffbc936aa236068bf5beb4116d9ba3bf Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 11 Apr 2019 16:12:29 -0700 Subject: [PATCH 25/48] Move min versions into jt/ts feature providers --- .../src/features/directiveCommentCompletions.ts | 4 +++- .../typescript-language-features/src/features/folding.ts | 4 +++- .../src/features/implementations.ts | 4 +++- .../src/features/implementationsCodeLens.ts | 3 ++- .../src/features/organizeImports.ts | 4 +++- .../typescript-language-features/src/features/quickFix.ts | 3 ++- .../typescript-language-features/src/features/refactor.ts | 4 +++- .../src/features/referencesCodeLens.ts | 3 ++- .../typescript-language-features/src/features/tagClosing.ts | 3 ++- .../src/features/typeDefinitions.ts | 4 +++- .../src/features/updatePathsOnRename.ts | 4 +++- 11 files changed, 29 insertions(+), 11 deletions(-) diff --git a/extensions/typescript-language-features/src/features/directiveCommentCompletions.ts b/extensions/typescript-language-features/src/features/directiveCommentCompletions.ts index 7b30b68a658..0b1ddeca929 100644 --- a/extensions/typescript-language-features/src/features/directiveCommentCompletions.ts +++ b/extensions/typescript-language-features/src/features/directiveCommentCompletions.ts @@ -36,6 +36,8 @@ const directives: Directive[] = [ ]; class DirectiveCommentCompletionProvider implements vscode.CompletionItemProvider { + public static readonly minVersion = API.v230; + constructor( private readonly client: ITypeScriptServiceClient, ) { } @@ -69,7 +71,7 @@ export function register( selector: vscode.DocumentSelector, client: ITypeScriptServiceClient, ) { - return new VersionDependentRegistration(client, API.v230, () => { + return new VersionDependentRegistration(client, DirectiveCommentCompletionProvider.minVersion, () => { return vscode.languages.registerCompletionItemProvider(selector, new DirectiveCommentCompletionProvider(client), '@'); diff --git a/extensions/typescript-language-features/src/features/folding.ts b/extensions/typescript-language-features/src/features/folding.ts index 228cb744a53..a00a2db5f00 100644 --- a/extensions/typescript-language-features/src/features/folding.ts +++ b/extensions/typescript-language-features/src/features/folding.ts @@ -11,6 +11,8 @@ import { VersionDependentRegistration } from '../utils/dependentRegistration'; import * as typeConverters from '../utils/typeConverters'; class TypeScriptFoldingProvider implements vscode.FoldingRangeProvider { + public static readonly minVersion = API.v280; + public constructor( private readonly client: ITypeScriptServiceClient ) { } @@ -75,7 +77,7 @@ export function register( selector: vscode.DocumentSelector, client: ITypeScriptServiceClient, ): vscode.Disposable { - return new VersionDependentRegistration(client, API.v280, () => { + return new VersionDependentRegistration(client, TypeScriptFoldingProvider.minVersion, () => { return vscode.languages.registerFoldingRangeProvider(selector, new TypeScriptFoldingProvider(client)); }); diff --git a/extensions/typescript-language-features/src/features/implementations.ts b/extensions/typescript-language-features/src/features/implementations.ts index d750587ea8d..7b7dc130175 100644 --- a/extensions/typescript-language-features/src/features/implementations.ts +++ b/extensions/typescript-language-features/src/features/implementations.ts @@ -10,6 +10,8 @@ import { VersionDependentRegistration } from '../utils/dependentRegistration'; import DefinitionProviderBase from './definitionProviderBase'; class TypeScriptImplementationProvider extends DefinitionProviderBase implements vscode.ImplementationProvider { + public static readonly minVersion = API.v220; + public provideImplementation(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): Promise { return this.getSymbolLocations('implementation', document, position, token); } @@ -19,7 +21,7 @@ export function register( selector: vscode.DocumentSelector, client: ITypeScriptServiceClient, ) { - return new VersionDependentRegistration(client, API.v220, () => { + return new VersionDependentRegistration(client, TypeScriptImplementationProvider.minVersion, () => { return vscode.languages.registerImplementationProvider(selector, new TypeScriptImplementationProvider(client)); }); diff --git a/extensions/typescript-language-features/src/features/implementationsCodeLens.ts b/extensions/typescript-language-features/src/features/implementationsCodeLens.ts index e2f7dc2b531..63cfc6222d9 100644 --- a/extensions/typescript-language-features/src/features/implementationsCodeLens.ts +++ b/extensions/typescript-language-features/src/features/implementationsCodeLens.ts @@ -17,6 +17,7 @@ import * as typeConverters from '../utils/typeConverters'; const localize = nls.loadMessageBundle(); export default class TypeScriptImplementationsCodeLensProvider extends TypeScriptBaseCodeLensProvider { + public static readonly minVersion = API.v220; public async resolveCodeLens( inputCodeLens: vscode.CodeLens, @@ -95,7 +96,7 @@ export function register( client: ITypeScriptServiceClient, cachedResponse: CachedResponse, ) { - return new VersionDependentRegistration(client, API.v220, () => + return new VersionDependentRegistration(client, TypeScriptImplementationsCodeLensProvider.minVersion, () => new ConfigurationDependentRegistration(modeId, 'implementationsCodeLens.enabled', () => { return vscode.languages.registerCodeLensProvider(selector, new TypeScriptImplementationsCodeLensProvider(client, cachedResponse)); diff --git a/extensions/typescript-language-features/src/features/organizeImports.ts b/extensions/typescript-language-features/src/features/organizeImports.ts index aeb1efae11f..cbae287db1e 100644 --- a/extensions/typescript-language-features/src/features/organizeImports.ts +++ b/extensions/typescript-language-features/src/features/organizeImports.ts @@ -57,6 +57,8 @@ class OrganizeImportsCommand implements Command { } export class OrganizeImportsCodeActionProvider implements vscode.CodeActionProvider { + public static readonly minVersion = API.v280; + public constructor( private readonly client: ITypeScriptServiceClient, commandManager: CommandManager, @@ -103,7 +105,7 @@ export function register( fileConfigurationManager: FileConfigurationManager, telemetryReporter: TelemetryReporter, ) { - return new VersionDependentRegistration(client, API.v280, () => { + return new VersionDependentRegistration(client, OrganizeImportsCodeActionProvider.minVersion, () => { const organizeImportsProvider = new OrganizeImportsCodeActionProvider(client, commandManager, fileConfigurationManager, telemetryReporter); return vscode.languages.registerCodeActionsProvider(selector, organizeImportsProvider, diff --git a/extensions/typescript-language-features/src/features/quickFix.ts b/extensions/typescript-language-features/src/features/quickFix.ts index 91c3f3b3265..8972df52185 100644 --- a/extensions/typescript-language-features/src/features/quickFix.ts +++ b/extensions/typescript-language-features/src/features/quickFix.ts @@ -174,6 +174,7 @@ class SupportedCodeActionProvider { } class TypeScriptQuickFixProvider implements vscode.CodeActionProvider { + public static readonly minVersion = API.v213; public static readonly metadata: vscode.CodeActionProviderMetadata = { providedCodeActionKinds: [vscode.CodeActionKind.QuickFix] @@ -326,7 +327,7 @@ export function register( diagnosticsManager: DiagnosticsManager, telemetryReporter: TelemetryReporter ) { - return new VersionDependentRegistration(client, API.v213, () => + return new VersionDependentRegistration(client, TypeScriptQuickFixProvider.minVersion, () => vscode.languages.registerCodeActionsProvider(selector, new TypeScriptQuickFixProvider(client, fileConfigurationManager, commandManager, diagnosticsManager, telemetryReporter), TypeScriptQuickFixProvider.metadata)); diff --git a/extensions/typescript-language-features/src/features/refactor.ts b/extensions/typescript-language-features/src/features/refactor.ts index d687fd61e6e..a3a7bb629e7 100644 --- a/extensions/typescript-language-features/src/features/refactor.ts +++ b/extensions/typescript-language-features/src/features/refactor.ts @@ -112,6 +112,8 @@ class SelectRefactorCommand implements Command { } class TypeScriptRefactorProvider implements vscode.CodeActionProvider { + public static readonly minVersion = API.v240; + private static readonly extractFunctionKind = vscode.CodeActionKind.RefactorExtract.append('function'); private static readonly extractConstantKind = vscode.CodeActionKind.RefactorExtract.append('constant'); private static readonly moveKind = vscode.CodeActionKind.Refactor.append('move'); @@ -236,7 +238,7 @@ export function register( commandManager: CommandManager, telemetryReporter: TelemetryReporter, ) { - return new VersionDependentRegistration(client, API.v240, () => { + return new VersionDependentRegistration(client, TypeScriptRefactorProvider.minVersion, () => { return vscode.languages.registerCodeActionsProvider(selector, new TypeScriptRefactorProvider(client, formattingOptionsManager, commandManager, telemetryReporter), TypeScriptRefactorProvider.metadata); diff --git a/extensions/typescript-language-features/src/features/referencesCodeLens.ts b/extensions/typescript-language-features/src/features/referencesCodeLens.ts index 7c256e3064f..ff09a9a4346 100644 --- a/extensions/typescript-language-features/src/features/referencesCodeLens.ts +++ b/extensions/typescript-language-features/src/features/referencesCodeLens.ts @@ -17,6 +17,7 @@ import { CachedResponse } from '../tsServer/cachedResponse'; const localize = nls.loadMessageBundle(); class TypeScriptReferencesCodeLensProvider extends TypeScriptBaseCodeLensProvider { + public static readonly minVersion = API.v206; public async resolveCodeLens(inputCodeLens: vscode.CodeLens, token: vscode.CancellationToken): Promise { const codeLens = inputCodeLens as ReferencesCodeLens; @@ -98,7 +99,7 @@ export function register( client: ITypeScriptServiceClient, cachedResponse: CachedResponse, ) { - return new VersionDependentRegistration(client, API.v206, () => + return new VersionDependentRegistration(client, TypeScriptReferencesCodeLensProvider.minVersion, () => new ConfigurationDependentRegistration(modeId, 'referencesCodeLens.enabled', () => { return vscode.languages.registerCodeLensProvider(selector, new TypeScriptReferencesCodeLensProvider(client, cachedResponse)); diff --git a/extensions/typescript-language-features/src/features/tagClosing.ts b/extensions/typescript-language-features/src/features/tagClosing.ts index 34ddd2c0285..c8db74597e5 100644 --- a/extensions/typescript-language-features/src/features/tagClosing.ts +++ b/extensions/typescript-language-features/src/features/tagClosing.ts @@ -12,6 +12,7 @@ import { Disposable } from '../utils/dispose'; import * as typeConverters from '../utils/typeConverters'; class TagClosing extends Disposable { + public static readonly minVersion = API.v300; private _disposed = false; private _timeout: NodeJS.Timer | undefined = undefined; @@ -167,7 +168,7 @@ export function register( modeId: string, client: ITypeScriptServiceClient, ) { - return new VersionDependentRegistration(client, API.v300, () => + return new VersionDependentRegistration(client, TagClosing.minVersion, () => new ConfigurationDependentRegistration(modeId, 'autoClosingTags', () => new ActiveDocumentDependentRegistration(selector, () => new TagClosing(client)))); diff --git a/extensions/typescript-language-features/src/features/typeDefinitions.ts b/extensions/typescript-language-features/src/features/typeDefinitions.ts index 45d89aeaedd..86510f65189 100644 --- a/extensions/typescript-language-features/src/features/typeDefinitions.ts +++ b/extensions/typescript-language-features/src/features/typeDefinitions.ts @@ -10,6 +10,8 @@ import { VersionDependentRegistration } from '../utils/dependentRegistration'; import DefinitionProviderBase from './definitionProviderBase'; export default class TypeScriptTypeDefinitionProvider extends DefinitionProviderBase implements vscode.TypeDefinitionProvider { + public static readonly minVersion = API.v213; + public provideTypeDefinition(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): Promise { return this.getSymbolLocations('typeDefinition', document, position, token); } @@ -19,7 +21,7 @@ export function register( selector: vscode.DocumentSelector, client: ITypeScriptServiceClient, ) { - return new VersionDependentRegistration(client, API.v213, () => { + return new VersionDependentRegistration(client, TypeScriptTypeDefinitionProvider.minVersion, () => { return vscode.languages.registerTypeDefinitionProvider(selector, new TypeScriptTypeDefinitionProvider(client)); }); diff --git a/extensions/typescript-language-features/src/features/updatePathsOnRename.ts b/extensions/typescript-language-features/src/features/updatePathsOnRename.ts index 18c58e73df3..c4c2e9ca135 100644 --- a/extensions/typescript-language-features/src/features/updatePathsOnRename.ts +++ b/extensions/typescript-language-features/src/features/updatePathsOnRename.ts @@ -40,6 +40,8 @@ enum UpdateImportsOnFileMoveSetting { } class UpdateImportsOnFileRenameHandler extends Disposable { + public static minVersion = API.v300; + public constructor( private readonly client: ITypeScriptServiceClient, private readonly fileConfigurationManager: FileConfigurationManager, @@ -233,6 +235,6 @@ export function register( fileConfigurationManager: FileConfigurationManager, handles: (uri: vscode.Uri) => Promise, ) { - return new VersionDependentRegistration(client, API.v300, () => + return new VersionDependentRegistration(client, UpdateImportsOnFileRenameHandler.minVersion, () => new UpdateImportsOnFileRenameHandler(client, fileConfigurationManager, handles)); } \ No newline at end of file From b7b9d3321a10f10cac083403519ccdfb93676054 Mon Sep 17 00:00:00 2001 From: Rachel Macfarlane Date: Thu, 11 Apr 2019 16:10:52 -0700 Subject: [PATCH 26/48] Add fallback script for ps --- build/gulpfile.vscode.js | 2 +- src/vs/base/node/ps.sh | 39 ++++++++++++++ src/vs/base/node/ps.ts | 106 +++++++++++++++++++++++---------------- 3 files changed, 102 insertions(+), 45 deletions(-) create mode 100755 src/vs/base/node/ps.sh diff --git a/build/gulpfile.vscode.js b/build/gulpfile.vscode.js index 2e077e83e4b..5d5d7ed7893 100644 --- a/build/gulpfile.vscode.js +++ b/build/gulpfile.vscode.js @@ -66,7 +66,7 @@ const vscodeResources = [ '!out-build/vs/code/browser/**/*.html', 'out-build/vs/base/common/performance.js', 'out-build/vs/base/node/languagePacks.js', - 'out-build/vs/base/node/{stdForkStart.js,terminateProcess.sh,cpuUsage.sh}', + 'out-build/vs/base/node/{stdForkStart.js,terminateProcess.sh,cpuUsage.sh,ps.sh}', 'out-build/vs/base/browser/ui/octiconLabel/octicons/**', 'out-build/vs/workbench/browser/media/*-theme.css', 'out-build/vs/workbench/contrib/debug/**/*.json', diff --git a/src/vs/base/node/ps.sh b/src/vs/base/node/ps.sh new file mode 100755 index 00000000000..4fe31039c5a --- /dev/null +++ b/src/vs/base/node/ps.sh @@ -0,0 +1,39 @@ +#!/bin/sh +PAGESIZE=`getconf PAGESIZE`; +TOTAL_MEMORY=`cat /proc/meminfo | head -n 1 | awk '{print $2}'`; + +# Mimic the output of ps -ax -o pid=,ppid=,pcpu=,pmem=,command= +# Read all numeric subdirectories in /proc +for pid in `cd /proc && ls -d [0-9]*` + do { + if [ -e /proc/$pid/stat ] + then + echo $pid; + + # ppid is the word at index 4 in the stat file for the process + awk '{print $4}' /proc/$pid/stat; + + # pcpu - calculation will be done later, this is a placeholder value + echo "0.0" + + # pmem - ratio of the process's working set size to total memory. + # use the page size to convert to bytes, total memory is in KB + # multiplied by 100 to get percentage, extra 10 to be able to move + # the decimal over by one place + RESIDENT_SET_SIZE=`awk '{print $24}' /proc/$pid/stat`; + PERCENT_MEMORY=$(((1000 * $PAGESIZE * $RESIDENT_SET_SIZE) / ($TOTAL_MEMORY * 1024))); + if [ $PERCENT_MEMORY -lt 10 ] + then + # replace the last character with 0. the last character + echo $PERCENT_MEMORY | sed 's/.$/0.&/'; #pmem + else + # insert . before the last character + echo $PERCENT_MEMORY | sed 's/.$/.&/'; + fi + + # cmdline + xargs -0 < /proc/$pid/cmdline; + fi + } | tr "\n" "\t"; # Replace newlines with tab so that all info for a process is shown on one line + echo; # But add new lines between processes +done diff --git a/src/vs/base/node/ps.ts b/src/vs/base/node/ps.ts index a3c32449255..55c3a73da57 100644 --- a/src/vs/base/node/ps.ts +++ b/src/vs/base/node/ps.ts @@ -14,6 +14,7 @@ export function listProcesses(rootPid: number): Promise { let rootItem: ProcessItem | undefined; const map = new Map(); + function addToTree(pid: number, ppid: number, cmd: string, load: number, mem: number) { const parent = map.get(ppid); @@ -162,66 +163,72 @@ export function listProcesses(rootPid: number): Promise { }, windowsProcessTree.ProcessDataFlag.CommandLine | windowsProcessTree.ProcessDataFlag.Memory); }); } else { // OS X & Linux + function calculateLinuxCpuUsage() { + // Flatten rootItem to get a list of all VSCode processes + let processes = [rootItem]; + const pids: number[] = []; + while (processes.length) { + const process = processes.shift(); + if (process) { + pids.push(process.pid); + if (process.children) { + processes = processes.concat(process.children); + } + } + } + + // The cpu usage value reported on Linux is the average over the process lifetime, + // recalculate the usage over a one second interval + // JSON.stringify is needed to escape spaces, https://github.com/nodejs/node/issues/6803 + let cmd = JSON.stringify(getPathFromAmdModule(require, 'vs/base/node/cpuUsage.sh')); + cmd += ' ' + pids.join(' '); + + exec(cmd, {}, (err, stdout, stderr) => { + if (err || stderr) { + reject(err || new Error(stderr.toString())); + } else { + const cpuUsage = stdout.toString().split('\n'); + for (let i = 0; i < pids.length; i++) { + const processInfo = map.get(pids[i])!; + processInfo.load = parseFloat(cpuUsage[i]); + } + + resolve(rootItem); + } + }); + } + exec('which ps', {}, (err, stdout, stderr) => { if (err || stderr) { - reject(err || new Error(stderr.toString())); + if (process.platform !== 'linux') { + reject(err || new Error(stderr.toString())); + } else { + const cmd = JSON.stringify(getPathFromAmdModule(require, 'vs/base/node/ps.sh')); + exec(cmd, {}, (err, stdout, stderr) => { + if (err || stderr) { + reject(err || new Error(stderr.toString())); + } else { + parsePsOutput(stdout, addToTree); + calculateLinuxCpuUsage(); + } + }); + } } else { const ps = stdout.toString().trim(); const args = '-ax -o pid=,ppid=,pcpu=,pmem=,command='; - const PID_CMD = /^\s*([0-9]+)\s+([0-9]+)\s+([0-9]+\.[0-9]+)\s+([0-9]+\.[0-9]+)\s+(.+)$/; // Set numeric locale to ensure '.' is used as the decimal separator exec(`${ps} ${args}`, { maxBuffer: 1000 * 1024, env: { LC_NUMERIC: 'en_US.UTF-8' } }, (err, stdout, stderr) => { - if (err || stderr) { reject(err || new Error(stderr.toString())); } else { - - const lines = stdout.toString().split('\n'); - for (const line of lines) { - const matches = PID_CMD.exec(line.trim()); - if (matches && matches.length === 6) { - addToTree(parseInt(matches[1]), parseInt(matches[2]), matches[5], parseFloat(matches[3]), parseFloat(matches[4])); - } - } + parsePsOutput(stdout, addToTree); if (process.platform === 'linux') { - // Flatten rootItem to get a list of all VSCode processes - let processes = [rootItem]; - const pids: number[] = []; - while (processes.length) { - const process = processes.shift(); - if (process) { - pids.push(process.pid); - if (process.children) { - processes = processes.concat(process.children); - } - } - } - - // The cpu usage value reported on Linux is the average over the process lifetime, - // recalculate the usage over a one second interval - // JSON.stringify is needed to escape spaces, https://github.com/nodejs/node/issues/6803 - let cmd = JSON.stringify(getPathFromAmdModule(require, 'vs/base/node/cpuUsage.sh')); - cmd += ' ' + pids.join(' '); - - exec(cmd, {}, (err, stdout, stderr) => { - if (err || stderr) { - reject(err || new Error(stderr.toString())); - } else { - const cpuUsage = stdout.toString().split('\n'); - for (let i = 0; i < pids.length; i++) { - const processInfo = map.get(pids[i])!; - processInfo.load = parseFloat(cpuUsage[i]); - } - - resolve(rootItem); - } - }); + calculateLinuxCpuUsage(); } else { resolve(rootItem); } - } }); } @@ -229,3 +236,14 @@ export function listProcesses(rootPid: number): Promise { } }); } + +function parsePsOutput(stdout: string, addToTree: (pid: number, ppid: number, cmd: string, load: number, mem: number) => void): void { + const PID_CMD = /^\s*([0-9]+)\s+([0-9]+)\s+([0-9]+\.[0-9]+)\s+([0-9]+\.[0-9]+)\s+(.+)$/; + const lines = stdout.toString().split('\n'); + for (const line of lines) { + const matches = PID_CMD.exec(line.trim()); + if (matches && matches.length === 6) { + addToTree(parseInt(matches[1]), parseInt(matches[2]), matches[5], parseFloat(matches[3]), parseFloat(matches[4])); + } + } +} \ No newline at end of file From 67c28b3f0382cb580292655e83f9d8584eef90c2 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Thu, 11 Apr 2019 17:25:56 -0700 Subject: [PATCH 27/48] move vscode.env.uriScheme to stable --- src/vs/vscode.d.ts | 5 +++++ src/vs/vscode.proposed.d.ts | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/vs/vscode.d.ts b/src/vs/vscode.d.ts index 81b5fce5fcd..9fb2ae1d32b 100644 --- a/src/vs/vscode.d.ts +++ b/src/vs/vscode.d.ts @@ -5973,6 +5973,11 @@ declare module 'vscode' { */ export const appRoot: string; + /** + * The custom uri scheme the editor registers to in the operating system. + */ + export const uriScheme: string; + /** * Represents the preferred user-language, like `de-CH`, `fr`, or `en-US`. */ diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 38b3150b24f..52ab98bc4aa 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -616,11 +616,6 @@ declare module 'vscode' { * An [event](#Event) that fires when the log level has changed. */ export const onDidChangeLogLevel: Event; - - /** - * The custom uri scheme the editor registers to in the operating system, like 'vscode', 'vscode-insiders'. - */ - export const uriScheme: string; } //#endregion From 1fd2993b540ccf11c34234774f7cc53825d60edf Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Fri, 12 Apr 2019 07:44:56 +0200 Subject: [PATCH 28/48] Fix #72185 --- extensions/git/package.json | 2 +- .../typescript-language-features/package.json | 4 +- .../common/configurationRegistry.ts | 10 +++ .../api/common/configurationExtensionPoint.ts | 13 +-- .../browser/configurationService.ts | 12 +-- .../configuration/common/configuration.ts | 2 +- .../common/configurationEditingService.ts | 9 ++ .../test/common/configurationModels.test.ts | 18 +++- .../configurationService.test.ts | 82 ++++++++++++++++++- 9 files changed, 133 insertions(+), 19 deletions(-) diff --git a/extensions/git/package.json b/extensions/git/package.json index 058fd6691a7..4395d306bb5 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -1031,7 +1031,7 @@ ], "markdownDescription": "%config.path%", "default": null, - "scope": "application" + "scope": "machine" }, "git.autoRepositoryDetection": { "type": [ diff --git a/extensions/typescript-language-features/package.json b/extensions/typescript-language-features/package.json index 89194ce1945..f5516fd5f98 100644 --- a/extensions/typescript-language-features/package.json +++ b/extensions/typescript-language-features/package.json @@ -83,7 +83,7 @@ ], "default": null, "description": "%typescript.npm%", - "scope": "application" + "scope": "machine" }, "typescript.check.npmIsInstalled": { "type": "boolean", @@ -129,7 +129,7 @@ }, "default": [], "description": "%typescript.tsserver.pluginPaths%", - "scope": "application" + "scope": "machine" }, "typescript.tsserver.trace": { "type": "string", diff --git a/src/vs/platform/configuration/common/configurationRegistry.ts b/src/vs/platform/configuration/common/configurationRegistry.ts index 2f787370ebe..19ca52ec2e4 100644 --- a/src/vs/platform/configuration/common/configurationRegistry.ts +++ b/src/vs/platform/configuration/common/configurationRegistry.ts @@ -84,6 +84,7 @@ export interface IConfigurationRegistry { export const enum ConfigurationScope { APPLICATION = 1, + MACHINE, WINDOW, RESOURCE, } @@ -116,6 +117,7 @@ export interface IDefaultConfigurationExtension { export const allSettings: { properties: {}, patternProperties: {} } = { properties: {}, patternProperties: {} }; export const applicationSettings: { properties: {}, patternProperties: {} } = { properties: {}, patternProperties: {} }; +export const machineSettings: { properties: {}, patternProperties: {} } = { properties: {}, patternProperties: {} }; export const windowSettings: { properties: {}, patternProperties: {} } = { properties: {}, patternProperties: {} }; export const resourceSettings: { properties: {}, patternProperties: {} } = { properties: {}, patternProperties: {} }; @@ -186,6 +188,9 @@ class ConfigurationRegistry implements IConfigurationRegistry { case ConfigurationScope.APPLICATION: delete applicationSettings.properties[key]; break; + case ConfigurationScope.MACHINE: + delete machineSettings.properties[key]; + break; case ConfigurationScope.WINDOW: delete windowSettings.properties[key]; break; @@ -334,6 +339,9 @@ class ConfigurationRegistry implements IConfigurationRegistry { case ConfigurationScope.APPLICATION: applicationSettings.properties[key] = properties[key]; break; + case ConfigurationScope.MACHINE: + machineSettings.properties[key] = properties[key]; + break; case ConfigurationScope.WINDOW: windowSettings.properties[key] = properties[key]; break; @@ -371,6 +379,7 @@ class ConfigurationRegistry implements IConfigurationRegistry { delete allSettings.patternProperties[this.overridePropertyPattern]; delete applicationSettings.patternProperties[this.overridePropertyPattern]; + delete machineSettings.patternProperties[this.overridePropertyPattern]; delete windowSettings.patternProperties[this.overridePropertyPattern]; delete resourceSettings.patternProperties[this.overridePropertyPattern]; @@ -378,6 +387,7 @@ class ConfigurationRegistry implements IConfigurationRegistry { allSettings.patternProperties[this.overridePropertyPattern] = patternProperties; applicationSettings.patternProperties[this.overridePropertyPattern] = patternProperties; + machineSettings.patternProperties[this.overridePropertyPattern] = patternProperties; windowSettings.patternProperties[this.overridePropertyPattern] = patternProperties; resourceSettings.patternProperties[this.overridePropertyPattern] = patternProperties; diff --git a/src/vs/workbench/api/common/configurationExtensionPoint.ts b/src/vs/workbench/api/common/configurationExtensionPoint.ts index 1a86479c17c..11459d62aee 100644 --- a/src/vs/workbench/api/common/configurationExtensionPoint.ts +++ b/src/vs/workbench/api/common/configurationExtensionPoint.ts @@ -35,16 +35,17 @@ const configurationEntrySchema: IJSONSchema = { properties: { isExecutable: { type: 'boolean', - deprecationMessage: 'This property is deprecated. Instead use `scope` property and set it to `application` value.' + deprecationMessage: 'This property is deprecated. Instead use `scope` property and set it to `machine` value.' }, scope: { type: 'string', - enum: ['application', 'window', 'resource'], + enum: ['application', 'machine', 'window', 'resource'], default: 'window', enumDescriptions: [ - nls.localize('scope.application.description', "Application specific configuration, which can be configured only in User settings."), - nls.localize('scope.window.description', "Window specific configuration, which can be configured in the User or Workspace settings."), - nls.localize('scope.resource.description', "Resource specific configuration, which can be configured in the User, Workspace or Folder settings.") + nls.localize('scope.application.description', "Application specific configuration, which can be configured only in application user settings."), + nls.localize('scope.machine.description', "Machine specific configuration, which can be configured only in user settings."), + nls.localize('scope.window.description', "Window specific configuration, which can be configured in the user or workspace settings."), + nls.localize('scope.resource.description', "Resource specific configuration, which can be configured in the wser, workspace or folder settings.") ], description: nls.localize('scope.description', "Scope in which the configuration is applicable. Available scopes are `window` and `resource`.") }, @@ -210,6 +211,8 @@ function validateProperties(configuration: IConfigurationNode, extension: IExten if (propertyConfiguration.scope) { if (propertyConfiguration.scope.toString() === 'application') { propertyConfiguration.scope = ConfigurationScope.APPLICATION; + } else if (propertyConfiguration.scope.toString() === 'machine') { + propertyConfiguration.scope = ConfigurationScope.MACHINE; } else if (propertyConfiguration.scope.toString() === 'resource') { propertyConfiguration.scope = ConfigurationScope.RESOURCE; } else { diff --git a/src/vs/workbench/services/configuration/browser/configurationService.ts b/src/vs/workbench/services/configuration/browser/configurationService.ts index efbd303489d..379261910a5 100644 --- a/src/vs/workbench/services/configuration/browser/configurationService.ts +++ b/src/vs/workbench/services/configuration/browser/configurationService.ts @@ -18,7 +18,7 @@ import { IConfigurationChangeEvent, ConfigurationTarget, IConfigurationOverrides import { Configuration, WorkspaceConfigurationChangeEvent, AllKeysConfigurationChangeEvent } from 'vs/workbench/services/configuration/common/configurationModels'; import { FOLDER_CONFIG_FOLDER_NAME, defaultSettingsSchemaId, userSettingsSchemaId, workspaceSettingsSchemaId, folderSettingsSchemaId, IConfigurationCache, IConfigurationFileService, machineSettingsSchemaId } from 'vs/workbench/services/configuration/common/configuration'; import { Registry } from 'vs/platform/registry/common/platform'; -import { IConfigurationRegistry, Extensions, allSettings, windowSettings, resourceSettings, applicationSettings } from 'vs/platform/configuration/common/configurationRegistry'; +import { IConfigurationRegistry, Extensions, allSettings, windowSettings, resourceSettings, applicationSettings, machineSettings } from 'vs/platform/configuration/common/configurationRegistry'; import { IWorkspaceIdentifier, isWorkspaceIdentifier, IStoredWorkspaceFolder, isStoredWorkspaceFolder, IWorkspaceFolderCreationData, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, IWorkspaceInitializationPayload, isSingleFolderWorkspaceInitializationPayload, ISingleFolderWorkspaceInitializationPayload, IEmptyWorkspaceInitializationPayload, useSlashForPath, getStoredWorkspaceFolder } from 'vs/platform/workspaces/common/workspaces'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ConfigurationEditingService } from 'vs/workbench/services/configuration/common/configurationEditingService'; @@ -503,16 +503,18 @@ export class WorkspaceService extends Disposable implements IConfigurationServic }; const allSettingsSchema: IJSONSchema = { properties: allSettings.properties, patternProperties: allSettings.patternProperties, additionalProperties: false, errorMessage: 'Unknown configuration setting' }; - const unsupportedApplicationSettings = convertToNotSuggestedProperties(applicationSettings.properties, localize('unsupportedApplicationSetting', "This setting can be applied only in User Settings")); - const workspaceSettingsSchema: IJSONSchema = { properties: { ...unsupportedApplicationSettings, ...windowSettings.properties, ...resourceSettings.properties }, patternProperties: allSettings.patternProperties, additionalProperties: false, errorMessage: 'Unknown configuration setting' }; + const unsupportedApplicationSettings = convertToNotSuggestedProperties(applicationSettings.properties, localize('unsupportedApplicationSetting', "This setting can be applied only in application user Settings")); + const unsupportedMachineSettings = convertToNotSuggestedProperties(machineSettings.properties, localize('unsupportedMachineSetting', "This setting can be applied only in user Settings")); + const machineSettingsSchema: IJSONSchema = { properties: { ...unsupportedApplicationSettings, ...windowSettings.properties, ...resourceSettings.properties }, patternProperties: allSettings.patternProperties, additionalProperties: false, errorMessage: 'Unknown configuration setting' }; + const workspaceSettingsSchema: IJSONSchema = { properties: { ...unsupportedApplicationSettings, ...unsupportedMachineSettings, ...windowSettings.properties, ...resourceSettings.properties }, patternProperties: allSettings.patternProperties, additionalProperties: false, errorMessage: 'Unknown configuration setting' }; jsonRegistry.registerSchema(defaultSettingsSchemaId, allSettingsSchema); jsonRegistry.registerSchema(userSettingsSchemaId, allSettingsSchema); - jsonRegistry.registerSchema(machineSettingsSchemaId, workspaceSettingsSchema); + jsonRegistry.registerSchema(machineSettingsSchemaId, machineSettingsSchema); if (WorkbenchState.WORKSPACE === this.getWorkbenchState()) { const unsupportedWindowSettings = convertToNotSuggestedProperties(windowSettings.properties, localize('unsupportedWindowSetting', "This setting cannot be applied now. It will be applied when you open this folder directly.")); - const folderSettingsSchema: IJSONSchema = { properties: { ...unsupportedApplicationSettings, ...unsupportedWindowSettings, ...resourceSettings.properties }, patternProperties: allSettings.patternProperties, additionalProperties: false, errorMessage: 'Unknown configuration setting' }; + const folderSettingsSchema: IJSONSchema = { properties: { ...unsupportedApplicationSettings, ...unsupportedMachineSettings, ...unsupportedWindowSettings, ...resourceSettings.properties }, patternProperties: allSettings.patternProperties, additionalProperties: false, errorMessage: 'Unknown configuration setting' }; jsonRegistry.registerSchema(workspaceSettingsSchemaId, workspaceSettingsSchema); jsonRegistry.registerSchema(folderSettingsSchemaId, folderSettingsSchema); } else { diff --git a/src/vs/workbench/services/configuration/common/configuration.ts b/src/vs/workbench/services/configuration/common/configuration.ts index 7c3a06db189..c8ec23ec441 100644 --- a/src/vs/workbench/services/configuration/common/configuration.ts +++ b/src/vs/workbench/services/configuration/common/configuration.ts @@ -20,7 +20,7 @@ export const workspaceSettingsSchemaId = 'vscode://schemas/settings/workspace'; export const folderSettingsSchemaId = 'vscode://schemas/settings/folder'; export const launchSchemaId = 'vscode://schemas/launch'; -export const MACHINE_SCOPES = [ConfigurationScope.WINDOW, ConfigurationScope.RESOURCE]; +export const MACHINE_SCOPES = [ConfigurationScope.MACHINE, ConfigurationScope.WINDOW, ConfigurationScope.RESOURCE]; export const WORKSPACE_SCOPES = [ConfigurationScope.WINDOW, ConfigurationScope.RESOURCE]; export const FOLDER_SCOPES = [ConfigurationScope.RESOURCE]; diff --git a/src/vs/workbench/services/configuration/common/configurationEditingService.ts b/src/vs/workbench/services/configuration/common/configurationEditingService.ts index c299913d7d4..ac6a652040d 100644 --- a/src/vs/workbench/services/configuration/common/configurationEditingService.ts +++ b/src/vs/workbench/services/configuration/common/configurationEditingService.ts @@ -42,6 +42,11 @@ export const enum ConfigurationEditingErrorCode { */ ERROR_INVALID_WORKSPACE_CONFIGURATION_APPLICATION, + /** + * Error when trying to write a machne setting into workspace settings. + */ + ERROR_INVALID_WORKSPACE_CONFIGURATION_MACHINE, + /** * Error when trying to write an invalid folder configuration key to folder settings. */ @@ -284,6 +289,7 @@ export class ConfigurationEditingService { // API constraints case ConfigurationEditingErrorCode.ERROR_UNKNOWN_KEY: return nls.localize('errorUnknownKey', "Unable to write to {0} because {1} is not a registered configuration.", this.stringifyTarget(target), operation.key); case ConfigurationEditingErrorCode.ERROR_INVALID_WORKSPACE_CONFIGURATION_APPLICATION: return nls.localize('errorInvalidWorkspaceConfigurationApplication', "Unable to write {0} to Workspace Settings. This setting can be written only into User settings.", operation.key); + case ConfigurationEditingErrorCode.ERROR_INVALID_WORKSPACE_CONFIGURATION_MACHINE: return nls.localize('errorInvalidWorkspaceConfigurationMachine', "Unable to write {0} to Workspace Settings. This setting can be written only into User settings.", operation.key); case ConfigurationEditingErrorCode.ERROR_INVALID_FOLDER_CONFIGURATION: return nls.localize('errorInvalidFolderConfiguration', "Unable to write to Folder Settings because {0} does not support the folder resource scope.", operation.key); case ConfigurationEditingErrorCode.ERROR_INVALID_USER_TARGET: return nls.localize('errorInvalidUserTarget', "Unable to write to User Settings because {0} does not support for global scope.", operation.key); case ConfigurationEditingErrorCode.ERROR_INVALID_WORKSPACE_TARGET: return nls.localize('errorInvalidWorkspaceTarget', "Unable to write to Workspace Settings because {0} does not support for workspace scope in a multi folder workspace.", operation.key); @@ -424,6 +430,9 @@ export class ConfigurationEditingService { if (configurationProperties[operation.key].scope === ConfigurationScope.APPLICATION) { return this.reject(ConfigurationEditingErrorCode.ERROR_INVALID_WORKSPACE_CONFIGURATION_APPLICATION, target, operation); } + if (configurationProperties[operation.key].scope === ConfigurationScope.MACHINE) { + return this.reject(ConfigurationEditingErrorCode.ERROR_INVALID_WORKSPACE_CONFIGURATION_MACHINE, target, operation); + } } } diff --git a/src/vs/workbench/services/configuration/test/common/configurationModels.test.ts b/src/vs/workbench/services/configuration/test/common/configurationModels.test.ts index 43d13d5ada3..950b215df35 100644 --- a/src/vs/workbench/services/configuration/test/common/configurationModels.test.ts +++ b/src/vs/workbench/services/configuration/test/common/configurationModels.test.ts @@ -35,6 +35,11 @@ suite('FolderSettingsModelParser', () => { 'type': 'string', 'default': 'isSet', scope: ConfigurationScope.APPLICATION + }, + 'FolderSettingsModelParser.machine': { + 'type': 'string', + 'default': 'isSet', + scope: ConfigurationScope.MACHINE } } }); @@ -43,7 +48,7 @@ suite('FolderSettingsModelParser', () => { test('parse all folder settings', () => { const testObject = new ConfigurationModelParser('settings', [ConfigurationScope.RESOURCE, ConfigurationScope.WINDOW]); - testObject.parseContent(JSON.stringify({ 'FolderSettingsModelParser.window': 'window', 'FolderSettingsModelParser.resource': 'resource', 'FolderSettingsModelParser.application': 'executable' })); + testObject.parseContent(JSON.stringify({ 'FolderSettingsModelParser.window': 'window', 'FolderSettingsModelParser.resource': 'resource', 'FolderSettingsModelParser.application': 'application', 'FolderSettingsModelParser.machine': 'executable' })); assert.deepEqual(testObject.configurationModel.contents, { 'FolderSettingsModelParser': { 'window': 'window', 'resource': 'resource' } }); }); @@ -51,7 +56,7 @@ suite('FolderSettingsModelParser', () => { test('parse resource folder settings', () => { const testObject = new ConfigurationModelParser('settings', [ConfigurationScope.RESOURCE]); - testObject.parseContent(JSON.stringify({ 'FolderSettingsModelParser.window': 'window', 'FolderSettingsModelParser.resource': 'resource', 'FolderSettingsModelParser.application': 'executable' })); + testObject.parseContent(JSON.stringify({ 'FolderSettingsModelParser.window': 'window', 'FolderSettingsModelParser.resource': 'resource', 'FolderSettingsModelParser.application': 'application', 'FolderSettingsModelParser.machine': 'executable' })); assert.deepEqual(testObject.configurationModel.contents, { 'FolderSettingsModelParser': { 'resource': 'resource' } }); }); @@ -59,12 +64,12 @@ suite('FolderSettingsModelParser', () => { test('parse overridable resource settings', () => { const testObject = new ConfigurationModelParser('settings', [ConfigurationScope.RESOURCE]); - testObject.parseContent(JSON.stringify({ '[json]': { 'FolderSettingsModelParser.window': 'window', 'FolderSettingsModelParser.resource': 'resource', 'FolderSettingsModelParser.application': 'executable' } })); + testObject.parseContent(JSON.stringify({ '[json]': { 'FolderSettingsModelParser.window': 'window', 'FolderSettingsModelParser.resource': 'resource', 'FolderSettingsModelParser.application': 'application', 'FolderSettingsModelParser.machine': 'executable' } })); assert.deepEqual(testObject.configurationModel.overrides, [{ 'contents': { 'FolderSettingsModelParser': { 'resource': 'resource' } }, 'identifiers': ['json'] }]); }); - test('reprocess folder settings excludes application setting', () => { + test('reprocess folder settings excludes application and machine setting', () => { const testObject = new ConfigurationModelParser('settings', [ConfigurationScope.RESOURCE, ConfigurationScope.WINDOW]); testObject.parseContent(JSON.stringify({ 'FolderSettingsModelParser.resource': 'resource', 'FolderSettingsModelParser.anotherApplicationSetting': 'executable' })); @@ -80,6 +85,11 @@ suite('FolderSettingsModelParser', () => { 'type': 'string', 'default': 'isSet', scope: ConfigurationScope.APPLICATION + }, + 'FolderSettingsModelParser.anotherMachineSetting': { + 'type': 'string', + 'default': 'isSet', + scope: ConfigurationScope.MACHINE } } }); diff --git a/src/vs/workbench/services/configuration/test/electron-browser/configurationService.test.ts b/src/vs/workbench/services/configuration/test/electron-browser/configurationService.test.ts index dee633e4c90..0c3d0a6910d 100644 --- a/src/vs/workbench/services/configuration/test/electron-browser/configurationService.test.ts +++ b/src/vs/workbench/services/configuration/test/electron-browser/configurationService.test.ts @@ -730,6 +730,11 @@ suite('WorkspaceConfigurationService - Folder', () => { 'default': 'isSet', scope: ConfigurationScope.APPLICATION }, + 'configurationService.folder.machineSetting': { + 'type': 'string', + 'default': 'isSet', + scope: ConfigurationScope.MACHINE + }, 'configurationService.folder.testSetting': { 'type': 'string', 'default': 'isSet', @@ -787,7 +792,7 @@ suite('WorkspaceConfigurationService - Folder', () => { }); test('defaults', () => { - assert.deepEqual(testObject.getValue('configurationService'), { 'folder': { 'applicationSetting': 'isSet', 'testSetting': 'isSet' } }); + assert.deepEqual(testObject.getValue('configurationService'), { 'folder': { 'applicationSetting': 'isSet', 'machineSetting': 'isSet', 'testSetting': 'isSet' } }); }); test('globals override defaults', () => { @@ -843,6 +848,13 @@ suite('WorkspaceConfigurationService - Folder', () => { .then(() => assert.equal(testObject.getValue('configurationService.folder.applicationSetting'), 'userValue')); }); + test('machine settings are not read from workspace', () => { + fs.writeFileSync(globalSettingsFile, '{ "configurationService.folder.machineSetting": "userValue" }'); + fs.writeFileSync(path.join(workspaceDir, '.vscode', 'settings.json'), '{ "configurationService.folder.machineSetting": "workspaceValue" }'); + return testObject.reloadConfiguration() + .then(() => assert.equal(testObject.getValue('configurationService.folder.machineSetting'), 'userValue')); + }); + test('get application scope settings are not loaded after defaults are registered', () => { fs.writeFileSync(path.join(workspaceDir, '.vscode', 'settings.json'), '{ "configurationService.folder.anotherApplicationSetting": "workspaceValue" }'); return testObject.reloadConfiguration() @@ -862,6 +874,25 @@ suite('WorkspaceConfigurationService - Folder', () => { }); }); + test('get machine scope settings are not loaded after defaults are registered', () => { + fs.writeFileSync(path.join(workspaceDir, '.vscode', 'settings.json'), '{ "configurationService.folder.anotherMachineSetting": "workspaceValue" }'); + return testObject.reloadConfiguration() + .then(() => { + configurationRegistry.registerConfiguration({ + 'id': '_test', + 'type': 'object', + 'properties': { + 'configurationService.folder.anotherMachineSetting': { + 'type': 'string', + 'default': 'isSet', + scope: ConfigurationScope.MACHINE + } + } + }); + assert.deepEqual(testObject.keys().workspace, []); + }); + }); + test('reload configuration emits events after global configuraiton changes', () => { fs.writeFileSync(globalSettingsFile, '{ "testworkbench.editor.tabs": true }'); const target = sinon.spy(); @@ -971,6 +1002,11 @@ suite('WorkspaceConfigurationService - Folder', () => { .then(() => assert.fail('Should not be supported'), (e) => assert.equal(e.code, ConfigurationEditingErrorCode.ERROR_INVALID_WORKSPACE_CONFIGURATION_APPLICATION)); }); + test('update machine setting into workspace configuration in a workspace is not supported', () => { + return testObject.updateValue('configurationService.folder.machineSetting', 'workspaceValue', {}, ConfigurationTarget.WORKSPACE, true) + .then(() => assert.fail('Should not be supported'), (e) => assert.equal(e.code, ConfigurationEditingErrorCode.ERROR_INVALID_WORKSPACE_CONFIGURATION_MACHINE)); + }); + test('update tasks configuration', () => { return testObject.updateValue('tasks', { 'version': '1.0.0', tasks: [{ 'taskName': 'myTask' }] }, ConfigurationTarget.WORKSPACE) .then(() => assert.deepEqual(testObject.getValue('tasks'), { 'version': '1.0.0', tasks: [{ 'taskName': 'myTask' }] })); @@ -1030,6 +1066,11 @@ suite('WorkspaceConfigurationService-Multiroot', () => { 'default': 'isSet', scope: ConfigurationScope.APPLICATION }, + 'configurationService.workspace.machineSetting': { + 'type': 'string', + 'default': 'isSet', + scope: ConfigurationScope.MACHINE + }, 'configurationService.workspace.testResourceSetting': { 'type': 'string', 'default': 'isSet', @@ -1095,6 +1136,13 @@ suite('WorkspaceConfigurationService-Multiroot', () => { .then(() => assert.equal(testObject.getValue('configurationService.workspace.applicationSetting'), 'userValue')); }); + test('machine settings are not read from workspace', () => { + fs.writeFileSync(environmentService.appSettingsPath, '{ "configurationService.workspace.machineSetting": "userValue" }'); + return jsonEditingServce.write(workspaceContextService.getWorkspace().configuration!, { key: 'settings', value: { 'configurationService.workspace.machineSetting': 'workspaceValue' } }, true) + .then(() => testObject.reloadConfiguration()) + .then(() => assert.equal(testObject.getValue('configurationService.workspace.machineSetting'), 'userValue')); + }); + test('workspace settings override user settings after defaults are registered ', () => { fs.writeFileSync(environmentService.appSettingsPath, '{ "configurationService.workspace.newSetting": "userValue" }'); return jsonEditingServce.write(workspaceContextService.getWorkspace().configuration!, { key: 'settings', value: { 'configurationService.workspace.newSetting': 'workspaceValue' } }, true) @@ -1121,6 +1169,13 @@ suite('WorkspaceConfigurationService-Multiroot', () => { .then(() => assert.equal(testObject.getValue('configurationService.workspace.applicationSetting'), 'userValue')); }); + test('machine settings are not read from workspace folder', () => { + fs.writeFileSync(environmentService.appSettingsPath, '{ "configurationService.workspace.machineSetting": "userValue" }'); + fs.writeFileSync(workspaceContextService.getWorkspace().folders[0].toResource('.vscode/settings.json').fsPath, '{ "configurationService.workspace.machineSetting": "workspaceFolderValue" }'); + return testObject.reloadConfiguration() + .then(() => assert.equal(testObject.getValue('configurationService.workspace.machineSetting'), 'userValue')); + }); + test('application settings are not read from workspace folder after defaults are registered', () => { fs.writeFileSync(environmentService.appSettingsPath, '{ "configurationService.workspace.testNewApplicationSetting": "userValue" }'); fs.writeFileSync(workspaceContextService.getWorkspace().folders[0].toResource('.vscode/settings.json').fsPath, '{ "configurationService.workspace.testNewApplicationSetting": "workspaceFolderValue" }'); @@ -1141,6 +1196,26 @@ suite('WorkspaceConfigurationService-Multiroot', () => { }); }); + test('application settings are not read from workspace folder after defaults are registered', () => { + fs.writeFileSync(environmentService.appSettingsPath, '{ "configurationService.workspace.testNewMachineSetting": "userValue" }'); + fs.writeFileSync(workspaceContextService.getWorkspace().folders[0].toResource('.vscode/settings.json').fsPath, '{ "configurationService.workspace.testNewMachineSetting": "workspaceFolderValue" }'); + return testObject.reloadConfiguration() + .then(() => { + configurationRegistry.registerConfiguration({ + 'id': '_test', + 'type': 'object', + 'properties': { + 'configurationService.workspace.testNewMachineSetting': { + 'type': 'string', + 'default': 'isSet', + scope: ConfigurationScope.MACHINE + } + } + }); + assert.equal(testObject.getValue('configurationService.workspace.testNewMachineSetting', { resource: workspaceContextService.getWorkspace().folders[0].uri }), 'userValue'); + }); + }); + test('resource setting in folder is read after it is registered later', () => { fs.writeFileSync(workspaceContextService.getWorkspace().folders[0].toResource('.vscode/settings.json').fsPath, '{ "configurationService.workspace.testNewResourceSetting2": "workspaceFolderValue" }'); return jsonEditingServce.write(workspaceContextService.getWorkspace().configuration!, { key: 'settings', value: { 'configurationService.workspace.testNewResourceSetting2': 'workspaceValue' } }, true) @@ -1290,6 +1365,11 @@ suite('WorkspaceConfigurationService-Multiroot', () => { .then(() => assert.fail('Should not be supported'), (e) => assert.equal(e.code, ConfigurationEditingErrorCode.ERROR_INVALID_WORKSPACE_CONFIGURATION_APPLICATION)); }); + test('update machine setting into workspace configuration in a workspace is not supported', () => { + return testObject.updateValue('configurationService.workspace.machineSetting', 'workspaceValue', {}, ConfigurationTarget.WORKSPACE, true) + .then(() => assert.fail('Should not be supported'), (e) => assert.equal(e.code, ConfigurationEditingErrorCode.ERROR_INVALID_WORKSPACE_CONFIGURATION_MACHINE)); + }); + test('update workspace folder configuration', () => { const workspace = workspaceContextService.getWorkspace(); return testObject.updateValue('configurationService.workspace.testResourceSetting', 'workspaceFolderValue', { resource: workspace.folders[0].uri }, ConfigurationTarget.WORKSPACE_FOLDER) From 1650cee35afff7228ea3344240431c97ecbadf18 Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Thu, 11 Apr 2019 23:14:47 -0700 Subject: [PATCH 29/48] Update vscode-octicons-font (#72159) --- cgmanifest.json | 4 ++-- .../ui/octiconLabel/octicons/octicons.css | 7 ++++--- .../ui/octiconLabel/octicons/octicons.svg | 13 ++++++++----- .../ui/octiconLabel/octicons/octicons.ttf | Bin 36832 -> 36908 bytes 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/cgmanifest.json b/cgmanifest.json index 927c66cbc37..01cdd8df5f1 100644 --- a/cgmanifest.json +++ b/cgmanifest.json @@ -111,11 +111,11 @@ "git": { "name": "vscode-octicons-font", "repositoryUrl": "https://github.com/Microsoft/vscode-octicons-font", - "commitHash": "5095860bb929919670646e2dfa0ee47d9b93bcb9" + "commitHash": "4f69de3a233ed501c2098e33047e116ac2fbbf42" } }, "license": "MIT", - "version": "1.0.0" + "version": "1.1.0" }, { "component": { diff --git a/src/vs/base/browser/ui/octiconLabel/octicons/octicons.css b/src/vs/base/browser/ui/octiconLabel/octicons/octicons.css index d24cc0b5258..d583733048e 100644 --- a/src/vs/base/browser/ui/octiconLabel/octicons/octicons.css +++ b/src/vs/base/browser/ui/octiconLabel/octicons/octicons.css @@ -1,7 +1,7 @@ @font-face { font-family: "octicons"; - src: url("./octicons.ttf?4cd2299755e93a2430ba5703f4476584") format("truetype"), -url("./octicons.svg?4cd2299755e93a2430ba5703f4476584#octicons") format("svg"); + src: url("./octicons.ttf?91284a5a76ea88faeb754359b7f7cd03") format("truetype"), +url("./octicons.svg?91284a5a76ea88faeb754359b7f7cd03#octicons") format("svg"); } .octicon, .mega-octicon { @@ -240,4 +240,5 @@ url("./octicons.svg?4cd2299755e93a2430ba5703f4476584#octicons") format("svg"); .octicon-fold-up:before { content: "\f105" } .octicon-github-action:before { content: "\f106" } .octicon-play:before { content: "\f107" } -.octicon-request-changes:before { content: "\f108" } +.octicon-remote:before { content: "\f108" } +.octicon-request-changes:before { content: "\f109" } diff --git a/src/vs/base/browser/ui/octiconLabel/octicons/octicons.svg b/src/vs/base/browser/ui/octiconLabel/octicons/octicons.svg index 4581795255c..af839609786 100644 --- a/src/vs/base/browser/ui/octiconLabel/octicons/octicons.svg +++ b/src/vs/base/browser/ui/octiconLabel/octicons/octicons.svg @@ -421,6 +421,9 @@ + @@ -446,7 +449,7 @@ unicode="" horiz-adv-x="1000" d=" M437.5 320H562.5V195H437.5z M437.5 632.5H562.5V382.5H437.5z M937.5 757.5H62.5C25 757.5 0 732.5 0 695V132.5C0 95 25 70 62.5 70H187.5V-180L437.5 70H937.5C975 70 1000 95 1000 132.5V695C1000 732.5 975 757.5 937.5 757.5zM937.5 132.5H406.25L250 -23.75V132.5H62.5V695H937.5z" /> + horiz-adv-x="1000" d=" M998.75 330.625L938.125 702.5C927.5 788.75 820.625 820 750 820H355.625C343.125 820 331.8750000000001 816.875 322.5 811.25L232.5 757.5H125C58.75 757.5 0 698.75 0 632.5V382.5C0 316.25 58.75 256.25 125 257.5H250C306.875 257.5 336.875 229.375 399.3750000000001 160.625C456.2500000000001 98.125 454.3750000000001 48.1249999999999 438.7500000000001 -43.75C433.75 -75 442.5 -106.25 465 -132.5C489.375 -161.875 526.25 -180 562.5 -180C676.875 -180 750 51.875 750 133.125L748.75 194.375H876.25C948.75 194.375 998.1249999999998 244.3750000000001 1000 317.5000000000001C1000 324.3750000000001 998.75 330.6250000000001 998.75 330.6250000000001zM875.625 256.25H751.25C707.5 256.25 686.875 238.7500000000001 686.875 195.625L688.75 131.25C688.75 51.875 615.625 -118.75 563.75 -118.75C532.5 -118.75 496.2499999999999 -87.5 501.25 -56.25C516.875 42.5 522.5 117.5 445.625 202.5000000000001C381.875 273.125 335 320 250 320V695L354.375 757.5H750C795.625 757.5 871.875 738.125 875 695L876.25 693.75L938.75 318.75C936.875 278.75 914.9999999999998 256.25 876.25 256.25H875.625z" /> + horiz-adv-x="1000" d=" M998.75 309.375L938.125 -62.5000000000001C927.5 -148.75 820.625 -180 750 -180H355.625C343.125 -180 331.8750000000001 -176.875 322.5 -171.25L232.5 -117.5H125C58.75 -117.5 0 -58.75 0 7.5V257.5C0 323.7500000000001 58.75 383.75 125 382.5H250C306.875 382.5 336.875 410.625 399.3750000000001 479.375C456.2500000000001 541.875 454.3750000000001 591.875 438.7500000000001 683.75C433.75 715 442.5 746.25 465 772.5C489.375 801.875 526.25 820 562.5 820C676.875 820 750 588.125 750 506.875L748.75 445.625H876.25C948.75 445.625 998.1249999999998 395.625 1000 322.5C1000 315.625 998.75 309.375 998.75 309.375zM875.625 383.75H751.25C707.5 383.75 686.875 401.25 686.875 444.375L688.75 508.75C688.75 588.125 615.625 758.75 563.75 758.75C532.5 758.75 496.2499999999999 727.5 501.25 696.25C516.875 597.5 522.5 522.5 445.625 437.5C381.875 366.875 335 320 250 320V-55L354.375 -117.5H750C795.625 -117.5 871.875 -98.125 875 -55L876.25 -53.75L938.75 321.25C936.875 361.25 914.9999999999998 383.75 876.25 383.75H875.625z" /> @@ -546,10 +549,10 @@ horiz-adv-x="1000" d=" M750 318.75C750 250.625 721.875 188.125 676.875 141.875L635 183.75C669.375 218.75 690.625 265.625 690.625 318.75C690.625 371.875 669.375 419.3750000000001 635 453.7500000000001L676.875 495.6250000000001A249.375 249.375 0 0 0 750 318.75zM482.5 677.5L250 445H125C90.625 445 62.5 416.875 62.5 382.5V257.5C62.5 223.125 90.625 195 125 195H250L482.5000000000001 -37.5C511.8750000000001 -66.8750000000001 562.5 -46.2500000000001 562.5 -4.3750000000001V644.375C562.5 686.25 511.8749999999999 706.875 482.5 677.5zM853.75 672.5L811.875 630.625A437.24999999999994 437.24999999999994 0 0 0 940.625 319.375C940.625 198.125 891.8750000000001 88.125 811.875 8.125L853.75 -33.75A498.31249999999994 498.31249999999994 0 0 1 1000 320C1000 458.7500000000001 944.375 583.75 853.75 673.75V672.5zM765.625 584.375L722.5 542.5A315.62499999999994 315.62499999999994 0 0 0 815.0000000000001 318.75C815.0000000000001 231.875 780 152.5 722.5 96.25L765.625 54.375A373.18750000000006 373.18750000000006 0 0 1 875 318.75C875 421.8750000000001 833.125 516.25 765.625 584.375z" /> + horiz-adv-x="1000" d=" M979.375 378.375L911.875 462.125A93.75 93.75 0 0 0 892.5625 510.2500000000001L880.6875000000001 616.375A94.375 94.375 0 0 1 797.625 699.5L691.4375 711.375C672.6875 713.25 656.4375 721.3125 642.6875000000001 731.9375L559.0625 799.375A94 94 0 0 1 441.6875 799.375L357.9375 731.875A93.75 93.75 0 0 0 309.8125000000001 712.5L203.6875000000001 700.625C159.9375000000001 695.625 125.5625000000001 661.25 120.5625000000001 617.5625L108.6875 511.375C106.8125 492.625 98.75 476.3750000000001 88.1250000000001 462.625L20.625 379.0625A94 94 0 0 1 20.625 261.6875L88.125 177.9375C98.75 164.1875 105.625 147.9375 107.5 129.8125L119.375 23.6875C124.375 -20.0624999999999 158.75 -54.4375 202.4375 -59.4375L308.625 -71.3125C327.375 -73.1874999999999 343.625 -81.25 357.375 -91.875L441.0625 -159.375C475.4375 -186.8124999999999 524.1250000000001 -186.8124999999999 558.4375 -159.375L642.1875 -91.875C655.9375000000001 -81.25 672.1875 -74.375 690.3125 -72.5L796.4375 -60.625C840.1875 -55.625 874.5625 -21.2499999999999 879.5625 22.4375L891.4375 128.625C893.3125 147.3750000000001 901.375 163.6250000000001 912 177.375L979.5 261.0625A94 94 0 0 1 979.5 378.4375000000001zM562.5 101.25C562.5 83.75 548.75 70 531.25 70H468.75C451.875 70 437.5 83.75 437.5 101.25V163.75C437.5 181.25 451.875 195 468.75 195H531.25C548.75 195 562.5 181.25 562.5 163.75V101.25zM660 406.875C656.25 396.25 649.375 386.25 641.25 377.5C633.1249999999999 367.5 632.5 365.625 620.625 353.75C610.625 343.125 601.25 335 588.125 325.625C581.25 320 575.625 313.75 570.625 308.75C565.625 303.75 561.875 298.125 558.7500000000001 291.875C555.625 285.6250000000001 553.7500000000001 280.0000000000001 551.8750000000001 273.125C550.0000000000001 266.25 550.0000000000001 265 550.0000000000001 257.5H445.625C445.625 271.25 445.625 276.875 447.5 287.5C449.375 299.375 452.5 310 456.25 320C459.9999999999999 328.75 464.9999999999999 337.5 471.875 346.25C478.75 354.375 486.25 361.875 497.5 370C514.375 381.875 520 388.75 527.5 402.5C534.9999999999999 416.25 539.9999999999999 426.25 539.9999999999999 439.375C539.9999999999999 456.25 536.2499999999999 467.5 527.5 475.625C519.3749999999999 483.75 508.1249999999999 487.5000000000001 491.2499999999999 487.5000000000001C485.625 487.5000000000001 479.3749999999999 486.2500000000001 472.5 484.3750000000001C465.6249999999999 482.5000000000001 461.875 478.7500000000001 456.875 474.3750000000001C451.8749999999999 470 448.125 467.5 444.375 461.8750000000001A25.624999999999996 25.624999999999996 0 0 1 438.75 444.375H313.75C313.75 468.125 321.875 479.3750000000001 330.625 496.25C340.625 513.125 353.125 527.5 368.75 538.125C384.375 548.75 403.125 556.875 423.75 561.875C444.375 566.875 467.4999999999999 570 491.8749999999999 570C519.3749999999999 570 543.75 566.875 565 561.875C586.2499999999999 556.25 604.375 548.125 620 537.5C634.375 526.875 645.625 513.75 654.375 498.1250000000001C662.5000000000001 482.5000000000001 666.25 463.7500000000001 666.25 443.1250000000001C666.25 429.3750000000001 666.25 416.8750000000001 661.25 406.2500000000001L660 406.8750000000001z" /> + horiz-adv-x="1000" d=" M979.375 378.375L911.875 462.125A93.75 93.75 0 0 0 892.5625 510.2500000000001L880.6875000000001 616.375A94.375 94.375 0 0 1 797.625 699.5L691.4375 711.375C672.6875 713.25 656.4375 721.3125 642.6875000000001 731.9375L559.0625 799.375A94 94 0 0 1 441.6875 799.375L357.9375 731.875A93.75 93.75 0 0 0 309.8125000000001 712.5L203.6875000000001 700.625C159.9375000000001 695.625 125.5625000000001 661.25 120.5625000000001 617.5625L108.6875 511.375C106.8125 492.625 98.75 476.3750000000001 88.1250000000001 462.625L20.625 379.0625A94 94 0 0 1 20.625 261.6875L88.125 177.9375C98.75 164.1875 105.625 147.9375 107.5 129.8125L119.375 23.6875C124.375 -20.0624999999999 158.75 -54.4375 202.4375 -59.4375L308.625 -71.3125C327.375 -73.1874999999999 343.625 -81.25 357.375 -91.875L441.0625 -159.375C475.4375 -186.8124999999999 524.1250000000001 -186.8124999999999 558.4375 -159.375L642.1875 -91.875C655.9375000000001 -81.25 672.1875 -74.375 690.3125 -72.5L796.4375 -60.625C840.1875 -55.625 874.5625 -21.2499999999999 879.5625 22.4375L891.4375 128.625C893.3125 147.3750000000001 901.375 163.6250000000001 912 177.375L979.5 261.0625A94 94 0 0 1 979.5 378.4375000000001zM406.25 69.375L187.5 288.125L281.25 381.875L406.25 256.875L718.75 569.375L812.5 472.5L406.25 69.375z" /> diff --git a/src/vs/base/browser/ui/octiconLabel/octicons/octicons.ttf b/src/vs/base/browser/ui/octiconLabel/octicons/octicons.ttf index 12b561cd47a71c8e3acfd42b45752b42082666e8..8c29d3383086aa5e948dae2b66b2fe4c8e04c5e8 100644 GIT binary patch delta 2313 zcmbW2ZE#f88OQ(U-n;L6_wGw}H=AtsB{$j4`-a`k?k1R|Ld2BN*4RiDln^BlB{4Ck z5-4F!zydWyzkm)c?U+hdj&}p4bZWma2ar%r`YH~&*%`l z%DSmtNaI6~_6+nMo&Kd0c&dxWdxi!d7e}VgPts!h`vK#nXXoVBi(oXCxU1>o!EWic zzrw=bpa?$sICq1sFW1R!wp%HM^J%#^!V=V00U*)SWX8NZ7Q*oi&Zf+Kha&*Cs7 zjN;pP6d{E1Aijx4ti(5P8(u>bnvumObYLyMg~zcG_hSQIK{*c4VlQG1euTI25}wD8 z5x@!TLLGAOU;zEFKo0>rJc&DTH{Q)6f*_8GdT04LicwlBWFqog zHONlnw`t%7rCvPAjwzprE7^xiflU_aY~~MW;H1)Kli90EpKT?ZR%UH`+51X`6!Vcl z`Li129r7fg3O-PVq!@ccnUPkqGs+*OZt*nrT-Cr^O1nKK(mBrmNdw1~efI8qo(4WM zX^@Xt*sVd1Vqr`JGgR-#Hx}03trUt5so7ARX+V=1-oY{5!4L(U{ z?mqew@sTJMIb13+xzxr=SV4fL6LF8%;|(xFfk97IBA!mEr6HP#r_u(wRPXi{=nZcxhXW}ul6~!vfsl@#!_d} zUr`<^_DUklrtV<7$HGCb${#GW2c4W*w3kJ^!9cjOk4;vV*K(|t3ze`AHd5jDi561> zO?E5XB(nmKBNA*X^CwqCy}n2&vm%`cHMeD2{Gr>UJF8=^5~-=QE>cxlTrIv5x->pH!;GH)fa9aLdW%+|wM|v1&`XTE zylO`)Ya#QO1qm?9od4Zw2WJ&xq3u3zSJ5h8m%I3paE!O|&ed-BY6oxmN|&dIx&#aF zY%5soaEUFV(@8g1kItskn`|y!qlq`@1fJ{TIKAF2S*=!{FZ3C#dZS?A^=wSw41yF3 zhUJJHEOh&HY?rp0U{S7&2X)KKDVrzU?KXqaB#AnD&1|$7j4q4huoan2qE~M+`3ePQ z5cGo4Y_l4yhT@=+F1tMzDx!l$pY<;Vp}(_crGC6g`Fz6O`ak9N#hE`mFvc1;ef{To wzOKgNr&l+PvCQV&=-%J*>|$>1{t?Epx!lhV?9&a{)~OEzhXO1{BiA@*bYhT#NQ;~&^D}vptjpsw*^KP%1280NVfoK zOE8eOltM}2tZ6CG2FhTiw9tAjA7TP_LBY|H*W#Dn}GG>jhmm?@H6SgRlwy39{=0m`hj)z zcP2&w+$Q7(DIq&+{zdV1LgV0;kwhayzyRj1IF; zSU<&ev|rgeux0(r$3Jue&)8|dXL#EWr4jwD2RN`l4wx<@#e>)i z1!1hkGAu+FmS7Ri@F|10bP7#)jw&C+*YG?p;5GaRFCmDNcoGS`2M@MjGb}Jb2R-)S zetZKL5k&}-aAE*2;1Dv%qY+Qz8MLAWWB4vE;T>$iINn4Ak6{oSaR47c#mjgFZfrsl zDRdx>M@lf`2k>GT^|0eO;#i6G*p4gkV?W-&Sv-Jm;WTP7gaVrJD%z374t$$LFp`c9 zsDlshVgKQLp^fC;|Ie4L%(hMEa>ici)g*)jfMjoNg9)>9hD z4a}r9kT00YXuwNcws_e|9<`|KJ-*yB&MxwgD4yiA7FBwIcCFBWLp);LDP5x3Dh+st zpS7y&P5vwE{Y@WGZoLL_2QwQqkWZM|r~$9=oOF&I=f9V_*cDzctI`{^@|*^o<;!K2 zo#tERF7_%vFORc#dBT=tQ+$oh%gTHQ#pn20TNitq|IyYjy+!9f)qwN-L3>iVOtU{| zzzP1my?+^fTeG_~kQ4N1fzvqEULY# zBOgwAJt5|jnJRv^NFVmMMPqZ@9rnJV@IqDXRL1-*buQKKVa#NTI5Q3LsM6q-WnoXQ zhcV%)U13FN_J@47kV`a|m~3l`dP2cSe2^Vn(9|jjMWzH;FB^&beUinTrGj6EJ5}cL zIAX!h#z49w?x~L|g^qkWytpSX8pLG*Wl4OrCFu;&~FQMoxVye9CM^f8gC*<^opbdiQzWZdb(K3@A#b$NE-|y{RBXPGznO)?V*!N~ z*={D;ybVgJDc+EEIwYN$dHkx=*Ww>jI;$dX?z1`Ap;)xdujm&G!qQwm;ItLlPMhR+ z5yNOA(rF7glP#n1B}zaE&K+QP7l+gNj)D@c_qYGcHb3Dl}cs4EBL0pt9oT-G`Q6a2~%YGqCnDQqH4rwurZ=OztBzh z&*w-hPgSj2qbmOPK8Ik{C6%ED_saTveJefno5D%a%E$JF9-8ZQO5KvvDHUbsfL_)a z%{HgrM1v>{3IdgstyZfj*43FT29w?(8pd>jQD;wtB9T}`@w$C_#-3d1ZkVsAbMVqW zMG&m~)IRr8o55_hk#;(RtHx-qt+6{~pT#73jb^jYD^eA`-dH1BjFPb-L^+e)mQ?C3 z)D2$|rhkdWe0XmsFO1ve|G#_fzb}5eW{efq{O<)^8e5;2*v|dw6WX(IpnQG&HzK=M UKD>W~m30T6)|V#^pJWXG0cexemjD0& From 62f59cf1713dc4dac7b92510b2bb7a5f65851c08 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 12 Apr 2019 08:43:15 +0200 Subject: [PATCH 30/48] fix #72186 --- .../splash/electron-browser/partsSplash.contribution.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/splash/electron-browser/partsSplash.contribution.ts b/src/vs/workbench/contrib/splash/electron-browser/partsSplash.contribution.ts index 34c0dd2a005..04b592967df 100644 --- a/src/vs/workbench/contrib/splash/electron-browser/partsSplash.contribution.ts +++ b/src/vs/workbench/contrib/splash/electron-browser/partsSplash.contribution.ts @@ -85,7 +85,8 @@ class PartsSplash { colorInfo, layoutInfo, baseTheme - }) + }), + { encoding: 'utf8', overwriteEncoding: true } ); if (baseTheme !== this._lastBaseTheme || colorInfo.editorBackground !== this._lastBackground) { From 1cc301c2a5919aa2e201fc4a31b8be4640e44242 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 12 Apr 2019 08:46:24 +0200 Subject: [PATCH 31/48] files2 - strengthen test --- .../services/files2/test/node/diskFileService.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/services/files2/test/node/diskFileService.test.ts b/src/vs/workbench/services/files2/test/node/diskFileService.test.ts index a4fb615b7de..5843fa18ebd 100644 --- a/src/vs/workbench/services/files2/test/node/diskFileService.test.ts +++ b/src/vs/workbench/services/files2/test/node/diskFileService.test.ts @@ -886,7 +886,8 @@ suite('Disk File Service', () => { assert.equal(fileStat.name, 'lorem.txt'); })); - assert.equal(readFileSync(resource.fsPath).toString(), '00000' + newContent); + const fileContent = readFileSync(resource.fsPath).toString(); + assert.ok(['0', '00', '000', '0000', '00000'].some(offset => fileContent === offset + newContent)); }); test('writeFile (readable)', async () => { From c763eea5c175acbc004aeb8c38fbdcd2e8ed6712 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 12 Apr 2019 08:59:35 +0200 Subject: [PATCH 32/48] files2 - restore more explicit encodings --- .../configuration/common/configurationEditingService.ts | 2 +- .../services/configuration/common/jsonEditingService.ts | 2 +- .../workbench/services/keybinding/common/keybindingEditing.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/services/configuration/common/configurationEditingService.ts b/src/vs/workbench/services/configuration/common/configurationEditingService.ts index ac6a652040d..28cb4da96ac 100644 --- a/src/vs/workbench/services/configuration/common/configurationEditingService.ts +++ b/src/vs/workbench/services/configuration/common/configurationEditingService.ts @@ -381,7 +381,7 @@ export class ConfigurationEditingService { private async resolveModelReference(resource: URI): Promise> { const exists = await this.fileService.exists(resource); if (!exists) { - await this.textFileService.write(resource, '{}'); + await this.textFileService.write(resource, '{}', { encoding: 'utf8' }); } return this.textModelResolverService.createModelReference(resource); } diff --git a/src/vs/workbench/services/configuration/common/jsonEditingService.ts b/src/vs/workbench/services/configuration/common/jsonEditingService.ts index 7916884a275..baeccb314dd 100644 --- a/src/vs/workbench/services/configuration/common/jsonEditingService.ts +++ b/src/vs/workbench/services/configuration/common/jsonEditingService.ts @@ -86,7 +86,7 @@ export class JSONEditingService implements IJSONEditingService { private async resolveModelReference(resource: URI): Promise> { const exists = await this.fileService.exists(resource); if (!exists) { - await this.textFileService.write(resource, '{}'); + await this.textFileService.write(resource, '{}', { encoding: 'utf8' }); } return this.textModelResolverService.createModelReference(resource); } diff --git a/src/vs/workbench/services/keybinding/common/keybindingEditing.ts b/src/vs/workbench/services/keybinding/common/keybindingEditing.ts index 18e3fdaf601..ffc63601409 100644 --- a/src/vs/workbench/services/keybinding/common/keybindingEditing.ts +++ b/src/vs/workbench/services/keybinding/common/keybindingEditing.ts @@ -211,7 +211,7 @@ export class KeybindingsEditingService extends Disposable implements IKeybinding return this.fileService.exists(this.resource) .then(exists => { const EOL = this.configurationService.getValue('files', { overrideIdentifier: 'json' })['eol']; - const result: Promise = exists ? Promise.resolve(null) : this.textFileService.write(this.resource, this.getEmptyContent(EOL)); + const result: Promise = exists ? Promise.resolve(null) : this.textFileService.write(this.resource, this.getEmptyContent(EOL), { encoding: 'utf8' }); return result.then(() => this.textModelResolverService.createModelReference(this.resource)); }); } From 7bd1dd90dd2086fcdac207c904ea9944700bd91c Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 12 Apr 2019 09:07:51 +0200 Subject: [PATCH 33/48] fix #72122 --- src/vs/editor/browser/widget/codeEditorWidget.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/browser/widget/codeEditorWidget.ts b/src/vs/editor/browser/widget/codeEditorWidget.ts index 8db9d0ab91c..adaf6b71bcf 100644 --- a/src/vs/editor/browser/widget/codeEditorWidget.ts +++ b/src/vs/editor/browser/widget/codeEditorWidget.ts @@ -1754,7 +1754,7 @@ export class EditorModeContext extends Disposable { this._hasSignatureHelpProvider.set(modes.SignatureHelpProviderRegistry.has(model)); this._hasDocumentFormattingProvider.set(modes.DocumentFormattingEditProviderRegistry.has(model) || modes.DocumentRangeFormattingEditProviderRegistry.has(model)); this._hasDocumentSelectionFormattingProvider.set(modes.DocumentRangeFormattingEditProviderRegistry.has(model)); - this._hasMultipleDocumentFormattingProvider.set(modes.DocumentFormattingEditProviderRegistry.all(model).length > 1 || modes.DocumentRangeFormattingEditProviderRegistry.all(model).length > 1); + this._hasMultipleDocumentFormattingProvider.set(modes.DocumentFormattingEditProviderRegistry.all(model).length + modes.DocumentRangeFormattingEditProviderRegistry.all(model).length > 1); this._hasMultipleDocumentSelectionFormattingProvider.set(modes.DocumentRangeFormattingEditProviderRegistry.all(model).length > 1); this._isInWalkThrough.set(model.uri.scheme === Schemas.walkThroughSnippet); }); From 24913a5342f73d9bcebe509330abcdb6c8bfb372 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Fri, 12 Apr 2019 09:00:05 +0200 Subject: [PATCH 34/48] arg help: isPipeSupported --- src/vs/platform/environment/node/argv.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/platform/environment/node/argv.ts b/src/vs/platform/environment/node/argv.ts index 6a70c8a62c4..78923c0be4a 100644 --- a/src/vs/platform/environment/node/argv.ts +++ b/src/vs/platform/environment/node/argv.ts @@ -188,7 +188,7 @@ function wrapText(text: string, columns: number): string[] { return lines; } -export function buildHelpMessage(productName: string, executableName: string, version: string, isOptionSupported = (_: Option) => true): string { +export function buildHelpMessage(productName: string, executableName: string, version: string, isOptionSupported = (_: Option) => true, isPipeSupported = true): string { const columns = (process.stdout).isTTY && (process.stdout).columns || 80; let categories = new HelpCategories(); From 5e5fbbb67d25314c5034afe044e5323b35540555 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 12 Apr 2019 09:31:25 +0200 Subject: [PATCH 35/48] minimize refilter delay (workaround) #71795 --- src/vs/editor/contrib/suggest/suggestModel.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/contrib/suggest/suggestModel.ts b/src/vs/editor/contrib/suggest/suggestModel.ts index 404c78aab22..ef68570326a 100644 --- a/src/vs/editor/contrib/suggest/suggestModel.ts +++ b/src/vs/editor/contrib/suggest/suggestModel.ts @@ -343,7 +343,7 @@ export class SuggestModel implements IDisposable { const position = this._editor.getPosition(); const ctx = new LineContext(model, position, this._state === State.Auto, false); this._onNewContext(ctx); - }, 25); + }, 0); } trigger(context: SuggestTriggerContext, retrigger: boolean = false, onlyFrom?: Set, existingItems?: CompletionItem[]): void { From e0bec82a4803c6c9223816491bcbd11907803aaf Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Fri, 12 Apr 2019 09:41:54 +0200 Subject: [PATCH 36/48] Tweak folder path --- build/azure-pipelines/win32/product-build-win32.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/azure-pipelines/win32/product-build-win32.yml b/build/azure-pipelines/win32/product-build-win32.yml index aea0e7ed79c..a49349150d2 100644 --- a/build/azure-pipelines/win32/product-build-win32.yml +++ b/build/azure-pipelines/win32/product-build-win32.yml @@ -58,7 +58,7 @@ steps: - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@1 inputs: ConnectedServiceName: 'ESRP CodeSign' - FolderPath: '$(agent.builddirectory)/VSCode-win32-$(VSCODE_ARCH)' + FolderPath: '$(agent.builddirectory)/VSCode-win32-$(VSCODE_ARCH),$(agent.builddirectory)/vscode-reh-win32-$(VSCODE_ARCH)' Pattern: '*.dll,*.exe,*.node' signConfigType: inlineSignParams inlineOperation: | From 39012b24631928b528c0e1fb83d28a06d9e6e491 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 12 Apr 2019 09:45:14 +0200 Subject: [PATCH 37/48] history - exclude some typical git files from dock/taskbar entries since those are limited to a few --- .../electron-main/historyMainService.ts | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/vs/platform/history/electron-main/historyMainService.ts b/src/vs/platform/history/electron-main/historyMainService.ts index 47fab1e6c8e..27a29298f40 100644 --- a/src/vs/platform/history/electron-main/historyMainService.ts +++ b/src/vs/platform/history/electron-main/historyMainService.ts @@ -15,7 +15,7 @@ import { isWindows, isMacintosh } from 'vs/base/common/platform'; import { IWorkspaceIdentifier, IWorkspacesMainService, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; import { IHistoryMainService, IRecentlyOpened, isRecentWorkspace, isRecentFolder, IRecent, isRecentFile, IRecentFolder, IRecentWorkspace, IRecentFile } from 'vs/platform/history/common/history'; import { ThrottledDelayer } from 'vs/base/common/async'; -import { isEqual as areResourcesEqual, dirname, originalFSPath } from 'vs/base/common/resources'; +import { isEqual as areResourcesEqual, dirname, originalFSPath, basename } from 'vs/base/common/resources'; import { URI } from 'vs/base/common/uri'; import { Schemas } from 'vs/base/common/network'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; @@ -29,6 +29,12 @@ export class HistoryMainService implements IHistoryMainService { private static readonly MAX_MACOS_DOCK_RECENT_FOLDERS = 10; private static readonly MAX_MACOS_DOCK_RECENT_FILES = 5; + // Exclude some very common files from the dock/taskbar + private static readonly COMMON_FILES_FILTER = [ + 'COMMIT_EDITMSG', + 'MERGE_MSG' + ]; + private static readonly recentlyOpenedStorageKey = 'openedPathsList'; _serviceBrand: any; @@ -63,8 +69,9 @@ export class HistoryMainService implements IHistoryMainService { } else { if (indexOfFile(files, curr.fileUri) === -1) { files.push(curr); + // Add to recent documents (Windows only, macOS later) - if (isWindows && curr.fileUri.scheme === Schemas.file) { + if (isWindows && curr.fileUri.scheme === Schemas.file && HistoryMainService.COMMON_FILES_FILTER.indexOf(basename(curr.fileUri)) === -1) { app.addRecentDocument(curr.fileUri.fsPath); } } @@ -76,6 +83,7 @@ export class HistoryMainService implements IHistoryMainService { if (workspaces.length > HistoryMainService.MAX_TOTAL_RECENT_ENTRIES) { workspaces.length = HistoryMainService.MAX_TOTAL_RECENT_ENTRIES; } + if (files.length > HistoryMainService.MAX_TOTAL_RECENT_ENTRIES) { files.length = HistoryMainService.MAX_TOTAL_RECENT_ENTRIES; } @@ -143,7 +151,7 @@ export class HistoryMainService implements IHistoryMainService { // Fill in files for (let i = 0, entries = 0; i < mru.files.length && entries < HistoryMainService.MAX_MACOS_DOCK_RECENT_FILES; i++) { const loc = location(mru.files[i]); - if (loc.scheme === Schemas.file) { + if (loc.scheme === Schemas.file && HistoryMainService.COMMON_FILES_FILTER.indexOf(basename(loc)) === -1) { const filePath = originalFSPath(loc); if (await exists(filePath)) { app.addRecentDocument(filePath); @@ -162,7 +170,6 @@ export class HistoryMainService implements IHistoryMainService { } getRecentlyOpened(currentWorkspace?: IWorkspaceIdentifier, currentFolder?: ISingleFolderWorkspaceIdentifier, currentFiles?: IPath[]): IRecentlyOpened { - const workspaces: Array = []; const files: IRecentFile[] = []; @@ -170,6 +177,7 @@ export class HistoryMainService implements IHistoryMainService { if (currentWorkspace && !this.workspacesMainService.isUntitledWorkspace(currentWorkspace)) { workspaces.push({ workspace: currentWorkspace }); } + if (currentFolder) { workspaces.push({ folderUri: currentFolder }); } @@ -183,12 +191,14 @@ export class HistoryMainService implements IHistoryMainService { } } } + this.addEntriesFromStorage(workspaces, files); return { workspaces, files }; } private addEntriesFromStorage(workspaces: Array, files: IRecentFile[]) { + // Get from storage let recents = this.getRecentlyOpenedFromStorage(); for (let recent of recents.workspaces) { @@ -199,6 +209,7 @@ export class HistoryMainService implements IHistoryMainService { workspaces.push(recent); } } + for (let recent of recents.files) { let index = indexOfFile(files, recent.fileUri); if (index >= 0) { @@ -211,11 +222,13 @@ export class HistoryMainService implements IHistoryMainService { private getRecentlyOpenedFromStorage(): IRecentlyOpened { const storedRecents = this.stateService.getItem(HistoryMainService.recentlyOpenedStorageKey); + return restoreRecentlyOpened(storedRecents); } private saveRecentlyOpened(recent: IRecentlyOpened): void { const serialized = toStoreData(recent); + this.stateService.setItem(HistoryMainService.recentlyOpenedStorageKey, serialized); } @@ -268,16 +281,17 @@ export class HistoryMainService implements IHistoryMainService { items: arrays.coalesce(this.getRecentlyOpened().workspaces.slice(0, 7 /* limit number of entries here */).map(recent => { const workspace = isRecentWorkspace(recent) ? recent.workspace : recent.folderUri; const title = recent.label || getSimpleWorkspaceLabel(workspace, this.environmentService.untitledWorkspacesHome); + let description; let args; if (isSingleFolderWorkspaceIdentifier(workspace)) { - const parentFolder = dirname(workspace); - description = nls.localize('folderDesc', "{0} {1}", getBaseLabel(workspace), getPathLabel(parentFolder, this.environmentService)); + description = nls.localize('folderDesc', "{0} {1}", getBaseLabel(workspace), getPathLabel(dirname(workspace), this.environmentService)); args = `--folder-uri "${workspace.toString()}"`; } else { description = nls.localize('codeWorkspace', "Code Workspace"); args = `--file-uri "${workspace.configPath.toString()}"`; } + return { type: 'task', title, @@ -308,9 +322,11 @@ function location(recent: IRecent): URI { if (isRecentFolder(recent)) { return recent.folderUri; } + if (isRecentFile(recent)) { return recent.fileUri; } + return recent.workspace.configPath; } From 261fa9f93910ec25a9836fcfe68d7f3cb4a6a06b Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 12 Apr 2019 09:59:18 +0200 Subject: [PATCH 38/48] fix #71992 --- src/vs/base/common/uri.ts | 6 ++++-- src/vs/base/test/common/uri.test.ts | 4 ++-- src/vs/monaco.d.ts | 3 ++- .../extensionManagement/node/extensionManagementIpc.ts | 4 ++-- src/vs/platform/history/electron-main/historyStorage.ts | 2 +- src/vs/workbench/api/browser/mainThreadDecorations.ts | 2 +- src/vs/workbench/api/browser/mainThreadSearch.ts | 2 +- src/vs/workbench/api/common/extHostDialogs.ts | 2 +- src/vs/workbench/api/common/extHostTypeConverters.ts | 4 ++-- src/vs/workbench/api/common/extHostWorkspace.ts | 2 +- src/vs/workbench/api/electron-browser/mainThreadWebview.ts | 2 +- .../workbench/browser/parts/editor/editor.contribution.ts | 6 +++--- .../workbench/contrib/files/browser/files.contribution.ts | 4 ++-- src/vs/workbench/electron-browser/window.ts | 2 +- src/vs/workbench/services/history/browser/history.ts | 6 +++--- 15 files changed, 27 insertions(+), 24 deletions(-) diff --git a/src/vs/base/common/uri.ts b/src/vs/base/common/uri.ts index 79560531ae8..44250c8bcad 100644 --- a/src/vs/base/common/uri.ts +++ b/src/vs/base/common/uri.ts @@ -373,9 +373,11 @@ export class URI implements UriComponents { return this; } - static revive(data: UriComponents | any): URI { + static revive(data: UriComponents | URI): URI; + static revive(data: UriComponents | URI | undefined | null): URI | undefined; + static revive(data: UriComponents | URI | undefined | null): URI | undefined { if (!data) { - return data; + return undefined; } else if (data instanceof URI) { return data; } else { diff --git a/src/vs/base/test/common/uri.test.ts b/src/vs/base/test/common/uri.test.ts index d2fb152cfe5..85f2ad691ac 100644 --- a/src/vs/base/test/common/uri.test.ts +++ b/src/vs/base/test/common/uri.test.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; -import { URI } from 'vs/base/common/uri'; +import { URI, UriComponents } from 'vs/base/common/uri'; import { isWindows } from 'vs/base/common/platform'; @@ -441,7 +441,7 @@ suite('URI', () => { // let c = 100000; // while (c-- > 0) { for (let value of values) { - let data = value.toJSON(); + let data = value.toJSON() as UriComponents; let clone = URI.revive(data); assert.equal(clone.scheme, value.scheme); diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index b79be56812a..bc86a988a45 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -172,7 +172,8 @@ declare namespace monaco { */ toString(skipEncoding?: boolean): string; toJSON(): object; - static revive(data: UriComponents | any): Uri; + static revive(data: UriComponents | Uri): Uri; + static revive(data: UriComponents | Uri | undefined | null): Uri | undefined; } export interface UriComponents { diff --git a/src/vs/platform/extensionManagement/node/extensionManagementIpc.ts b/src/vs/platform/extensionManagement/node/extensionManagementIpc.ts index 9937ddec04c..963e304601e 100644 --- a/src/vs/platform/extensionManagement/node/extensionManagementIpc.ts +++ b/src/vs/platform/extensionManagement/node/extensionManagementIpc.ts @@ -86,7 +86,7 @@ export class ExtensionManagementChannelClient implements IExtensionManagementSer get onDidUninstallExtension(): Event { return this.channel.listen('onDidUninstallExtension'); } zip(extension: ILocalExtension): Promise { - return Promise.resolve(this.channel.call('zip', [extension]).then(result => URI.revive(result))); + return Promise.resolve(this.channel.call('zip', [extension]).then(result => URI.revive(result))); } unzip(zipLocation: URI, type: ExtensionType): Promise { @@ -122,4 +122,4 @@ export class ExtensionManagementChannelClient implements IExtensionManagementSer getExtensionsReport(): Promise { return Promise.resolve(this.channel.call('getExtensionsReport')); } -} \ No newline at end of file +} diff --git a/src/vs/platform/history/electron-main/historyStorage.ts b/src/vs/platform/history/electron-main/historyStorage.ts index b46e6b2cdae..c9175cdb919 100644 --- a/src/vs/platform/history/electron-main/historyStorage.ts +++ b/src/vs/platform/history/electron-main/historyStorage.ts @@ -55,7 +55,7 @@ export function restoreRecentlyOpened(data: RecentlyOpenedStorageData | undefine result.workspaces.push({ workspace: { id: workspace['id'], configPath: URI.file(workspace['configPath']) } }); } else if (workspace && typeof workspace['path'] === 'string' && typeof workspace['scheme'] === 'string') { // added by 1.26-insiders - result.workspaces.push({ folderUri: URI.revive(workspace) }); + result.workspaces.push({ folderUri: URI.revive(workspace) }); } } } diff --git a/src/vs/workbench/api/browser/mainThreadDecorations.ts b/src/vs/workbench/api/browser/mainThreadDecorations.ts index f8ac59feaa3..f34105ddf73 100644 --- a/src/vs/workbench/api/browser/mainThreadDecorations.ts +++ b/src/vs/workbench/api/browser/mainThreadDecorations.ts @@ -112,7 +112,7 @@ export class MainThreadDecorations implements MainThreadDecorationsShape { const provider = this._provider.get(handle); if (provider) { const [emitter] = provider; - emitter.fire(resources && resources.map(URI.revive)); + emitter.fire(resources && resources.map(r => URI.revive(r))); } } diff --git a/src/vs/workbench/api/browser/mainThreadSearch.ts b/src/vs/workbench/api/browser/mainThreadSearch.ts index dd1d9ec1df1..5fa7df39b18 100644 --- a/src/vs/workbench/api/browser/mainThreadSearch.ts +++ b/src/vs/workbench/api/browser/mainThreadSearch.ts @@ -162,7 +162,7 @@ class RemoteSearchProvider implements ISearchResultProvider, IDisposable { }); } else { searchOp.addMatch({ - resource: URI.revive(result) + resource: URI.revive(result) }); } }); diff --git a/src/vs/workbench/api/common/extHostDialogs.ts b/src/vs/workbench/api/common/extHostDialogs.ts index 1581de27683..06fcd380275 100644 --- a/src/vs/workbench/api/common/extHostDialogs.ts +++ b/src/vs/workbench/api/common/extHostDialogs.ts @@ -17,7 +17,7 @@ export class ExtHostDialogs { showOpenDialog(options: vscode.OpenDialogOptions): Promise { return this._proxy.$showOpenDialog(options).then(filepaths => { - return filepaths ? filepaths.map(URI.revive) : undefined; + return filepaths ? filepaths.map(p => URI.revive(p)) : undefined; }); } diff --git a/src/vs/workbench/api/common/extHostTypeConverters.ts b/src/vs/workbench/api/common/extHostTypeConverters.ts index fac19abf67f..2a499df5b16 100644 --- a/src/vs/workbench/api/common/extHostTypeConverters.ts +++ b/src/vs/workbench/api/common/extHostTypeConverters.ts @@ -478,8 +478,8 @@ export namespace WorkspaceEdit { ); } else { result.renameFile( - URI.revive((edit).oldUri), - URI.revive((edit).newUri), + URI.revive((edit).oldUri!), + URI.revive((edit).newUri!), (edit).options ); } diff --git a/src/vs/workbench/api/common/extHostWorkspace.ts b/src/vs/workbench/api/common/extHostWorkspace.ts index dc57dbbd1ad..2e6eb740df1 100644 --- a/src/vs/workbench/api/common/extHostWorkspace.ts +++ b/src/vs/workbench/api/common/extHostWorkspace.ts @@ -420,7 +420,7 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape, IExtHostWorkspac } return this._proxy.$startFileSearch(includePattern, includeFolder, excludePatternOrDisregardExcludes, maxResults, token) - .then(data => Array.isArray(data) ? data.map(URI.revive) : []); + .then(data => Array.isArray(data) ? data.map(d => URI.revive(d)) : []); } findTextInFiles(query: vscode.TextSearchQuery, options: vscode.FindTextInFilesOptions, callback: (result: vscode.TextSearchResult) => void, extensionId: ExtensionIdentifier, token: vscode.CancellationToken = CancellationToken.None): Promise { diff --git a/src/vs/workbench/api/electron-browser/mainThreadWebview.ts b/src/vs/workbench/api/electron-browser/mainThreadWebview.ts index fce140111aa..670b40951ca 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadWebview.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadWebview.ts @@ -414,7 +414,7 @@ export class MainThreadWebviews extends Disposable implements MainThreadWebviews function reviveWebviewOptions(options: WebviewInputOptions): WebviewInputOptions { return { ...options, - localResourceRoots: Array.isArray(options.localResourceRoots) ? options.localResourceRoots.map(URI.revive) : undefined, + localResourceRoots: Array.isArray(options.localResourceRoots) ? options.localResourceRoots.map(r => URI.revive(r)) : undefined, }; } diff --git a/src/vs/workbench/browser/parts/editor/editor.contribution.ts b/src/vs/workbench/browser/parts/editor/editor.contribution.ts index 58d633c7e1e..99e6640c4ba 100644 --- a/src/vs/workbench/browser/parts/editor/editor.contribution.ts +++ b/src/vs/workbench/browser/parts/editor/editor.contribution.ts @@ -5,7 +5,7 @@ import { Registry } from 'vs/platform/registry/common/platform'; import * as nls from 'vs/nls'; -import { URI } from 'vs/base/common/uri'; +import { URI, UriComponents } from 'vs/base/common/uri'; import { Action, IAction } from 'vs/base/common/actions'; import { IEditorQuickOpenEntry, IQuickOpenRegistry, Extensions as QuickOpenExtensions, QuickOpenHandlerDescriptor } from 'vs/workbench/browser/quickopen'; import { StatusbarItemDescriptor, IStatusbarRegistry, Extensions as StatusExtensions } from 'vs/workbench/browser/parts/statusbar/statusbar'; @@ -142,7 +142,7 @@ class UntitledEditorInputFactory implements IEditorInputFactory { deserialize(instantiationService: IInstantiationService, serializedEditorInput: string): UntitledEditorInput { return instantiationService.invokeFunction(accessor => { const deserialized: ISerializedUntitledEditorInput = JSON.parse(serializedEditorInput); - const resource = !!deserialized.resourceJSON ? URI.revive(deserialized.resourceJSON) : URI.parse(deserialized.resource); + const resource = !!deserialized.resourceJSON ? URI.revive(deserialized.resourceJSON) : URI.parse(deserialized.resource); const filePath = resource.scheme === Schemas.untitled ? undefined : resource.scheme === Schemas.file ? resource.fsPath : resource.path; const language = deserialized.modeId; const encoding = deserialized.encoding; @@ -925,4 +925,4 @@ MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, { title: nls.localize({ key: 'miSwitchGroup', comment: ['&& denotes a mnemonic'] }, "Switch &&Group"), submenu: MenuId.MenubarSwitchGroupMenu, order: 2 -}); \ No newline at end of file +}); diff --git a/src/vs/workbench/contrib/files/browser/files.contribution.ts b/src/vs/workbench/contrib/files/browser/files.contribution.ts index 4109a95b145..4083f4a6e95 100644 --- a/src/vs/workbench/contrib/files/browser/files.contribution.ts +++ b/src/vs/workbench/contrib/files/browser/files.contribution.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { URI } from 'vs/base/common/uri'; +import { URI, UriComponents } from 'vs/base/common/uri'; import { ViewletRegistry, Extensions as ViewletExtensions, ViewletDescriptor, ShowViewletAction } from 'vs/workbench/browser/viewlet'; import * as nls from 'vs/nls'; import { sep } from 'vs/base/common/path'; @@ -157,7 +157,7 @@ class FileEditorInputFactory implements IEditorInputFactory { public deserialize(instantiationService: IInstantiationService, serializedEditorInput: string): FileEditorInput { return instantiationService.invokeFunction(accessor => { const fileInput: ISerializedFileInput = JSON.parse(serializedEditorInput); - const resource = !!fileInput.resourceJSON ? URI.revive(fileInput.resourceJSON) : URI.parse(fileInput.resource); + const resource = !!fileInput.resourceJSON ? URI.revive(fileInput.resourceJSON) : URI.parse(fileInput.resource); const encoding = fileInput.encoding; return accessor.get(IEditorService).createInput({ resource, encoding, forceFile: true }) as FileEditorInput; diff --git a/src/vs/workbench/electron-browser/window.ts b/src/vs/workbench/electron-browser/window.ts index 8c4b7a71963..755efd95864 100644 --- a/src/vs/workbench/electron-browser/window.ts +++ b/src/vs/workbench/electron-browser/window.ts @@ -526,7 +526,7 @@ export class ElectronWindow extends Disposable { const resource = URI.revive(p.fileUri); let input: IResourceInput | IUntitledResourceInput; if (isNew) { - input = { filePath: resource.fsPath, options: { pinned: true } }; + input = { filePath: resource!.fsPath, options: { pinned: true } }; } else { input = { resource, options: { pinned: true } }; } diff --git a/src/vs/workbench/services/history/browser/history.ts b/src/vs/workbench/services/history/browser/history.ts index a5a3216f8e6..74ef7b96867 100644 --- a/src/vs/workbench/services/history/browser/history.ts +++ b/src/vs/workbench/services/history/browser/history.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { onUnexpectedError } from 'vs/base/common/errors'; -import { URI } from 'vs/base/common/uri'; +import { URI, UriComponents } from 'vs/base/common/uri'; import { IEditor } from 'vs/editor/common/editorCommon'; import { ITextEditorOptions, IResourceInput, ITextEditorSelection } from 'vs/platform/editor/common/editor'; import { IEditorInput, IEditor as IBaseEditor, Extensions as EditorExtensions, EditorInput, IEditorCloseEvent, IEditorInputFactoryRegistry, toResource, Extensions as EditorInputExtensions, IFileInputFactory, IEditorIdentifier } from 'vs/workbench/common/editor'; @@ -888,7 +888,7 @@ export class HistoryService extends Disposable implements IHistoryService { // File resource: via URI.revive() if (serializedEditorHistoryEntry.resourceJSON) { - return { resource: URI.revive(serializedEditorHistoryEntry.resourceJSON) }; + return { resource: URI.revive(serializedEditorHistoryEntry.resourceJSON) }; } // Editor input: via factory @@ -974,4 +974,4 @@ export class HistoryService extends Disposable implements IHistoryService { } } -registerSingleton(IHistoryService, HistoryService); \ No newline at end of file +registerSingleton(IHistoryService, HistoryService); From 5ccbc56c750b94b5b8d576b99cb85b21a141506c Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 12 Apr 2019 10:03:25 +0200 Subject: [PATCH 39/48] also make null-lovers happy, #71992 --- src/vs/base/common/uri.ts | 8 +++++--- src/vs/monaco.d.ts | 4 +++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/vs/base/common/uri.ts b/src/vs/base/common/uri.ts index 44250c8bcad..ac0c206cd27 100644 --- a/src/vs/base/common/uri.ts +++ b/src/vs/base/common/uri.ts @@ -374,10 +374,12 @@ export class URI implements UriComponents { } static revive(data: UriComponents | URI): URI; - static revive(data: UriComponents | URI | undefined | null): URI | undefined; - static revive(data: UriComponents | URI | undefined | null): URI | undefined { + static revive(data: UriComponents | URI | undefined): URI | undefined; + static revive(data: UriComponents | URI | null): URI | null; + static revive(data: UriComponents | URI | undefined | null): URI | undefined | null; + static revive(data: UriComponents | URI | undefined | null): URI | undefined | null { if (!data) { - return undefined; + return data; } else if (data instanceof URI) { return data; } else { diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index bc86a988a45..7bab804dfa6 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -173,7 +173,9 @@ declare namespace monaco { toString(skipEncoding?: boolean): string; toJSON(): object; static revive(data: UriComponents | Uri): Uri; - static revive(data: UriComponents | Uri | undefined | null): Uri | undefined; + static revive(data: UriComponents | Uri | undefined): Uri | undefined; + static revive(data: UriComponents | Uri | null): Uri | null; + static revive(data: UriComponents | Uri | undefined | null): Uri | undefined | null; } export interface UriComponents { From bcb4b3fa78a6a6127024ec346c812072b66668e8 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 12 Apr 2019 10:05:42 +0200 Subject: [PATCH 40/48] :lipstick: --- src/vs/base/common/uri.ts | 16 ++++++++-------- src/vs/monaco.d.ts | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/vs/base/common/uri.ts b/src/vs/base/common/uri.ts index ac0c206cd27..ec6497ef0b6 100644 --- a/src/vs/base/common/uri.ts +++ b/src/vs/base/common/uri.ts @@ -226,7 +226,7 @@ export class URI implements UriComponents { // ---- modify to new ------------------------- - public with(change: { scheme?: string; authority?: string | null; path?: string | null; query?: string | null; fragment?: string | null }): URI { + with(change: { scheme?: string; authority?: string | null; path?: string | null; query?: string | null; fragment?: string | null }): URI { if (!change) { return this; @@ -279,7 +279,7 @@ export class URI implements UriComponents { * * @param value A string which represents an URI (see `URI#toString`). */ - public static parse(value: string, _strict: boolean = false): URI { + static parse(value: string, _strict: boolean = false): URI { const match = _regexp.exec(value); if (!match) { return new _URI(_empty, _empty, _empty, _empty, _empty); @@ -315,7 +315,7 @@ export class URI implements UriComponents { * * @param path A file system path (see `URI#fsPath`) */ - public static file(path: string): URI { + static file(path: string): URI { let authority = _empty; @@ -342,7 +342,7 @@ export class URI implements UriComponents { return new _URI('file', authority, path, _empty, _empty); } - public static from(components: { scheme: string; authority?: string; path?: string; query?: string; fragment?: string }): URI { + static from(components: { scheme: string; authority?: string; path?: string; query?: string; fragment?: string }): URI { return new _URI( components.scheme, components.authority, @@ -365,11 +365,11 @@ export class URI implements UriComponents { * * @param skipEncoding Do not encode the result, default is `false` */ - public toString(skipEncoding: boolean = false): string { + toString(skipEncoding: boolean = false): string { return _asFormatted(this, skipEncoding); } - public toJSON(): object { + toJSON(): UriComponents { return this; } @@ -419,7 +419,7 @@ class _URI extends URI { return this._fsPath; } - public toString(skipEncoding: boolean = false): string { + toString(skipEncoding: boolean = false): string { if (!skipEncoding) { if (!this._formatted) { this._formatted = _asFormatted(this, false); @@ -431,7 +431,7 @@ class _URI extends URI { } } - toJSON(): object { + toJSON(): UriComponents { const res = { $mid: 1 }; diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 7bab804dfa6..a99de0ecaf3 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -171,7 +171,7 @@ declare namespace monaco { * @param skipEncoding Do not encode the result, default is `false` */ toString(skipEncoding?: boolean): string; - toJSON(): object; + toJSON(): UriComponents; static revive(data: UriComponents | Uri): Uri; static revive(data: UriComponents | Uri | undefined): Uri | undefined; static revive(data: UriComponents | Uri | null): Uri | null; From 10736e07cf11ee9dbaf353f72e56271547b871bf Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Fri, 12 Apr 2019 10:06:11 +0200 Subject: [PATCH 41/48] Use editbale configuration target while editing. Adopt user remote target --- .../browser/configurationService.ts | 66 ++++++++++---- .../common/configurationEditingService.ts | 85 ++++++++++--------- .../common/configurationModels.ts | 2 + .../configurationEditingService.test.ts | 38 ++++----- 4 files changed, 119 insertions(+), 72 deletions(-) diff --git a/src/vs/workbench/services/configuration/browser/configurationService.ts b/src/vs/workbench/services/configuration/browser/configurationService.ts index 379261910a5..78957e2c301 100644 --- a/src/vs/workbench/services/configuration/browser/configurationService.ts +++ b/src/vs/workbench/services/configuration/browser/configurationService.ts @@ -21,7 +21,7 @@ import { Registry } from 'vs/platform/registry/common/platform'; import { IConfigurationRegistry, Extensions, allSettings, windowSettings, resourceSettings, applicationSettings, machineSettings } from 'vs/platform/configuration/common/configurationRegistry'; import { IWorkspaceIdentifier, isWorkspaceIdentifier, IStoredWorkspaceFolder, isStoredWorkspaceFolder, IWorkspaceFolderCreationData, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, IWorkspaceInitializationPayload, isSingleFolderWorkspaceInitializationPayload, ISingleFolderWorkspaceInitializationPayload, IEmptyWorkspaceInitializationPayload, useSlashForPath, getStoredWorkspaceFolder } from 'vs/platform/workspaces/common/workspaces'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { ConfigurationEditingService } from 'vs/workbench/services/configuration/common/configurationEditingService'; +import { ConfigurationEditingService, EditableConfigurationTarget } from 'vs/workbench/services/configuration/common/configurationEditingService'; import { WorkspaceConfiguration, FolderConfiguration, RemoteUserConfiguration, UserConfiguration } from 'vs/workbench/services/configuration/browser/configuration'; import { JSONEditingService } from 'vs/workbench/services/configuration/common/jsonEditingService'; import { IJSONSchema, IJSONSchemaMap } from 'vs/base/common/jsonSchema'; @@ -269,6 +269,8 @@ export class WorkspaceService extends Disposable implements IConfigurationServic inspect(key: string, overrides?: IConfigurationOverrides): { default: T, user: T, + userLocal?: T, + userRemote?: T, workspace?: T, workspaceFolder?: T, memory?: T, @@ -419,8 +421,15 @@ export class WorkspaceService extends Disposable implements IConfigurationServic } private reloadUserConfiguration(key?: string): Promise<{ local: ConfigurationModel, remote: ConfigurationModel }> { - return Promise.all([this.localUserConfiguration ? this.localUserConfiguration.reload() : Promise.resolve(new ConfigurationModel()), this.remoteUserConfiguration ? this.remoteUserConfiguration.reload() : Promise.resolve(new ConfigurationModel())]) - .then(([local, remote]) => ({ local, remote })); + return Promise.all([this.reloadLocalUserConfiguration(), this.reloadRemoeUserConfiguration()]).then(([local, remote]) => ({ local, remote })); + } + + private reloadLocalUserConfiguration(key?: string): Promise { + return this.localUserConfiguration ? this.localUserConfiguration.reload() : Promise.resolve(new ConfigurationModel()); + } + + private reloadRemoeUserConfiguration(key?: string): Promise { + return this.remoteUserConfiguration ? this.remoteUserConfiguration.reload() : Promise.resolve(new ConfigurationModel()); } private reloadWorkspaceConfiguration(key?: string): Promise { @@ -615,20 +624,25 @@ export class WorkspaceService extends Disposable implements IConfigurationServic return Promise.resolve(undefined); } - return this.configurationEditingService.writeConfiguration(target, { key, value }, { scopes: overrides, donotNotifyError }) + const editableConfigurationTarget = this.toEditableConfigurationTarget(target, key); + if (!editableConfigurationTarget) { + return Promise.reject(new Error('Invalid configuration target')); + } + + if (editableConfigurationTarget === EditableConfigurationTarget.USER_REMOTE && !this.remoteUserConfiguration) { + return Promise.reject(new Error('Invalid configuration target')); + } + + return this.configurationEditingService.writeConfiguration(editableConfigurationTarget, { key, value }, { scopes: overrides, donotNotifyError }) .then(() => { - switch (target) { - case ConfigurationTarget.USER: - return this.reloadUserConfiguration() - .then(({ local, remote }) => { - this.onLocalUserConfigurationChanged(local); - if (this.remoteUserConfiguration) { - this.onRemoteUserConfigurationChanged(remote); - } - }); - case ConfigurationTarget.WORKSPACE: + switch (editableConfigurationTarget) { + case EditableConfigurationTarget.USER_LOCAL: + return this.reloadLocalUserConfiguration().then(local => this.onLocalUserConfigurationChanged(local)); + case EditableConfigurationTarget.USER_REMOTE: + return this.reloadRemoeUserConfiguration().then(remote => this.onRemoteUserConfigurationChanged(remote)); + case EditableConfigurationTarget.WORKSPACE: return this.reloadWorkspaceConfiguration(); - case ConfigurationTarget.WORKSPACE_FOLDER: + case EditableConfigurationTarget.WORKSPACE_FOLDER: const workspaceFolder = overrides && overrides.resource ? this.workspace.getFolder(overrides.resource) : null; if (workspaceFolder) { return this.reloadWorkspaceFolderConfiguration(workspaceFolder, key); @@ -683,4 +697,26 @@ export class WorkspaceService extends Disposable implements IConfigurationServic } return {}; } + + private toEditableConfigurationTarget(target: ConfigurationTarget, key: string): EditableConfigurationTarget | null { + if (target === ConfigurationTarget.USER) { + if (this.inspect(key).userRemote !== undefined) { + return EditableConfigurationTarget.USER_REMOTE; + } + return EditableConfigurationTarget.USER_LOCAL; + } + if (target === ConfigurationTarget.USER_LOCAL) { + return EditableConfigurationTarget.USER_LOCAL; + } + if (target === ConfigurationTarget.USER_REMOTE) { + return EditableConfigurationTarget.USER_REMOTE; + } + if (target === ConfigurationTarget.WORKSPACE) { + return EditableConfigurationTarget.WORKSPACE; + } + if (target === ConfigurationTarget.WORKSPACE_FOLDER) { + return EditableConfigurationTarget.WORKSPACE_FOLDER; + } + return null; + } } \ No newline at end of file diff --git a/src/vs/workbench/services/configuration/common/configurationEditingService.ts b/src/vs/workbench/services/configuration/common/configurationEditingService.ts index 28cb4da96ac..7f4147d64a3 100644 --- a/src/vs/workbench/services/configuration/common/configurationEditingService.ts +++ b/src/vs/workbench/services/configuration/common/configurationEditingService.ts @@ -18,7 +18,7 @@ import { Selection } from 'vs/editor/common/core/selection'; import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; -import { IConfigurationService, IConfigurationOverrides, keyFromOverrideIdentifier, ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; +import { IConfigurationService, IConfigurationOverrides, keyFromOverrideIdentifier } from 'vs/platform/configuration/common/configuration'; import { FOLDER_SETTINGS_PATH, WORKSPACE_STANDALONE_CONFIGURATIONS, TASKS_CONFIGURATION_KEY, LAUNCH_CONFIGURATION_KEY } from 'vs/workbench/services/configuration/common/configuration'; import { IFileService } from 'vs/platform/files/common/files'; import { ITextModelService, IResolvedTextEditorModel } from 'vs/editor/common/services/resolverService'; @@ -109,8 +109,15 @@ export interface IConfigurationEditingOptions { scopes?: IConfigurationOverrides; } +export const enum EditableConfigurationTarget { + USER_LOCAL = 1, + USER_REMOTE, + WORKSPACE, + WORKSPACE_FOLDER +} + interface IConfigurationEditOperation extends IConfigurationValue { - target: ConfigurationTarget; + target: EditableConfigurationTarget; jsonPath: json.JSONPath; resource?: URI; workspaceStandAloneConfigurationKey?: string; @@ -148,7 +155,7 @@ export class ConfigurationEditingService { }); } - writeConfiguration(target: ConfigurationTarget, value: IConfigurationValue, options: IConfigurationEditingOptions = {}): Promise { + writeConfiguration(target: EditableConfigurationTarget, value: IConfigurationValue, options: IConfigurationEditingOptions = {}): Promise { const operation = this.getConfigurationEditOperation(target, value, options.scopes || {}); return Promise.resolve(this.queue.queue(() => this.doWriteConfiguration(operation, options) // queue up writes to prevent race conditions .then(() => null, @@ -256,13 +263,16 @@ export class ConfigurationEditingService { private openSettings(operation: IConfigurationEditOperation): void { switch (operation.target) { - case ConfigurationTarget.USER: + case EditableConfigurationTarget.USER_LOCAL: this.preferencesService.openGlobalSettings(true); break; - case ConfigurationTarget.WORKSPACE: + case EditableConfigurationTarget.USER_REMOTE: + this.preferencesService.openRemoteSettings(); + break; + case EditableConfigurationTarget.WORKSPACE: this.preferencesService.openWorkspaceSettings(true); break; - case ConfigurationTarget.WORKSPACE_FOLDER: + case EditableConfigurationTarget.WORKSPACE_FOLDER: if (operation.resource) { const workspaceFolder = this.contextService.getWorkspaceFolder(operation.resource); if (workspaceFolder) { @@ -277,13 +287,13 @@ export class ConfigurationEditingService { this.editorService.openEditor({ resource }); } - private reject(code: ConfigurationEditingErrorCode, target: ConfigurationTarget, operation: IConfigurationEditOperation): Promise { + private reject(code: ConfigurationEditingErrorCode, target: EditableConfigurationTarget, operation: IConfigurationEditOperation): Promise { const message = this.toErrorMessage(code, target, operation); return Promise.reject(new ConfigurationEditingError(message, code)); } - private toErrorMessage(error: ConfigurationEditingErrorCode, target: ConfigurationTarget, operation: IConfigurationEditOperation): string { + private toErrorMessage(error: ConfigurationEditingErrorCode, target: EditableConfigurationTarget, operation: IConfigurationEditOperation): string { switch (error) { // API constraints @@ -305,11 +315,13 @@ export class ConfigurationEditingService { return nls.localize('errorInvalidLaunchConfiguration', "Unable to write into the launch configuration file. Please open it to correct errors/warnings in it and try again."); } switch (target) { - case ConfigurationTarget.USER: + case EditableConfigurationTarget.USER_LOCAL: return nls.localize('errorInvalidConfiguration', "Unable to write into user settings. Please open the user settings to correct errors/warnings in it and try again."); - case ConfigurationTarget.WORKSPACE: + case EditableConfigurationTarget.USER_REMOTE: + return nls.localize('errorInvalidRemoteConfiguration', "Unable to write into remote user settings. Please open the remote user settings to correct errors/warnings in it and try again."); + case EditableConfigurationTarget.WORKSPACE: return nls.localize('errorInvalidConfigurationWorkspace', "Unable to write into workspace settings. Please open the workspace settings to correct errors/warnings in the file and try again."); - case ConfigurationTarget.WORKSPACE_FOLDER: + case EditableConfigurationTarget.WORKSPACE_FOLDER: let workspaceFolderName: string = '<>'; if (operation.resource) { const folder = this.contextService.getWorkspaceFolder(operation.resource); @@ -329,11 +341,13 @@ export class ConfigurationEditingService { return nls.localize('errorLaunchConfigurationFileDirty', "Unable to write into launch configuration file because the file is dirty. Please save it first and then try again."); } switch (target) { - case ConfigurationTarget.USER: + case EditableConfigurationTarget.USER_LOCAL: return nls.localize('errorConfigurationFileDirty', "Unable to write into user settings because the file is dirty. Please save the user settings file first and then try again."); - case ConfigurationTarget.WORKSPACE: + case EditableConfigurationTarget.USER_REMOTE: + return nls.localize('errorRemoteConfigurationFileDirty', "Unable to write into remote user settings because the file is dirty. Please save the remote user settings file first and then try again."); + case EditableConfigurationTarget.WORKSPACE: return nls.localize('errorConfigurationFileDirtyWorkspace', "Unable to write into workspace settings because the file is dirty. Please save the workspace settings file first and then try again."); - case ConfigurationTarget.WORKSPACE_FOLDER: + case EditableConfigurationTarget.WORKSPACE_FOLDER: let workspaceFolderName: string = '<>'; if (operation.resource) { const folder = this.contextService.getWorkspaceFolder(operation.resource); @@ -348,13 +362,15 @@ export class ConfigurationEditingService { } } - private stringifyTarget(target: ConfigurationTarget): string { + private stringifyTarget(target: EditableConfigurationTarget): string { switch (target) { - case ConfigurationTarget.USER: + case EditableConfigurationTarget.USER_LOCAL: return nls.localize('userTarget', "User Settings"); - case ConfigurationTarget.WORKSPACE: + case EditableConfigurationTarget.USER_REMOTE: + return nls.localize('remoteUserTarget', "Remote User Settings"); + case EditableConfigurationTarget.WORKSPACE: return nls.localize('workspaceTarget', "Workspace Settings"); - case ConfigurationTarget.WORKSPACE_FOLDER: + case EditableConfigurationTarget.WORKSPACE_FOLDER: return nls.localize('folderTarget', "Folder Settings"); } return ''; @@ -397,7 +413,7 @@ export class ConfigurationEditingService { return parseErrors.length > 0; } - private resolveAndValidate(target: ConfigurationTarget, operation: IConfigurationEditOperation, checkDirty: boolean, overrides: IConfigurationOverrides): Promise> { + private resolveAndValidate(target: EditableConfigurationTarget, operation: IConfigurationEditOperation, checkDirty: boolean, overrides: IConfigurationOverrides): Promise> { // Any key must be a known setting from the registry (unless this is a standalone config) if (!operation.workspaceStandAloneConfigurationKey) { @@ -409,22 +425,22 @@ export class ConfigurationEditingService { if (operation.workspaceStandAloneConfigurationKey) { // Global tasks and launches are not supported - if (target === ConfigurationTarget.USER) { + if (target === EditableConfigurationTarget.USER_LOCAL || target === EditableConfigurationTarget.USER_REMOTE) { return this.reject(ConfigurationEditingErrorCode.ERROR_INVALID_USER_TARGET, target, operation); } // Workspace tasks are not supported - if (operation.workspaceStandAloneConfigurationKey === TASKS_CONFIGURATION_KEY && this.contextService.getWorkbenchState() === WorkbenchState.WORKSPACE && operation.target === ConfigurationTarget.WORKSPACE) { + if (operation.workspaceStandAloneConfigurationKey === TASKS_CONFIGURATION_KEY && this.contextService.getWorkbenchState() === WorkbenchState.WORKSPACE && operation.target === EditableConfigurationTarget.WORKSPACE) { return this.reject(ConfigurationEditingErrorCode.ERROR_INVALID_WORKSPACE_TARGET, target, operation); } } // Target cannot be workspace or folder if no workspace opened - if ((target === ConfigurationTarget.WORKSPACE || target === ConfigurationTarget.WORKSPACE_FOLDER) && this.contextService.getWorkbenchState() === WorkbenchState.EMPTY) { + if ((target === EditableConfigurationTarget.WORKSPACE || target === EditableConfigurationTarget.WORKSPACE_FOLDER) && this.contextService.getWorkbenchState() === WorkbenchState.EMPTY) { return this.reject(ConfigurationEditingErrorCode.ERROR_NO_WORKSPACE_OPENED, target, operation); } - if (target === ConfigurationTarget.WORKSPACE) { + if (target === EditableConfigurationTarget.WORKSPACE) { if (!operation.workspaceStandAloneConfigurationKey) { const configurationProperties = Registry.as(ConfigurationExtensions.Configuration).getConfigurationProperties(); if (configurationProperties[operation.key].scope === ConfigurationScope.APPLICATION) { @@ -436,7 +452,7 @@ export class ConfigurationEditingService { } } - if (target === ConfigurationTarget.WORKSPACE_FOLDER) { + if (target === EditableConfigurationTarget.WORKSPACE_FOLDER) { if (!operation.resource) { return this.reject(ConfigurationEditingErrorCode.ERROR_INVALID_FOLDER_TARGET, target, operation); } @@ -469,7 +485,7 @@ export class ConfigurationEditingService { }); } - private getConfigurationEditOperation(target: ConfigurationTarget, config: IConfigurationValue, overrides: IConfigurationOverrides): IConfigurationEditOperation { + private getConfigurationEditOperation(target: EditableConfigurationTarget, config: IConfigurationValue, overrides: IConfigurationOverrides): IConfigurationEditOperation { // Check for standalone workspace configurations if (config.key) { @@ -494,7 +510,7 @@ export class ConfigurationEditingService { let key = config.key; let jsonPath = overrides.overrideIdentifier ? [keyFromOverrideIdentifier(overrides.overrideIdentifier), key] : [key]; - if (target === ConfigurationTarget.USER) { + if (target === EditableConfigurationTarget.USER_LOCAL || target === EditableConfigurationTarget.USER_REMOTE) { return { key, jsonPath, value: config.value, resource: withNullAsUndefined(this.getConfigurationFileResource(target, config, '', null)), target }; } @@ -510,26 +526,19 @@ export class ConfigurationEditingService { return !!(workspace.configuration && resource && workspace.configuration.fsPath === resource.fsPath); } - private getConfigurationFileResource(target: ConfigurationTarget, config: IConfigurationValue, relativePath: string, resource: URI | null | undefined): URI | null { - if (target === ConfigurationTarget.USER_LOCAL) { + private getConfigurationFileResource(target: EditableConfigurationTarget, config: IConfigurationValue, relativePath: string, resource: URI | null | undefined): URI | null { + if (target === EditableConfigurationTarget.USER_LOCAL) { return URI.file(this.environmentService.appSettingsPath); } - if (target === ConfigurationTarget.USER_REMOTE) { + if (target === EditableConfigurationTarget.USER_REMOTE) { return this.remoteSettingsResource; } - if (target === ConfigurationTarget.USER) { - if (this.configurationService.inspect(config.key).userRemote !== undefined) { - return this.remoteSettingsResource; - } - return URI.file(this.environmentService.appSettingsPath); - } - const workbenchState = this.contextService.getWorkbenchState(); if (workbenchState !== WorkbenchState.EMPTY) { const workspace = this.contextService.getWorkspace(); - if (target === ConfigurationTarget.WORKSPACE) { + if (target === EditableConfigurationTarget.WORKSPACE) { if (workbenchState === WorkbenchState.WORKSPACE) { return withUndefinedAsNull(workspace.configuration); } @@ -538,7 +547,7 @@ export class ConfigurationEditingService { } } - if (target === ConfigurationTarget.WORKSPACE_FOLDER) { + if (target === EditableConfigurationTarget.WORKSPACE_FOLDER) { if (resource) { const folder = this.contextService.getWorkspaceFolder(resource); if (folder) { diff --git a/src/vs/workbench/services/configuration/common/configurationModels.ts b/src/vs/workbench/services/configuration/common/configurationModels.ts index e9ac592d79c..7a30ad06477 100644 --- a/src/vs/workbench/services/configuration/common/configurationModels.ts +++ b/src/vs/workbench/services/configuration/common/configurationModels.ts @@ -97,6 +97,8 @@ export class Configuration extends BaseConfiguration { inspect(key: string, overrides: IConfigurationOverrides = {}): { default: C, user: C, + userLocal?: C, + userRemote?: C, workspace?: C, workspaceFolder?: C memory?: C diff --git a/src/vs/workbench/services/configuration/test/electron-browser/configurationEditingService.test.ts b/src/vs/workbench/services/configuration/test/electron-browser/configurationEditingService.test.ts index 6e6f0cf18ca..d5bd26501f7 100644 --- a/src/vs/workbench/services/configuration/test/electron-browser/configurationEditingService.test.ts +++ b/src/vs/workbench/services/configuration/test/electron-browser/configurationEditingService.test.ts @@ -19,9 +19,9 @@ import * as uuid from 'vs/base/common/uuid'; import { IConfigurationRegistry, Extensions as ConfigurationExtensions } from 'vs/platform/configuration/common/configurationRegistry'; import { WorkspaceService } from 'vs/workbench/services/configuration/browser/configurationService'; import { LegacyFileService } from 'vs/workbench/services/files/node/fileService'; -import { ConfigurationEditingService, ConfigurationEditingError, ConfigurationEditingErrorCode } from 'vs/workbench/services/configuration/common/configurationEditingService'; +import { ConfigurationEditingService, ConfigurationEditingError, ConfigurationEditingErrorCode, EditableConfigurationTarget } from 'vs/workbench/services/configuration/common/configurationEditingService'; import { WORKSPACE_STANDALONE_CONFIGURATIONS } from 'vs/workbench/services/configuration/common/configuration'; -import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { ITextModelService } from 'vs/editor/common/services/resolverService'; @@ -152,41 +152,41 @@ suite('ConfigurationEditingService', () => { } test('errors cases - invalid key', () => { - return testObject.writeConfiguration(ConfigurationTarget.WORKSPACE, { key: 'unknown.key', value: 'value' }) + return testObject.writeConfiguration(EditableConfigurationTarget.WORKSPACE, { key: 'unknown.key', value: 'value' }) .then(() => assert.fail('Should fail with ERROR_UNKNOWN_KEY'), (error: ConfigurationEditingError) => assert.equal(error.code, ConfigurationEditingErrorCode.ERROR_UNKNOWN_KEY)); }); test('errors cases - invalid target', () => { - return testObject.writeConfiguration(ConfigurationTarget.USER, { key: 'tasks.something', value: 'value' }) + return testObject.writeConfiguration(EditableConfigurationTarget.USER_LOCAL, { key: 'tasks.something', value: 'value' }) .then(() => assert.fail('Should fail with ERROR_INVALID_TARGET'), (error: ConfigurationEditingError) => assert.equal(error.code, ConfigurationEditingErrorCode.ERROR_INVALID_USER_TARGET)); }); test('errors cases - no workspace', () => { return setUpServices(true) - .then(() => testObject.writeConfiguration(ConfigurationTarget.WORKSPACE, { key: 'configurationEditing.service.testSetting', value: 'value' })) + .then(() => testObject.writeConfiguration(EditableConfigurationTarget.WORKSPACE, { key: 'configurationEditing.service.testSetting', value: 'value' })) .then(() => assert.fail('Should fail with ERROR_NO_WORKSPACE_OPENED'), (error: ConfigurationEditingError) => assert.equal(error.code, ConfigurationEditingErrorCode.ERROR_NO_WORKSPACE_OPENED)); }); test('errors cases - invalid configuration', () => { fs.writeFileSync(globalSettingsFile, ',,,,,,,,,,,,,,'); - return testObject.writeConfiguration(ConfigurationTarget.USER, { key: 'configurationEditing.service.testSetting', value: 'value' }) + return testObject.writeConfiguration(EditableConfigurationTarget.USER_LOCAL, { key: 'configurationEditing.service.testSetting', value: 'value' }) .then(() => assert.fail('Should fail with ERROR_INVALID_CONFIGURATION'), (error: ConfigurationEditingError) => assert.equal(error.code, ConfigurationEditingErrorCode.ERROR_INVALID_CONFIGURATION)); }); test('errors cases - dirty', () => { instantiationService.stub(ITextFileService, 'isDirty', true); - return testObject.writeConfiguration(ConfigurationTarget.USER, { key: 'configurationEditing.service.testSetting', value: 'value' }) + return testObject.writeConfiguration(EditableConfigurationTarget.USER_LOCAL, { key: 'configurationEditing.service.testSetting', value: 'value' }) .then(() => assert.fail('Should fail with ERROR_CONFIGURATION_FILE_DIRTY error.'), (error: ConfigurationEditingError) => assert.equal(error.code, ConfigurationEditingErrorCode.ERROR_CONFIGURATION_FILE_DIRTY)); }); test('dirty error is not thrown if not asked to save', () => { instantiationService.stub(ITextFileService, 'isDirty', true); - return testObject.writeConfiguration(ConfigurationTarget.USER, { key: 'configurationEditing.service.testSetting', value: 'value' }, { donotSave: true }) + return testObject.writeConfiguration(EditableConfigurationTarget.USER_LOCAL, { key: 'configurationEditing.service.testSetting', value: 'value' }, { donotSave: true }) .then(() => null, error => assert.fail('Should not fail.')); }); @@ -194,7 +194,7 @@ suite('ConfigurationEditingService', () => { instantiationService.stub(ITextFileService, 'isDirty', true); const target = sinon.stub(); instantiationService.stub(INotificationService, { prompt: target, _serviceBrand: null, notify: null!, error: null!, info: null!, warn: null! }); - return testObject.writeConfiguration(ConfigurationTarget.USER, { key: 'configurationEditing.service.testSetting', value: 'value' }, { donotNotifyError: true }) + return testObject.writeConfiguration(EditableConfigurationTarget.USER_LOCAL, { key: 'configurationEditing.service.testSetting', value: 'value' }, { donotNotifyError: true }) .then(() => assert.fail('Should fail with ERROR_CONFIGURATION_FILE_DIRTY error.'), (error: ConfigurationEditingError) => { assert.equal(false, target.calledOnce); @@ -203,7 +203,7 @@ suite('ConfigurationEditingService', () => { }); test('write one setting - empty file', () => { - return testObject.writeConfiguration(ConfigurationTarget.USER, { key: 'configurationEditing.service.testSetting', value: 'value' }) + return testObject.writeConfiguration(EditableConfigurationTarget.USER_LOCAL, { key: 'configurationEditing.service.testSetting', value: 'value' }) .then(() => { const contents = fs.readFileSync(globalSettingsFile).toString('utf8'); const parsed = json.parse(contents); @@ -213,7 +213,7 @@ suite('ConfigurationEditingService', () => { test('write one setting - existing file', () => { fs.writeFileSync(globalSettingsFile, '{ "my.super.setting": "my.super.value" }'); - return testObject.writeConfiguration(ConfigurationTarget.USER, { key: 'configurationEditing.service.testSetting', value: 'value' }) + return testObject.writeConfiguration(EditableConfigurationTarget.USER_LOCAL, { key: 'configurationEditing.service.testSetting', value: 'value' }) .then(() => { const contents = fs.readFileSync(globalSettingsFile).toString('utf8'); const parsed = json.parse(contents); @@ -224,7 +224,7 @@ suite('ConfigurationEditingService', () => { test('remove an existing setting - existing file', () => { fs.writeFileSync(globalSettingsFile, '{ "my.super.setting": "my.super.value", "configurationEditing.service.testSetting": "value" }'); - return testObject.writeConfiguration(ConfigurationTarget.USER, { key: 'configurationEditing.service.testSetting', value: undefined }) + return testObject.writeConfiguration(EditableConfigurationTarget.USER_LOCAL, { key: 'configurationEditing.service.testSetting', value: undefined }) .then(() => { const contents = fs.readFileSync(globalSettingsFile).toString('utf8'); const parsed = json.parse(contents); @@ -235,7 +235,7 @@ suite('ConfigurationEditingService', () => { test('remove non existing setting - existing file', () => { fs.writeFileSync(globalSettingsFile, '{ "my.super.setting": "my.super.value" }'); - return testObject.writeConfiguration(ConfigurationTarget.USER, { key: 'configurationEditing.service.testSetting', value: undefined }) + return testObject.writeConfiguration(EditableConfigurationTarget.USER_LOCAL, { key: 'configurationEditing.service.testSetting', value: undefined }) .then(() => { const contents = fs.readFileSync(globalSettingsFile).toString('utf8'); const parsed = json.parse(contents); @@ -245,7 +245,7 @@ suite('ConfigurationEditingService', () => { }); test('write workspace standalone setting - empty file', () => { - return testObject.writeConfiguration(ConfigurationTarget.WORKSPACE, { key: 'tasks.service.testSetting', value: 'value' }) + return testObject.writeConfiguration(EditableConfigurationTarget.WORKSPACE, { key: 'tasks.service.testSetting', value: 'value' }) .then(() => { const target = path.join(workspaceDir, WORKSPACE_STANDALONE_CONFIGURATIONS['tasks']); const contents = fs.readFileSync(target).toString('utf8'); @@ -257,7 +257,7 @@ suite('ConfigurationEditingService', () => { test('write workspace standalone setting - existing file', () => { const target = path.join(workspaceDir, WORKSPACE_STANDALONE_CONFIGURATIONS['launch']); fs.writeFileSync(target, '{ "my.super.setting": "my.super.value" }'); - return testObject.writeConfiguration(ConfigurationTarget.WORKSPACE, { key: 'launch.service.testSetting', value: 'value' }) + return testObject.writeConfiguration(EditableConfigurationTarget.WORKSPACE, { key: 'launch.service.testSetting', value: 'value' }) .then(() => { const contents = fs.readFileSync(target).toString('utf8'); const parsed = json.parse(contents); @@ -267,7 +267,7 @@ suite('ConfigurationEditingService', () => { }); test('write workspace standalone setting - empty file - full JSON', () => { - return testObject.writeConfiguration(ConfigurationTarget.WORKSPACE, { key: 'tasks', value: { 'version': '1.0.0', tasks: [{ 'taskName': 'myTask' }] } }) + return testObject.writeConfiguration(EditableConfigurationTarget.WORKSPACE, { key: 'tasks', value: { 'version': '1.0.0', tasks: [{ 'taskName': 'myTask' }] } }) .then(() => { const target = path.join(workspaceDir, WORKSPACE_STANDALONE_CONFIGURATIONS['tasks']); const contents = fs.readFileSync(target).toString('utf8'); @@ -281,7 +281,7 @@ suite('ConfigurationEditingService', () => { test('write workspace standalone setting - existing file - full JSON', () => { const target = path.join(workspaceDir, WORKSPACE_STANDALONE_CONFIGURATIONS['tasks']); fs.writeFileSync(target, '{ "my.super.setting": "my.super.value" }'); - return testObject.writeConfiguration(ConfigurationTarget.WORKSPACE, { key: 'tasks', value: { 'version': '1.0.0', tasks: [{ 'taskName': 'myTask' }] } }) + return testObject.writeConfiguration(EditableConfigurationTarget.WORKSPACE, { key: 'tasks', value: { 'version': '1.0.0', tasks: [{ 'taskName': 'myTask' }] } }) .then(() => { const contents = fs.readFileSync(target).toString('utf8'); const parsed = json.parse(contents); @@ -294,7 +294,7 @@ suite('ConfigurationEditingService', () => { test('write workspace standalone setting - existing file with JSON errors - full JSON', () => { const target = path.join(workspaceDir, WORKSPACE_STANDALONE_CONFIGURATIONS['tasks']); fs.writeFileSync(target, '{ "my.super.setting": '); // invalid JSON - return testObject.writeConfiguration(ConfigurationTarget.WORKSPACE, { key: 'tasks', value: { 'version': '1.0.0', tasks: [{ 'taskName': 'myTask' }] } }) + return testObject.writeConfiguration(EditableConfigurationTarget.WORKSPACE, { key: 'tasks', value: { 'version': '1.0.0', tasks: [{ 'taskName': 'myTask' }] } }) .then(() => { const contents = fs.readFileSync(target).toString('utf8'); const parsed = json.parse(contents); @@ -317,7 +317,7 @@ suite('ConfigurationEditingService', () => { } ] }`); - return testObject.writeConfiguration(ConfigurationTarget.WORKSPACE, { key: 'tasks', value: { 'version': '1.0.0', tasks: [{ 'taskName': 'myTask1' }] } }) + return testObject.writeConfiguration(EditableConfigurationTarget.WORKSPACE, { key: 'tasks', value: { 'version': '1.0.0', tasks: [{ 'taskName': 'myTask1' }] } }) .then(() => { const actual = fs.readFileSync(target).toString('utf8'); const expected = JSON.stringify({ 'version': '1.0.0', tasks: [{ 'taskName': 'myTask1' }] }, null, '\t'); From f1f37c212e6838db23a6241a5e0645cbb9c5c47a Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Fri, 12 Apr 2019 10:08:30 +0200 Subject: [PATCH 42/48] double log language, only one works. Fixes #72192 --- extensions/log/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/log/package.json b/extensions/log/package.json index 96fa29a0b30..38da616a8d4 100644 --- a/extensions/log/package.json +++ b/extensions/log/package.json @@ -19,7 +19,7 @@ "*.log.?" ], "aliases": [ - "log" + "Log" ] } ], From 55270a468b32d73c420399c8ca7898ed3aef4ad7 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Fri, 12 Apr 2019 10:09:28 +0200 Subject: [PATCH 43/48] :lipstick: --- .../configuration/common/configurationRegistry.ts | 12 ++++++++++++ .../api/common/configurationExtensionPoint.ts | 6 +++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/vs/platform/configuration/common/configurationRegistry.ts b/src/vs/platform/configuration/common/configurationRegistry.ts index 19ca52ec2e4..6dea0f0bc22 100644 --- a/src/vs/platform/configuration/common/configurationRegistry.ts +++ b/src/vs/platform/configuration/common/configurationRegistry.ts @@ -83,9 +83,21 @@ export interface IConfigurationRegistry { } export const enum ConfigurationScope { + /** + * Application specific configuration, which can be configured only in local user settings. + */ APPLICATION = 1, + /** + * Machine specific configuration, which can be configured only in local and remote user settings. + */ MACHINE, + /** + * Window specific configuration, which can be configured in the user or workspace settings. + */ WINDOW, + /** + * Resource specific configuration, which can be configured in the user, workspace or folder settings. + */ RESOURCE, } diff --git a/src/vs/workbench/api/common/configurationExtensionPoint.ts b/src/vs/workbench/api/common/configurationExtensionPoint.ts index 11459d62aee..73969b69470 100644 --- a/src/vs/workbench/api/common/configurationExtensionPoint.ts +++ b/src/vs/workbench/api/common/configurationExtensionPoint.ts @@ -42,10 +42,10 @@ const configurationEntrySchema: IJSONSchema = { enum: ['application', 'machine', 'window', 'resource'], default: 'window', enumDescriptions: [ - nls.localize('scope.application.description', "Application specific configuration, which can be configured only in application user settings."), - nls.localize('scope.machine.description', "Machine specific configuration, which can be configured only in user settings."), + nls.localize('scope.application.description', "Application specific configuration, which can be configured only in local user settings."), + nls.localize('scope.machine.description', "Machine specific configuration, which can be configured only in local and remote user settings."), nls.localize('scope.window.description', "Window specific configuration, which can be configured in the user or workspace settings."), - nls.localize('scope.resource.description', "Resource specific configuration, which can be configured in the wser, workspace or folder settings.") + nls.localize('scope.resource.description', "Resource specific configuration, which can be configured in the user, workspace or folder settings.") ], description: nls.localize('scope.description', "Scope in which the configuration is applicable. Available scopes are `window` and `resource`.") }, From aca1494c4ef91f18cf5e067c974aca34b7389b47 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 12 Apr 2019 10:14:34 +0200 Subject: [PATCH 44/48] align monaco compiler settings --- src/tsconfig.monaco.json | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/tsconfig.monaco.json b/src/tsconfig.monaco.json index 1303af547f4..afcbcaff39c 100644 --- a/src/tsconfig.monaco.json +++ b/src/tsconfig.monaco.json @@ -1,18 +1,16 @@ { + "extends": "./tsconfig.base.json", "compilerOptions": { "noEmit": true, + "types": [], + "paths": {}, "module": "amd", "moduleResolution": "classic", - "noImplicitAny": false, "removeComments": false, "preserveConstEnums": true, "target": "es5", "sourceMap": false, - "experimentalDecorators": true, "declaration": true, - "noImplicitReturns": true, - "baseUrl": ".", - "types": [] }, "include": [ "typings/require.d.ts", From 116434f7020b9de0804fe644298326c995c7650c Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 12 Apr 2019 10:21:13 +0200 Subject: [PATCH 45/48] fix #71661 --- src/vs/editor/contrib/snippet/snippetController2.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/contrib/snippet/snippetController2.ts b/src/vs/editor/contrib/snippet/snippetController2.ts index eadc88a2545..a6fc98d4760 100644 --- a/src/vs/editor/contrib/snippet/snippetController2.ts +++ b/src/vs/editor/contrib/snippet/snippetController2.ts @@ -197,7 +197,7 @@ export class SnippetController2 implements IEditorContribution { insertText: option.value, // insertText: `\${1|${after.concat(before).join(',')}|}$0`, // snippetType: 'textmate', - sortText: repeat('a', i), + sortText: repeat('a', i + 1), range: Range.fromPositions(this._editor.getPosition()!, this._editor.getPosition()!.delta(0, first.value.length)) }; })); From 8c0e1b420c0c14be4dc0ecd1277cd099c85e6bdf Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 12 Apr 2019 10:21:35 +0200 Subject: [PATCH 46/48] Support command links in notifications (fixes #46571) --- src/vs/workbench/common/notifications.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/common/notifications.ts b/src/vs/workbench/common/notifications.ts index 43baae61ba5..3c0544e5f53 100644 --- a/src/vs/workbench/common/notifications.ts +++ b/src/vs/workbench/common/notifications.ts @@ -324,8 +324,8 @@ export class NotificationViewItem extends Disposable implements INotificationVie private static MAX_MESSAGE_LENGTH = 1000; // Example link: "Some message with [link text](http://link.href)." - // RegEx: [, anything not ], ], (, http:|https:, //, no whitespace) - private static LINK_REGEX = /\[([^\]]+)\]\((https?:\/\/[^\)\s]+)\)/gi; + // RegEx: [, anything not ], ], (, http://|https://|command:, no whitespace) + private static LINK_REGEX = /\[([^\]]+)\]\(((?:https?:\/\/|command:)[^\)\s]+)\)/gi; private _expanded: boolean; From 49c5a5bd17d94ff7e382e6c9b94b5fe69fae4d75 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Fri, 12 Apr 2019 10:31:30 +0200 Subject: [PATCH 47/48] ext management - do not sync --- .../node/multiExtensionManagement.ts | 25 ++++--------------- 1 file changed, 5 insertions(+), 20 deletions(-) diff --git a/src/vs/workbench/services/extensions/node/multiExtensionManagement.ts b/src/vs/workbench/services/extensions/node/multiExtensionManagement.ts index 1a7fa42fec8..5d9270a6e6b 100644 --- a/src/vs/workbench/services/extensions/node/multiExtensionManagement.ts +++ b/src/vs/workbench/services/extensions/node/multiExtensionManagement.ts @@ -19,7 +19,6 @@ import { areSameExtensions } from 'vs/platform/extensionManagement/common/extens import { localize } from 'vs/nls'; import { isUIExtension } from 'vs/workbench/services/extensions/node/extensionsUtil'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; -import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; export class MultiExtensionManagementService extends Disposable implements IExtensionManagementService { @@ -35,8 +34,7 @@ export class MultiExtensionManagementService extends Disposable implements IExte constructor( @IExtensionManagementServerService private readonly extensionManagementServerService: IExtensionManagementServerService, @IExtensionGalleryService private readonly extensionGalleryService: IExtensionGalleryService, - @IConfigurationService private readonly configurationService: IConfigurationService, - @IRemoteAgentService private readonly remoteAgentService: IRemoteAgentService + @IConfigurationService private readonly configurationService: IConfigurationService ) { super(); this.servers = this.extensionManagementServerService.remoteExtensionManagementServer ? [this.extensionManagementServerService.localExtensionManagementServer, this.extensionManagementServerService.remoteExtensionManagementServer] : [this.extensionManagementServerService.localExtensionManagementServer]; @@ -58,8 +56,7 @@ export class MultiExtensionManagementService extends Disposable implements IExte if (!server) { return Promise.reject(`Invalid location ${extension.location.toString()}`); } - const syncExtensions = await this.hasToSyncExtensions(); - if (syncExtensions || isLanguagePackExtension(extension.manifest)) { + if (isLanguagePackExtension(extension.manifest)) { return this.uninstallEverywhere(extension, force); } return this.uninstallInServer(extension, server, force); @@ -134,9 +131,8 @@ export class MultiExtensionManagementService extends Disposable implements IExte async install(vsix: URI): Promise { if (this.extensionManagementServerService.remoteExtensionManagementServer) { - const syncExtensions = await this.hasToSyncExtensions(); const manifest = await getManifest(vsix.fsPath); - if (syncExtensions || isLanguagePackExtension(manifest)) { + if (isLanguagePackExtension(manifest)) { // Install on both servers const [extensionIdentifier] = await Promise.all(this.servers.map(server => server.extensionManagementService.install(vsix))); return extensionIdentifier; @@ -156,9 +152,9 @@ export class MultiExtensionManagementService extends Disposable implements IExte async installFromGallery(gallery: IGalleryExtension): Promise { if (this.extensionManagementServerService.remoteExtensionManagementServer) { - const [manifest, syncExtensions] = await Promise.all([this.extensionGalleryService.getManifest(gallery, CancellationToken.None), this.hasToSyncExtensions()]); + const manifest = await this.extensionGalleryService.getManifest(gallery, CancellationToken.None); if (manifest) { - if (syncExtensions || isLanguagePackExtension(manifest)) { + if (isLanguagePackExtension(manifest)) { // Install on both servers return Promise.all(this.servers.map(server => server.extensionManagementService.installFromGallery(gallery))).then(() => undefined); } @@ -199,17 +195,6 @@ export class MultiExtensionManagementService extends Disposable implements IExte private getServer(extension: ILocalExtension): IExtensionManagementServer | null { return this.extensionManagementServerService.getExtensionManagementServer(extension.location); } - - private async hasToSyncExtensions(): Promise { - if (!this.extensionManagementServerService.remoteExtensionManagementServer) { - return false; - } - const remoteEnv = await this.remoteAgentService.getEnvironment(); - if (!remoteEnv) { - return false; - } - return remoteEnv.syncExtensions; - } } registerSingleton(IExtensionManagementService, MultiExtensionManagementService); \ No newline at end of file From e6215b9fc9a14a379157fa5cbe1f8317595dd854 Mon Sep 17 00:00:00 2001 From: isidor Date: Fri, 12 Apr 2019 11:40:31 +0200 Subject: [PATCH 48/48] extensionHostDebugService: use sessionId instead of passing session root uri fixes #72195 --- .../debug/electron-browser/debugService.ts | 6 ++-- .../extensions/common/extensionHostDebug.ts | 17 +++++++---- .../electron-browser/extensionHost.ts | 19 +++--------- .../extensionHostDebugService.ts | 29 +++++++++---------- 4 files changed, 32 insertions(+), 39 deletions(-) diff --git a/src/vs/workbench/contrib/debug/electron-browser/debugService.ts b/src/vs/workbench/contrib/debug/electron-browser/debugService.ts index 50191d93340..2e4ef24b083 100644 --- a/src/vs/workbench/contrib/debug/electron-browser/debugService.ts +++ b/src/vs/workbench/contrib/debug/electron-browser/debugService.ts @@ -509,7 +509,7 @@ export class DebugService implements IDebugService { // 'Run without debugging' mode VSCode must terminate the extension host. More details: #3905 if (isExtensionHostDebugging(session.configuration) && session.state === State.Running && session.configuration.noDebug) { - this.extensionHostDebugService.close(session.root.uri); + this.extensionHostDebugService.close(session.getId()); } this.telemetryDebugSessionStop(session, adapterExitEvent); @@ -556,8 +556,8 @@ export class DebugService implements IDebugService { return runTasks().then(taskResult => taskResult === TaskRunResult.Success ? session.restart() : undefined); } - if (isExtensionHostDebugging(session.configuration) && session.root) { - return runTasks().then(taskResult => taskResult === TaskRunResult.Success ? this.extensionHostDebugService.reload(session.root.uri) : undefined); + if (isExtensionHostDebugging(session.configuration)) { + return runTasks().then(taskResult => taskResult === TaskRunResult.Success ? this.extensionHostDebugService.reload(session.getId()) : undefined); } const shouldFocus = this.viewModel.focusedSession && session.getId() === this.viewModel.focusedSession.getId(); diff --git a/src/vs/workbench/services/extensions/common/extensionHostDebug.ts b/src/vs/workbench/services/extensions/common/extensionHostDebug.ts index de19f9a2d9f..08d14adc775 100644 --- a/src/vs/workbench/services/extensions/common/extensionHostDebug.ts +++ b/src/vs/workbench/services/extensions/common/extensionHostDebug.ts @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; -import { URI } from 'vs/base/common/uri'; import { Event } from 'vs/base/common/event'; import { IRemoteConsoleLog } from 'vs/base/common/console'; @@ -26,14 +25,22 @@ export interface ITerminateSessionEvent { subId?: string; } +export interface IReloadSessionEvent { + sessionId: string; +} + +export interface ICloseSessionEvent { + sessionId: string; +} + export interface IExtensionHostDebugService { _serviceBrand: any; - reload(resource: URI): void; - onReload: Event; + reload(sessionId: string): void; + onReload: Event; - close(resource: URI): void; - onClose: Event; + close(sessionId: string): void; + onClose: Event; attachSession(sessionId: string, port: number, subId?: string): void; onAttachSession: Event; diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts index 60d73c52d93..d1cc2b3b40e 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts @@ -14,7 +14,6 @@ import { Emitter, Event } from 'vs/base/common/event'; import { IDisposable, dispose, toDisposable } from 'vs/base/common/lifecycle'; import * as objects from 'vs/base/common/objects'; import * as platform from 'vs/base/common/platform'; -import { isEqual } from 'vs/base/common/resources'; import pkg from 'vs/platform/product/node/package'; import { URI } from 'vs/base/common/uri'; import { IRemoteConsoleLog, log, parse } from 'vs/base/common/console'; @@ -102,13 +101,13 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter { this._toDispose.push(this._onCrashed); this._toDispose.push(this._lifecycleService.onWillShutdown(e => this._onWillShutdown(e))); this._toDispose.push(this._lifecycleService.onShutdown(reason => this.terminate())); - this._toDispose.push(this._extensionHostDebugService.onClose(resource => { - if (this._isExtensionDevHost && this.matchesExtDevLocations(resource)) { + this._toDispose.push(this._extensionHostDebugService.onClose(event => { + if (this._isExtensionDevHost && this._environmentService.debugExtensionHost.debugId === event.sessionId) { this._windowService.closeWindow(); } })); - this._toDispose.push(this._extensionHostDebugService.onReload(resource => { - if (this._isExtensionDevHost && this.matchesExtDevLocations(resource)) { + this._toDispose.push(this._extensionHostDebugService.onReload(event => { + if (this._isExtensionDevHost && this._environmentService.debugExtensionHost.debugId === event.sessionId) { this._windowService.reloadWindow(); } })); @@ -120,16 +119,6 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter { })); } - // returns true if the given resource url matches one of the extension development paths passed to VS Code - private matchesExtDevLocations(resource: URI): boolean { - - const extDevLocs = this._environmentService.extensionDevelopmentLocationURI; - if (extDevLocs) { - return extDevLocs.some(extDevLoc => isEqual(extDevLoc, resource)); - } - return false; - } - public dispose(): void { this.terminate(); } diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionHostDebugService.ts b/src/vs/workbench/services/extensions/electron-browser/extensionHostDebugService.ts index a5e7a2dffd7..aa4a35f54dd 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionHostDebugService.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionHostDebugService.ts @@ -6,23 +6,20 @@ import { Event, Emitter } from 'vs/base/common/event'; import { IWindowService } from 'vs/platform/windows/common/windows'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; -import { IExtensionHostDebugService, IAttachSessionEvent, ITerminateSessionEvent, ILogToSessionEvent } from 'vs/workbench/services/extensions/common/extensionHostDebug'; -import { URI } from 'vs/base/common/uri'; +import { IExtensionHostDebugService, IAttachSessionEvent, ITerminateSessionEvent, ILogToSessionEvent, IReloadSessionEvent, ICloseSessionEvent } from 'vs/workbench/services/extensions/common/extensionHostDebug'; import { IRemoteConsoleLog } from 'vs/base/common/console'; import { ipcRenderer as ipc } from 'electron'; -interface IReloadBroadcast { +interface IReloadBroadcast extends IReloadSessionEvent { type: 'vscode:extensionReload'; - resource: string; } interface IAttachSessionBroadcast extends IAttachSessionEvent { type: 'vscode:extensionAttach'; } -interface ICloseBroadcast { +interface ICloseBroadcast extends ICloseSessionEvent { type: 'vscode:extensionCloseExtensionHost'; - resource: string; } interface ILogToSessionBroadcast extends ILogToSessionEvent { @@ -39,8 +36,8 @@ class ExtensionHostDebugService implements IExtensionHostDebugService { _serviceBrand: any; private windowId: number; - private readonly _onReload = new Emitter(); - private readonly _onClose = new Emitter(); + private readonly _onReload = new Emitter(); + private readonly _onClose = new Emitter(); private readonly _onAttachSession = new Emitter(); private readonly _onLogToSession = new Emitter(); private readonly _onTerminateSession = new Emitter(); @@ -53,10 +50,10 @@ class ExtensionHostDebugService implements IExtensionHostDebugService { ipc.on(CHANNEL, (_: unknown, broadcast: IReloadBroadcast | ICloseBroadcast | IAttachSessionBroadcast | ILogToSessionBroadcast | ITerminateSessionBroadcast) => { switch (broadcast.type) { case 'vscode:extensionReload': - this._onReload.fire(URI.parse(broadcast.resource)); + this._onReload.fire(broadcast); break; case 'vscode:extensionCloseExtensionHost': - this._onClose.fire(URI.parse(broadcast.resource)); + this._onClose.fire(broadcast); break; case 'vscode:extensionAttach': this._onAttachSession.fire(broadcast); @@ -71,25 +68,25 @@ class ExtensionHostDebugService implements IExtensionHostDebugService { }); } - reload(resource: URI): void { + reload(sessionId: string): void { ipc.send(CHANNEL, this.windowId, { type: 'vscode:extensionReload', - resource: resource.toString() + sessionId }); } - get onReload(): Event { + get onReload(): Event { return this._onReload.event; } - close(resource: URI): void { + close(sessionId: string): void { ipc.send(CHANNEL, this.windowId, { type: 'vscode:extensionCloseExtensionHost', - resource: resource.toString() + sessionId }); } - get onClose(): Event { + get onClose(): Event { return this._onClose.event; }