Merge branch 'main' into hediet/integrated-mule

This commit is contained in:
Henning Dieterichs 2022-11-14 16:43:57 +01:00
commit f637ecf996
No known key found for this signature in database
GPG key ID: 771381EFFDB9EC06
521 changed files with 6414 additions and 12346 deletions

View file

@ -18,7 +18,7 @@ If you already have VS Code and Docker installed, you can click the badge above
3. Install [Visual Studio Code Stable](https://code.visualstudio.com/) or [Insiders](https://code.visualstudio.com/insiders/) and the [Dev Containers](https://aka.ms/vscode-remote/download/containers) extension. 3. Install [Visual Studio Code Stable](https://code.visualstudio.com/) or [Insiders](https://code.visualstudio.com/insiders/) and the [Dev Containers](https://aka.ms/vscode-remote/download/containers) extension.
![Image of Dev Containers extension](https://microsoft.github.io/vscode-remote-release/images/remote-containers-extn.png) ![Image of Dev Containers extension](https://microsoft.github.io/vscode-remote-release/images/dev-containers-extn.png)
> **Note:** The Dev Containers extension requires the Visual Studio Code distribution of Code - OSS. See the [FAQ](https://aka.ms/vscode-remote/faq/license) for details. > **Note:** The Dev Containers extension requires the Visual Studio Code distribution of Code - OSS. See the [FAQ](https://aka.ms/vscode-remote/faq/license) for details.

View file

@ -0,0 +1,27 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as eslint from 'eslint';
export = new class DeclareServiceBrand implements eslint.Rule.RuleModule {
readonly meta: eslint.Rule.RuleMetaData = {
fixable: 'code'
};
create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener {
return {
['PropertyDefinition[key.name="_serviceBrand"][value]']: (node: any) => {
return context.report({
node,
message: `The '_serviceBrand'-property should not have a value`,
fix: (fixer) => {
return fixer.replaceText(node, 'declare _serviceBrand: undefined;')
}
});
}
};
}
};

View file

@ -85,6 +85,27 @@ export = new class NoUnexternalizedStrings implements eslint.Rule.RuleModule {
} }
} }
function visitL10NCall(node: TSESTree.CallExpression) {
// localize(key, message)
const [messageNode] = (<TSESTree.CallExpression>node).arguments;
// remove message-argument from doubleQuoted list and make
// sure it is a string-literal
if (isStringLiteral(messageNode)) {
doubleQuotedStringLiterals.delete(messageNode);
} else if (messageNode.type === AST_NODE_TYPES.ObjectExpression) {
for (const prop of messageNode.properties) {
if (prop.type === AST_NODE_TYPES.Property) {
if (prop.key.type === AST_NODE_TYPES.Identifier && prop.key.name === 'message') {
doubleQuotedStringLiterals.delete(prop.value);
break;
}
}
}
}
}
function reportBadStringsAndBadKeys() { function reportBadStringsAndBadKeys() {
// (1) // (1)
// report all strings that are in double quotes // report all strings that are in double quotes
@ -117,7 +138,16 @@ export = new class NoUnexternalizedStrings implements eslint.Rule.RuleModule {
return { return {
['Literal']: (node: any) => collectDoubleQuotedStrings(node), ['Literal']: (node: any) => collectDoubleQuotedStrings(node),
['ExpressionStatement[directive] Literal:exit']: (node: any) => doubleQuotedStringLiterals.delete(node), ['ExpressionStatement[directive] Literal:exit']: (node: any) => doubleQuotedStringLiterals.delete(node),
// localize(...)
['CallExpression[callee.type="MemberExpression"][callee.object.name="nls"][callee.property.name="localize"]:exit']: (node: any) => visitLocalizeCall(node), ['CallExpression[callee.type="MemberExpression"][callee.object.name="nls"][callee.property.name="localize"]:exit']: (node: any) => visitLocalizeCall(node),
// vscode.l10n.t(...)
['CallExpression[callee.type="MemberExpression"][callee.object.property.name="l10n"][callee.property.name="t"]:exit']: (node: any) => visitL10NCall(node),
// l10n.t(...)
['CallExpression[callee.object.name="l10n"][callee.property.name="t"]:exit']: (node: any) => visitL10NCall(node),
['CallExpression[callee.name="localize"][arguments.length>=2]:exit']: (node: any) => visitLocalizeCall(node), ['CallExpression[callee.name="localize"][arguments.length>=2]:exit']: (node: any) => visitLocalizeCall(node),
['Program:exit']: reportBadStringsAndBadKeys, ['Program:exit']: reportBadStringsAndBadKeys,
}; };

View file

@ -72,6 +72,7 @@
"local/code-no-nls-in-standalone-editor": "warn", "local/code-no-nls-in-standalone-editor": "warn",
"local/code-no-standalone-editor": "warn", "local/code-no-standalone-editor": "warn",
"local/code-no-unexternalized-strings": "warn", "local/code-no-unexternalized-strings": "warn",
"local/code-declare-service-brand": "warn",
"local/code-layering": [ "local/code-layering": [
"warn", "warn",
{ {
@ -331,7 +332,7 @@
"vs/base/parts/*/~", "vs/base/parts/*/~",
"vs/platform/*/~", "vs/platform/*/~",
"tas-client-umd", // node module allowed even in /common/ "tas-client-umd", // node module allowed even in /common/
"@microsoft/1ds-core-js",// node module allowed even in /common/ "@microsoft/1ds-core-js", // node module allowed even in /common/
"@microsoft/1ds-post-js" // node module allowed even in /common/ "@microsoft/1ds-post-js" // node module allowed even in /common/
] ]
}, },

View file

@ -7,7 +7,7 @@
"labels": { "labels": {
"L10N": {"assign": ["TylerLeonhardt", "csigs"]}, "L10N": {"assign": ["TylerLeonhardt", "csigs"]},
"VIM": {"assign": []}, "VIM": {"assign": []},
"accessibility": { "assign": ["isidorn"]}, "accessibility": { "assign": ["meganrogge"]},
"api": {"assign": ["jrieken"]}, "api": {"assign": ["jrieken"]},
"api-finalization": {"assign": []}, "api-finalization": {"assign": []},
"api-proposal": {"assign": ["jrieken"]}, "api-proposal": {"assign": ["jrieken"]},

View file

@ -157,7 +157,7 @@
{ {
"kind": 2, "kind": 2,
"language": "github-issues", "language": "github-issues",
"value": "$REPOS $MILESTONE -$MINE is:issue is:closed reason:completed sort:updated-asc label:bug -label:unreleased -label:verified -label:z-author-verified -label:on-testplan -label:*duplicate -label:duplicate -label:invalid -label:*as-designed -label:error-telemetry -label:verification-steps-needed -label:verification-found -author:aeschli -author:alexdima -author:alexr00 -author:AmandaSilver -author:andreamah -author:bamurtaugh -author:bpasero -author:chrisdias -author:chrmarti -author:Chuxel -author:claudiaregio -author:connor4312 -author:dbaeumer -author:deepak1556 -author:devinvalenciano -author:digitarald -author:DonJayamanne -author:egamma -author:fiveisprime -author:gregvanl -author:hediet -author:IanMatthewHuff -author:isidorn -author:joaomoreno -author:joyceerhl -author:jrieken -author:karrtikr -author:kieferrm -author:lramos15 -author:lszomoru -author:meganrogge -author:misolori -author:mjbvz -author:rebornix -author:roblourens -author:rzhao271 -author:sandy081 -author:sbatten -author:stevencl -author:tanhakabir -author:TylerLeonhardt -author:Tyriar -author:weinand -author:amunger" "value": "$REPOS $MILESTONE -$MINE is:issue is:closed reason:completed sort:updated-asc label:bug -label:unreleased -label:verified -label:z-author-verified -label:on-testplan -label:*duplicate -label:duplicate -label:invalid -label:*as-designed -label:error-telemetry -label:verification-steps-needed -label:verification-found -author:aeschli -author:alexdima -author:alexr00 -author:AmandaSilver -author:andreamah -author:bamurtaugh -author:bpasero -author:chrisdias -author:chrmarti -author:Chuxel -author:claudiaregio -author:connor4312 -author:dbaeumer -author:deepak1556 -author:devinvalenciano -author:digitarald -author:DonJayamanne -author:egamma -author:fiveisprime -author:gregvanl -author:hediet -author:isidorn -author:joaomoreno -author:joyceerhl -author:jrieken -author:karrtikr -author:kieferrm -author:lramos15 -author:lszomoru -author:meganrogge -author:misolori -author:mjbvz -author:rebornix -author:roblourens -author:rzhao271 -author:sandy081 -author:sbatten -author:stevencl -author:tanhakabir -author:TylerLeonhardt -author:Tyriar -author:weinand -author:amunger"
}, },
{ {
"kind": 1, "kind": 1,

View file

@ -32,7 +32,7 @@
{ {
"kind": 2, "kind": 2,
"language": "github-issues", "language": "github-issues",
"value": "$repos $milestone is:closed reason:completed -assignee:@me label:bug -label:verified -label:*duplicate -author:@me -assignee:@me label:bug -label:verified -author:@me -author:aeschli -author:alexdima -author:alexr00 -author:bpasero -author:chrisdias -author:chrmarti -author:connor4312 -author:dbaeumer -author:deepak1556 -author:eamodio -author:egamma -author:gregvanl -author:isidorn -author:JacksonKearl -author:joaomoreno -author:jrieken -author:lramos15 -author:lszomoru -author:meganrogge -author:misolori -author:mjbvz -author:rebornix -author:RMacfarlane -author:roblourens -author:sana-ajani -author:sandy081 -author:sbatten -author:Tyriar -author:weinand -author:rzhao271 -author:kieferrm -author:TylerLeonhardt -author:bamurtaugh -author:hediet -author:joyceerhl -author:rchiodo -author:IanMatthewHuff" "value": "$repos $milestone is:closed reason:completed -assignee:@me label:bug -label:verified -label:*duplicate -author:@me -assignee:@me label:bug -label:verified -author:@me -author:aeschli -author:alexdima -author:alexr00 -author:bpasero -author:chrisdias -author:chrmarti -author:connor4312 -author:dbaeumer -author:deepak1556 -author:eamodio -author:egamma -author:gregvanl -author:isidorn -author:JacksonKearl -author:joaomoreno -author:jrieken -author:lramos15 -author:lszomoru -author:meganrogge -author:misolori -author:mjbvz -author:rebornix -author:RMacfarlane -author:roblourens -author:sana-ajani -author:sandy081 -author:sbatten -author:Tyriar -author:weinand -author:rzhao271 -author:kieferrm -author:TylerLeonhardt -author:bamurtaugh -author:hediet -author:joyceerhl -author:rchiodo"
}, },
{ {
"kind": 1, "kind": 1,

View file

@ -36,3 +36,16 @@ xterm-addon-webgl/out/**
# This makes sure the model is included in the package # This makes sure the model is included in the package
!@vscode/vscode-languagedetection/model/** !@vscode/vscode-languagedetection/model/**
# Ensure only the required telemetry pieces are loaded in web to reduce bundle size
@microsoft/1ds-core-js/**
@microsoft/1ds-post-js/**
@microsoft/applicationinsights-core-js/**
@microsoft/applicationinsights-shims/**
!@microsoft/1ds-core-js/dist/ms.core.min.js
!@microsoft/1ds-post-js/dist/ms.post.min.js
!@microsoft/applicationinsights-core-js/browser/applicationinsights-core-js.min.js
!@microsoft/applicationinsights-shims/dist/umd/applicationinsights-shims.min.js

View file

@ -1,7 +1,7 @@
parameters: parameters:
- name: channel - name: channel
type: string type: string
default: stable default: 1.65.0
- name: targets - name: targets
default: [] default: []
type: object type: object

View file

@ -1,7 +1,7 @@
parameters: parameters:
- name: channel - name: channel
type: string type: string
default: stable default: 1.65.0
- name: targets - name: targets
default: [] default: []
type: object type: object

View file

@ -1,16 +1,5 @@
parameters:
- name: VSCODE_CLI_TARGETS
default: []
type: object
- name: VSCODE_CLI_RUST_CHANNEL
type: string
default: stable
steps: steps:
- template: ./install-rust-posix.yml - template: ./install-rust-posix.yml
parameters:
targets: []
channel: ${{ parameters.VSCODE_CLI_RUST_CHANNEL }}
- script: rustup component add clippy && cargo clippy -- -D warnings - script: rustup component add clippy && cargo clippy -- -D warnings
workingDirectory: cli workingDirectory: cli

View file

@ -7,9 +7,6 @@ parameters:
- name: VSCODE_BUILD_MACOS_ARM64 - name: VSCODE_BUILD_MACOS_ARM64
type: boolean type: boolean
default: false default: false
- name: channel
type: string
default: stable
steps: steps:
- task: Npm@1 - task: Npm@1

View file

@ -16,9 +16,6 @@ parameters:
default: false default: false
- name: VSCODE_QUALITY - name: VSCODE_QUALITY
type: string type: string
- name: channel
type: string
default: stable
steps: steps:
- task: Npm@1 - task: Npm@1

View file

@ -59,6 +59,23 @@ steps:
condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none'))
displayName: Setup NPM Registry displayName: Setup NPM Registry
# In Alpine, we always want to setup and authenticate against the NPM_REGISTRY
# because of the Prebuild step, since it always runs `yarn` from inside an alpine
# container
- script: |
set -e
npm config set registry "$NPM_REGISTRY" --location=project
npm config set always-auth=true --location=project
yarn config set registry "$NPM_REGISTRY"
condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none'))
displayName: Setup NPM & Yarn
- task: npmAuthenticate@0
inputs:
workingFile: .npmrc
condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none'))
displayName: Setup NPM Authentication
- script: | - script: |
mkdir -p .build mkdir -p .build
node build/azure-pipelines/common/computeNodeModulesCacheKey.js "alpine" > .build/yarnlockhash node build/azure-pipelines/common/computeNodeModulesCacheKey.js "alpine" > .build/yarnlockhash
@ -84,20 +101,6 @@ steps:
condition: and(succeeded(), eq(variables.NODE_MODULES_RESTORED, 'true')) condition: and(succeeded(), eq(variables.NODE_MODULES_RESTORED, 'true'))
displayName: Extract node_modules cache displayName: Extract node_modules cache
- script: |
set -e
npm config set registry "$NPM_REGISTRY" --location=project
npm config set always-auth=true --location=project
yarn config set registry "$NPM_REGISTRY"
condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), ne(variables['NPM_REGISTRY'], 'none'))
displayName: Setup NPM & Yarn
- task: npmAuthenticate@0
inputs:
workingFile: .npmrc
condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), ne(variables['NPM_REGISTRY'], 'none'))
displayName: Setup NPM Authentication
- script: | - script: |
set -e set -e
for i in {1..3}; do # try 3 times for i in {1..3}; do # try 3 times

View file

@ -191,7 +191,7 @@ stages:
VSCODE_BUILD_LINUX: ${{ parameters.VSCODE_BUILD_LINUX }} VSCODE_BUILD_LINUX: ${{ parameters.VSCODE_BUILD_LINUX }}
VSCODE_BUILD_LINUX_ALPINE: ${{ parameters.VSCODE_BUILD_LINUX_ALPINE }} VSCODE_BUILD_LINUX_ALPINE: ${{ parameters.VSCODE_BUILD_LINUX_ALPINE }}
- ${{ if or(eq(parameters.VSCODE_BUILD_LINUX_ARMHF, true), eq(parameters.VSCODE_BUILD_LINUX_ARM64, true)) }}: - ${{ if and(eq(variables['VSCODE_CIBUILD'], false), or(eq(parameters.VSCODE_BUILD_LINUX_ARMHF, true), eq(parameters.VSCODE_BUILD_LINUX_ARM64, true))) }}:
- job: LinuxGnuARM - job: LinuxGnuARM
pool: vscode-1es-linux pool: vscode-1es-linux
steps: steps:
@ -201,7 +201,7 @@ stages:
VSCODE_BUILD_LINUX_ARMHF: ${{ parameters.VSCODE_BUILD_LINUX_ARMHF }} VSCODE_BUILD_LINUX_ARMHF: ${{ parameters.VSCODE_BUILD_LINUX_ARMHF }}
VSCODE_BUILD_LINUX_ARM64: ${{ parameters.VSCODE_BUILD_LINUX_ARM64 }} VSCODE_BUILD_LINUX_ARM64: ${{ parameters.VSCODE_BUILD_LINUX_ARM64 }}
- ${{ if eq(parameters.VSCODE_BUILD_LINUX_ALPINE_ARM64, true) }}: - ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_LINUX_ALPINE_ARM64, true)) }}:
- job: LinuxAlpineARM64 - job: LinuxAlpineARM64
pool: vscode-1es-linux-20.04-arm64 pool: vscode-1es-linux-20.04-arm64
steps: steps:
@ -228,7 +228,7 @@ stages:
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_BUILD_MACOS: ${{ parameters.VSCODE_BUILD_MACOS }} VSCODE_BUILD_MACOS: ${{ parameters.VSCODE_BUILD_MACOS }}
- ${{ if eq(parameters.VSCODE_BUILD_MACOS_ARM64, true) }}: - ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_MACOS_ARM64, true)) }}:
- job: MacOSARM64 - job: MacOSARM64
pool: pool:
vmImage: macOS-11 vmImage: macOS-11
@ -247,7 +247,7 @@ stages:
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_BUILD_WIN32: ${{ parameters.VSCODE_BUILD_WIN32 }} VSCODE_BUILD_WIN32: ${{ parameters.VSCODE_BUILD_WIN32 }}
- ${{ if eq(parameters.VSCODE_BUILD_WIN32_ARM64, true) }}: - ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_WIN32_ARM64, true)) }}:
- job: WindowsARM64 - job: WindowsARM64
pool: vscode-1es-windows pool: vscode-1es-windows
steps: steps:
@ -256,7 +256,7 @@ stages:
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_BUILD_WIN32_ARM64: ${{ parameters.VSCODE_BUILD_WIN32_ARM64 }} VSCODE_BUILD_WIN32_ARM64: ${{ parameters.VSCODE_BUILD_WIN32_ARM64 }}
- ${{ if eq(parameters.VSCODE_BUILD_WIN32_32BIT, true) }}: - ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_WIN32_32BIT, true)) }}:
- job: WindowsX86 - job: WindowsX86
pool: vscode-1es-windows pool: vscode-1es-windows
steps: steps:

View file

@ -10,6 +10,10 @@ steps:
KeyVaultName: vscode KeyVaultName: vscode
SecretsFilter: "github-distro-mixin-password" SecretsFilter: "github-distro-mixin-password"
# allow-any-unicode-next-line
- pwsh: Write-Host "##vso[build.addbuildtag]🚀"
displayName: Add build tag
- script: | - script: |
set -e set -e
cat << EOF > ~/.netrc cat << EOF > ~/.netrc

View file

@ -10,9 +10,6 @@ parameters:
default: false default: false
- name: VSCODE_QUALITY - name: VSCODE_QUALITY
type: string type: string
- name: channel
type: string
default: stable
steps: steps:
- task: Npm@1 - task: Npm@1

View file

@ -86,14 +86,13 @@ steps:
- powershell: | - powershell: |
if (!(Test-Path ".build")) { New-Item -Path ".build" -ItemType Directory } if (!(Test-Path ".build")) { New-Item -Path ".build" -ItemType Directory }
"$(VSCODE_ARCH)" | Out-File -Encoding ascii -NoNewLine .build\arch node build/azure-pipelines/common/computeNodeModulesCacheKey.js $(VSCODE_ARCH) > .build/yarnlockhash
node build/azure-pipelines/common/computeNodeModulesCacheKey.js > .build/yarnlockhash
node build/azure-pipelines/common/computeBuiltInDepsCacheKey.js > .build/builtindepshash node build/azure-pipelines/common/computeBuiltInDepsCacheKey.js > .build/builtindepshash
displayName: Prepare yarn cache flags displayName: Prepare yarn cache flags
- task: Cache@2 - task: Cache@2
inputs: inputs:
key: "nodeModules | $(Agent.OS) | .build/arch, .build/yarnlockhash" key: "nodeModules | $(Agent.OS) | .build/yarnlockhash"
path: .build/node_modules_cache path: .build/node_modules_cache
cacheHitVar: NODE_MODULES_RESTORED cacheHitVar: NODE_MODULES_RESTORED
displayName: Restore node_modules cache displayName: Restore node_modules cache

View file

@ -87,7 +87,7 @@ function buildWin32Setup(arch, target) {
productJson['target'] = target; productJson['target'] = target;
fs.writeFileSync(productJsonPath, JSON.stringify(productJson, undefined, '\t')); fs.writeFileSync(productJsonPath, JSON.stringify(productJson, undefined, '\t'));
const quality = product.quality; const quality = product.quality || 'dev';
const definitions = { const definitions = {
NameLong: product.nameLong, NameLong: product.nameLong,
NameShort: product.nameShort, NameShort: product.nameShort,
@ -115,11 +115,7 @@ function buildWin32Setup(arch, target) {
}; };
if (quality === 'insider') { if (quality === 'insider') {
const appxPackagePrefix = 'code_insiders'; definitions['AppxPackage'] = `code_insiders_explorer_${arch === 'ia32' ? 'x86' : arch}.appx`;
definitions['AppxPackage'] = `${appxPackagePrefix}_explorer_${arch}.appx`;
if (arch === 'ia32') {
definitions['AppxPackage'] = `${appxPackagePrefix}_explorer_x86.appx`;
}
definitions['AppxPackageFullname'] = `Microsoft.${product.win32RegValueName}_1.0.0.0_neutral__8wekyb3d8bbwe`; definitions['AppxPackageFullname'] = `Microsoft.${product.win32RegValueName}_1.0.0.0_neutral__8wekyb3d8bbwe`;
} }

View file

@ -122,8 +122,12 @@ function watchTask(out, build) {
exports.watchTask = watchTask; exports.watchTask = watchTask;
const REPO_SRC_FOLDER = path.join(__dirname, '../../src'); const REPO_SRC_FOLDER = path.join(__dirname, '../../src');
class MonacoGenerator { class MonacoGenerator {
_isWatch;
stream;
_watchedFiles;
_fsProvider;
_declarationResolver;
constructor(isWatch) { constructor(isWatch) {
this._executeSoonTimer = null;
this._isWatch = isWatch; this._isWatch = isWatch;
this.stream = es.through(); this.stream = es.through();
this._watchedFiles = {}; this._watchedFiles = {};
@ -153,6 +157,7 @@ class MonacoGenerator {
}); });
} }
} }
_executeSoonTimer = null;
_executeSoon() { _executeSoon() {
if (this._executeSoonTimer !== null) { if (this._executeSoonTimer !== null) {
clearTimeout(this._executeSoonTimer); clearTimeout(this._executeSoonTimer);

View file

@ -36,12 +36,6 @@ exports.extraLanguages = [
{ id: 'hu', folderName: 'hun' }, { id: 'hu', folderName: 'hun' },
{ id: 'tr', folderName: 'trk' } { id: 'tr', folderName: 'trk' }
]; ];
// non built-in extensions also that are transifex and need to be part of the language packs
const externalExtensionsWithTranslations = {
'vscode-chrome-debug': 'msjsdiag.debugger-for-chrome',
'vscode-node-debug': 'ms-vscode.node-debug',
'vscode-node-debug2': 'ms-vscode.node-debug2'
};
var LocalizeInfo; var LocalizeInfo;
(function (LocalizeInfo) { (function (LocalizeInfo) {
function is(value) { function is(value) {
@ -63,8 +57,8 @@ var BundledFormat;
BundledFormat.is = is; BundledFormat.is = is;
})(BundledFormat || (BundledFormat = {})); })(BundledFormat || (BundledFormat = {}));
class Line { class Line {
buffer = [];
constructor(indent = 0) { constructor(indent = 0) {
this.buffer = [];
if (indent > 0) { if (indent > 0) {
this.buffer.push(new Array(indent + 1).join(' ')); this.buffer.push(new Array(indent + 1).join(' '));
} }
@ -79,6 +73,7 @@ class Line {
} }
exports.Line = Line; exports.Line = Line;
class TextModel { class TextModel {
_lines;
constructor(contents) { constructor(contents) {
this._lines = contents.split(/\r\n|\r|\n/); this._lines = contents.split(/\r\n|\r|\n/);
} }
@ -87,6 +82,10 @@ class TextModel {
} }
} }
class XLF { class XLF {
project;
buffer;
files;
numberOfMessages;
constructor(project) { constructor(project) {
this.project = project; this.project = project;
this.buffer = []; this.buffer = [];
@ -168,55 +167,55 @@ class XLF {
line.append(content); line.append(content);
this.buffer.push(line.toString()); this.buffer.push(line.toString());
} }
static parse = function (xlfString) {
return new Promise((resolve, reject) => {
const parser = new xml2js.Parser();
const files = [];
parser.parseString(xlfString, function (err, result) {
if (err) {
reject(new Error(`XLF parsing error: Failed to parse XLIFF string. ${err}`));
}
const fileNodes = result['xliff']['file'];
if (!fileNodes) {
reject(new Error(`XLF parsing error: XLIFF file does not contain "xliff" or "file" node(s) required for parsing.`));
}
fileNodes.forEach((file) => {
const name = file.$.original;
if (!name) {
reject(new Error(`XLF parsing error: XLIFF file node does not contain original attribute to determine the original location of the resource file.`));
}
const language = file.$['target-language'];
if (!language) {
reject(new Error(`XLF parsing error: XLIFF file node does not contain target-language attribute to determine translated language.`));
}
const messages = {};
const transUnits = file.body[0]['trans-unit'];
if (transUnits) {
transUnits.forEach((unit) => {
const key = unit.$.id;
if (!unit.target) {
return; // No translation available
}
let val = unit.target[0];
if (typeof val !== 'string') {
// We allow empty source values so support them for translations as well.
val = val._ ? val._ : '';
}
if (!key) {
reject(new Error(`XLF parsing error: trans-unit ${JSON.stringify(unit, undefined, 0)} defined in file ${name} is missing the ID attribute.`));
return;
}
messages[key] = decodeEntities(val);
});
files.push({ messages, name, language: language.toLowerCase() });
}
});
resolve(files);
});
});
};
} }
exports.XLF = XLF; exports.XLF = XLF;
XLF.parse = function (xlfString) {
return new Promise((resolve, reject) => {
const parser = new xml2js.Parser();
const files = [];
parser.parseString(xlfString, function (err, result) {
if (err) {
reject(new Error(`XLF parsing error: Failed to parse XLIFF string. ${err}`));
}
const fileNodes = result['xliff']['file'];
if (!fileNodes) {
reject(new Error(`XLF parsing error: XLIFF file does not contain "xliff" or "file" node(s) required for parsing.`));
}
fileNodes.forEach((file) => {
const name = file.$.original;
if (!name) {
reject(new Error(`XLF parsing error: XLIFF file node does not contain original attribute to determine the original location of the resource file.`));
}
const language = file.$['target-language'];
if (!language) {
reject(new Error(`XLF parsing error: XLIFF file node does not contain target-language attribute to determine translated language.`));
}
const messages = {};
const transUnits = file.body[0]['trans-unit'];
if (transUnits) {
transUnits.forEach((unit) => {
const key = unit.$.id;
if (!unit.target) {
return; // No translation available
}
let val = unit.target[0];
if (typeof val !== 'string') {
// We allow empty source values so support them for translations as well.
val = val._ ? val._ : '';
}
if (!key) {
reject(new Error(`XLF parsing error: trans-unit ${JSON.stringify(unit, undefined, 0)} defined in file ${name} is missing the ID attribute.`));
return;
}
messages[key] = decodeEntities(val);
});
files.push({ messages, name, language: language.toLowerCase() });
}
});
resolve(files);
});
});
};
function sortLanguages(languages) { function sortLanguages(languages) {
return languages.sort((a, b) => { return languages.sort((a, b) => {
return a.id < b.id ? -1 : (a.id > b.id ? 1 : 0); return a.id < b.id ? -1 : (a.id > b.id ? 1 : 0);
@ -508,21 +507,27 @@ function createXlfFilesForCoreBundle() {
}); });
} }
exports.createXlfFilesForCoreBundle = createXlfFilesForCoreBundle; exports.createXlfFilesForCoreBundle = createXlfFilesForCoreBundle;
function createL10nBundleForExtension(extensionName) { function createL10nBundleForExtension(extensionFolderName) {
const result = (0, event_stream_1.through)(); const result = (0, event_stream_1.through)();
gulp.src([ gulp.src([
`extensions/${extensionName}/src/**/*.ts`, // For source code of extensions
`extensions/${extensionFolderName}/src/**/*.{ts,tsx}`,
// For any dependencies pulled in (think vscode-css-languageservice or @vscode/emmet-helper)
`extensions/${extensionFolderName}/node_modules/**/*.{js,jsx}`
]).pipe((0, event_stream_1.writeArray)((err, files) => { ]).pipe((0, event_stream_1.writeArray)((err, files) => {
if (err) { if (err) {
result.emit('error', err); result.emit('error', err);
return; return;
} }
const json = (0, l10n_dev_1.getL10nJson)(files.map(file => { const json = (0, l10n_dev_1.getL10nJson)(files
return file.contents.toString('utf8'); .filter(file => file.isBuffer())
})); .map(file => ({
contents: file.contents.toString('utf8'),
extension: path.extname(file.path)
})));
if (Object.keys(json).length > 0) { if (Object.keys(json).length > 0) {
result.emit('data', new File({ result.emit('data', new File({
path: `${extensionName}/bundle.l10n.json`, path: `extensions/${extensionFolderName}/bundle.l10n.json`,
contents: Buffer.from(JSON.stringify(json), 'utf8') contents: Buffer.from(JSON.stringify(json), 'utf8')
})); }));
} }
@ -540,10 +545,14 @@ function createXlfFilesForExtensions() {
if (!stat.isDirectory()) { if (!stat.isDirectory()) {
return; return;
} }
const extensionName = path.basename(extensionFolder.path); const extensionFolderName = path.basename(extensionFolder.path);
if (extensionName === 'node_modules') { if (extensionFolderName === 'node_modules') {
return; return;
} }
// Get extension id and use that as the id
const manifest = fs.readFileSync(path.join(extensionFolder.path, 'package.json'), 'utf-8');
const manifestJson = JSON.parse(manifest);
const extensionId = manifestJson.publisher + '.' + manifestJson.name;
counter++; counter++;
let _l10nMap; let _l10nMap;
function getL10nMap() { function getL10nMap() {
@ -552,17 +561,17 @@ function createXlfFilesForExtensions() {
} }
return _l10nMap; return _l10nMap;
} }
(0, event_stream_1.merge)(gulp.src([`.build/extensions/${extensionName}/package.nls.json`, `.build/extensions/${extensionName}/**/nls.metadata.json`], { allowEmpty: true }), createL10nBundleForExtension(extensionName)).pipe((0, event_stream_1.through)(function (file) { (0, event_stream_1.merge)(gulp.src([`.build/extensions/${extensionFolderName}/package.nls.json`, `.build/extensions/${extensionFolderName}/**/nls.metadata.json`], { allowEmpty: true }), createL10nBundleForExtension(extensionFolderName)).pipe((0, event_stream_1.through)(function (file) {
if (file.isBuffer()) { if (file.isBuffer()) {
const buffer = file.contents; const buffer = file.contents;
const basename = path.basename(file.path); const basename = path.basename(file.path);
if (basename === 'package.nls.json') { if (basename === 'package.nls.json') {
const json = JSON.parse(buffer.toString('utf8')); const json = JSON.parse(buffer.toString('utf8'));
getL10nMap().set(`extensions/${extensionName}/package`, json); getL10nMap().set(`extensions/${extensionId}/package`, json);
} }
else if (basename === 'nls.metadata.json') { else if (basename === 'nls.metadata.json') {
const json = JSON.parse(buffer.toString('utf8')); const json = JSON.parse(buffer.toString('utf8'));
const relPath = path.relative(`.build/extensions/${extensionName}`, path.dirname(file.path)); const relPath = path.relative(`.build/extensions/${extensionFolderName}`, path.dirname(file.path));
for (const file in json) { for (const file in json) {
const fileContent = json[file]; const fileContent = json[file];
const info = Object.create(null); const info = Object.create(null);
@ -573,12 +582,12 @@ function createXlfFilesForExtensions() {
: { key: fileContent.keys[i], comment: undefined }; : { key: fileContent.keys[i], comment: undefined };
info[key] = comment ? { message, comment } : message; info[key] = comment ? { message, comment } : message;
} }
getL10nMap().set(`extensions/${extensionName}/${relPath}/${file}`, info); getL10nMap().set(`extensions/${extensionId}/${relPath}/${file}`, info);
} }
} }
else if (basename === 'bundle.l10n.json') { else if (basename === 'bundle.l10n.json') {
const json = JSON.parse(buffer.toString('utf8')); const json = JSON.parse(buffer.toString('utf8'));
getL10nMap().set(`extensions/${extensionName}/bundle`, json); getL10nMap().set(`extensions/${extensionId}/bundle`, json);
} }
else { else {
this.emit('error', new Error(`${file.path} is not a valid extension nls file`)); this.emit('error', new Error(`${file.path} is not a valid extension nls file`));
@ -588,7 +597,7 @@ function createXlfFilesForExtensions() {
}, function () { }, function () {
if (_l10nMap?.size > 0) { if (_l10nMap?.size > 0) {
const xlfFile = new File({ const xlfFile = new File({
path: path.join(extensionsProject, extensionName + '.xlf'), path: path.join(extensionsProject, extensionId + '.xlf'),
contents: Buffer.from((0, l10n_dev_1.getL10nXlf)(_l10nMap), 'utf8') contents: Buffer.from((0, l10n_dev_1.getL10nXlf)(_l10nMap), 'utf8')
}); });
folderStream.queue(xlfFile); folderStream.queue(xlfFile);
@ -707,18 +716,14 @@ function prepareI18nPackFiles(resultingTranslationPaths) {
const path = file.name; const path = file.name;
const firstSlash = path.indexOf('/'); const firstSlash = path.indexOf('/');
if (project === extensionsProject) { if (project === extensionsProject) {
// resource will be the extension id
let extPack = extensionsPacks[resource]; let extPack = extensionsPacks[resource];
if (!extPack) { if (!extPack) {
extPack = extensionsPacks[resource] = { version: i18nPackVersion, contents: {} }; extPack = extensionsPacks[resource] = { version: i18nPackVersion, contents: {} };
} }
const externalId = externalExtensionsWithTranslations[resource]; // remove 'extensions/extensionId/' segment
if (!externalId) { // internal extension: remove 'extensions/extensionId/' segnent const secondSlash = path.indexOf('/', firstSlash + 1);
const secondSlash = path.indexOf('/', firstSlash + 1); extPack.contents[path.substring(secondSlash + 1)] = getRecordFromL10nJsonFormat(file.messages);
extPack.contents[path.substring(secondSlash + 1)] = getRecordFromL10nJsonFormat(file.messages);
}
else {
extPack.contents[path] = getRecordFromL10nJsonFormat(file.messages);
}
} }
else { else {
mainPack.contents[path.substring(firstSlash + 1)] = getRecordFromL10nJsonFormat(file.messages); mainPack.contents[path.substring(firstSlash + 1)] = getRecordFromL10nJsonFormat(file.messages);
@ -736,16 +741,10 @@ function prepareI18nPackFiles(resultingTranslationPaths) {
const translatedMainFile = createI18nFile('./main', mainPack); const translatedMainFile = createI18nFile('./main', mainPack);
resultingTranslationPaths.push({ id: 'vscode', resourceName: 'main.i18n.json' }); resultingTranslationPaths.push({ id: 'vscode', resourceName: 'main.i18n.json' });
this.queue(translatedMainFile); this.queue(translatedMainFile);
for (const extension in extensionsPacks) { for (const extensionId in extensionsPacks) {
const translatedExtFile = createI18nFile(`extensions/${extension}`, extensionsPacks[extension]); const translatedExtFile = createI18nFile(`extensions/${extensionId}`, extensionsPacks[extensionId]);
this.queue(translatedExtFile); this.queue(translatedExtFile);
const externalExtensionId = externalExtensionsWithTranslations[extension]; resultingTranslationPaths.push({ id: extensionId, resourceName: `extensions/${extensionId}.i18n.json` });
if (externalExtensionId) {
resultingTranslationPaths.push({ id: externalExtensionId, resourceName: `extensions/${extension}.i18n.json` });
}
else {
resultingTranslationPaths.push({ id: `vscode.${extension}`, resourceName: `extensions/${extension}.i18n.json` });
}
} }
this.queue(null); this.queue(null);
}) })

View file

@ -49,13 +49,6 @@ export const extraLanguages: Language[] = [
{ id: 'tr', folderName: 'trk' } { id: 'tr', folderName: 'trk' }
]; ];
// non built-in extensions also that are transifex and need to be part of the language packs
const externalExtensionsWithTranslations: Record<string, string> = {
'vscode-chrome-debug': 'msjsdiag.debugger-for-chrome',
'vscode-node-debug': 'ms-vscode.node-debug',
'vscode-node-debug2': 'ms-vscode.node-debug2'
};
interface Item { interface Item {
id: string; id: string;
message: string; message: string;
@ -586,23 +579,29 @@ export function createXlfFilesForCoreBundle(): ThroughStream {
}); });
} }
function createL10nBundleForExtension(extensionName: string): ThroughStream { function createL10nBundleForExtension(extensionFolderName: string): ThroughStream {
const result = through(); const result = through();
gulp.src([ gulp.src([
`extensions/${extensionName}/src/**/*.ts`, // For source code of extensions
`extensions/${extensionFolderName}/src/**/*.{ts,tsx}`,
// For any dependencies pulled in (think vscode-css-languageservice or @vscode/emmet-helper)
`extensions/${extensionFolderName}/node_modules/**/*.{js,jsx}`
]).pipe(writeArray((err, files: File[]) => { ]).pipe(writeArray((err, files: File[]) => {
if (err) { if (err) {
result.emit('error', err); result.emit('error', err);
return; return;
} }
const json = getL10nJson(files.map(file => { const json = getL10nJson(files
return file.contents.toString('utf8'); .filter(file => file.isBuffer())
})); .map(file => ({
contents: file.contents.toString('utf8'),
extension: path.extname(file.path)
})));
if (Object.keys(json).length > 0) { if (Object.keys(json).length > 0) {
result.emit('data', new File({ result.emit('data', new File({
path: `${extensionName}/bundle.l10n.json`, path: `extensions/${extensionFolderName}/bundle.l10n.json`,
contents: Buffer.from(JSON.stringify(json), 'utf8') contents: Buffer.from(JSON.stringify(json), 'utf8')
})); }));
} }
@ -622,10 +621,15 @@ export function createXlfFilesForExtensions(): ThroughStream {
if (!stat.isDirectory()) { if (!stat.isDirectory()) {
return; return;
} }
const extensionName = path.basename(extensionFolder.path); const extensionFolderName = path.basename(extensionFolder.path);
if (extensionName === 'node_modules') { if (extensionFolderName === 'node_modules') {
return; return;
} }
// Get extension id and use that as the id
const manifest = fs.readFileSync(path.join(extensionFolder.path, 'package.json'), 'utf-8');
const manifestJson = JSON.parse(manifest);
const extensionId = manifestJson.publisher + '.' + manifestJson.name;
counter++; counter++;
let _l10nMap: Map<string, l10nJsonFormat>; let _l10nMap: Map<string, l10nJsonFormat>;
function getL10nMap() { function getL10nMap() {
@ -635,18 +639,18 @@ export function createXlfFilesForExtensions(): ThroughStream {
return _l10nMap; return _l10nMap;
} }
merge( merge(
gulp.src([`.build/extensions/${extensionName}/package.nls.json`, `.build/extensions/${extensionName}/**/nls.metadata.json`], { allowEmpty: true }), gulp.src([`.build/extensions/${extensionFolderName}/package.nls.json`, `.build/extensions/${extensionFolderName}/**/nls.metadata.json`], { allowEmpty: true }),
createL10nBundleForExtension(extensionName) createL10nBundleForExtension(extensionFolderName)
).pipe(through(function (file: File) { ).pipe(through(function (file: File) {
if (file.isBuffer()) { if (file.isBuffer()) {
const buffer: Buffer = file.contents as Buffer; const buffer: Buffer = file.contents as Buffer;
const basename = path.basename(file.path); const basename = path.basename(file.path);
if (basename === 'package.nls.json') { if (basename === 'package.nls.json') {
const json: l10nJsonFormat = JSON.parse(buffer.toString('utf8')); const json: l10nJsonFormat = JSON.parse(buffer.toString('utf8'));
getL10nMap().set(`extensions/${extensionName}/package`, json); getL10nMap().set(`extensions/${extensionId}/package`, json);
} else if (basename === 'nls.metadata.json') { } else if (basename === 'nls.metadata.json') {
const json: BundledExtensionFormat = JSON.parse(buffer.toString('utf8')); const json: BundledExtensionFormat = JSON.parse(buffer.toString('utf8'));
const relPath = path.relative(`.build/extensions/${extensionName}`, path.dirname(file.path)); const relPath = path.relative(`.build/extensions/${extensionFolderName}`, path.dirname(file.path));
for (const file in json) { for (const file in json) {
const fileContent = json[file]; const fileContent = json[file];
const info: l10nJsonFormat = Object.create(null); const info: l10nJsonFormat = Object.create(null);
@ -658,11 +662,11 @@ export function createXlfFilesForExtensions(): ThroughStream {
info[key] = comment ? { message, comment } : message; info[key] = comment ? { message, comment } : message;
} }
getL10nMap().set(`extensions/${extensionName}/${relPath}/${file}`, info); getL10nMap().set(`extensions/${extensionId}/${relPath}/${file}`, info);
} }
} else if (basename === 'bundle.l10n.json') { } else if (basename === 'bundle.l10n.json') {
const json: l10nJsonFormat = JSON.parse(buffer.toString('utf8')); const json: l10nJsonFormat = JSON.parse(buffer.toString('utf8'));
getL10nMap().set(`extensions/${extensionName}/bundle`, json); getL10nMap().set(`extensions/${extensionId}/bundle`, json);
} else { } else {
this.emit('error', new Error(`${file.path} is not a valid extension nls file`)); this.emit('error', new Error(`${file.path} is not a valid extension nls file`));
return; return;
@ -671,7 +675,7 @@ export function createXlfFilesForExtensions(): ThroughStream {
}, function () { }, function () {
if (_l10nMap?.size > 0) { if (_l10nMap?.size > 0) {
const xlfFile = new File({ const xlfFile = new File({
path: path.join(extensionsProject, extensionName + '.xlf'), path: path.join(extensionsProject, extensionId + '.xlf'),
contents: Buffer.from(getL10nXlf(_l10nMap), 'utf8') contents: Buffer.from(getL10nXlf(_l10nMap), 'utf8')
}); });
folderStream.queue(xlfFile); folderStream.queue(xlfFile);
@ -813,17 +817,14 @@ export function prepareI18nPackFiles(resultingTranslationPaths: TranslationPath[
const firstSlash = path.indexOf('/'); const firstSlash = path.indexOf('/');
if (project === extensionsProject) { if (project === extensionsProject) {
// resource will be the extension id
let extPack = extensionsPacks[resource]; let extPack = extensionsPacks[resource];
if (!extPack) { if (!extPack) {
extPack = extensionsPacks[resource] = { version: i18nPackVersion, contents: {} }; extPack = extensionsPacks[resource] = { version: i18nPackVersion, contents: {} };
} }
const externalId = externalExtensionsWithTranslations[resource]; // remove 'extensions/extensionId/' segment
if (!externalId) { // internal extension: remove 'extensions/extensionId/' segnent const secondSlash = path.indexOf('/', firstSlash + 1);
const secondSlash = path.indexOf('/', firstSlash + 1); extPack.contents[path.substring(secondSlash + 1)] = getRecordFromL10nJsonFormat(file.messages);
extPack.contents[path.substring(secondSlash + 1)] = getRecordFromL10nJsonFormat(file.messages);
} else {
extPack.contents[path] = getRecordFromL10nJsonFormat(file.messages);
}
} else { } else {
mainPack.contents[path.substring(firstSlash + 1)] = getRecordFromL10nJsonFormat(file.messages); mainPack.contents[path.substring(firstSlash + 1)] = getRecordFromL10nJsonFormat(file.messages);
} }
@ -842,17 +843,11 @@ export function prepareI18nPackFiles(resultingTranslationPaths: TranslationPath[
resultingTranslationPaths.push({ id: 'vscode', resourceName: 'main.i18n.json' }); resultingTranslationPaths.push({ id: 'vscode', resourceName: 'main.i18n.json' });
this.queue(translatedMainFile); this.queue(translatedMainFile);
for (const extension in extensionsPacks) { for (const extensionId in extensionsPacks) {
const translatedExtFile = createI18nFile(`extensions/${extension}`, extensionsPacks[extension]); const translatedExtFile = createI18nFile(`extensions/${extensionId}`, extensionsPacks[extensionId]);
this.queue(translatedExtFile); this.queue(translatedExtFile);
const externalExtensionId = externalExtensionsWithTranslations[extension]; resultingTranslationPaths.push({ id: extensionId, resourceName: `extensions/${extensionId}.i18n.json` });
if (externalExtensionId) {
resultingTranslationPaths.push({ id: externalExtensionId, resourceName: `extensions/${extension}.i18n.json` });
} else {
resultingTranslationPaths.push({ id: `vscode.${extension}`, resourceName: `extensions/${extension}.i18n.json` });
}
} }
this.queue(null); this.queue(null);
}) })

View file

@ -492,12 +492,17 @@ class FSProvider {
} }
exports.FSProvider = FSProvider; exports.FSProvider = FSProvider;
class CacheEntry { class CacheEntry {
sourceFile;
mtime;
constructor(sourceFile, mtime) { constructor(sourceFile, mtime) {
this.sourceFile = sourceFile; this.sourceFile = sourceFile;
this.mtime = mtime; this.mtime = mtime;
} }
} }
class DeclarationResolver { class DeclarationResolver {
_fsProvider;
ts;
_sourceFileCache;
constructor(_fsProvider) { constructor(_fsProvider) {
this._fsProvider = _fsProvider; this._fsProvider = _fsProvider;
this.ts = require('typescript'); this.ts = require('typescript');
@ -553,6 +558,10 @@ function run3(resolver) {
} }
exports.run3 = run3; exports.run3 = run3;
class TypeScriptLanguageServiceHost { class TypeScriptLanguageServiceHost {
_ts;
_libs;
_files;
_compilerOptions;
constructor(ts, libs, files, compilerOptions) { constructor(ts, libs, files, compilerOptions) {
this._ts = ts; this._ts = ts;
this._libs = libs; this._libs = libs;

View file

@ -95,18 +95,22 @@ var _nls;
return { line: position.line - 1, character: position.column }; return { line: position.line - 1, character: position.column };
} }
class SingleFileServiceHost { class SingleFileServiceHost {
options;
filename;
file;
lib;
constructor(ts, options, filename, contents) { constructor(ts, options, filename, contents) {
this.options = options; this.options = options;
this.filename = filename; this.filename = filename;
this.getCompilationSettings = () => this.options;
this.getScriptFileNames = () => [this.filename];
this.getScriptVersion = () => '1';
this.getScriptSnapshot = (name) => name === this.filename ? this.file : this.lib;
this.getCurrentDirectory = () => '';
this.getDefaultLibFileName = () => 'lib.d.ts';
this.file = ts.ScriptSnapshot.fromString(contents); this.file = ts.ScriptSnapshot.fromString(contents);
this.lib = ts.ScriptSnapshot.fromString(''); this.lib = ts.ScriptSnapshot.fromString('');
} }
getCompilationSettings = () => this.options;
getScriptFileNames = () => [this.filename];
getScriptVersion = () => '1';
getScriptSnapshot = (name) => name === this.filename ? this.file : this.lib;
getCurrentDirectory = () => '';
getDefaultLibFileName = () => 'lib.d.ts';
readFile(path, _encoding) { readFile(path, _encoding) {
if (path === this.filename) { if (path === this.filename) {
return this.file.getText(0, this.file.getLength()); return this.file.getText(0, this.file.getLength());
@ -208,6 +212,8 @@ var _nls;
}; };
} }
class TextModel { class TextModel {
lines;
lineEndings;
constructor(contents) { constructor(contents) {
const regex = /\r\n|\r|\n/g; const regex = /\r\n|\r|\n/g;
let index = 0; let index = 0;

View file

@ -41,6 +41,12 @@ function renderADMLString(prefix, moduleName, nlsString, translations) {
return `<string id="${prefix}_${nlsString.nlsKey}">${value}</string>`; return `<string id="${prefix}_${nlsString.nlsKey}">${value}</string>`;
} }
class BasePolicy { class BasePolicy {
policyType;
name;
category;
minimumVersion;
description;
moduleName;
constructor(policyType, name, category, minimumVersion, description, moduleName) { constructor(policyType, name, category, minimumVersion, description, moduleName) {
this.policyType = policyType; this.policyType = policyType;
this.name = name; this.name = name;
@ -96,6 +102,7 @@ class BooleanPolicy extends BasePolicy {
} }
} }
class IntPolicy extends BasePolicy { class IntPolicy extends BasePolicy {
defaultValue;
static from(name, category, minimumVersion, description, moduleName, settingNode) { static from(name, category, minimumVersion, description, moduleName, settingNode) {
const type = getStringProperty(settingNode, 'type'); const type = getStringProperty(settingNode, 'type');
if (type !== 'number') { if (type !== 'number') {
@ -140,6 +147,8 @@ class StringPolicy extends BasePolicy {
} }
} }
class StringEnumPolicy extends BasePolicy { class StringEnumPolicy extends BasePolicy {
enum_;
enumDescriptions;
static from(name, category, minimumVersion, description, moduleName, settingNode) { static from(name, category, minimumVersion, description, moduleName, settingNode) {
const type = getStringProperty(settingNode, 'type'); const type = getStringProperty(settingNode, 'type');
if (type !== 'string') { if (type !== 'string') {

View file

@ -12,12 +12,13 @@ const ansiColors = require("ansi-colors");
const fs = require("fs"); const fs = require("fs");
const path = require("path"); const path = require("path");
class ErrorLog { class ErrorLog {
id;
constructor(id) { constructor(id) {
this.id = id; this.id = id;
this.allErrors = [];
this.startTime = null;
this.count = 0;
} }
allErrors = [];
startTime = null;
count = 0;
onStart() { onStart() {
if (this.count++ > 0) { if (this.count++ > 0) {
return; return;

View file

@ -9,6 +9,9 @@ const es = require("event-stream");
const fancyLog = require("fancy-log"); const fancyLog = require("fancy-log");
const ansiColors = require("ansi-colors"); const ansiColors = require("ansi-colors");
class Entry { class Entry {
name;
totalCount;
totalSize;
constructor(name, totalCount, totalSize) { constructor(name, totalCount, totalSize) {
this.name = name; this.name = name;
this.totalCount = totalCount; this.totalCount = totalCount;

View file

@ -163,6 +163,10 @@ function processLibFiles(ts, options) {
* A TypeScript language service host * A TypeScript language service host
*/ */
class TypeScriptLanguageServiceHost { class TypeScriptLanguageServiceHost {
_ts;
_libs;
_files;
_compilerOptions;
constructor(ts, libs, files, compilerOptions) { constructor(ts, libs, files, compilerOptions) {
this._ts = ts; this._ts = ts;
this._libs = libs; this._libs = libs;
@ -747,6 +751,8 @@ function findSymbolFromHeritageType(ts, checker, type) {
return null; return null;
} }
class SymbolImportTuple { class SymbolImportTuple {
symbol;
symbolImportNode;
constructor(symbol, symbolImportNode) { constructor(symbol, symbolImportNode) {
this.symbol = symbol; this.symbol = symbol;
this.symbolImportNode = symbolImportNode; this.symbolImportNode = symbolImportNode;

View file

@ -299,6 +299,8 @@ function createTypeScriptBuilder(config, projectFile, cmd) {
} }
exports.createTypeScriptBuilder = createTypeScriptBuilder; exports.createTypeScriptBuilder = createTypeScriptBuilder;
class ScriptSnapshot { class ScriptSnapshot {
_text;
_mtime;
constructor(text, mtime) { constructor(text, mtime) {
this._text = text; this._text = text;
this._mtime = mtime; this._mtime = mtime;
@ -317,6 +319,7 @@ class ScriptSnapshot {
} }
} }
class VinylScriptSnapshot extends ScriptSnapshot { class VinylScriptSnapshot extends ScriptSnapshot {
_base;
constructor(file) { constructor(file) {
super(file.contents.toString(), file.stat.mtime); super(file.contents.toString(), file.stat.mtime);
this._base = file.base; this._base = file.base;
@ -326,15 +329,20 @@ class VinylScriptSnapshot extends ScriptSnapshot {
} }
} }
class LanguageServiceHost { class LanguageServiceHost {
_cmdLine;
_projectPath;
_log;
_snapshots;
_filesInProject;
_filesAdded;
_dependencies;
_dependenciesRecomputeList;
_fileNameToDeclaredModule;
_projectVersion;
constructor(_cmdLine, _projectPath, _log) { constructor(_cmdLine, _projectPath, _log) {
this._cmdLine = _cmdLine; this._cmdLine = _cmdLine;
this._projectPath = _projectPath; this._projectPath = _projectPath;
this._log = _log; this._log = _log;
this.directoryExists = ts.sys.directoryExists;
this.getDirectories = ts.sys.getDirectories;
this.fileExists = ts.sys.fileExists;
this.readFile = ts.sys.readFile;
this.readDirectory = ts.sys.readDirectory;
this._snapshots = Object.create(null); this._snapshots = Object.create(null);
this._filesInProject = new Set(_cmdLine.fileNames); this._filesInProject = new Set(_cmdLine.fileNames);
this._filesAdded = new Set(); this._filesAdded = new Set();
@ -389,6 +397,7 @@ class LanguageServiceHost {
} }
return result; return result;
} }
static _declareModule = /declare\s+module\s+('|")(.+)\1/g;
addScriptSnapshot(filename, snapshot) { addScriptSnapshot(filename, snapshot) {
this._projectVersion++; this._projectVersion++;
filename = normalize(filename); filename = normalize(filename);
@ -432,6 +441,11 @@ class LanguageServiceHost {
getDefaultLibFileName(options) { getDefaultLibFileName(options) {
return ts.getDefaultLibFilePath(options); return ts.getDefaultLibFilePath(options);
} }
directoryExists = ts.sys.directoryExists;
getDirectories = ts.sys.getDirectories;
fileExists = ts.sys.fileExists;
readFile = ts.sys.readFile;
readDirectory = ts.sys.readDirectory;
// ---- dependency management // ---- dependency management
collectDependents(filename, target) { collectDependents(filename, target) {
while (this._dependenciesRecomputeList.length) { while (this._dependenciesRecomputeList.length) {
@ -488,4 +502,3 @@ class LanguageServiceHost {
}); });
} }
} }
LanguageServiceHost._declareModule = /declare\s+module\s+('|")(.+)\1/g;

View file

@ -3,7 +3,6 @@
* Copyright (c) Microsoft Corporation. All rights reserved. * Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information. * Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
var _a;
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
exports.SwcTranspiler = exports.TscTranspiler = void 0; exports.SwcTranspiler = exports.TscTranspiler = void 0;
const swc = require("@swc/core"); const swc = require("@swc/core");
@ -39,6 +38,7 @@ if (!threads.isMainThread) {
}); });
} }
class OutputFileNameOracle { class OutputFileNameOracle {
getOutputFileName;
constructor(cmdLine, configFilePath) { constructor(cmdLine, configFilePath) {
this.getOutputFileName = (file) => { this.getOutputFileName = (file) => {
try { try {
@ -68,10 +68,12 @@ class OutputFileNameOracle {
} }
} }
class TranspileWorker { class TranspileWorker {
static pool = 1;
id = TranspileWorker.pool++;
_worker = new threads.Worker(__filename);
_pending;
_durations = [];
constructor(outFileFn) { constructor(outFileFn) {
this.id = TranspileWorker.pool++;
this._worker = new threads.Worker(__filename);
this._durations = [];
this._worker.addListener('message', (res) => { this._worker.addListener('message', (res) => {
if (!this._pending) { if (!this._pending) {
console.error('RECEIVING data WITHOUT request'); console.error('RECEIVING data WITHOUT request');
@ -142,14 +144,18 @@ class TranspileWorker {
}); });
} }
} }
TranspileWorker.pool = 1;
class TscTranspiler { class TscTranspiler {
_onError;
_cmdLine;
static P = Math.floor((0, node_os_1.cpus)().length * .5);
_outputFileNames;
onOutfile;
_workerPool = [];
_queue = [];
_allJobs = [];
constructor(logFn, _onError, configFilePath, _cmdLine) { constructor(logFn, _onError, configFilePath, _cmdLine) {
this._onError = _onError; this._onError = _onError;
this._cmdLine = _cmdLine; this._cmdLine = _cmdLine;
this._workerPool = [];
this._queue = [];
this._allJobs = [];
logFn('Transpile', `will use ${TscTranspiler.P} transpile worker`); logFn('Transpile', `will use ${TscTranspiler.P} transpile worker`);
this._outputFileNames = new OutputFileNameOracle(_cmdLine, configFilePath); this._outputFileNames = new OutputFileNameOracle(_cmdLine, configFilePath);
} }
@ -218,7 +224,6 @@ class TscTranspiler {
} }
} }
exports.TscTranspiler = TscTranspiler; exports.TscTranspiler = TscTranspiler;
TscTranspiler.P = Math.floor((0, node_os_1.cpus)().length * .5);
function _isDefaultEmpty(src) { function _isDefaultEmpty(src) {
return src return src
.replace('"use strict";', '') .replace('"use strict";', '')
@ -226,11 +231,16 @@ function _isDefaultEmpty(src) {
.trim().length === 0; .trim().length === 0;
} }
class SwcTranspiler { class SwcTranspiler {
_logFn;
_onError;
_cmdLine;
onOutfile;
_outputFileNames;
_jobs = [];
constructor(_logFn, _onError, configFilePath, _cmdLine) { constructor(_logFn, _onError, configFilePath, _cmdLine) {
this._logFn = _logFn; this._logFn = _logFn;
this._onError = _onError; this._onError = _onError;
this._cmdLine = _cmdLine; this._cmdLine = _cmdLine;
this._jobs = [];
_logFn('Transpile', `will use SWC to transpile source files`); _logFn('Transpile', `will use SWC to transpile source files`);
this._outputFileNames = new OutputFileNameOracle(_cmdLine, configFilePath); this._outputFileNames = new OutputFileNameOracle(_cmdLine, configFilePath);
} }
@ -274,41 +284,40 @@ class SwcTranspiler {
this._onError(err); this._onError(err);
})); }));
} }
// --- .swcrc
static _swcrcAmd = {
exclude: '\.js$',
jsc: {
parser: {
syntax: 'typescript',
tsx: false,
decorators: true
},
target: 'es2020',
loose: false,
minify: {
compress: false,
mangle: false
}
},
module: {
type: 'amd',
noInterop: true
},
minify: false,
};
static _swcrcCommonJS = {
...this._swcrcAmd,
module: {
type: 'commonjs',
importInterop: 'none'
}
};
static _swcrcEsm = {
...this._swcrcAmd,
module: {
type: 'es6'
}
};
} }
exports.SwcTranspiler = SwcTranspiler; exports.SwcTranspiler = SwcTranspiler;
_a = SwcTranspiler;
// --- .swcrc
SwcTranspiler._swcrcAmd = {
exclude: '\.js$',
jsc: {
parser: {
syntax: 'typescript',
tsx: false,
decorators: true
},
target: 'es2020',
loose: false,
minify: {
compress: false,
mangle: false
}
},
module: {
type: 'amd',
noInterop: true
},
minify: false,
};
SwcTranspiler._swcrcCommonJS = {
..._a._swcrcAmd,
module: {
type: 'commonjs',
importInterop: 'none'
}
};
SwcTranspiler._swcrcEsm = {
..._a._swcrcAmd,
module: {
type: 'es6'
}
};

View file

@ -71,9 +71,10 @@ var graph;
} }
graph.newNode = newNode; graph.newNode = newNode;
class Graph { class Graph {
_hashFn;
_nodes = {};
constructor(_hashFn) { constructor(_hashFn) {
this._hashFn = _hashFn; this._hashFn = _hashFn;
this._nodes = {};
// empty // empty
} }
traverse(start, inwards, callback) { traverse(start, inwards, callback) {

View file

@ -1,6 +1,6 @@
{ {
"compilerOptions": { "compilerOptions": {
"target": "es2020", "target": "es2022",
"lib": ["ES2020"], "lib": ["ES2020"],
"module": "commonjs", "module": "commonjs",
"alwaysStrict": true, "alwaysStrict": true,
@ -8,7 +8,6 @@
"preserveConstEnums": true, "preserveConstEnums": true,
"sourceMap": false, "sourceMap": false,
"resolveJsonModule": true, "resolveJsonModule": true,
"experimentalDecorators": true,
// enable JavaScript type checking for the language service // enable JavaScript type checking for the language service
// use the tsconfig.build.json for compiling which disable JavaScript // use the tsconfig.build.json for compiling which disable JavaScript
// type checking so that JavaScript file are not transpiled // type checking so that JavaScript file are not transpiled

View file

@ -88,8 +88,10 @@ Name: "{app}"; AfterInstall: DisableAppDirInheritance
[Files] [Files]
Source: "*"; Excludes: "\CodeSignSummary*.md,\tools,\tools\*,\appx,\appx\*,\resources\app\product.json"; DestDir: "{code:GetDestDir}"; Flags: ignoreversion recursesubdirs createallsubdirs Source: "*"; Excludes: "\CodeSignSummary*.md,\tools,\tools\*,\appx,\appx\*,\resources\app\product.json"; DestDir: "{code:GetDestDir}"; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "tools\*"; DestDir: "{app}\tools"; Flags: ignoreversion Source: "tools\*"; DestDir: "{app}\tools"; Flags: ignoreversion
Source: "appx\*"; DestDir: "{app}\appx"; BeforeInstall: RemoveAppxPackage; AfterInstall: AddAppxPackage; Flags: ignoreversion; Check: IsWindows11OrLater and QualityIsInsiders
Source: "{#ProductJsonPath}"; DestDir: "{code:GetDestDir}\resources\app"; Flags: ignoreversion Source: "{#ProductJsonPath}"; DestDir: "{code:GetDestDir}\resources\app"; Flags: ignoreversion
#ifdef AppxPackageFullname
Source: "appx\*"; DestDir: "{app}\appx"; BeforeInstall: RemoveAppxPackage; AfterInstall: AddAppxPackage; Flags: ignoreversion; Check: IsWindows11OrLater and QualityIsInsiders
#endif
[Icons] [Icons]
Name: "{group}\{#NameLong}"; Filename: "{app}\{#ExeBasename}.exe"; AppUserModelID: "{#AppUserId}" Name: "{group}\{#NameLong}"; Filename: "{app}\{#ExeBasename}.exe"; AppUserModelID: "{#AppUserId}"
@ -100,8 +102,10 @@ Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\{#NameLong}"; File
Filename: "{app}\{#ExeBasename}.exe"; Description: "{cm:LaunchProgram,{#NameLong}}"; Tasks: runcode; Flags: nowait postinstall; Check: ShouldRunAfterUpdate Filename: "{app}\{#ExeBasename}.exe"; Description: "{cm:LaunchProgram,{#NameLong}}"; Tasks: runcode; Flags: nowait postinstall; Check: ShouldRunAfterUpdate
Filename: "{app}\{#ExeBasename}.exe"; Description: "{cm:LaunchProgram,{#NameLong}}"; Flags: nowait postinstall; Check: WizardNotSilent Filename: "{app}\{#ExeBasename}.exe"; Description: "{cm:LaunchProgram,{#NameLong}}"; Flags: nowait postinstall; Check: WizardNotSilent
#ifdef AppxPackageFullname
[UninstallRun] [UninstallRun]
Filename: "powershell.exe"; Parameters: "Invoke-Command -ScriptBlock {{Remove-AppxPackage -Package ""{#AppxPackageFullname}""}"; Check: IsWindows11OrLater and QualityIsInsiders; Flags: shellexec waituntilterminated runhidden Filename: "powershell.exe"; Parameters: "Invoke-Command -ScriptBlock {{Remove-AppxPackage -Package ""{#AppxPackageFullname}""}"; Check: IsWindows11OrLater and QualityIsInsiders; Flags: shellexec waituntilterminated runhidden
#endif
[Registry] [Registry]
#if "user" == InstallTarget #if "user" == InstallTarget
@ -1418,6 +1422,7 @@ begin
Result := False; Result := False;
end; end;
#ifdef AppxPackageFullname
procedure AddAppxPackage(); procedure AddAppxPackage();
var var
AddAppxPackageResultCode: Integer; AddAppxPackageResultCode: Integer;
@ -1440,6 +1445,7 @@ begin
RegDeleteKeyIncludingSubkeys({#EnvironmentRootKey}, 'Software\Classes\{#RegValueName}ContextMenu'); RegDeleteKeyIncludingSubkeys({#EnvironmentRootKey}, 'Software\Classes\{#RegValueName}ContextMenu');
end; end;
end; end;
#endif
procedure CurStepChanged(CurStep: TSetupStep); procedure CurStepChanged(CurStep: TSetupStep);
var var

View file

@ -138,6 +138,18 @@ impl CodeVersionManager {
pub async fn get_entrypoint_for_install_dir(path: &Path) -> Option<PathBuf> { pub async fn get_entrypoint_for_install_dir(path: &Path) -> Option<PathBuf> {
use tokio::sync::mpsc; use tokio::sync::mpsc;
// Check whether the user is supplying a path to the CLI directly (e.g. #164622)
if let Ok(true) = path.metadata().map(|m| m.is_file()) {
let result = std::process::Command::new(path)
.args(["--version"])
.output()
.map(|o| o.status.success());
if let Ok(true) = result {
return Some(path.to_owned());
}
}
let (tx, mut rx) = mpsc::channel(1); let (tx, mut rx) = mpsc::channel(1);
// Look for all the possible paths in parallel // Look for all the possible paths in parallel
@ -576,4 +588,37 @@ mod tests {
.is_none() .is_none()
); );
} }
#[tokio::test]
async fn test_gets_entrypoint_as_binary() {
let dir = tempfile::tempdir().expect("expected to make temp dir");
#[cfg(windows)]
let binary_file_path = {
let path = dir.path().join("code.cmd");
File::create(&path).expect("expected to create file");
path
};
#[cfg(unix)]
let binary_file_path = {
use std::fs;
use std::os::unix::fs::PermissionsExt;
let path = dir.path().join("code");
{
let mut f = File::create(&path).expect("expected to create file");
f.write_all(b"#!/bin/sh")
.expect("expected to write to file");
}
fs::set_permissions(&path, fs::Permissions::from_mode(0o777))
.expect("expected to set permissions");
path
};
assert_eq!(
CodeVersionManager::get_entrypoint_for_install_dir(&binary_file_path).await,
Some(binary_file_path)
);
}
} }

View file

@ -150,7 +150,7 @@ fn copy_file_metadata(from: &Path, to: &Path) -> Result<(), std::io::Error> {
use std::os::unix::fs::MetadataExt; use std::os::unix::fs::MetadataExt;
let metadata = from.metadata()?; let metadata = from.metadata()?;
fs::set_permissions(&to, metadata.permissions())?; fs::set_permissions(to, metadata.permissions())?;
// based on coreutils' chown https://github.com/uutils/coreutils/blob/72b4629916abe0852ad27286f4e307fbca546b6e/src/chown/chown.rs#L266-L281 // based on coreutils' chown https://github.com/uutils/coreutils/blob/72b4629916abe0852ad27286f4e307fbca546b6e/src/chown/chown.rs#L266-L281
let s = std::ffi::CString::new(to.as_os_str().as_bytes()).unwrap(); let s = std::ffi::CString::new(to.as_os_str().as_bytes()).unwrap();

View file

@ -352,7 +352,7 @@ fn install_server(
unzip_downloaded_release(compressed_file, &paths.server_dir, SilentCopyProgress())?; unzip_downloaded_release(compressed_file, &paths.server_dir, SilentCopyProgress())?;
match fs::remove_file(&compressed_file) { match fs::remove_file(compressed_file) {
Ok(()) => {} Ok(()) => {}
Err(e) => { Err(e) => {
if e.kind() != ErrorKind::NotFound { if e.kind() != ErrorKind::NotFound {

View file

@ -300,6 +300,8 @@ impl Platform {
Some(Platform::WindowsX64) Some(Platform::WindowsX64)
} else if cfg!(all(target_os = "windows", target_arch = "x86")) { } else if cfg!(all(target_os = "windows", target_arch = "x86")) {
Some(Platform::WindowsX86) Some(Platform::WindowsX86)
} else if cfg!(all(target_os = "windows", target_arch = "aarch64")) {
Some(Platform::WindowsARM64)
} else { } else {
None None
} }

View file

@ -39,7 +39,7 @@ impl PreReqChecker {
#[cfg(not(target_os = "linux"))] #[cfg(not(target_os = "linux"))]
pub async fn verify(&self) -> Result<Platform, AnyError> { pub async fn verify(&self) -> Result<Platform, AnyError> {
Platform::env_default().ok_or_else(|| { Platform::env_default().ok_or_else(|| {
SetupError("VS Code it not supported on this platform".to_owned()).into() SetupError("VS Code is not supported on this platform".to_owned()).into()
}) })
} }

View file

@ -87,7 +87,7 @@ where
}); });
if let Some(p) = path.parent() { if let Some(p) = path.parent() {
fs::create_dir_all(&p) fs::create_dir_all(p)
.map_err(|e| wrap(e, format!("could not create dir for {}", p.display())))?; .map_err(|e| wrap(e, format!("could not create dir for {}", p.display())))?;
} }

View file

@ -20,8 +20,7 @@
"watch": "gulp watch-extension:configuration-editing" "watch": "gulp watch-extension:configuration-editing"
}, },
"dependencies": { "dependencies": {
"jsonc-parser": "^2.2.1", "jsonc-parser": "^2.2.1"
"vscode-nls": "^5.2.0"
}, },
"capabilities": { "capabilities": {
"virtualWorkspaces": true, "virtualWorkspaces": true,

View file

@ -5,10 +5,8 @@
import { getLocation, JSONPath, parse, visit, Location } from 'jsonc-parser'; import { getLocation, JSONPath, parse, visit, Location } from 'jsonc-parser';
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
import { SettingsDocument } from './settingsDocumentHelper'; import { SettingsDocument } from './settingsDocumentHelper';
import { provideInstalledExtensionProposals } from './extensionsProposals'; import { provideInstalledExtensionProposals } from './extensionsProposals';
const localize = nls.loadMessageBundle();
export function activate(context: vscode.ExtensionContext): void { export function activate(context: vscode.ExtensionContext): void {
//settings.json suggestions //settings.json suggestions
@ -46,21 +44,21 @@ function registerVariableCompletions(pattern: string): vscode.Disposable {
} }
return [ return [
{ label: 'workspaceFolder', detail: localize('workspaceFolder', "The path of the folder opened in VS Code") }, { label: 'workspaceFolder', detail: vscode.l10n.t("The path of the folder opened in VS Code") },
{ label: 'workspaceFolderBasename', detail: localize('workspaceFolderBasename', "The name of the folder opened in VS Code without any slashes (/)") }, { label: 'workspaceFolderBasename', detail: vscode.l10n.t("The name of the folder opened in VS Code without any slashes (/)") },
{ label: 'relativeFile', detail: localize('relativeFile', "The current opened file relative to ${workspaceFolder}") }, { label: 'relativeFile', detail: vscode.l10n.t("The current opened file relative to ${workspaceFolder}") },
{ label: 'relativeFileDirname', detail: localize('relativeFileDirname', "The current opened file's dirname relative to ${workspaceFolder}") }, { label: 'relativeFileDirname', detail: vscode.l10n.t("The current opened file's dirname relative to ${workspaceFolder}") },
{ label: 'file', detail: localize('file', "The current opened file") }, { label: 'file', detail: vscode.l10n.t("The current opened file") },
{ label: 'cwd', detail: localize('cwd', "The task runner's current working directory on startup") }, { label: 'cwd', detail: vscode.l10n.t("The task runner's current working directory on startup") },
{ label: 'lineNumber', detail: localize('lineNumber', "The current selected line number in the active file") }, { label: 'lineNumber', detail: vscode.l10n.t("The current selected line number in the active file") },
{ label: 'selectedText', detail: localize('selectedText', "The current selected text in the active file") }, { label: 'selectedText', detail: vscode.l10n.t("The current selected text in the active file") },
{ label: 'fileDirname', detail: localize('fileDirname', "The current opened file's dirname") }, { label: 'fileDirname', detail: vscode.l10n.t("The current opened file's dirname") },
{ label: 'fileExtname', detail: localize('fileExtname', "The current opened file's extension") }, { label: 'fileExtname', detail: vscode.l10n.t("The current opened file's extension") },
{ label: 'fileBasename', detail: localize('fileBasename', "The current opened file's basename") }, { label: 'fileBasename', detail: vscode.l10n.t("The current opened file's basename") },
{ label: 'fileBasenameNoExtension', detail: localize('fileBasenameNoExtension', "The current opened file's basename with no file extension") }, { label: 'fileBasenameNoExtension', detail: vscode.l10n.t("The current opened file's basename with no file extension") },
{ label: 'defaultBuildTask', detail: localize('defaultBuildTask', "The name of the default build task. If there is not a single default build task then a quick pick is shown to choose the build task.") }, { label: 'defaultBuildTask', detail: vscode.l10n.t("The name of the default build task. If there is not a single default build task then a quick pick is shown to choose the build task.") },
{ label: 'pathSeparator', detail: localize('pathSeparator', "The character used by the operating system to separate components in file paths") }, { label: 'pathSeparator', detail: vscode.l10n.t("The character used by the operating system to separate components in file paths") },
{ label: 'extensionInstallFolder', detail: localize('extensionInstallFolder', "The path where an an extension is installed."), param: 'publisher.extension' }, { label: 'extensionInstallFolder', detail: vscode.l10n.t("The path where an an extension is installed."), param: 'publisher.extension' },
].map(variable => ({ ].map(variable => ({
label: `\${${variable.label}}`, label: `\${${variable.label}}`,
range, range,

View file

@ -4,8 +4,6 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle();
export async function provideInstalledExtensionProposals(existing: string[], additionalText: string, range: vscode.Range, includeBuiltinExtensions: boolean): Promise<vscode.CompletionItem[] | vscode.CompletionList> { export async function provideInstalledExtensionProposals(existing: string[], additionalText: string, range: vscode.Range, includeBuiltinExtensions: boolean): Promise<vscode.CompletionItem[] | vscode.CompletionList> {
@ -23,7 +21,7 @@ export async function provideInstalledExtensionProposals(existing: string[], add
return item; return item;
}); });
} else { } else {
const example = new vscode.CompletionItem(localize('exampleExtension', "Example")); const example = new vscode.CompletionItem(vscode.l10n.t("Example"));
example.insertText = '"vscode.csharp"'; example.insertText = '"vscode.csharp"';
example.kind = vscode.CompletionItemKind.Value; example.kind = vscode.CompletionItemKind.Value;
example.range = range; example.range = range;
@ -48,7 +46,7 @@ export async function provideWorkspaceTrustExtensionProposals(existing: string[]
return item; return item;
}); });
} else { } else {
const example = new vscode.CompletionItem(localize('exampleExtension', "Example")); const example = new vscode.CompletionItem(vscode.l10n.t("Example"));
example.insertText = '"vscode.csharp: {\n\t"supported": false,\n\t"version": "0.0.0"\n}`;"'; example.insertText = '"vscode.csharp: {\n\t"supported": false,\n\t"version": "0.0.0"\n}`;"';
example.kind = vscode.CompletionItemKind.Value; example.kind = vscode.CompletionItemKind.Value;
example.range = range; example.range = range;

View file

@ -5,10 +5,8 @@
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import { getLocation, Location, parse } from 'jsonc-parser'; import { getLocation, Location, parse } from 'jsonc-parser';
import * as nls from 'vscode-nls';
import { provideInstalledExtensionProposals } from './extensionsProposals'; import { provideInstalledExtensionProposals } from './extensionsProposals';
const localize = nls.loadMessageBundle();
const OVERRIDE_IDENTIFIER_REGEX = /\[([^\[\]]*)\]/g; const OVERRIDE_IDENTIFIER_REGEX = /\[([^\[\]]*)\]/g;
export class SettingsDocument { export class SettingsDocument {
@ -107,20 +105,20 @@ export class SettingsDocument {
}; };
completions.push(this.newSimpleCompletionItem(getText('activeEditorShort'), range, localize('activeEditorShort', "the file name (e.g. myFile.txt)"))); completions.push(this.newSimpleCompletionItem(getText('activeEditorShort'), range, vscode.l10n.t("the file name (e.g. myFile.txt)")));
completions.push(this.newSimpleCompletionItem(getText('activeEditorMedium'), range, localize('activeEditorMedium', "the path of the file relative to the workspace folder (e.g. myFolder/myFileFolder/myFile.txt)"))); completions.push(this.newSimpleCompletionItem(getText('activeEditorMedium'), range, vscode.l10n.t("the path of the file relative to the workspace folder (e.g. myFolder/myFileFolder/myFile.txt)")));
completions.push(this.newSimpleCompletionItem(getText('activeEditorLong'), range, localize('activeEditorLong', "the full path of the file (e.g. /Users/Development/myFolder/myFileFolder/myFile.txt)"))); completions.push(this.newSimpleCompletionItem(getText('activeEditorLong'), range, vscode.l10n.t("the full path of the file (e.g. /Users/Development/myFolder/myFileFolder/myFile.txt)")));
completions.push(this.newSimpleCompletionItem(getText('activeFolderShort'), range, localize('activeFolderShort', "the name of the folder the file is contained in (e.g. myFileFolder)"))); completions.push(this.newSimpleCompletionItem(getText('activeFolderShort'), range, vscode.l10n.t("the name of the folder the file is contained in (e.g. myFileFolder)")));
completions.push(this.newSimpleCompletionItem(getText('activeFolderMedium'), range, localize('activeFolderMedium', "the path of the folder the file is contained in, relative to the workspace folder (e.g. myFolder/myFileFolder)"))); completions.push(this.newSimpleCompletionItem(getText('activeFolderMedium'), range, vscode.l10n.t("the path of the folder the file is contained in, relative to the workspace folder (e.g. myFolder/myFileFolder)")));
completions.push(this.newSimpleCompletionItem(getText('activeFolderLong'), range, localize('activeFolderLong', "the full path of the folder the file is contained in (e.g. /Users/Development/myFolder/myFileFolder)"))); completions.push(this.newSimpleCompletionItem(getText('activeFolderLong'), range, vscode.l10n.t("the full path of the folder the file is contained in (e.g. /Users/Development/myFolder/myFileFolder)")));
completions.push(this.newSimpleCompletionItem(getText('rootName'), range, localize('rootName', "name of the workspace (e.g. myFolder or myWorkspace)"))); completions.push(this.newSimpleCompletionItem(getText('rootName'), range, vscode.l10n.t("name of the workspace (e.g. myFolder or myWorkspace)")));
completions.push(this.newSimpleCompletionItem(getText('rootPath'), range, localize('rootPath', "file path of the workspace (e.g. /Users/Development/myWorkspace)"))); completions.push(this.newSimpleCompletionItem(getText('rootPath'), range, vscode.l10n.t("file path of the workspace (e.g. /Users/Development/myWorkspace)")));
completions.push(this.newSimpleCompletionItem(getText('folderName'), range, localize('folderName', "name of the workspace folder the file is contained in (e.g. myFolder)"))); completions.push(this.newSimpleCompletionItem(getText('folderName'), range, vscode.l10n.t("name of the workspace folder the file is contained in (e.g. myFolder)")));
completions.push(this.newSimpleCompletionItem(getText('folderPath'), range, localize('folderPath', "file path of the workspace folder the file is contained in (e.g. /Users/Development/myFolder)"))); completions.push(this.newSimpleCompletionItem(getText('folderPath'), range, vscode.l10n.t("file path of the workspace folder the file is contained in (e.g. /Users/Development/myFolder)")));
completions.push(this.newSimpleCompletionItem(getText('appName'), range, localize('appName', "e.g. VS Code"))); completions.push(this.newSimpleCompletionItem(getText('appName'), range, vscode.l10n.t("e.g. VS Code")));
completions.push(this.newSimpleCompletionItem(getText('remoteName'), range, localize('remoteName', "e.g. SSH"))); completions.push(this.newSimpleCompletionItem(getText('remoteName'), range, vscode.l10n.t("e.g. SSH")));
completions.push(this.newSimpleCompletionItem(getText('dirty'), range, localize('dirty', "an indicator for when the active editor has unsaved changes"))); completions.push(this.newSimpleCompletionItem(getText('dirty'), range, vscode.l10n.t("an indicator for when the active editor has unsaved changes")));
completions.push(this.newSimpleCompletionItem(getText('separator'), range, localize('separator', "a conditional separator (' - ') that only shows when surrounded by variables with values"))); completions.push(this.newSimpleCompletionItem(getText('separator'), range, vscode.l10n.t("a conditional separator (' - ') that only shows when surrounded by variables with values")));
return completions; return completions;
} }
@ -134,15 +132,15 @@ export class SettingsDocument {
const range = this.getReplaceRange(location, position); const range = this.getReplaceRange(location, position);
completions.push(this.newSnippetCompletionItem({ completions.push(this.newSnippetCompletionItem({
label: localize('assocLabelFile', "Files with Extension"), label: vscode.l10n.t("Files with Extension"),
documentation: localize('assocDescriptionFile', "Map all files matching the glob pattern in their filename to the language with the given identifier."), documentation: vscode.l10n.t("Map all files matching the glob pattern in their filename to the language with the given identifier."),
snippet: location.isAtPropertyKey ? '"*.${1:extension}": "${2:language}"' : '{ "*.${1:extension}": "${2:language}" }', snippet: location.isAtPropertyKey ? '"*.${1:extension}": "${2:language}"' : '{ "*.${1:extension}": "${2:language}" }',
range range
})); }));
completions.push(this.newSnippetCompletionItem({ completions.push(this.newSnippetCompletionItem({
label: localize('assocLabelPath', "Files with Path"), label: vscode.l10n.t("Files with Path"),
documentation: localize('assocDescriptionPath', "Map all files matching the absolute path glob pattern in their path to the language with the given identifier."), documentation: vscode.l10n.t("Map all files matching the absolute path glob pattern in their path to the language with the given identifier."),
snippet: location.isAtPropertyKey ? '"/${1:path to file}/*.${2:extension}": "${3:language}"' : '{ "/${1:path to file}/*.${2:extension}": "${3:language}" }', snippet: location.isAtPropertyKey ? '"/${1:path to file}/*.${2:extension}": "${3:language}"' : '{ "/${1:path to file}/*.${2:extension}": "${3:language}" }',
range range
})); }));
@ -163,43 +161,43 @@ export class SettingsDocument {
const range = this.getReplaceRange(location, position); const range = this.getReplaceRange(location, position);
completions.push(this.newSnippetCompletionItem({ completions.push(this.newSnippetCompletionItem({
label: localize('fileLabel', "Files by Extension"), label: vscode.l10n.t("Files by Extension"),
documentation: localize('fileDescription', "Match all files of a specific file extension."), documentation: vscode.l10n.t("Match all files of a specific file extension."),
snippet: location.path.length === 2 ? '"**/*.${1:extension}": true' : '{ "**/*.${1:extension}": true }', snippet: location.path.length === 2 ? '"**/*.${1:extension}": true' : '{ "**/*.${1:extension}": true }',
range range
})); }));
completions.push(this.newSnippetCompletionItem({ completions.push(this.newSnippetCompletionItem({
label: localize('filesLabel', "Files with Multiple Extensions"), label: vscode.l10n.t("Files with Multiple Extensions"),
documentation: localize('filesDescription', "Match all files with any of the file extensions."), documentation: vscode.l10n.t("Match all files with any of the file extensions."),
snippet: location.path.length === 2 ? '"**/*.{ext1,ext2,ext3}": true' : '{ "**/*.{ext1,ext2,ext3}": true }', snippet: location.path.length === 2 ? '"**/*.{ext1,ext2,ext3}": true' : '{ "**/*.{ext1,ext2,ext3}": true }',
range range
})); }));
completions.push(this.newSnippetCompletionItem({ completions.push(this.newSnippetCompletionItem({
label: localize('derivedLabel', "Files with Siblings by Name"), label: vscode.l10n.t("Files with Siblings by Name"),
documentation: localize('derivedDescription', "Match files that have siblings with the same name but a different extension."), documentation: vscode.l10n.t("Match files that have siblings with the same name but a different extension."),
snippet: location.path.length === 2 ? '"**/*.${1:source-extension}": { "when": "$(basename).${2:target-extension}" }' : '{ "**/*.${1:source-extension}": { "when": "$(basename).${2:target-extension}" } }', snippet: location.path.length === 2 ? '"**/*.${1:source-extension}": { "when": "$(basename).${2:target-extension}" }' : '{ "**/*.${1:source-extension}": { "when": "$(basename).${2:target-extension}" } }',
range range
})); }));
completions.push(this.newSnippetCompletionItem({ completions.push(this.newSnippetCompletionItem({
label: localize('topFolderLabel', "Folder by Name (Top Level)"), label: vscode.l10n.t("Folder by Name (Top Level)"),
documentation: localize('topFolderDescription', "Match a top level folder with a specific name."), documentation: vscode.l10n.t("Match a top level folder with a specific name."),
snippet: location.path.length === 2 ? '"${1:name}": true' : '{ "${1:name}": true }', snippet: location.path.length === 2 ? '"${1:name}": true' : '{ "${1:name}": true }',
range range
})); }));
completions.push(this.newSnippetCompletionItem({ completions.push(this.newSnippetCompletionItem({
label: localize('topFoldersLabel', "Folders with Multiple Names (Top Level)"), label: vscode.l10n.t("Folders with Multiple Names (Top Level)"),
documentation: localize('topFoldersDescription', "Match multiple top level folders."), documentation: vscode.l10n.t("Match multiple top level folders."),
snippet: location.path.length === 2 ? '"{folder1,folder2,folder3}": true' : '{ "{folder1,folder2,folder3}": true }', snippet: location.path.length === 2 ? '"{folder1,folder2,folder3}": true' : '{ "{folder1,folder2,folder3}": true }',
range range
})); }));
completions.push(this.newSnippetCompletionItem({ completions.push(this.newSnippetCompletionItem({
label: localize('folderLabel', "Folder by Name (Any Location)"), label: vscode.l10n.t("Folder by Name (Any Location)"),
documentation: localize('folderDescription', "Match a folder with a specific name in any location."), documentation: vscode.l10n.t("Match a folder with a specific name in any location."),
snippet: location.path.length === 2 ? '"**/${1:name}": true' : '{ "**/${1:name}": true }', snippet: location.path.length === 2 ? '"**/${1:name}": true' : '{ "**/${1:name}": true }',
range range
})); }));
@ -209,8 +207,8 @@ export class SettingsDocument {
else if (location.path.length === 2 && this.isCompletingPropertyValue(location, position)) { else if (location.path.length === 2 && this.isCompletingPropertyValue(location, position)) {
const range = this.getReplaceRange(location, position); const range = this.getReplaceRange(location, position);
completions.push(this.newSnippetCompletionItem({ completions.push(this.newSnippetCompletionItem({
label: localize('derivedLabel', "Files with Siblings by Name"), label: vscode.l10n.t("Files with Siblings by Name"),
documentation: localize('siblingsDescription', "Match files that have siblings with the same name but a different extension."), documentation: vscode.l10n.t("Match files that have siblings with the same name but a different extension."),
snippet: '{ "when": "$(basename).${1:extension}" }', snippet: '{ "when": "$(basename).${1:extension}" }',
range range
})); }));
@ -224,7 +222,7 @@ export class SettingsDocument {
const range = this.getReplaceRange(location, position); const range = this.getReplaceRange(location, position);
const languages = await vscode.languages.getLanguages(); const languages = await vscode.languages.getLanguages();
return [ return [
this.newSimpleCompletionItem(JSON.stringify('${activeEditorLanguage}'), range, localize('activeEditor', "Use the language of the currently active text editor if any")), this.newSimpleCompletionItem(JSON.stringify('${activeEditorLanguage}'), range, vscode.l10n.t("Use the language of the currently active text editor if any")),
...languages.map(l => this.newSimpleCompletionItem(JSON.stringify(l), range)) ...languages.map(l => this.newSimpleCompletionItem(JSON.stringify(l), range))
]; ];
} }

View file

@ -11,8 +11,3 @@ jsonc-parser@^2.2.1:
version "2.2.1" version "2.2.1"
resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-2.2.1.tgz#db73cd59d78cce28723199466b2a03d1be1df2bc" resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-2.2.1.tgz#db73cd59d78cce28723199466b2a03d1be1df2bc"
integrity sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w== integrity sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w==
vscode-nls@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-5.2.0.tgz#3cb6893dd9bd695244d8a024bdf746eea665cc3f"
integrity sha512-RAaHx7B14ZU04EU31pT+rKz2/zSl7xMsfIZuo8pd+KZO6PXtQmpevpq3vxvWNcrGbdmhM/rr5Uw5Mz+NBfhVng==

View file

@ -6,11 +6,11 @@
"git": { "git": {
"name": "jeff-hykin/better-cpp-syntax", "name": "jeff-hykin/better-cpp-syntax",
"repositoryUrl": "https://github.com/jeff-hykin/better-cpp-syntax", "repositoryUrl": "https://github.com/jeff-hykin/better-cpp-syntax",
"commitHash": "32be139c7d3cdf07195af4b3a5c639ebf4e3b356" "commitHash": "1866de22c09781cbceacc2c98063f7bf77b1ca62"
} }
}, },
"license": "MIT", "license": "MIT",
"version": "1.15.23", "version": "1.16.1",
"description": "The original JSON grammars were derived from https://github.com/atom/language-c which was originally converted from the C TextMate bundle https://github.com/textmate/c.tmbundle." "description": "The original JSON grammars were derived from https://github.com/atom/language-c which was originally converted from the C TextMate bundle https://github.com/textmate/c.tmbundle."
}, },
{ {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -4,12 +4,10 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
import { Node, HtmlNode, Rule, Property, Stylesheet } from 'EmmetFlatNode'; import { Node, HtmlNode, Rule, Property, Stylesheet } from 'EmmetFlatNode';
import { getEmmetHelper, getFlatNode, getHtmlFlatNode, getMappingForIncludedLanguages, validate, getEmmetConfiguration, isStyleSheet, getEmmetMode, parsePartialStylesheet, isStyleAttribute, getEmbeddedCssNodeIfAny, allowedMimeTypesInScriptTag, toLSTextDocument, isOffsetInsideOpenOrCloseTag } from './util'; import { getEmmetHelper, getFlatNode, getHtmlFlatNode, getMappingForIncludedLanguages, validate, getEmmetConfiguration, isStyleSheet, getEmmetMode, parsePartialStylesheet, isStyleAttribute, getEmbeddedCssNodeIfAny, allowedMimeTypesInScriptTag, toLSTextDocument, isOffsetInsideOpenOrCloseTag } from './util';
import { getRootNode as parseDocument } from './parseDocument'; import { getRootNode as parseDocument } from './parseDocument';
const localize = nls.loadMessageBundle();
const trimRegex = /[\u00a0]*[\d#\-\*\u2022]+\.?/; const trimRegex = /[\u00a0]*[\d#\-\*\u2022]+\.?/;
const hexColorRegex = /^#[\da-fA-F]{0,6}$/; const hexColorRegex = /^#[\da-fA-F]{0,6}$/;
@ -250,7 +248,7 @@ export async function wrapWithAbbreviation(args: any): Promise<boolean> {
return ''; return '';
} }
const prompt = localize('wrapWithAbbreviationPrompt', "Enter Abbreviation"); const prompt = vscode.l10n.t("Enter Abbreviation");
const inputAbbreviation = (args && args['abbreviation']) const inputAbbreviation = (args && args['abbreviation'])
? (args['abbreviation'] as string) ? (args['abbreviation'] as string)
: await vscode.window.showInputBox({ prompt, validateInput: inputChanged }); : await vscode.window.showInputBox({ prompt, validateInput: inputChanged });

View file

@ -28,8 +28,7 @@
"dependencies": { "dependencies": {
"jsonc-parser": "^2.2.1", "jsonc-parser": "^2.2.1",
"markdown-it": "^12.3.2", "markdown-it": "^12.3.2",
"parse5": "^3.0.2", "parse5": "^3.0.2"
"vscode-nls": "^5.2.0"
}, },
"contributes": { "contributes": {
"jsonValidation": [ "jsonValidation": [

View file

@ -6,13 +6,11 @@
import * as path from 'path'; import * as path from 'path';
import * as fs from 'fs'; import * as fs from 'fs';
import { URL } from 'url'; import { URL } from 'url';
import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle();
import { parseTree, findNodeAtLocation, Node as JsonNode, getNodeValue } from 'jsonc-parser'; import { parseTree, findNodeAtLocation, Node as JsonNode, getNodeValue } from 'jsonc-parser';
import * as MarkdownItType from 'markdown-it'; import * as MarkdownItType from 'markdown-it';
import { languages, workspace, Disposable, TextDocument, Uri, Diagnostic, Range, DiagnosticSeverity, Position, env } from 'vscode'; import { languages, workspace, Disposable, TextDocument, Uri, Diagnostic, Range, DiagnosticSeverity, Position, env, l10n } from 'vscode';
const product = JSON.parse(fs.readFileSync(path.join(env.appRoot, 'product.json'), { encoding: 'utf-8' })); const product = JSON.parse(fs.readFileSync(path.join(env.appRoot, 'product.json'), { encoding: 'utf-8' }));
const allowedBadgeProviders: string[] = (product.extensionAllowedBadgeProviders || []).map((s: string) => s.toLowerCase()); const allowedBadgeProviders: string[] = (product.extensionAllowedBadgeProviders || []).map((s: string) => s.toLowerCase());
@ -23,14 +21,14 @@ function isTrustedSVGSource(uri: Uri): boolean {
return allowedBadgeProviders.includes(uri.authority.toLowerCase()) || allowedBadgeProvidersRegex.some(r => r.test(uri.toString())); return allowedBadgeProviders.includes(uri.authority.toLowerCase()) || allowedBadgeProvidersRegex.some(r => r.test(uri.toString()));
} }
const httpsRequired = localize('httpsRequired', "Images must use the HTTPS protocol."); const httpsRequired = l10n.t("Images must use the HTTPS protocol.");
const svgsNotValid = localize('svgsNotValid', "SVGs are not a valid image source."); const svgsNotValid = l10n.t("SVGs are not a valid image source.");
const embeddedSvgsNotValid = localize('embeddedSvgsNotValid', "Embedded SVGs are not a valid image source."); const embeddedSvgsNotValid = l10n.t("Embedded SVGs are not a valid image source.");
const dataUrlsNotValid = localize('dataUrlsNotValid', "Data URLs are not a valid image source."); const dataUrlsNotValid = l10n.t("Data URLs are not a valid image source.");
const relativeUrlRequiresHttpsRepository = localize('relativeUrlRequiresHttpsRepository', "Relative image URLs require a repository with HTTPS protocol to be specified in the package.json."); const relativeUrlRequiresHttpsRepository = l10n.t("Relative image URLs require a repository with HTTPS protocol to be specified in the package.json.");
const relativeIconUrlRequiresHttpsRepository = localize('relativeIconUrlRequiresHttpsRepository', "An icon requires a repository with HTTPS protocol to be specified in this package.json."); const relativeIconUrlRequiresHttpsRepository = l10n.t("An icon requires a repository with HTTPS protocol to be specified in this package.json.");
const relativeBadgeUrlRequiresHttpsRepository = localize('relativeBadgeUrlRequiresHttpsRepository', "Relative badge URLs require a repository with HTTPS protocol to be specified in this package.json."); const relativeBadgeUrlRequiresHttpsRepository = l10n.t("Relative badge URLs require a repository with HTTPS protocol to be specified in this package.json.");
const apiProposalNotListed = localize('apiProposalNotListed', "This proposal cannot be used because for this extension the product defines a fixed set of API proposals. You can test your extension but before publishing you MUST reach out to the VS Code team."); const apiProposalNotListed = l10n.t("This proposal cannot be used because for this extension the product defines a fixed set of API proposals. You can test your extension but before publishing you MUST reach out to the VS Code team.");
enum Context { enum Context {
ICON, ICON,

View file

@ -5,9 +5,7 @@
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import { getLocation, Location } from 'jsonc-parser'; import { getLocation, Location } from 'jsonc-parser';
import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle();
export class PackageDocument { export class PackageDocument {
@ -40,8 +38,8 @@ export class PackageDocument {
} }
return Promise.resolve([this.newSnippetCompletionItem({ return Promise.resolve([this.newSnippetCompletionItem({
label: localize('languageSpecificEditorSettings', "Language specific editor settings"), label: vscode.l10n.t("Language specific editor settings"),
documentation: localize('languageSpecificEditorSettingsDescription', "Override editor settings for language"), documentation: vscode.l10n.t("Override editor settings for language"),
snippet, snippet,
range range
})]); })]);

View file

@ -66,8 +66,3 @@ uc.micro@^1.0.1, uc.micro@^1.0.5:
version "1.0.6" version "1.0.6"
resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac" resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac"
integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA== integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==
vscode-nls@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-5.2.0.tgz#3cb6893dd9bd695244d8a024bdf746eea665cc3f"
integrity sha512-RAaHx7B14ZU04EU31pT+rKz2/zSl7xMsfIZuo8pd+KZO6PXtQmpevpq3vxvWNcrGbdmhM/rr5Uw5Mz+NBfhVng==

View file

@ -2543,6 +2543,15 @@
"default": false, "default": false,
"markdownDescription": "%config.mergeEditor%", "markdownDescription": "%config.mergeEditor%",
"scope": "window" "scope": "window"
},
"git.optimisticUpdate": {
"type": "boolean",
"default": true,
"markdownDescription": "%config.optimisticUpdate%",
"scope": "resource",
"tags": [
"experimental"
]
} }
} }
}, },

View file

@ -236,6 +236,7 @@
"config.repositoryScanMaxDepth": "Controls the depth used when scanning workspace folders for Git repositories when `#git.autoRepositoryDetection#` is set to `true` or `subFolders`. Can be set to `-1` for no limit.", "config.repositoryScanMaxDepth": "Controls the depth used when scanning workspace folders for Git repositories when `#git.autoRepositoryDetection#` is set to `true` or `subFolders`. Can be set to `-1` for no limit.",
"config.useIntegratedAskPass": "Controls whether GIT_ASKPASS should be overwritten to use the integrated version.", "config.useIntegratedAskPass": "Controls whether GIT_ASKPASS should be overwritten to use the integrated version.",
"config.mergeEditor": "Open the merge editor for files that are currently under conflict.", "config.mergeEditor": "Open the merge editor for files that are currently under conflict.",
"config.optimisticUpdate": "Controls whether to optimistically update the state of the Source Control view after running git commands.",
"submenu.explorer": "Git", "submenu.explorer": "Git",
"submenu.commit": "Commit", "submenu.commit": "Commit",
"submenu.commit.amend": "Amend", "submenu.commit.amend": "Amend",

View file

@ -4,11 +4,10 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import * as fs from 'fs'; import * as fs from 'fs';
import { l10n } from 'vscode';
import { IPCClient } from './ipc/ipcClient'; import { IPCClient } from './ipc/ipcClient';
function fatal(err: any): void { function fatal(err: any): void {
console.error(l10n.t('Missing or invalid credentials.')); console.error('Missing or invalid credentials.');
console.error(err); console.error(err);
process.exit(1); process.exit(1);
} }

View file

@ -5,7 +5,7 @@
import * as os from 'os'; import * as os from 'os';
import * as path from 'path'; import * as path from 'path';
import { Command, commands, Disposable, LineChange, MessageOptions, Position, ProgressLocation, QuickPickItem, Range, SourceControlResourceState, TextDocumentShowOptions, TextEditor, Uri, ViewColumn, window, workspace, WorkspaceEdit, WorkspaceFolder, TimelineItem, env, Selection, TextDocumentContentProvider, InputBoxValidationSeverity, TabInputText, TabInputTextMerge, QuickPickItemKind, TextDocument, LogOutputChannel, l10n } from 'vscode'; import { Command, commands, Disposable, LineChange, MessageOptions, Position, ProgressLocation, QuickPickItem, Range, SourceControlResourceState, TextDocumentShowOptions, TextEditor, Uri, ViewColumn, window, workspace, WorkspaceEdit, WorkspaceFolder, TimelineItem, env, Selection, TextDocumentContentProvider, InputBoxValidationSeverity, TabInputText, TabInputTextMerge, QuickPickItemKind, TextDocument, LogOutputChannel, l10n, Memento } from 'vscode';
import TelemetryReporter from '@vscode/extension-telemetry'; import TelemetryReporter from '@vscode/extension-telemetry';
import { uniqueNamesGenerator, adjectives, animals, colors, NumberDictionary } from '@joaomoreno/unique-names-generator'; import { uniqueNamesGenerator, adjectives, animals, colors, NumberDictionary } from '@joaomoreno/unique-names-generator';
import { Branch, ForcePushMode, GitErrorCodes, Ref, RefType, Status, CommitOptions, RemoteSourcePublisher, Remote } from './api/git'; import { Branch, ForcePushMode, GitErrorCodes, Ref, RefType, Status, CommitOptions, RemoteSourcePublisher, Remote } from './api/git';
@ -351,6 +351,7 @@ export class CommandCenter {
constructor( constructor(
private git: Git, private git: Git,
private model: Model, private model: Model,
private globalState: Memento,
private logger: LogOutputChannel, private logger: LogOutputChannel,
private telemetryReporter: TelemetryReporter private telemetryReporter: TelemetryReporter
) { ) {
@ -543,7 +544,7 @@ export class CommandCenter {
canSelectMany: false, canSelectMany: false,
defaultUri: Uri.file(defaultCloneDirectory), defaultUri: Uri.file(defaultCloneDirectory),
title: l10n.t('Choose a folder to clone {0} into', url), title: l10n.t('Choose a folder to clone {0} into', url),
openLabel: l10n.t('Select Repository Location') openLabel: l10n.t('Select as Repository Destination')
}); });
if (!uris || uris.length === 0) { if (!uris || uris.length === 0) {
@ -1570,7 +1571,7 @@ export class CommandCenter {
repository: Repository, repository: Repository,
getCommitMessage: () => Promise<string | undefined>, getCommitMessage: () => Promise<string | undefined>,
opts: CommitOptions opts: CommitOptions
): Promise<boolean> { ): Promise<void> {
const config = workspace.getConfiguration('git', Uri.file(repository.root)); const config = workspace.getConfiguration('git', Uri.file(repository.root));
let promptToSaveFilesBeforeCommit = config.get<'always' | 'staged' | 'never'>('promptToSaveFilesBeforeCommit'); let promptToSaveFilesBeforeCommit = config.get<'always' | 'staged' | 'never'>('promptToSaveFilesBeforeCommit');
@ -1610,7 +1611,7 @@ export class CommandCenter {
noStagedChanges = repository.indexGroup.resourceStates.length === 0; noStagedChanges = repository.indexGroup.resourceStates.length === 0;
noUnstagedChanges = repository.workingTreeGroup.resourceStates.length === 0; noUnstagedChanges = repository.workingTreeGroup.resourceStates.length === 0;
} else if (pick !== commit) { } else if (pick !== commit) {
return false; // do not commit on cancel return; // do not commit on cancel
} }
} }
} }
@ -1620,7 +1621,7 @@ export class CommandCenter {
const suggestSmartCommit = config.get<boolean>('suggestSmartCommit') === true; const suggestSmartCommit = config.get<boolean>('suggestSmartCommit') === true;
if (!suggestSmartCommit) { if (!suggestSmartCommit) {
return false; return;
} }
// prompt the user if we want to commit all or not // prompt the user if we want to commit all or not
@ -1634,9 +1635,9 @@ export class CommandCenter {
config.update('enableSmartCommit', true, true); config.update('enableSmartCommit', true, true);
} else if (pick === never) { } else if (pick === never) {
config.update('suggestSmartCommit', false, true); config.update('suggestSmartCommit', false, true);
return false; return;
} else if (pick !== yes) { } else if (pick !== yes) {
return false; // do not commit on cancel return; // do not commit on cancel
} }
} }
@ -1682,7 +1683,7 @@ export class CommandCenter {
const answer = await window.showInformationMessage(l10n.t('There are no changes to commit.'), commitAnyway); const answer = await window.showInformationMessage(l10n.t('There are no changes to commit.'), commitAnyway);
if (answer !== commitAnyway) { if (answer !== commitAnyway) {
return false; return;
} }
opts.empty = true; opts.empty = true;
@ -1691,7 +1692,7 @@ export class CommandCenter {
if (opts.noVerify) { if (opts.noVerify) {
if (!config.get<boolean>('allowNoVerifyCommit')) { if (!config.get<boolean>('allowNoVerifyCommit')) {
await window.showErrorMessage(l10n.t('Commits without verification are not allowed, please enable them with the "git.allowNoVerifyCommit" setting.')); await window.showErrorMessage(l10n.t('Commits without verification are not allowed, please enable them with the "git.allowNoVerifyCommit" setting.'));
return false; return;
} }
if (config.get<boolean>('confirmNoVerifyCommit')) { if (config.get<boolean>('confirmNoVerifyCommit')) {
@ -1703,7 +1704,7 @@ export class CommandCenter {
if (pick === neverAgain) { if (pick === neverAgain) {
config.update('confirmNoVerifyCommit', false, true); config.update('confirmNoVerifyCommit', false, true);
} else if (pick !== yes) { } else if (pick !== yes) {
return false; return;
} }
} }
} }
@ -1711,7 +1712,7 @@ export class CommandCenter {
const message = await getCommitMessage(); const message = await getCommitMessage();
if (!message && !opts.amend && !opts.useEditor) { if (!message && !opts.amend && !opts.useEditor) {
return false; return;
} }
if (opts.all && smartCommitChanges === 'tracked') { if (opts.all && smartCommitChanges === 'tracked') {
@ -1737,12 +1738,12 @@ export class CommandCenter {
} }
if (!pick) { if (!pick) {
return false; return;
} else if (pick === commitToNewBranch) { } else if (pick === commitToNewBranch) {
const branchName = await this.promptForBranchName(repository); const branchName = await this.promptForBranchName(repository);
if (!branchName) { if (!branchName) {
return false; return;
} }
await repository.branch(branchName, true); await repository.branch(branchName, true);
@ -1750,8 +1751,6 @@ export class CommandCenter {
} }
await repository.commit(message, opts); await repository.commit(message, opts);
return true;
} }
private async commitWithAnyInput(repository: Repository, opts: CommitOptions): Promise<void> { private async commitWithAnyInput(repository: Repository, opts: CommitOptions): Promise<void> {
@ -1789,11 +1788,7 @@ export class CommandCenter {
return _message; return _message;
}; };
const didCommit = await this.smartCommit(repository, getCommitMessage, opts); await this.smartCommit(repository, getCommitMessage, opts);
if (message && didCommit) {
repository.inputBox.value = await repository.getInputTemplate();
}
} }
@command('git.commit', { repository: true }) @command('git.commit', { repository: true })
@ -2007,8 +2002,8 @@ export class CommandCenter {
const quickpick = window.createQuickPick(); const quickpick = window.createQuickPick();
quickpick.items = picks; quickpick.items = picks;
quickpick.placeholder = opts?.detached quickpick.placeholder = opts?.detached
? l10n.t('Select a ref to checkout in detached mode') ? l10n.t('Select a branch or tag to checkout in detached mode')
: l10n.t('Select a ref to checkout'); : l10n.t('Select a branch or tag to checkout');
quickpick.show(); quickpick.show();
@ -2544,12 +2539,20 @@ export class CommandCenter {
return; return;
} }
const branchName = repository.HEAD.name; if (this.globalState.get<boolean>('confirmBranchPublish', true)) {
const message = l10n.t('The branch "{0}" has no remote branch. Would you like to publish this branch?', branchName); const branchName = repository.HEAD.name;
const yes = l10n.t('OK'); const message = l10n.t('The branch "{0}" has no remote branch. Would you like to publish this branch?', branchName);
const pick = await window.showWarningMessage(message, { modal: true }, yes); const yes = l10n.t('OK');
const neverAgain = l10n.t('OK, Don\'t Ask Again');
const pick = await window.showWarningMessage(message, { modal: true }, yes, neverAgain);
if (pick === yes) { if (pick === yes || pick === neverAgain) {
if (pick === neverAgain) {
this.globalState.update('confirmBranchPublish', false);
}
await this.publish(repository);
}
} else {
await this.publish(repository); await this.publish(repository);
} }
} }

View file

@ -46,7 +46,9 @@ export class GitEditSessionIdentityProvider implements vscode.EditSessionIdentit
normalizedIdentity1.sha === normalizedIdentity2.sha) { normalizedIdentity1.sha === normalizedIdentity2.sha) {
// This is a perfect match // This is a perfect match
return vscode.EditSessionIdentityMatch.Complete; return vscode.EditSessionIdentityMatch.Complete;
} else if (normalizedIdentity1.sha !== normalizedIdentity2.sha) { } else if (normalizedIdentity1.remote === normalizedIdentity2.remote &&
normalizedIdentity1.ref === normalizedIdentity2.ref &&
normalizedIdentity1.sha !== normalizedIdentity2.sha) {
// Same branch and remote but different SHA // Same branch and remote but different SHA
return vscode.EditSessionIdentityMatch.Partial; return vscode.EditSessionIdentityMatch.Partial;
} else { } else {

View file

@ -18,7 +18,6 @@ import { detectEncoding } from './encoding';
import { Ref, RefType, Branch, Remote, ForcePushMode, GitErrorCodes, LogOptions, Change, Status, CommitOptions, BranchQuery } from './api/git'; import { Ref, RefType, Branch, Remote, ForcePushMode, GitErrorCodes, LogOptions, Change, Status, CommitOptions, BranchQuery } from './api/git';
import * as byline from 'byline'; import * as byline from 'byline';
import { StringDecoder } from 'string_decoder'; import { StringDecoder } from 'string_decoder';
import TelemetryReporter from '@vscode/extension-telemetry';
// https://github.com/microsoft/vscode/issues/65693 // https://github.com/microsoft/vscode/issues/65693
const MAX_CLI_LENGTH = 30000; const MAX_CLI_LENGTH = 30000;
@ -375,14 +374,11 @@ export class Git {
private _onOutput = new EventEmitter(); private _onOutput = new EventEmitter();
get onOutput(): EventEmitter { return this._onOutput; } get onOutput(): EventEmitter { return this._onOutput; }
private readonly telemetryReporter: TelemetryReporter; constructor(options: IGitOptions) {
constructor(options: IGitOptions, telemetryReporter: TelemetryReporter) {
this.path = options.gitPath; this.path = options.gitPath;
this.version = options.version; this.version = options.version;
this.userAgent = options.userAgent; this.userAgent = options.userAgent;
this.env = options.env || {}; this.env = options.env || {};
this.telemetryReporter = telemetryReporter;
const onConfigurationChanged = (e?: ConfigurationChangeEvent) => { const onConfigurationChanged = (e?: ConfigurationChangeEvent) => {
if (e !== undefined && !e.affectsConfiguration('git.commandsToLog')) { if (e !== undefined && !e.affectsConfiguration('git.commandsToLog')) {
@ -563,9 +559,7 @@ export class Git {
} }
private async _exec(args: string[], options: SpawnOptions = {}): Promise<IExecutionResult<string>> { private async _exec(args: string[], options: SpawnOptions = {}): Promise<IExecutionResult<string>> {
const startSpawn = Date.now();
const child = this.spawn(args, options); const child = this.spawn(args, options);
const durSpawn = Date.now() - startSpawn;
options.onSpawn?.(child); options.onSpawn?.(child);
@ -592,16 +586,6 @@ export class Git {
} }
} }
/* __GDPR__
"git.execDuration" : {
"owner": "lszomoru",
"comment": "Time it takes to spawn and execute a git command",
"durSpawn": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth","isMeasurement": true, "comment": "Time it took to run spawn git" },
"durExec": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth","isMeasurement": true, "comment": "Time git took" }
}
*/
this.telemetryReporter.sendTelemetryEvent('git.execDuration', undefined, { durSpawn, durExec });
let encoding = options.encoding || 'utf8'; let encoding = options.encoding || 'utf8';
encoding = iconv.encodingExists(encoding) ? encoding : 'utf8'; encoding = iconv.encodingExists(encoding) ? encoding : 'utf8';
@ -2083,7 +2067,7 @@ export class Repository {
} }
async getHEADFS(): Promise<Ref> { async getHEADFS(): Promise<Ref> {
const raw = await fs.readFile(path.join(this.dotGit.commonPath ?? this.dotGit.path, 'HEAD'), 'utf8'); const raw = await fs.readFile(path.join(this.dotGit.path, 'HEAD'), 'utf8');
// Branch // Branch
const branchMatch = raw.match(/^ref: refs\/heads\/(?<name>.*)$/m); const branchMatch = raw.match(/^ref: refs\/heads\/(?<name>.*)$/m);

View file

@ -85,7 +85,7 @@ async function createModel(context: ExtensionContext, logger: LogOutputChannel,
userAgent: `git/${info.version} (${(os as any).version?.() ?? os.type()} ${os.release()}; ${os.platform()} ${os.arch()}) vscode/${vscodeVersion} (${env.appName})`, userAgent: `git/${info.version} (${(os as any).version?.() ?? os.type()} ${os.release()}; ${os.platform()} ${os.arch()}) vscode/${vscodeVersion} (${env.appName})`,
version: info.version, version: info.version,
env: environment, env: environment,
}, telemetryReporter); });
const model = new Model(git, askpass, context.globalState, logger, telemetryReporter); const model = new Model(git, askpass, context.globalState, logger, telemetryReporter);
disposables.push(model); disposables.push(model);
@ -106,7 +106,7 @@ async function createModel(context: ExtensionContext, logger: LogOutputChannel,
git.onOutput.addListener('log', onOutput); git.onOutput.addListener('log', onOutput);
disposables.push(toDisposable(() => git.onOutput.removeListener('log', onOutput))); disposables.push(toDisposable(() => git.onOutput.removeListener('log', onOutput)));
const cc = new CommandCenter(git, model, logger, telemetryReporter); const cc = new CommandCenter(git, model, context.globalState, logger, telemetryReporter);
disposables.push( disposables.push(
cc, cc,
new GitFileSystemProvider(model), new GitFileSystemProvider(model),

View file

@ -447,6 +447,13 @@ export interface GitResourceGroup extends SourceControlResourceGroup {
resourceStates: Resource[]; resourceStates: Resource[];
} }
interface GitResourceGroups {
indexGroup?: Resource[];
mergeGroup?: Resource[];
untrackedGroup?: Resource[];
workingTreeGroup?: Resource[];
}
export interface OperationResult { export interface OperationResult {
operation: Operation; operation: Operation;
error: any; error: any;
@ -974,7 +981,7 @@ export class Repository implements Disposable {
|| e.affectsConfiguration('git.ignoreSubmodules', root) || e.affectsConfiguration('git.ignoreSubmodules', root)
|| e.affectsConfiguration('git.openDiffOnClick', root) || e.affectsConfiguration('git.openDiffOnClick', root)
|| e.affectsConfiguration('git.showActionButton', root) || e.affectsConfiguration('git.showActionButton', root)
)(this.updateModelState, this, this.disposables); )(() => this.updateModelState(), this, this.disposables);
const updateInputBoxVisibility = () => { const updateInputBoxVisibility = () => {
const config = workspace.getConfiguration('git', root); const config = workspace.getConfiguration('git', root);
@ -1247,40 +1254,42 @@ export class Repository implements Disposable {
} }
async commit(message: string | undefined, opts: CommitOptions = Object.create(null)): Promise<void> { async commit(message: string | undefined, opts: CommitOptions = Object.create(null)): Promise<void> {
const indexResources = [...this.indexGroup.resourceStates.map(r => r.resourceUri.fsPath)];
const workingGroupResources = opts.all && opts.all !== 'tracked' ?
[...this.workingTreeGroup.resourceStates.map(r => r.resourceUri.fsPath)] : [];
if (this.rebaseCommit) { if (this.rebaseCommit) {
await this.run(Operation.RebaseContinue, async () => { await this.run(
if (opts.all) { Operation.RebaseContinue,
const addOpts = opts.all === 'tracked' ? { update: true } : {}; async () => {
await this.repository.add([], addOpts); if (opts.all) {
} const addOpts = opts.all === 'tracked' ? { update: true } : {};
await this.repository.add([], addOpts);
}
await this.repository.rebaseContinue(); await this.repository.rebaseContinue();
this.closeDiffEditors(indexResources, workingGroupResources); await this.commitOperationCleanup(message, opts);
}); },
() => this.commitOperationGetOptimisticResourceGroups(opts));
} else { } else {
// Set post-commit command to render the correct action button // Set post-commit command to render the correct action button
this.commitCommandCenter.postCommitCommand = opts.postCommitCommand; this.commitCommandCenter.postCommitCommand = opts.postCommitCommand;
await this.run(Operation.Commit, async () => { await this.run(
if (opts.all) { Operation.Commit,
const addOpts = opts.all === 'tracked' ? { update: true } : {}; async () => {
await this.repository.add([], addOpts); if (opts.all) {
} const addOpts = opts.all === 'tracked' ? { update: true } : {};
await this.repository.add([], addOpts);
}
delete opts.all; delete opts.all;
if (opts.requireUserConfig === undefined || opts.requireUserConfig === null) { if (opts.requireUserConfig === undefined || opts.requireUserConfig === null) {
const config = workspace.getConfiguration('git', Uri.file(this.root)); const config = workspace.getConfiguration('git', Uri.file(this.root));
opts.requireUserConfig = config.get<boolean>('requireGitUserConfig'); opts.requireUserConfig = config.get<boolean>('requireGitUserConfig');
} }
await this.repository.commit(message, opts); await this.repository.commit(message, opts);
this.closeDiffEditors(indexResources, workingGroupResources); await this.commitOperationCleanup(message, opts);
}); },
() => this.commitOperationGetOptimisticResourceGroups(opts));
// Execute post-commit command // Execute post-commit command
await this.run(Operation.PostCommitCommand, async () => { await this.run(Operation.PostCommitCommand, async () => {
@ -1289,6 +1298,32 @@ export class Repository implements Disposable {
} }
} }
private async commitOperationCleanup(message: string | undefined, opts: CommitOptions) {
if (message) {
this.inputBox.value = await this.getInputTemplate();
}
const indexResources = [...this.indexGroup.resourceStates.map(r => r.resourceUri.fsPath)];
const workingGroupResources = opts.all && opts.all !== 'tracked' ?
[...this.workingTreeGroup.resourceStates.map(r => r.resourceUri.fsPath)] : [];
this.closeDiffEditors(indexResources, workingGroupResources);
}
private commitOperationGetOptimisticResourceGroups(opts: CommitOptions): GitResourceGroups {
let untrackedGroup: Resource[] | undefined = undefined,
workingTreeGroup: Resource[] | undefined = undefined;
if (opts.all === 'tracked') {
workingTreeGroup = this.workingTreeGroup.resourceStates
.filter(r => r.type === Status.UNTRACKED);
} else if (opts.all) {
untrackedGroup = workingTreeGroup = [];
}
return { indexGroup: [], mergeGroup: [], untrackedGroup, workingTreeGroup };
}
async clean(resources: Uri[]): Promise<void> { async clean(resources: Uri[]): Promise<void> {
await this.run(Operation.Clean, async () => { await this.run(Operation.Clean, async () => {
const toClean: string[] = []; const toClean: string[] = [];
@ -1869,7 +1904,10 @@ export class Repository implements Disposable {
} }
} }
private async run<T>(operation: Operation, runOperation: () => Promise<T> = () => Promise.resolve<any>(null)): Promise<T> { private async run<T>(
operation: Operation,
runOperation: () => Promise<T> = () => Promise.resolve<any>(null),
getOptimisticResourceGroups: () => GitResourceGroups | undefined = () => undefined): Promise<T> {
if (this.state !== RepositoryState.Idle) { if (this.state !== RepositoryState.Idle) {
throw new Error('Repository not initialized'); throw new Error('Repository not initialized');
} }
@ -1883,7 +1921,10 @@ export class Repository implements Disposable {
const result = await this.retryRun(operation, runOperation); const result = await this.retryRun(operation, runOperation);
if (!isReadOnly(operation)) { if (!isReadOnly(operation)) {
await this.updateModelState(); const scopedConfig = workspace.getConfiguration('git', Uri.file(this.repository.root));
const optimisticUpdate = scopedConfig.get<boolean>('optimisticUpdate') === true;
await this.updateModelState(optimisticUpdate ? getOptimisticResourceGroups() : undefined);
} }
return result; return result;
@ -1942,18 +1983,14 @@ export class Repository implements Disposable {
return folderPaths.filter(p => !ignored.has(p)); return folderPaths.filter(p => !ignored.has(p));
} }
private async updateModelState() { private async updateModelState(optimisticResourcesGroups?: GitResourceGroups) {
this.updateModelStateCancellationTokenSource?.cancel(); this.updateModelStateCancellationTokenSource?.cancel();
this.updateModelStateCancellationTokenSource = new CancellationTokenSource(); this.updateModelStateCancellationTokenSource = new CancellationTokenSource();
await this._updateModelState(this.updateModelStateCancellationTokenSource.token); await this._updateModelState(optimisticResourcesGroups, this.updateModelStateCancellationTokenSource.token);
} }
private async _updateModelState(cancellationToken?: CancellationToken): Promise<void> { private async _updateModelState(optimisticResourcesGroups?: GitResourceGroups, cancellationToken?: CancellationToken): Promise<void> {
if (cancellationToken && cancellationToken.isCancellationRequested) {
return;
}
try { try {
const config = workspace.getConfiguration('git'); const config = workspace.getConfiguration('git');
let sort = config.get<'alphabetically' | 'committerdate'>('branchSortOrder') || 'alphabetically'; let sort = config.get<'alphabetically' | 'committerdate'>('branchSortOrder') || 'alphabetically';
@ -1961,13 +1998,12 @@ export class Repository implements Disposable {
sort = 'alphabetically'; sort = 'alphabetically';
} }
const [HEAD, refs, remotes, submodules, status, rebaseCommit, mergeInProgress, commitTemplate] = const [HEAD, refs, remotes, submodules, rebaseCommit, mergeInProgress, commitTemplate] =
await Promise.all([ await Promise.all([
this.repository.getHEADBranch(), this.repository.getHEADBranch(),
this.repository.getRefs({ sort }), this.repository.getRefs({ sort }),
this.repository.getRemotes(), this.repository.getRemotes(),
this.repository.getSubmodules(), this.repository.getSubmodules(),
this.getStatus(cancellationToken),
this.getRebaseCommit(), this.getRebaseCommit(),
this.isMergeInProgress(), this.isMergeInProgress(),
this.getInputTemplate()]); this.getInputTemplate()]);
@ -1979,18 +2015,15 @@ export class Repository implements Disposable {
this.rebaseCommit = rebaseCommit; this.rebaseCommit = rebaseCommit;
this.mergeInProgress = mergeInProgress; this.mergeInProgress = mergeInProgress;
// set resource groups
this.mergeGroup.resourceStates = status.merge;
this.indexGroup.resourceStates = status.index;
this.workingTreeGroup.resourceStates = status.workingTree;
this.untrackedGroup.resourceStates = status.untracked;
// set count badge
this.setCountBadge();
this._onDidChangeStatus.fire();
this._sourceControl.commitTemplate = commitTemplate; this._sourceControl.commitTemplate = commitTemplate;
// Optimistically update the resource states
if (optimisticResourcesGroups) {
this._updateResourceGroupsState(optimisticResourcesGroups);
}
// Update resource states based on status information
this._updateResourceGroupsState(await this.getStatus(cancellationToken));
} }
catch (err) { catch (err) {
if (err instanceof CancellationError) { if (err instanceof CancellationError) {
@ -2001,7 +2034,20 @@ export class Repository implements Disposable {
} }
} }
private async getStatus(cancellationToken?: CancellationToken): Promise<{ index: Resource[]; workingTree: Resource[]; merge: Resource[]; untracked: Resource[] }> { private _updateResourceGroupsState(resourcesGroups: GitResourceGroups): void {
// set resource groups
if (resourcesGroups.indexGroup) { this.indexGroup.resourceStates = resourcesGroups.indexGroup; }
if (resourcesGroups.mergeGroup) { this.mergeGroup.resourceStates = resourcesGroups.mergeGroup; }
if (resourcesGroups.untrackedGroup) { this.untrackedGroup.resourceStates = resourcesGroups.untrackedGroup; }
if (resourcesGroups.workingTreeGroup) { this.workingTreeGroup.resourceStates = resourcesGroups.workingTreeGroup; }
// set count badge
this.setCountBadge();
this._onDidChangeStatus.fire();
}
private async getStatus(cancellationToken?: CancellationToken): Promise<GitResourceGroups> {
if (cancellationToken && cancellationToken.isCancellationRequested) { if (cancellationToken && cancellationToken.isCancellationRequested) {
throw new CancellationError(); throw new CancellationError();
} }
@ -2088,10 +2134,10 @@ export class Repository implements Disposable {
} }
} }
const index: Resource[] = [], const indexGroup: Resource[] = [],
workingTree: Resource[] = [], mergeGroup: Resource[] = [],
merge: Resource[] = [], untrackedGroup: Resource[] = [],
untracked: Resource[] = []; workingTreeGroup: Resource[] = [];
status.forEach(raw => { status.forEach(raw => {
const uri = Uri.file(path.join(this.repository.root, raw.path)); const uri = Uri.file(path.join(this.repository.root, raw.path));
@ -2101,42 +2147,42 @@ export class Repository implements Disposable {
switch (raw.x + raw.y) { switch (raw.x + raw.y) {
case '??': switch (untrackedChanges) { case '??': switch (untrackedChanges) {
case 'mixed': return workingTree.push(new Resource(this.resourceCommandResolver, ResourceGroupType.WorkingTree, uri, Status.UNTRACKED, useIcons)); case 'mixed': return workingTreeGroup.push(new Resource(this.resourceCommandResolver, ResourceGroupType.WorkingTree, uri, Status.UNTRACKED, useIcons));
case 'separate': return untracked.push(new Resource(this.resourceCommandResolver, ResourceGroupType.Untracked, uri, Status.UNTRACKED, useIcons)); case 'separate': return untrackedGroup.push(new Resource(this.resourceCommandResolver, ResourceGroupType.Untracked, uri, Status.UNTRACKED, useIcons));
default: return undefined; default: return undefined;
} }
case '!!': switch (untrackedChanges) { case '!!': switch (untrackedChanges) {
case 'mixed': return workingTree.push(new Resource(this.resourceCommandResolver, ResourceGroupType.WorkingTree, uri, Status.IGNORED, useIcons)); case 'mixed': return workingTreeGroup.push(new Resource(this.resourceCommandResolver, ResourceGroupType.WorkingTree, uri, Status.IGNORED, useIcons));
case 'separate': return untracked.push(new Resource(this.resourceCommandResolver, ResourceGroupType.Untracked, uri, Status.IGNORED, useIcons)); case 'separate': return untrackedGroup.push(new Resource(this.resourceCommandResolver, ResourceGroupType.Untracked, uri, Status.IGNORED, useIcons));
default: return undefined; default: return undefined;
} }
case 'DD': return merge.push(new Resource(this.resourceCommandResolver, ResourceGroupType.Merge, uri, Status.BOTH_DELETED, useIcons)); case 'DD': return mergeGroup.push(new Resource(this.resourceCommandResolver, ResourceGroupType.Merge, uri, Status.BOTH_DELETED, useIcons));
case 'AU': return merge.push(new Resource(this.resourceCommandResolver, ResourceGroupType.Merge, uri, Status.ADDED_BY_US, useIcons)); case 'AU': return mergeGroup.push(new Resource(this.resourceCommandResolver, ResourceGroupType.Merge, uri, Status.ADDED_BY_US, useIcons));
case 'UD': return merge.push(new Resource(this.resourceCommandResolver, ResourceGroupType.Merge, uri, Status.DELETED_BY_THEM, useIcons)); case 'UD': return mergeGroup.push(new Resource(this.resourceCommandResolver, ResourceGroupType.Merge, uri, Status.DELETED_BY_THEM, useIcons));
case 'UA': return merge.push(new Resource(this.resourceCommandResolver, ResourceGroupType.Merge, uri, Status.ADDED_BY_THEM, useIcons)); case 'UA': return mergeGroup.push(new Resource(this.resourceCommandResolver, ResourceGroupType.Merge, uri, Status.ADDED_BY_THEM, useIcons));
case 'DU': return merge.push(new Resource(this.resourceCommandResolver, ResourceGroupType.Merge, uri, Status.DELETED_BY_US, useIcons)); case 'DU': return mergeGroup.push(new Resource(this.resourceCommandResolver, ResourceGroupType.Merge, uri, Status.DELETED_BY_US, useIcons));
case 'AA': return merge.push(new Resource(this.resourceCommandResolver, ResourceGroupType.Merge, uri, Status.BOTH_ADDED, useIcons)); case 'AA': return mergeGroup.push(new Resource(this.resourceCommandResolver, ResourceGroupType.Merge, uri, Status.BOTH_ADDED, useIcons));
case 'UU': return merge.push(new Resource(this.resourceCommandResolver, ResourceGroupType.Merge, uri, Status.BOTH_MODIFIED, useIcons)); case 'UU': return mergeGroup.push(new Resource(this.resourceCommandResolver, ResourceGroupType.Merge, uri, Status.BOTH_MODIFIED, useIcons));
} }
switch (raw.x) { switch (raw.x) {
case 'M': index.push(new Resource(this.resourceCommandResolver, ResourceGroupType.Index, uri, Status.INDEX_MODIFIED, useIcons)); break; case 'M': indexGroup.push(new Resource(this.resourceCommandResolver, ResourceGroupType.Index, uri, Status.INDEX_MODIFIED, useIcons)); break;
case 'A': index.push(new Resource(this.resourceCommandResolver, ResourceGroupType.Index, uri, Status.INDEX_ADDED, useIcons)); break; case 'A': indexGroup.push(new Resource(this.resourceCommandResolver, ResourceGroupType.Index, uri, Status.INDEX_ADDED, useIcons)); break;
case 'D': index.push(new Resource(this.resourceCommandResolver, ResourceGroupType.Index, uri, Status.INDEX_DELETED, useIcons)); break; case 'D': indexGroup.push(new Resource(this.resourceCommandResolver, ResourceGroupType.Index, uri, Status.INDEX_DELETED, useIcons)); break;
case 'R': index.push(new Resource(this.resourceCommandResolver, ResourceGroupType.Index, uri, Status.INDEX_RENAMED, useIcons, renameUri)); break; case 'R': indexGroup.push(new Resource(this.resourceCommandResolver, ResourceGroupType.Index, uri, Status.INDEX_RENAMED, useIcons, renameUri)); break;
case 'C': index.push(new Resource(this.resourceCommandResolver, ResourceGroupType.Index, uri, Status.INDEX_COPIED, useIcons, renameUri)); break; case 'C': indexGroup.push(new Resource(this.resourceCommandResolver, ResourceGroupType.Index, uri, Status.INDEX_COPIED, useIcons, renameUri)); break;
} }
switch (raw.y) { switch (raw.y) {
case 'M': workingTree.push(new Resource(this.resourceCommandResolver, ResourceGroupType.WorkingTree, uri, Status.MODIFIED, useIcons, renameUri)); break; case 'M': workingTreeGroup.push(new Resource(this.resourceCommandResolver, ResourceGroupType.WorkingTree, uri, Status.MODIFIED, useIcons, renameUri)); break;
case 'D': workingTree.push(new Resource(this.resourceCommandResolver, ResourceGroupType.WorkingTree, uri, Status.DELETED, useIcons, renameUri)); break; case 'D': workingTreeGroup.push(new Resource(this.resourceCommandResolver, ResourceGroupType.WorkingTree, uri, Status.DELETED, useIcons, renameUri)); break;
case 'A': workingTree.push(new Resource(this.resourceCommandResolver, ResourceGroupType.WorkingTree, uri, Status.INTENT_TO_ADD, useIcons, renameUri)); break; case 'A': workingTreeGroup.push(new Resource(this.resourceCommandResolver, ResourceGroupType.WorkingTree, uri, Status.INTENT_TO_ADD, useIcons, renameUri)); break;
} }
return undefined; return undefined;
}); });
return { index, workingTree, merge, untracked }; return { indexGroup, mergeGroup, untrackedGroup, workingTreeGroup };
} }
private setCountBadge(): void { private setCountBadge(): void {

View file

@ -16,9 +16,7 @@
"compile": "gulp compile-extension:grunt", "compile": "gulp compile-extension:grunt",
"watch": "gulp watch-extension:grunt" "watch": "gulp watch-extension:grunt"
}, },
"dependencies": { "dependencies": {},
"vscode-nls": "^5.2.0"
},
"devDependencies": { "devDependencies": {
"@types/node": "16.x" "@types/node": "16.x"
}, },

View file

@ -7,8 +7,6 @@ import * as path from 'path';
import * as fs from 'fs'; import * as fs from 'fs';
import * as cp from 'child_process'; import * as cp from 'child_process';
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle();
type AutoDetect = 'on' | 'off'; type AutoDetect = 'on' | 'off';
@ -60,8 +58,8 @@ function getOutputChannel(): vscode.OutputChannel {
} }
function showError() { function showError() {
vscode.window.showWarningMessage(localize('gruntTaskDetectError', 'Problem finding grunt tasks. See the output for more information.'), vscode.window.showWarningMessage(vscode.l10n.t("Problem finding grunt tasks. See the output for more information."),
localize('gruntShowOutput', 'Go to output')).then(() => { vscode.l10n.t("Go to output")).then(() => {
getOutputChannel().show(true); getOutputChannel().show(true);
}); });
} }
@ -215,7 +213,7 @@ class FolderDetector {
if (err.stdout) { if (err.stdout) {
channel.appendLine(err.stdout); channel.appendLine(err.stdout);
} }
channel.appendLine(localize('execFailed', 'Auto detecting Grunt for folder {0} failed with error: {1}', this.workspaceFolder.name, err.error ? err.error.toString() : 'unknown')); channel.appendLine(vscode.l10n.t("Auto detecting Grunt for folder {0} failed with error: {1}', this.workspaceFolder.name, err.error ? err.error.toString() : 'unknown"));
showError(); showError();
return emptyTasks; return emptyTasks;
} }

View file

@ -6,8 +6,3 @@
version "16.11.6" version "16.11.6"
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.6.tgz#6bef7a2a0ad684cf6e90fcfe31cecabd9ce0a3ae" resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.6.tgz#6bef7a2a0ad684cf6e90fcfe31cecabd9ce0a3ae"
integrity sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w== integrity sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w==
vscode-nls@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-5.2.0.tgz#3cb6893dd9bd695244d8a024bdf746eea665cc3f"
integrity sha512-RAaHx7B14ZU04EU31pT+rKz2/zSl7xMsfIZuo8pd+KZO6PXtQmpevpq3vxvWNcrGbdmhM/rr5Uw5Mz+NBfhVng==

View file

@ -16,9 +16,7 @@
"compile": "gulp compile-extension:gulp", "compile": "gulp compile-extension:gulp",
"watch": "gulp watch-extension:gulp" "watch": "gulp watch-extension:gulp"
}, },
"dependencies": { "dependencies": {},
"vscode-nls": "^5.2.0"
},
"devDependencies": { "devDependencies": {
"@types/node": "16.x" "@types/node": "16.x"
}, },

View file

@ -7,9 +7,7 @@ import * as path from 'path';
import * as fs from 'fs'; import * as fs from 'fs';
import * as cp from 'child_process'; import * as cp from 'child_process';
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle();
type AutoDetect = 'on' | 'off'; type AutoDetect = 'on' | 'off';
@ -80,8 +78,8 @@ function getOutputChannel(): vscode.OutputChannel {
} }
function showError() { function showError() {
vscode.window.showWarningMessage(localize('gulpTaskDetectError', 'Problem finding gulp tasks. See the output for more information.'), vscode.window.showWarningMessage(vscode.l10n.t("Problem finding gulp tasks. See the output for more information."),
localize('gulpShowOutput', 'Go to output')).then((choice) => { vscode.l10n.t("Go to output")).then((choice) => {
if (choice !== undefined) { if (choice !== undefined) {
_channel.show(true); _channel.show(true);
} }
@ -256,7 +254,7 @@ class FolderDetector {
if (err.stdout) { if (err.stdout) {
channel.appendLine(err.stdout); channel.appendLine(err.stdout);
} }
channel.appendLine(localize('execFailed', 'Auto detecting gulp for folder {0} failed with error: {1}', this.workspaceFolder.name, err.error ? err.error.toString() : 'unknown')); channel.appendLine(vscode.l10n.t("Auto detecting gulp for folder {0} failed with error: {1}', this.workspaceFolder.name, err.error ? err.error.toString() : 'unknown"));
showError(); showError();
return emptyTasks; return emptyTasks;
} }

View file

@ -6,8 +6,3 @@
version "16.11.6" version "16.11.6"
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.6.tgz#6bef7a2a0ad684cf6e90fcfe31cecabd9ce0a3ae" resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.6.tgz#6bef7a2a0ad684cf6e90fcfe31cecabd9ce0a3ae"
integrity sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w== integrity sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w==
vscode-nls@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-5.2.0.tgz#3cb6893dd9bd695244d8a024bdf746eea665cc3f"
integrity sha512-RAaHx7B14ZU04EU31pT+rKz2/zSl7xMsfIZuo8pd+KZO6PXtQmpevpq3vxvWNcrGbdmhM/rr5Uw5Mz+NBfhVng==

View file

@ -16,9 +16,7 @@
"compile": "gulp compile-extension:jake", "compile": "gulp compile-extension:jake",
"watch": "gulp watch-extension:jake" "watch": "gulp watch-extension:jake"
}, },
"dependencies": { "dependencies": {},
"vscode-nls": "^5.2.0"
},
"devDependencies": { "devDependencies": {
"@types/node": "16.x" "@types/node": "16.x"
}, },

View file

@ -7,8 +7,6 @@ import * as path from 'path';
import * as fs from 'fs'; import * as fs from 'fs';
import * as cp from 'child_process'; import * as cp from 'child_process';
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle();
type AutoDetect = 'on' | 'off'; type AutoDetect = 'on' | 'off';
@ -60,8 +58,8 @@ function getOutputChannel(): vscode.OutputChannel {
} }
function showError() { function showError() {
vscode.window.showWarningMessage(localize('jakeTaskDetectError', 'Problem finding jake tasks. See the output for more information.'), vscode.window.showWarningMessage(vscode.l10n.t("Problem finding jake tasks. See the output for more information."),
localize('jakeShowOutput', 'Go to output')).then(() => { vscode.l10n.t("Go to output")).then(() => {
getOutputChannel().show(true); getOutputChannel().show(true);
}); });
} }
@ -189,7 +187,7 @@ class FolderDetector {
if (err.stdout) { if (err.stdout) {
channel.appendLine(err.stdout); channel.appendLine(err.stdout);
} }
channel.appendLine(localize('execFailed', 'Auto detecting Jake for folder {0} failed with error: {1}', this.workspaceFolder.name, err.error ? err.error.toString() : 'unknown')); channel.appendLine(vscode.l10n.t("Auto detecting Jake for folder {0} failed with error: {1}', this.workspaceFolder.name, err.error ? err.error.toString() : 'unknown"));
showError(); showError();
return emptyTasks; return emptyTasks;
} }

View file

@ -6,8 +6,3 @@
version "16.11.6" version "16.11.6"
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.6.tgz#6bef7a2a0ad684cf6e90fcfe31cecabd9ce0a3ae" resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.6.tgz#6bef7a2a0ad684cf6e90fcfe31cecabd9ce0a3ae"
integrity sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w== integrity sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w==
vscode-nls@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-5.2.0.tgz#3cb6893dd9bd695244d8a024bdf746eea665cc3f"
integrity sha512-RAaHx7B14ZU04EU31pT+rKz2/zSl7xMsfIZuo8pd+KZO6PXtQmpevpq3vxvWNcrGbdmhM/rr5Uw5Mz+NBfhVng==

View file

@ -107,7 +107,7 @@
} }
}, },
"wordPattern": { "wordPattern": {
"pattern": "(-?\\d*\\.\\d\\w*)|([^\\`\\~\\!\\%\\^\\&\\*\\(\\)\\-\\=\\+\\[\\{\\]\\}\\\\\\|\\;\\:\\'\\\"\\,\\.\\<\\>/\\?\\s]+)", "pattern": "(-?\\d*\\.\\d\\w*)|([^\\`\\~\\@\\!\\%\\^\\&\\*\\(\\)\\-\\=\\+\\[\\{\\]\\}\\\\\\|\\;\\:\\'\\\"\\,\\.\\<\\>/\\?\\s]+)",
}, },
"indentationRules": { "indentationRules": {
"decreaseIndentPattern": { "decreaseIndentPattern": {

View file

@ -149,8 +149,7 @@ function showSchemaList(input: ShowSchemasInput) {
items.push({ label: localize('schema.showdocs', 'Learn more about JSON schema configuration...'), uri: Uri.parse('https://code.visualstudio.com/docs/languages/json#_json-schemas-and-settings') }); items.push({ label: localize('schema.showdocs', 'Learn more about JSON schema configuration...'), uri: Uri.parse('https://code.visualstudio.com/docs/languages/json#_json-schemas-and-settings') });
const quickPick = window.createQuickPick<ShowSchemasItem>(); const quickPick = window.createQuickPick<ShowSchemasItem>();
quickPick.title = localize('schemaPicker.title', 'JSON Schemas used for {0}', input.uri); quickPick.placeholder = items.length ? localize('schemaPicker.placeholder', 'Select the schema to use for {0}', input.uri) : undefined;
// quickPick.placeholder = items.length ? localize('schemaPicker.placeholder', 'Select the schema to open') : undefined;
quickPick.items = items; quickPick.items = items;
quickPick.show(); quickPick.show();
quickPick.onDidAccept(() => { quickPick.onDidAccept(() => {

View file

@ -628,7 +628,6 @@
"morphdom": "^2.6.1", "morphdom": "^2.6.1",
"picomatch": "^2.3.1", "picomatch": "^2.3.1",
"vscode-languageclient": "^8.0.2", "vscode-languageclient": "^8.0.2",
"vscode-nls": "^5.2.0",
"vscode-uri": "^3.0.3" "vscode-uri": "^3.0.3"
}, },
"devDependencies": { "devDependencies": {

View file

@ -2,8 +2,8 @@
"displayName": "Markdown Language Features", "displayName": "Markdown Language Features",
"description": "Provides rich language support for Markdown.", "description": "Provides rich language support for Markdown.",
"markdown.preview.breaks.desc": "Sets how line-breaks are rendered in the Markdown preview. Setting it to 'true' creates a <br> for newlines inside paragraphs.", "markdown.preview.breaks.desc": "Sets how line-breaks are rendered in the Markdown preview. Setting it to 'true' creates a <br> for newlines inside paragraphs.",
"markdown.preview.linkify": "Enable or disable conversion of URL-like text to links in the Markdown preview.", "markdown.preview.linkify": "Convert URL-like text to links in the Markdown preview.",
"markdown.preview.typographer": "Enable or disable some language-neutral replacement and quotes beautification in the Markdown preview.", "markdown.preview.typographer": "Enable some language-neutral replacement and quotes beautification in the Markdown preview.",
"markdown.preview.doubleClickToSwitchToEditor.desc": "Double click in the Markdown preview to switch to the editor.", "markdown.preview.doubleClickToSwitchToEditor.desc": "Double click in the Markdown preview to switch to the editor.",
"markdown.preview.fontFamily.desc": "Controls the font family used in the Markdown preview.", "markdown.preview.fontFamily.desc": "Controls the font family used in the Markdown preview.",
"markdown.preview.fontSize.desc": "Controls the font size in pixels used in the Markdown preview.", "markdown.preview.fontSize.desc": "Controls the font size in pixels used in the Markdown preview.",
@ -30,10 +30,10 @@
"configuration.markdown.links.openLocation.description": "Controls where links in Markdown files should be opened.", "configuration.markdown.links.openLocation.description": "Controls where links in Markdown files should be opened.",
"configuration.markdown.links.openLocation.currentGroup": "Open links in the active editor group.", "configuration.markdown.links.openLocation.currentGroup": "Open links in the active editor group.",
"configuration.markdown.links.openLocation.beside": "Open links beside the active editor.", "configuration.markdown.links.openLocation.beside": "Open links beside the active editor.",
"configuration.markdown.suggest.paths.enabled.description": "Enable/disable path suggestions while writing links in Markdown files.", "configuration.markdown.suggest.paths.enabled.description": "Enable path suggestions while writing links in Markdown files.",
"configuration.markdown.editor.drop.enabled": "Enable/disable dropping files into a Markdown editor by holding down shift. Requires enabling `#editor.dropIntoEditor.enabled#`.", "configuration.markdown.editor.drop.enabled": "Enable dropping files into a Markdown editor while holding Shift. Requires enabling `#editor.dropIntoEditor.enabled#`.",
"configuration.markdown.editor.pasteLinks.enabled": "Enable/disable pasting files into a Markdown editor inserts Markdown links. Requires enabling `#editor.experimental.pasteActions.enabled#`.", "configuration.markdown.editor.pasteLinks.enabled": "Enable pasting files into a Markdown editor inserts Markdown links. Requires enabling `#editor.experimental.pasteActions.enabled#`.",
"configuration.markdown.validate.enabled.description": "Enable/disable all error reporting in Markdown files.", "configuration.markdown.validate.enabled.description": "Enable all error reporting in Markdown files.",
"configuration.markdown.validate.referenceLinks.enabled.description": "Validate reference links in Markdown files, e.g. `[link][ref]`. Requires enabling `#markdown.validate.enabled#`.", "configuration.markdown.validate.referenceLinks.enabled.description": "Validate reference links in Markdown files, e.g. `[link][ref]`. Requires enabling `#markdown.validate.enabled#`.",
"configuration.markdown.validate.fragmentLinks.enabled.description": "Validate fragment links to headers in the current Markdown file, e.g. `[link](#header)`. Requires enabling `#markdown.validate.enabled#`.", "configuration.markdown.validate.fragmentLinks.enabled.description": "Validate fragment links to headers in the current Markdown file, e.g. `[link](#header)`. Requires enabling `#markdown.validate.enabled#`.",
"configuration.markdown.validate.fileLinks.enabled.description": "Validate links to other files in Markdown files, e.g. `[link](/path/to/file.md)`. This checks that the target files exists. Requires enabling `#markdown.validate.enabled#`.", "configuration.markdown.validate.fileLinks.enabled.description": "Validate links to other files in Markdown files, e.g. `[link](/path/to/file.md)`. This checks that the target files exists. Requires enabling `#markdown.validate.enabled#`.",
@ -46,8 +46,8 @@
"configuration.markdown.updateLinksOnFileMove.enabled.always": "Always update links automatically.", "configuration.markdown.updateLinksOnFileMove.enabled.always": "Always update links automatically.",
"configuration.markdown.updateLinksOnFileMove.enabled.never": "Never try to update link and don't prompt.", "configuration.markdown.updateLinksOnFileMove.enabled.never": "Never try to update link and don't prompt.",
"configuration.markdown.updateLinksOnFileMove.include": "Glob patterns that specifies which files that trigger automatic link updates. See `#markdown.updateLinksOnFileMove.enabled#` for details about this feature.", "configuration.markdown.updateLinksOnFileMove.include": "Glob patterns that specifies which files that trigger automatic link updates. See `#markdown.updateLinksOnFileMove.enabled#` for details about this feature.",
"configuration.markdown.updateLinksOnFileMove.include.property": "The glob pattern to match file paths against. Set to true or false to enable or disable the pattern.", "configuration.markdown.updateLinksOnFileMove.include.property": "The glob pattern to match file paths against. Set to true to enable the pattern.",
"configuration.markdown.updateLinksOnFileMove.enableForDirectories": "Enable/disable updating links when a directory is moved or renamed in the workspace.", "configuration.markdown.updateLinksOnFileMove.enableForDirectories": "Enable updating links when a directory is moved or renamed in the workspace.",
"configuration.markdown.occurrencesHighlight.enabled": "Enable/disable highlighting link occurrences in the current document.", "configuration.markdown.occurrencesHighlight.enabled": "Enable highlighting link occurrences in the current document.",
"workspaceTrust": "Required for loading styles configured in the workspace." "workspaceTrust": "Required for loading styles configured in the workspace."
} }

View file

@ -5,7 +5,6 @@
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import { BaseLanguageClient, LanguageClientOptions, NotebookDocumentSyncRegistrationType } from 'vscode-languageclient'; import { BaseLanguageClient, LanguageClientOptions, NotebookDocumentSyncRegistrationType } from 'vscode-languageclient';
import * as nls from 'vscode-nls';
import { IMdParser } from '../markdownEngine'; import { IMdParser } from '../markdownEngine';
import * as proto from './protocol'; import * as proto from './protocol';
import { looksLikeMarkdownPath, markdownFileExtensions } from '../util/file'; import { looksLikeMarkdownPath, markdownFileExtensions } from '../util/file';
@ -13,7 +12,6 @@ import { VsCodeMdWorkspace } from './workspace';
import { FileWatcherManager } from './fileWatchingManager'; import { FileWatcherManager } from './fileWatchingManager';
import { IDisposable } from '../util/dispose'; import { IDisposable } from '../util/dispose';
const localize = nls.loadMessageBundle();
export type LanguageClientConstructor = (name: string, description: string, clientOptions: LanguageClientOptions) => BaseLanguageClient; export type LanguageClientConstructor = (name: string, description: string, clientOptions: LanguageClientOptions) => BaseLanguageClient;
@ -64,7 +62,7 @@ export async function startClient(factory: LanguageClientConstructor, parser: IM
}, },
}; };
const client = factory('markdown', localize('markdownServer.name', 'Markdown Language Server'), clientOptions); const client = factory('markdown', vscode.l10n.t("Markdown Language Server"), clientOptions);
client.registerProposedFeatures(); client.registerProposedFeatures();

View file

@ -4,14 +4,12 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
import { Utils } from 'vscode-uri'; import { Utils } from 'vscode-uri';
import { Command } from '../commandManager'; import { Command } from '../commandManager';
import { createUriListSnippet, getParentDocumentUri, imageFileExtensions } from '../languageFeatures/dropIntoEditor'; import { createUriListSnippet, getParentDocumentUri, imageFileExtensions } from '../languageFeatures/dropIntoEditor';
import { coalesce } from '../util/arrays'; import { coalesce } from '../util/arrays';
import { Schemes } from '../util/schemes'; import { Schemes } from '../util/schemes';
const localize = nls.loadMessageBundle();
export class InsertLinkFromWorkspace implements Command { export class InsertLinkFromWorkspace implements Command {
@ -27,8 +25,8 @@ export class InsertLinkFromWorkspace implements Command {
canSelectFiles: true, canSelectFiles: true,
canSelectFolders: false, canSelectFolders: false,
canSelectMany: true, canSelectMany: true,
openLabel: localize('insertLink.openLabel', "Insert link"), openLabel: vscode.l10n.t("Insert link"),
title: localize('insertLink.title', "Insert link"), title: vscode.l10n.t("Insert link"),
defaultUri: getDefaultUri(activeEditor.document), defaultUri: getDefaultUri(activeEditor.document),
}); });
@ -50,10 +48,10 @@ export class InsertImageFromWorkspace implements Command {
canSelectFolders: false, canSelectFolders: false,
canSelectMany: true, canSelectMany: true,
filters: { filters: {
[localize('insertImage.imagesLabel', "Images")]: Array.from(imageFileExtensions) [vscode.l10n.t("Images")]: Array.from(imageFileExtensions)
}, },
openLabel: localize('insertImage.openLabel', "Insert image"), openLabel: vscode.l10n.t("Insert image"),
title: localize('insertImage.title', "Insert image"), title: vscode.l10n.t("Insert image"),
defaultUri: getDefaultUri(activeEditor.document), defaultUri: getDefaultUri(activeEditor.document),
}); });

View file

@ -4,10 +4,8 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
import { CommandManager } from '../commandManager'; import { CommandManager } from '../commandManager';
const localize = nls.loadMessageBundle();
// Copied from markdown language service // Copied from markdown language service
export enum DiagnosticCode { export enum DiagnosticCode {
@ -55,7 +53,7 @@ class AddToIgnoreLinksQuickFixProvider implements vscode.CodeActionProvider {
const hrefText = (diagnostic as any).data?.hrefText; const hrefText = (diagnostic as any).data?.hrefText;
if (hrefText) { if (hrefText) {
const fix = new vscode.CodeAction( const fix = new vscode.CodeAction(
localize('ignoreLinksQuickFix.title', "Exclude '{0}' from link validation.", hrefText), vscode.l10n.t("Exclude '{0}' from link validation.", hrefText),
vscode.CodeActionKind.QuickFix); vscode.CodeActionKind.QuickFix);
fix.command = { fix.command = {

View file

@ -5,12 +5,9 @@
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import type * as lsp from 'vscode-languageserver-types'; import type * as lsp from 'vscode-languageserver-types';
import * as nls from 'vscode-nls';
import { MdLanguageClient } from '../client/client'; import { MdLanguageClient } from '../client/client';
import { Command, CommandManager } from '../commandManager'; import { Command, CommandManager } from '../commandManager';
const localize = nls.loadMessageBundle();
export class FindFileReferencesCommand implements Command { export class FindFileReferencesCommand implements Command {
@ -23,13 +20,13 @@ export class FindFileReferencesCommand implements Command {
public async execute(resource?: vscode.Uri) { public async execute(resource?: vscode.Uri) {
resource ??= vscode.window.activeTextEditor?.document.uri; resource ??= vscode.window.activeTextEditor?.document.uri;
if (!resource) { if (!resource) {
vscode.window.showErrorMessage(localize('error.noResource', "Find file references failed. No resource provided.")); vscode.window.showErrorMessage(vscode.l10n.t("Find file references failed. No resource provided."));
return; return;
} }
await vscode.window.withProgress({ await vscode.window.withProgress({
location: vscode.ProgressLocation.Window, location: vscode.ProgressLocation.Window,
title: localize('progress.title', "Finding file references") title: vscode.l10n.t("Finding file references")
}, async (_progress, token) => { }, async (_progress, token) => {
const locations = (await this._client.getReferencesToFileInWorkspace(resource!, token)).map(loc => { const locations = (await this._client.getReferencesToFileInWorkspace(resource!, token)).map(loc => {
return new vscode.Location(vscode.Uri.parse(loc.uri), convertRange(loc.range)); return new vscode.Location(vscode.Uri.parse(loc.uri), convertRange(loc.range));

View file

@ -7,14 +7,12 @@ import * as path from 'path';
import * as picomatch from 'picomatch'; import * as picomatch from 'picomatch';
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import { TextDocumentEdit } from 'vscode-languageclient'; import { TextDocumentEdit } from 'vscode-languageclient';
import * as nls from 'vscode-nls';
import { MdLanguageClient } from '../client/client'; import { MdLanguageClient } from '../client/client';
import { Delayer } from '../util/async'; import { Delayer } from '../util/async';
import { noopToken } from '../util/cancellation'; import { noopToken } from '../util/cancellation';
import { Disposable } from '../util/dispose'; import { Disposable } from '../util/dispose';
import { convertRange } from './fileReferences'; import { convertRange } from './fileReferences';
const localize = nls.loadMessageBundle();
const settingNames = Object.freeze({ const settingNames = Object.freeze({
enabled: 'updateLinksOnFileMove.enabled', enabled: 'updateLinksOnFileMove.enabled',
@ -54,7 +52,7 @@ class UpdateLinksOnFileRenameHandler extends Disposable {
this._delayer.trigger(() => { this._delayer.trigger(() => {
vscode.window.withProgress({ vscode.window.withProgress({
location: vscode.ProgressLocation.Window, location: vscode.ProgressLocation.Window,
title: localize('renameProgress.title', "Checking for Markdown links to update") title: vscode.l10n.t("Checking for Markdown links to update")
}, () => this._flushRenames()); }, () => this._flushRenames());
}); });
} }
@ -121,26 +119,26 @@ class UpdateLinksOnFileRenameHandler extends Disposable {
} }
const rejectItem: vscode.MessageItem = { const rejectItem: vscode.MessageItem = {
title: localize('reject.title', "No"), title: vscode.l10n.t("No"),
isCloseAffordance: true, isCloseAffordance: true,
}; };
const acceptItem: vscode.MessageItem = { const acceptItem: vscode.MessageItem = {
title: localize('accept.title', "Yes"), title: vscode.l10n.t("Yes"),
}; };
const alwaysItem: vscode.MessageItem = { const alwaysItem: vscode.MessageItem = {
title: localize('always.title', "Always"), title: vscode.l10n.t("Always"),
}; };
const neverItem: vscode.MessageItem = { const neverItem: vscode.MessageItem = {
title: localize('never.title', "Never"), title: vscode.l10n.t("Never"),
}; };
const choice = await vscode.window.showInformationMessage( const choice = await vscode.window.showInformationMessage(
newResources.length === 1 newResources.length === 1
? localize('prompt', "Update Markdown links for '{0}'?", path.basename(newResources[0].fsPath)) ? vscode.l10n.t("Update Markdown links for '{0}'?", path.basename(newResources[0].fsPath))
: this._getConfirmMessage(localize('promptMoreThanOne', "Update Markdown links for the following {0} files?", newResources.length), newResources), { : this._getConfirmMessage(vscode.l10n.t("Update Markdown links for the following {0} files?", newResources.length), newResources), {
modal: true, modal: true,
}, rejectItem, acceptItem, alwaysItem, neverItem); }, rejectItem, acceptItem, alwaysItem, neverItem);
@ -203,9 +201,9 @@ class UpdateLinksOnFileRenameHandler extends Disposable {
if (resourcesToConfirm.length > MAX_CONFIRM_FILES) { if (resourcesToConfirm.length > MAX_CONFIRM_FILES) {
if (resourcesToConfirm.length - MAX_CONFIRM_FILES === 1) { if (resourcesToConfirm.length - MAX_CONFIRM_FILES === 1) {
paths.push(localize('moreFile', "...1 additional file not shown")); paths.push(vscode.l10n.t("...1 additional file not shown"));
} else { } else {
paths.push(localize('moreFiles', "...{0} additional files not shown", resourcesToConfirm.length - MAX_CONFIRM_FILES)); paths.push(vscode.l10n.t("...{0} additional files not shown", resourcesToConfirm.length - MAX_CONFIRM_FILES));
} }
} }

View file

@ -4,7 +4,6 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
import * as uri from 'vscode-uri'; import * as uri from 'vscode-uri';
import { ILogger } from '../logging'; import { ILogger } from '../logging';
import { MarkdownItEngine } from '../markdownEngine'; import { MarkdownItEngine } from '../markdownEngine';
@ -14,7 +13,6 @@ import { WebviewResourceProvider } from '../util/resources';
import { MarkdownPreviewConfiguration, MarkdownPreviewConfigurationManager } from './previewConfig'; import { MarkdownPreviewConfiguration, MarkdownPreviewConfigurationManager } from './previewConfig';
import { ContentSecurityPolicyArbiter, MarkdownPreviewSecurityLevel } from './security'; import { ContentSecurityPolicyArbiter, MarkdownPreviewSecurityLevel } from './security';
const localize = nls.loadMessageBundle();
/** /**
* Strings used inside the markdown preview. * Strings used inside the markdown preview.
@ -23,17 +21,11 @@ const localize = nls.loadMessageBundle();
* can be localized using our normal localization process. * can be localized using our normal localization process.
*/ */
const previewStrings = { const previewStrings = {
cspAlertMessageText: localize( cspAlertMessageText: vscode.l10n.t("Some content has been disabled in this document"),
'preview.securityMessage.text',
'Some content has been disabled in this document'),
cspAlertMessageTitle: localize( cspAlertMessageTitle: vscode.l10n.t("Potentially unsafe or insecure content has been disabled in the Markdown preview. Change the Markdown preview security setting to allow insecure content or enable scripts"),
'preview.securityMessage.title',
'Potentially unsafe or insecure content has been disabled in the Markdown preview. Change the Markdown preview security setting to allow insecure content or enable scripts'),
cspAlertMessageLabel: localize( cspAlertMessageLabel: vscode.l10n.t("Content Disabled Security Warning")
'preview.securityMessage.label',
'Content Disabled Security Warning')
}; };
export interface MarkdownContentProviderOutput { export interface MarkdownContentProviderOutput {
@ -130,7 +122,7 @@ export class MdDocumentRenderer {
public renderFileNotFoundDocument(resource: vscode.Uri): string { public renderFileNotFoundDocument(resource: vscode.Uri): string {
const resourcePath = uri.Utils.basename(resource); const resourcePath = uri.Utils.basename(resource);
const body = localize('preview.notFound', '{0} cannot be found', resourcePath); const body = vscode.l10n.t('{0} cannot be found', resourcePath);
return `<!DOCTYPE html> return `<!DOCTYPE html>
<html> <html>
<body class="vscode-body"> <body class="vscode-body">

View file

@ -4,7 +4,6 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
import * as uri from 'vscode-uri'; import * as uri from 'vscode-uri';
import { ILogger } from '../logging'; import { ILogger } from '../logging';
import { MarkdownContributionProvider } from '../markdownExtensions'; import { MarkdownContributionProvider } from '../markdownExtensions';
@ -18,7 +17,6 @@ import { MarkdownPreviewConfigurationManager } from './previewConfig';
import { scrollEditorToLine, StartingScrollFragment, StartingScrollLine, StartingScrollLocation } from './scrolling'; import { scrollEditorToLine, StartingScrollFragment, StartingScrollLine, StartingScrollLocation } from './scrolling';
import { getVisibleLine, LastScrollLocation, TopmostLineMonitor } from './topmostLineMonitor'; import { getVisibleLine, LastScrollLocation, TopmostLineMonitor } from './topmostLineMonitor';
const localize = nls.loadMessageBundle();
interface WebviewMessage { interface WebviewMessage {
readonly source: string; readonly source: string;
@ -192,9 +190,7 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider {
case 'previewStyleLoadError': case 'previewStyleLoadError':
vscode.window.showWarningMessage( vscode.window.showWarningMessage(
localize('onPreviewStyleLoadError', vscode.l10n.t("Could not load 'markdown.styles': {0}", e.body.unloadedStyles.join(', ')));
"Could not load 'markdown.styles': {0}",
e.body.unloadedStyles.join(', ')));
break; break;
} }
})); }));
@ -372,7 +368,7 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider {
.then((editor) => { .then((editor) => {
revealLineInEditor(editor); revealLineInEditor(editor);
}, () => { }, () => {
vscode.window.showErrorMessage(localize('preview.clickOpenFailed', 'Could not open {0}', this._resource.toString())); vscode.window.showErrorMessage(vscode.l10n.t('Could not open {0}', this._resource.toString()));
}); });
} }
@ -773,8 +769,8 @@ export class DynamicMarkdownPreview extends Disposable implements IManagedMarkdo
private static _getPreviewTitle(resource: vscode.Uri, locked: boolean): string { private static _getPreviewTitle(resource: vscode.Uri, locked: boolean): string {
const resourceLabel = uri.Utils.basename(resource); const resourceLabel = uri.Utils.basename(resource);
return locked return locked
? localize('lockedPreviewTitle', '[Preview] {0}', resourceLabel) ? vscode.l10n.t('[Preview] {0}', resourceLabel)
: localize('previewTitle', 'Preview {0}', resourceLabel); : vscode.l10n.t('Preview {0}', resourceLabel);
} }
public get position(): vscode.ViewColumn | undefined { public get position(): vscode.ViewColumn | undefined {

View file

@ -4,7 +4,6 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
import { ILogger } from '../logging'; import { ILogger } from '../logging';
import { MarkdownContributionProvider } from '../markdownExtensions'; import { MarkdownContributionProvider } from '../markdownExtensions';
import { Disposable, disposeAll } from '../util/dispose'; import { Disposable, disposeAll } from '../util/dispose';
@ -16,8 +15,6 @@ import { MarkdownPreviewConfigurationManager } from './previewConfig';
import { scrollEditorToLine, StartingScrollFragment } from './scrolling'; import { scrollEditorToLine, StartingScrollFragment } from './scrolling';
import { TopmostLineMonitor } from './topmostLineMonitor'; import { TopmostLineMonitor } from './topmostLineMonitor';
const localize = nls.loadMessageBundle();
export interface DynamicPreviewSettings { export interface DynamicPreviewSettings {
readonly resourceColumn: vscode.ViewColumn; readonly resourceColumn: vscode.ViewColumn;
@ -216,7 +213,7 @@ export class MarkdownPreviewManager extends Disposable implements vscode.Webview
<meta http-equiv="Content-Security-Policy" content="default-src 'none';"> <meta http-equiv="Content-Security-Policy" content="default-src 'none';">
</head> </head>
<body class="error-container"> <body class="error-container">
<p>${localize('preview.restoreError', "An unexpected error occurred while restoring the Markdown preview.")}</p> <p>${vscode.l10n.t("An unexpected error occurred while restoring the Markdown preview.")}</p>
</body> </body>
</html>`; </html>`;
} }

View file

@ -4,13 +4,9 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
import { MarkdownPreviewManager } from './previewManager'; import { MarkdownPreviewManager } from './previewManager';
const localize = nls.loadMessageBundle();
export const enum MarkdownPreviewSecurityLevel { export const enum MarkdownPreviewSecurityLevel {
Strict = 0, Strict = 0,
AllowInsecureContent = 1, AllowInsecureContent = 1,
@ -108,35 +104,33 @@ export class PreviewSecuritySelector {
[ [
{ {
type: MarkdownPreviewSecurityLevel.Strict, type: MarkdownPreviewSecurityLevel.Strict,
label: markActiveWhen(currentSecurityLevel === MarkdownPreviewSecurityLevel.Strict) + localize('strict.title', 'Strict'), label: markActiveWhen(currentSecurityLevel === MarkdownPreviewSecurityLevel.Strict) + vscode.l10n.t("Strict"),
description: localize('strict.description', 'Only load secure content'), description: vscode.l10n.t("Only load secure content"),
}, { }, {
type: MarkdownPreviewSecurityLevel.AllowInsecureLocalContent, type: MarkdownPreviewSecurityLevel.AllowInsecureLocalContent,
label: markActiveWhen(currentSecurityLevel === MarkdownPreviewSecurityLevel.AllowInsecureLocalContent) + localize('insecureLocalContent.title', 'Allow insecure local content'), label: markActiveWhen(currentSecurityLevel === MarkdownPreviewSecurityLevel.AllowInsecureLocalContent) + vscode.l10n.t("Allow insecure local content"),
description: localize('insecureLocalContent.description', 'Enable loading content over http served from localhost'), description: vscode.l10n.t("Enable loading content over http served from localhost"),
}, { }, {
type: MarkdownPreviewSecurityLevel.AllowInsecureContent, type: MarkdownPreviewSecurityLevel.AllowInsecureContent,
label: markActiveWhen(currentSecurityLevel === MarkdownPreviewSecurityLevel.AllowInsecureContent) + localize('insecureContent.title', 'Allow insecure content'), label: markActiveWhen(currentSecurityLevel === MarkdownPreviewSecurityLevel.AllowInsecureContent) + vscode.l10n.t("Allow insecure content"),
description: localize('insecureContent.description', 'Enable loading content over http'), description: vscode.l10n.t("Enable loading content over http"),
}, { }, {
type: MarkdownPreviewSecurityLevel.AllowScriptsAndAllContent, type: MarkdownPreviewSecurityLevel.AllowScriptsAndAllContent,
label: markActiveWhen(currentSecurityLevel === MarkdownPreviewSecurityLevel.AllowScriptsAndAllContent) + localize('disable.title', 'Disable'), label: markActiveWhen(currentSecurityLevel === MarkdownPreviewSecurityLevel.AllowScriptsAndAllContent) + vscode.l10n.t("Disable"),
description: localize('disable.description', 'Allow all content and script execution. Not recommended'), description: vscode.l10n.t("Allow all content and script execution. Not recommended"),
}, { }, {
type: 'moreinfo', type: 'moreinfo',
label: localize('moreInfo.title', 'More Information'), label: vscode.l10n.t("More Information"),
description: '' description: ''
}, { }, {
type: 'toggle', type: 'toggle',
label: this._cspArbiter.shouldDisableSecurityWarnings() label: this._cspArbiter.shouldDisableSecurityWarnings()
? localize('enableSecurityWarning.title', "Enable preview security warnings in this workspace") ? vscode.l10n.t("Enable preview security warnings in this workspace")
: localize('disableSecurityWarning.title', "Disable preview security warning in this workspace"), : vscode.l10n.t("Disable preview security warning in this workspace"),
description: localize('toggleSecurityWarning.description', 'Does not affect the content security level') description: vscode.l10n.t("Does not affect the content security level")
}, },
], { ], {
placeHolder: localize( placeHolder: vscode.l10n.t("Select security settings for Markdown previews in this workspace"),
'preview.showPreviewSecuritySelector.title',
'Select security settings for Markdown previews in this workspace'),
}); });
if (!selection) { if (!selection) {
return; return;

View file

@ -258,11 +258,6 @@ vscode-nls@^5.0.1:
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-5.0.1.tgz#ba23fc4d4420d25e7f886c8e83cbdcec47aa48b2" resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-5.0.1.tgz#ba23fc4d4420d25e7f886c8e83cbdcec47aa48b2"
integrity sha512-hHQV6iig+M21lTdItKPkJAaWrxALQb/nqpVffakO4knJOh3DrU2SXOMzUzNgo1eADPzu3qSsJY1weCzvR52q9A== integrity sha512-hHQV6iig+M21lTdItKPkJAaWrxALQb/nqpVffakO4knJOh3DrU2SXOMzUzNgo1eADPzu3qSsJY1weCzvR52q9A==
vscode-nls@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-5.2.0.tgz#3cb6893dd9bd695244d8a024bdf746eea665cc3f"
integrity sha512-RAaHx7B14ZU04EU31pT+rKz2/zSl7xMsfIZuo8pd+KZO6PXtQmpevpq3vxvWNcrGbdmhM/rr5Uw5Mz+NBfhVng==
vscode-uri@^3.0.3: vscode-uri@^3.0.3:
version "3.0.3" version "3.0.3"
resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-3.0.3.tgz#a95c1ce2e6f41b7549f86279d19f47951e4f4d84" resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-3.0.3.tgz#a95c1ce2e6f41b7549f86279d19f47951e4f4d84"

View file

@ -33,6 +33,9 @@ export async function activate(ctx: RendererContext<void>) {
.katex-error { .katex-error {
color: var(--vscode-editorError-foreground); color: var(--vscode-editorError-foreground);
} }
.katex-block {
counter-reset: katexEqnNo mmlEqnNo;
}
`; `;
// Put Everything into a template // Put Everything into a template

View file

@ -101,8 +101,7 @@
"watch-web": "npx webpack-cli --config extension-browser.webpack.config --mode none --watch --info-verbosity verbose" "watch-web": "npx webpack-cli --config extension-browser.webpack.config --mode none --watch --info-verbosity verbose"
}, },
"dependencies": { "dependencies": {
"@vscode/extension-telemetry": "0.6.2", "@vscode/extension-telemetry": "0.6.2"
"vscode-nls": "^5.2.0"
}, },
"repository": { "repository": {
"type": "git", "type": "git",

View file

@ -4,13 +4,10 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
import { BinarySizeStatusBarEntry } from './binarySizeStatusBarEntry'; import { BinarySizeStatusBarEntry } from './binarySizeStatusBarEntry';
import { MediaPreview, reopenAsText } from './mediaPreview'; import { MediaPreview, reopenAsText } from './mediaPreview';
import { escapeAttribute, getNonce } from './util/dom'; import { escapeAttribute, getNonce } from './util/dom';
const localize = nls.loadMessageBundle();
class AudioPreviewProvider implements vscode.CustomReadonlyEditorProvider { class AudioPreviewProvider implements vscode.CustomReadonlyEditorProvider {
public static readonly viewType = 'vscode.audioPreview'; public static readonly viewType = 'vscode.audioPreview';
@ -82,8 +79,8 @@ class AudioPreview extends MediaPreview {
<body class="container loading"> <body class="container loading">
<div class="loading-indicator"></div> <div class="loading-indicator"></div>
<div class="loading-error"> <div class="loading-error">
<p>${localize('preview.audioLoadError', "An error occurred while loading the audio file.")}</p> <p>${vscode.l10n.t("An error occurred while loading the audio file.")}</p>
<a href="#" class="open-file-link">${localize('preview.audioLoadErrorLink', "Open file using VS Code's standard text/binary editor?")}</a> <a href="#" class="open-file-link">${vscode.l10n.t("Open file using VS Code's standard text/binary editor?")}</a>
</div> </div>
<script src="${escapeAttribute(this.extensionResource('media', 'audioPreview.js'))}" nonce="${nonce}"></script> <script src="${escapeAttribute(this.extensionResource('media', 'audioPreview.js'))}" nonce="${nonce}"></script>
</body> </body>

View file

@ -4,10 +4,8 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
import { PreviewStatusBarEntry } from './ownedStatusBarEntry'; import { PreviewStatusBarEntry } from './ownedStatusBarEntry';
const localize = nls.loadMessageBundle();
class BinarySize { class BinarySize {
static readonly KB = 1024; static readonly KB = 1024;
@ -17,29 +15,29 @@ class BinarySize {
static formatSize(size: number): string { static formatSize(size: number): string {
if (size < BinarySize.KB) { if (size < BinarySize.KB) {
return localize('sizeB', "{0}B", size); return vscode.l10n.t("{0}B", size);
} }
if (size < BinarySize.MB) { if (size < BinarySize.MB) {
return localize('sizeKB', "{0}KB", (size / BinarySize.KB).toFixed(2)); return vscode.l10n.t("{0}KB", (size / BinarySize.KB).toFixed(2));
} }
if (size < BinarySize.GB) { if (size < BinarySize.GB) {
return localize('sizeMB', "{0}MB", (size / BinarySize.MB).toFixed(2)); return vscode.l10n.t("{0}MB", (size / BinarySize.MB).toFixed(2));
} }
if (size < BinarySize.TB) { if (size < BinarySize.TB) {
return localize('sizeGB', "{0}GB", (size / BinarySize.GB).toFixed(2)); return vscode.l10n.t("{0}GB", (size / BinarySize.GB).toFixed(2));
} }
return localize('sizeTB', "{0}TB", (size / BinarySize.TB).toFixed(2)); return vscode.l10n.t("{0}TB", (size / BinarySize.TB).toFixed(2));
} }
} }
export class BinarySizeStatusBarEntry extends PreviewStatusBarEntry { export class BinarySizeStatusBarEntry extends PreviewStatusBarEntry {
constructor() { constructor() {
super('status.imagePreview.binarySize', localize('sizeStatusBar.name', "Image Binary Size"), vscode.StatusBarAlignment.Right, 100); super('status.imagePreview.binarySize', vscode.l10n.t("Image Binary Size"), vscode.StatusBarAlignment.Right, 100);
} }
public show(owner: unknown, size: number | undefined) { public show(owner: unknown, size: number | undefined) {

View file

@ -4,14 +4,12 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
import { BinarySizeStatusBarEntry } from '../binarySizeStatusBarEntry'; import { BinarySizeStatusBarEntry } from '../binarySizeStatusBarEntry';
import { MediaPreview, PreviewState, reopenAsText } from '../mediaPreview'; import { MediaPreview, PreviewState, reopenAsText } from '../mediaPreview';
import { escapeAttribute, getNonce } from '../util/dom'; import { escapeAttribute, getNonce } from '../util/dom';
import { SizeStatusBarEntry } from './sizeStatusBarEntry'; import { SizeStatusBarEntry } from './sizeStatusBarEntry';
import { Scale, ZoomStatusBarEntry } from './zoomStatusBarEntry'; import { Scale, ZoomStatusBarEntry } from './zoomStatusBarEntry';
const localize = nls.loadMessageBundle();
export class PreviewManager implements vscode.CustomReadonlyEditorProvider { export class PreviewManager implements vscode.CustomReadonlyEditorProvider {
@ -181,8 +179,8 @@ class ImagePreview extends MediaPreview {
<body class="container image scale-to-fit loading"> <body class="container image scale-to-fit loading">
<div class="loading-indicator"></div> <div class="loading-indicator"></div>
<div class="image-load-error"> <div class="image-load-error">
<p>${localize('preview.imageLoadError', "An error occurred while loading the image.")}</p> <p>${vscode.l10n.t("An error occurred while loading the image.")}</p>
<a href="#" class="open-file-link">${localize('preview.imageLoadErrorLink', "Open file using VS Code's standard text/binary editor?")}</a> <a href="#" class="open-file-link">${vscode.l10n.t("Open file using VS Code's standard text/binary editor?")}</a>
</div> </div>
<script src="${escapeAttribute(this.extensionResource('media', 'imagePreview.js'))}" nonce="${nonce}"></script> <script src="${escapeAttribute(this.extensionResource('media', 'imagePreview.js'))}" nonce="${nonce}"></script>
</body> </body>

View file

@ -4,15 +4,13 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
import { PreviewStatusBarEntry } from '../ownedStatusBarEntry'; import { PreviewStatusBarEntry } from '../ownedStatusBarEntry';
const localize = nls.loadMessageBundle();
export class SizeStatusBarEntry extends PreviewStatusBarEntry { export class SizeStatusBarEntry extends PreviewStatusBarEntry {
constructor() { constructor() {
super('status.imagePreview.size', localize('sizeStatusBar.name', "Image Size"), vscode.StatusBarAlignment.Right, 101 /* to the left of editor status (100) */); super('status.imagePreview.size', vscode.l10n.t("Image Size"), vscode.StatusBarAlignment.Right, 101 /* to the left of editor status (100) */);
} }
public show(owner: unknown, text: string) { public show(owner: unknown, text: string) {

View file

@ -4,10 +4,8 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
import { PreviewStatusBarEntry as OwnedStatusBarEntry } from '../ownedStatusBarEntry'; import { PreviewStatusBarEntry as OwnedStatusBarEntry } from '../ownedStatusBarEntry';
const localize = nls.loadMessageBundle();
const selectZoomLevelCommandId = '_imagePreview.selectZoomLevel'; const selectZoomLevelCommandId = '_imagePreview.selectZoomLevel';
@ -19,7 +17,7 @@ export class ZoomStatusBarEntry extends OwnedStatusBarEntry {
public readonly onDidChangeScale = this._onDidChangeScale.event; public readonly onDidChangeScale = this._onDidChangeScale.event;
constructor() { constructor() {
super('status.imagePreview.zoom', localize('zoomStatusBar.name', "Image Zoom"), vscode.StatusBarAlignment.Right, 102 /* to the left of editor size entry (101) */); super('status.imagePreview.zoom', vscode.l10n.t("Image Zoom"), vscode.StatusBarAlignment.Right, 102 /* to the left of editor size entry (101) */);
this._register(vscode.commands.registerCommand(selectZoomLevelCommandId, async () => { this._register(vscode.commands.registerCommand(selectZoomLevelCommandId, async () => {
type MyPickItem = vscode.QuickPickItem & { scale: Scale }; type MyPickItem = vscode.QuickPickItem & { scale: Scale };
@ -31,7 +29,7 @@ export class ZoomStatusBarEntry extends OwnedStatusBarEntry {
})); }));
const pick = await vscode.window.showQuickPick(options, { const pick = await vscode.window.showQuickPick(options, {
placeHolder: localize('zoomStatusBar.placeholder', "Select zoom level") placeHolder: vscode.l10n.t("Select zoom level")
}); });
if (pick) { if (pick) {
this._onDidChangeScale.fire({ scale: pick.scale }); this._onDidChangeScale.fire({ scale: pick.scale });
@ -47,7 +45,7 @@ export class ZoomStatusBarEntry extends OwnedStatusBarEntry {
private zoomLabel(scale: Scale): string { private zoomLabel(scale: Scale): string {
return scale === 'fit' return scale === 'fit'
? localize('zoomStatusBar.wholeImageLabel', "Whole Image") ? vscode.l10n.t("Whole Image")
: `${Math.round(scale * 100)}%`; : `${Math.round(scale * 100)}%`;
} }
} }

View file

@ -4,12 +4,10 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
import { BinarySizeStatusBarEntry } from './binarySizeStatusBarEntry'; import { BinarySizeStatusBarEntry } from './binarySizeStatusBarEntry';
import { MediaPreview, reopenAsText } from './mediaPreview'; import { MediaPreview, reopenAsText } from './mediaPreview';
import { escapeAttribute, getNonce } from './util/dom'; import { escapeAttribute, getNonce } from './util/dom';
const localize = nls.loadMessageBundle();
class VideoPreviewProvider implements vscode.CustomReadonlyEditorProvider { class VideoPreviewProvider implements vscode.CustomReadonlyEditorProvider {
@ -82,8 +80,8 @@ class VideoPreview extends MediaPreview {
<body class="loading"> <body class="loading">
<div class="loading-indicator"></div> <div class="loading-indicator"></div>
<div class="loading-error"> <div class="loading-error">
<p>${localize('preview.videoLoadError', "An error occurred while loading the video file.")}</p> <p>${vscode.l10n.t("An error occurred while loading the video file.")}</p>
<a href="#" class="open-file-link">${localize('preview.videoLoadErrorLink', "Open file using VS Code's standard text/binary editor?")}</a> <a href="#" class="open-file-link">${vscode.l10n.t("Open file using VS Code's standard text/binary editor?")}</a>
</div> </div>
<script src="${escapeAttribute(this.extensionResource('media', 'videoPreview.js'))}" nonce="${nonce}"></script> <script src="${escapeAttribute(this.extensionResource('media', 'videoPreview.js'))}" nonce="${nonce}"></script>
</body> </body>

View file

@ -45,8 +45,3 @@
dependencies: dependencies:
"@microsoft/1ds-core-js" "^3.2.3" "@microsoft/1ds-core-js" "^3.2.3"
"@microsoft/1ds-post-js" "^3.2.3" "@microsoft/1ds-post-js" "^3.2.3"
vscode-nls@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-5.2.0.tgz#3cb6893dd9bd695244d8a024bdf746eea665cc3f"
integrity sha512-RAaHx7B14ZU04EU31pT+rKz2/zSl7xMsfIZuo8pd+KZO6PXtQmpevpq3vxvWNcrGbdmhM/rr5Uw5Mz+NBfhVng==

View file

@ -165,9 +165,7 @@
} }
} }
}, },
"dependencies": { "dependencies": {},
"vscode-nls": "^5.2.0"
},
"devDependencies": { "devDependencies": {
"@types/node": "16.x" "@types/node": "16.x"
}, },

View file

@ -5,8 +5,6 @@
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import * as interfaces from './interfaces'; import * as interfaces from './interfaces';
import { loadMessageBundle } from 'vscode-nls';
const localize = loadMessageBundle();
export default class MergeConflictCodeLensProvider implements vscode.CodeLensProvider, vscode.Disposable { export default class MergeConflictCodeLensProvider implements vscode.CodeLensProvider, vscode.Disposable {
private codeLensRegistrationHandle?: vscode.Disposable | null; private codeLensRegistrationHandle?: vscode.Disposable | null;
@ -65,25 +63,25 @@ export default class MergeConflictCodeLensProvider implements vscode.CodeLensPro
conflicts.forEach(conflict => { conflicts.forEach(conflict => {
const acceptCurrentCommand: vscode.Command = { const acceptCurrentCommand: vscode.Command = {
command: 'merge-conflict.accept.current', command: 'merge-conflict.accept.current',
title: localize('acceptCurrentChange', 'Accept Current Change'), title: vscode.l10n.t("Accept Current Change"),
arguments: ['known-conflict', conflict] arguments: ['known-conflict', conflict]
}; };
const acceptIncomingCommand: vscode.Command = { const acceptIncomingCommand: vscode.Command = {
command: 'merge-conflict.accept.incoming', command: 'merge-conflict.accept.incoming',
title: localize('acceptIncomingChange', 'Accept Incoming Change'), title: vscode.l10n.t("Accept Incoming Change"),
arguments: ['known-conflict', conflict] arguments: ['known-conflict', conflict]
}; };
const acceptBothCommand: vscode.Command = { const acceptBothCommand: vscode.Command = {
command: 'merge-conflict.accept.both', command: 'merge-conflict.accept.both',
title: localize('acceptBothChanges', 'Accept Both Changes'), title: vscode.l10n.t("Accept Both Changes"),
arguments: ['known-conflict', conflict] arguments: ['known-conflict', conflict]
}; };
const diffCommand: vscode.Command = { const diffCommand: vscode.Command = {
command: 'merge-conflict.compare', command: 'merge-conflict.compare',
title: localize('compareChanges', 'Compare Changes'), title: vscode.l10n.t("Compare Changes"),
arguments: [conflict] arguments: [conflict]
}; };

View file

@ -5,8 +5,6 @@
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import * as interfaces from './interfaces'; import * as interfaces from './interfaces';
import ContentProvider from './contentProvider'; import ContentProvider from './contentProvider';
import { loadMessageBundle } from 'vscode-nls';
const localize = loadMessageBundle();
interface IDocumentMergeConflictNavigationResults { interface IDocumentMergeConflictNavigationResults {
canNavigate: boolean; canNavigate: boolean;
@ -92,7 +90,7 @@ export default class CommandHandler implements vscode.Disposable {
// Still failed to find conflict, warn the user and exit // Still failed to find conflict, warn the user and exit
if (!conflict) { if (!conflict) {
vscode.window.showWarningMessage(localize('cursorNotInConflict', 'Editor cursor is not within a merge conflict')); vscode.window.showWarningMessage(vscode.l10n.t("Editor cursor is not within a merge conflict"));
return; return;
} }
} }
@ -101,7 +99,7 @@ export default class CommandHandler implements vscode.Disposable {
// Still failed to find conflict, warn the user and exit // Still failed to find conflict, warn the user and exit
if (!conflicts) { if (!conflicts) {
vscode.window.showWarningMessage(localize('cursorNotInConflict', 'Editor cursor is not within a merge conflict')); vscode.window.showWarningMessage(vscode.l10n.t("Editor cursor is not within a merge conflict"));
return; return;
} }
@ -134,7 +132,7 @@ export default class CommandHandler implements vscode.Disposable {
const docPath = editor.document.uri.path; const docPath = editor.document.uri.path;
const fileName = docPath.substring(docPath.lastIndexOf('/') + 1); // avoid NodeJS path to keep browser webpack small const fileName = docPath.substring(docPath.lastIndexOf('/') + 1); // avoid NodeJS path to keep browser webpack small
const title = localize('compareChangesTitle', '{0}: Current Changes ↔ Incoming Changes', fileName); const title = vscode.l10n.t("{0}: Current Changes ↔ Incoming Changes", fileName);
const mergeConflictConfig = vscode.workspace.getConfiguration('merge-conflict'); const mergeConflictConfig = vscode.workspace.getConfiguration('merge-conflict');
const openToTheSide = mergeConflictConfig.get<string>('diffViewPosition'); const openToTheSide = mergeConflictConfig.get<string>('diffViewPosition');
const opts: vscode.TextDocumentShowOptions = { const opts: vscode.TextDocumentShowOptions = {
@ -161,7 +159,7 @@ export default class CommandHandler implements vscode.Disposable {
const conflict = await this.findConflictContainingSelection(editor); const conflict = await this.findConflictContainingSelection(editor);
if (!conflict) { if (!conflict) {
vscode.window.showWarningMessage(localize('cursorNotInConflict', 'Editor cursor is not within a merge conflict')); vscode.window.showWarningMessage(vscode.l10n.t("Editor cursor is not within a merge conflict"));
return; return;
} }
@ -184,11 +182,11 @@ export default class CommandHandler implements vscode.Disposable {
typeToAccept = interfaces.CommitType.Incoming; typeToAccept = interfaces.CommitType.Incoming;
} }
else if (editor.selection.active.isBefore(conflict.splitter.start)) { else if (editor.selection.active.isBefore(conflict.splitter.start)) {
vscode.window.showWarningMessage(localize('cursorOnCommonAncestorsRange', 'Editor cursor is within the common ancestors block, please move it to either the "current" or "incoming" block')); vscode.window.showWarningMessage(vscode.l10n.t('Editor cursor is within the common ancestors block, please move it to either the "current" or "incoming" block'));
return; return;
} }
else { else {
vscode.window.showWarningMessage(localize('cursorOnSplitterRange', 'Editor cursor is within the merge conflict splitter, please move it to either the "current" or "incoming" block')); vscode.window.showWarningMessage(vscode.l10n.t('Editor cursor is within the merge conflict splitter, please move it to either the "current" or "incoming" block'));
return; return;
} }
@ -210,11 +208,11 @@ export default class CommandHandler implements vscode.Disposable {
if (mergeConflictConfig.get<boolean>('autoNavigateNextConflict.enabled')) { if (mergeConflictConfig.get<boolean>('autoNavigateNextConflict.enabled')) {
return; return;
} }
vscode.window.showWarningMessage(localize('noConflicts', 'No merge conflicts found in this file')); vscode.window.showWarningMessage(vscode.l10n.t("No merge conflicts found in this file"));
return; return;
} }
else if (!navigationResult.canNavigate) { else if (!navigationResult.canNavigate) {
vscode.window.showWarningMessage(localize('noOtherConflictsInThisFile', 'No other merge conflicts within this file')); vscode.window.showWarningMessage(vscode.l10n.t("No other merge conflicts within this file"));
return; return;
} }
else if (!navigationResult.conflict) { else if (!navigationResult.conflict) {
@ -241,7 +239,7 @@ export default class CommandHandler implements vscode.Disposable {
} }
if (!conflict) { if (!conflict) {
vscode.window.showWarningMessage(localize('cursorNotInConflict', 'Editor cursor is not within a merge conflict')); vscode.window.showWarningMessage(vscode.l10n.t("Editor cursor is not within a merge conflict"));
return; return;
} }
@ -261,7 +259,7 @@ export default class CommandHandler implements vscode.Disposable {
const conflicts = await this.tracker.getConflicts(editor.document); const conflicts = await this.tracker.getConflicts(editor.document);
if (!conflicts || conflicts.length === 0) { if (!conflicts || conflicts.length === 0) {
vscode.window.showWarningMessage(localize('noConflicts', 'No merge conflicts found in this file')); vscode.window.showWarningMessage(vscode.l10n.t("No merge conflicts found in this file"));
return; return;
} }

View file

@ -4,8 +4,7 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import * as interfaces from './interfaces'; import * as interfaces from './interfaces';
import { loadMessageBundle } from 'vscode-nls';
const localize = loadMessageBundle();
export default class MergeDecorator implements vscode.Disposable { export default class MergeDecorator implements vscode.Disposable {
@ -88,7 +87,7 @@ export default class MergeDecorator implements vscode.Disposable {
outlineWidth: '1pt', outlineWidth: '1pt',
outlineColor: new vscode.ThemeColor('merge.border'), outlineColor: new vscode.ThemeColor('merge.border'),
after: { after: {
contentText: ' ' + localize('currentChange', '(Current Change)'), contentText: ' ' + vscode.l10n.t("(Current Change)"),
color: new vscode.ThemeColor('descriptionForeground') color: new vscode.ThemeColor('descriptionForeground')
} }
}); });
@ -118,7 +117,7 @@ export default class MergeDecorator implements vscode.Disposable {
outlineColor: new vscode.ThemeColor('merge.border'), outlineColor: new vscode.ThemeColor('merge.border'),
isWholeLine: this.decorationUsesWholeLine, isWholeLine: this.decorationUsesWholeLine,
after: { after: {
contentText: ' ' + localize('incomingChange', '(Incoming Change)'), contentText: ' ' + vscode.l10n.t("(Incoming Change)"),
color: new vscode.ThemeColor('descriptionForeground') color: new vscode.ThemeColor('descriptionForeground')
} }
}); });

View file

@ -6,8 +6,3 @@
version "16.11.6" version "16.11.6"
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.6.tgz#6bef7a2a0ad684cf6e90fcfe31cecabd9ce0a3ae" resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.6.tgz#6bef7a2a0ad684cf6e90fcfe31cecabd9ce0a3ae"
integrity sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w== integrity sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w==
vscode-nls@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-5.2.0.tgz#3cb6893dd9bd695244d8a024bdf746eea665cc3f"
integrity sha512-RAaHx7B14ZU04EU31pT+rKz2/zSl7xMsfIZuo8pd+KZO6PXtQmpevpq3vxvWNcrGbdmhM/rr5Uw5Mz+NBfhVng==

View file

@ -22,7 +22,6 @@
"jsonc-parser": "^2.2.1", "jsonc-parser": "^2.2.1",
"minimatch": "^3.0.4", "minimatch": "^3.0.4",
"request-light": "^0.5.7", "request-light": "^0.5.7",
"vscode-nls": "^5.2.0",
"which": "^2.0.2", "which": "^2.0.2",
"which-pm": "^2.0.0" "which-pm": "^2.0.0"
}, },

View file

@ -3,7 +3,6 @@
* Licensed under the MIT License. See License.txt in the project root for license information. * Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import * as nls from 'vscode-nls';
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import { import {
@ -13,7 +12,6 @@ import {
IFolderTaskItem IFolderTaskItem
} from './tasks'; } from './tasks';
const localize = nls.loadMessageBundle();
export function runSelectedScript(context: vscode.ExtensionContext) { export function runSelectedScript(context: vscode.ExtensionContext) {
const editor = vscode.window.activeTextEditor; const editor = vscode.window.activeTextEditor;
@ -26,7 +24,7 @@ export function runSelectedScript(context: vscode.ExtensionContext) {
if (script) { if (script) {
runScript(context, script, document); runScript(context, script, document);
} else { } else {
const message = localize('noScriptFound', 'Could not find a valid npm script at the selection.'); const message = vscode.l10n.t("Could not find a valid npm script at the selection.");
vscode.window.showErrorMessage(message); vscode.window.showErrorMessage(message);
} }
} }
@ -41,8 +39,7 @@ export async function selectAndRunScriptFromFolder(context: vscode.ExtensionCont
if (taskList && taskList.length > 0) { if (taskList && taskList.length > 0) {
const quickPick = vscode.window.createQuickPick<IFolderTaskItem>(); const quickPick = vscode.window.createQuickPick<IFolderTaskItem>();
quickPick.title = 'Run NPM script in Folder'; quickPick.placeholder = 'Select an npm script to run in folder';
quickPick.placeholder = 'Select an npm script';
quickPick.items = taskList; quickPick.items = taskList;
const toDispose: vscode.Disposable[] = []; const toDispose: vscode.Disposable[] = [];

View file

@ -3,13 +3,11 @@
* Licensed under the MIT License. See License.txt in the project root for license information. * Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import { MarkdownString, CompletionItemKind, CompletionItem, DocumentSelector, SnippetString, workspace, Uri } from 'vscode'; import { MarkdownString, CompletionItemKind, CompletionItem, DocumentSelector, SnippetString, workspace, Uri, l10n } from 'vscode';
import { IJSONContribution, ISuggestionsCollector } from './jsonContributions'; import { IJSONContribution, ISuggestionsCollector } from './jsonContributions';
import { XHRRequest } from 'request-light'; import { XHRRequest } from 'request-light';
import { Location } from 'jsonc-parser'; import { Location } from 'jsonc-parser';
import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle();
const USER_AGENT = 'Visual Studio Code'; const USER_AGENT = 'Visual Studio Code';
@ -46,7 +44,7 @@ export class BowerJSONContribution implements IJSONContribution {
'main': '${5:pathToMain}', 'main': '${5:pathToMain}',
'dependencies': {} 'dependencies': {}
}; };
const proposal = new CompletionItem(localize('json.bower.default', 'Default bower.json')); const proposal = new CompletionItem(l10n.t("Default bower.json"));
proposal.kind = CompletionItemKind.Class; proposal.kind = CompletionItemKind.Class;
proposal.insertText = new SnippetString(JSON.stringify(defaultValue, null, '\t')); proposal.insertText = new SnippetString(JSON.stringify(defaultValue, null, '\t'));
collector.add(proposal); collector.add(proposal);
@ -93,12 +91,12 @@ export class BowerJSONContribution implements IJSONContribution {
// ignore // ignore
} }
} else { } else {
collector.error(localize('json.bower.error.repoaccess', 'Request to the bower repository failed: {0}', success.responseText)); collector.error(l10n.t("Request to the bower repository failed: {0}", success.responseText));
return 0; return 0;
} }
return undefined; return undefined;
}, (error) => { }, (error) => {
collector.error(localize('json.bower.error.repoaccess', 'Request to the bower repository failed: {0}', error.responseText)); collector.error(l10n.t("Request to the bower repository failed: {0}", error.responseText));
return 0; return 0;
}); });
} else { } else {
@ -131,7 +129,7 @@ export class BowerJSONContribution implements IJSONContribution {
} }
if ((location.matches(['dependencies', '*']) || location.matches(['devDependencies', '*']))) { if ((location.matches(['dependencies', '*']) || location.matches(['devDependencies', '*']))) {
// not implemented. Could be do done calling the bower command. Waiting for web API: https://github.com/bower/registry/issues/26 // not implemented. Could be do done calling the bower command. Waiting for web API: https://github.com/bower/registry/issues/26
const proposal = new CompletionItem(localize('json.bower.latest.version', 'latest')); const proposal = new CompletionItem(l10n.t("latest"));
proposal.insertText = new SnippetString('"${1:latest}"'); proposal.insertText = new SnippetString('"${1:latest}"');
proposal.filterText = '""'; proposal.filterText = '""';
proposal.kind = CompletionItemKind.Value; proposal.kind = CompletionItemKind.Value;

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