Archived
Merge from vscode a5cf1da01d5db3d2557132be8d30f89c38019f6c (#8525)
* Merge from vscode a5cf1da01d5db3d2557132be8d30f89c38019f6c * remove files we don't want * fix hygiene * update distro * update distro * fix hygiene * fix strict nulls * distro * distro * fix tests * fix tests * add another edit * fix viewlet icon * fix azure dialog * fix some padding * fix more padding issues
This commit is contained in:
@@ -74,7 +74,7 @@
|
||||
"vscode-nls": "^3.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "10",
|
||||
"@types/node": "^12.11.7",
|
||||
"mocha-junit-reporter": "^1.17.0",
|
||||
"mocha-multi-reporters": "^1.1.7",
|
||||
"should": "^13.2.3",
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@types/node@10":
|
||||
version "10.17.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.4.tgz#8993a4fe3c4022fda66bf4ea660d615fc5659c6f"
|
||||
integrity sha512-F2pgg+LcIr/elguz+x+fdBX5KeZXGUOp7TV8M0TVIrDezYLFRNt8oMTyps0VQ1kj5WGGoR18RdxnRDHXrIFHMQ==
|
||||
"@types/node@^12.11.7":
|
||||
version "12.12.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.7.tgz#01e4ea724d9e3bd50d90c11fd5980ba317d8fa11"
|
||||
integrity sha512-E6Zn0rffhgd130zbCbAr/JdXfXkoOUFAKNs/rF8qnafSJ8KYaA/j3oz7dcwal+lYjLA7xvdd5J4wdYpCTlP8+w==
|
||||
|
||||
"ads-extension-telemetry@github:Charles-Gagnon/ads-extension-telemetry#0.1.0":
|
||||
version "0.1.0"
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/mocha": "^5.2.5",
|
||||
"@types/node": "^10.14.8",
|
||||
"@types/node": "^12.11.7",
|
||||
"mocha": "^5.2.0",
|
||||
"mocha-junit-reporter": "^1.17.0",
|
||||
"mocha-multi-reporters": "^1.1.7",
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-5.2.6.tgz#b8622d50557dd155e9f2f634b7d68fd38de5e94b"
|
||||
integrity sha512-1axi39YdtBI7z957vdqXI4Ac25e7YihYQtJa+Clnxg1zTJEaIRbndt71O3sP4GAMgiAm0pY26/b9BrY4MR/PMw==
|
||||
|
||||
"@types/node@^10.14.8":
|
||||
version "10.14.17"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.17.tgz#b96d4dd3e427382482848948041d3754d40fd5ce"
|
||||
integrity sha512-p/sGgiPaathCfOtqu2fx5Mu1bcjuP8ALFg4xpGgNkcin7LwRyzUKniEHBKdcE1RPsenq5JVPIpMTJSygLboygQ==
|
||||
"@types/node@^12.11.7":
|
||||
version "12.12.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.7.tgz#01e4ea724d9e3bd50d90c11fd5980ba317d8fa11"
|
||||
integrity sha512-E6Zn0rffhgd130zbCbAr/JdXfXkoOUFAKNs/rF8qnafSJ8KYaA/j3oz7dcwal+lYjLA7xvdd5J4wdYpCTlP8+w==
|
||||
|
||||
agent-base@4, agent-base@^4.3.0:
|
||||
version "4.3.0"
|
||||
|
||||
@@ -186,7 +186,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/mocha": "^5.2.5",
|
||||
"@types/node": "^10.12.12",
|
||||
"@types/node": "^12.11.7",
|
||||
"@types/request": "^2.48.1",
|
||||
"mocha": "^5.2.0",
|
||||
"mocha-junit-reporter": "^1.17.0",
|
||||
|
||||
@@ -59,11 +59,16 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-5.2.5.tgz#8a4accfc403c124a0bafe8a9fc61a05ec1032073"
|
||||
integrity sha512-lAVp+Kj54ui/vLUFxsJTMtWvZraZxum3w3Nwkble2dNuV5VnPA+Mi2oGX9XYJAaIvZi3tn3cbjS/qcJXRb6Bww==
|
||||
|
||||
"@types/node@*", "@types/node@^10.12.12":
|
||||
"@types/node@*":
|
||||
version "10.14.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.4.tgz#1c586b991457cbb58fef51bc4e0cfcfa347714b5"
|
||||
integrity sha512-DT25xX/YgyPKiHFOpNuANIQIVvYEwCWXgK2jYYwqgaMrYE6+tq+DtmMwlD3drl6DJbUwtlIDnn0d7tIn/EbXBg==
|
||||
|
||||
"@types/node@^12.11.7":
|
||||
version "12.12.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.7.tgz#01e4ea724d9e3bd50d90c11fd5980ba317d8fa11"
|
||||
integrity sha512-E6Zn0rffhgd130zbCbAr/JdXfXkoOUFAKNs/rF8qnafSJ8KYaA/j3oz7dcwal+lYjLA7xvdd5J4wdYpCTlP8+w==
|
||||
|
||||
"@types/node@^8.0.47":
|
||||
version "8.10.45"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.45.tgz#4c49ba34106bc7dced77ff6bae8eb6543cde8351"
|
||||
|
||||
@@ -633,7 +633,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/mocha": "^5.2.5",
|
||||
"@types/node": "^10.14.8",
|
||||
"@types/node": "^12.11.7",
|
||||
"mocha-junit-reporter": "^1.17.0",
|
||||
"mocha-multi-reporters": "^1.1.7",
|
||||
"mocha": "^5.2.0",
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
resolved "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.5.tgz#8a4accfc403c124a0bafe8a9fc61a05ec1032073"
|
||||
integrity sha512-lAVp+Kj54ui/vLUFxsJTMtWvZraZxum3w3Nwkble2dNuV5VnPA+Mi2oGX9XYJAaIvZi3tn3cbjS/qcJXRb6Bww==
|
||||
|
||||
"@types/node@^10.14.8":
|
||||
version "10.14.17"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.17.tgz#b96d4dd3e427382482848948041d3754d40fd5ce"
|
||||
integrity sha512-p/sGgiPaathCfOtqu2fx5Mu1bcjuP8ALFg4xpGgNkcin7LwRyzUKniEHBKdcE1RPsenq5JVPIpMTJSygLboygQ==
|
||||
"@types/node@^12.11.7":
|
||||
version "12.12.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.7.tgz#01e4ea724d9e3bd50d90c11fd5980ba317d8fa11"
|
||||
integrity sha512-E6Zn0rffhgd130zbCbAr/JdXfXkoOUFAKNs/rF8qnafSJ8KYaA/j3oz7dcwal+lYjLA7xvdd5J4wdYpCTlP8+w==
|
||||
|
||||
ajv@^5.3.0:
|
||||
version "5.5.2"
|
||||
|
||||
@@ -38,7 +38,8 @@
|
||||
"tasks.json",
|
||||
"keybindings.json",
|
||||
"extensions.json",
|
||||
"argv.json"
|
||||
"argv.json",
|
||||
"profiles.json"
|
||||
]
|
||||
}
|
||||
],
|
||||
@@ -114,6 +115,6 @@
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^10.14.8"
|
||||
"@types/node": "^12.11.7"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,20 @@
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"remoteEnv": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"description": "Remote environment variables."
|
||||
},
|
||||
"remoteUser": {
|
||||
"type": "string",
|
||||
"description": "The user VS Code Server will be started with. The default is the same user as the container."
|
||||
},
|
||||
"extensions": {
|
||||
"type": "array",
|
||||
"description": "An array of extensions that should be installed into the container.",
|
||||
|
||||
@@ -22,6 +22,20 @@
|
||||
"$ref": "vscode://schemas/settings/machine",
|
||||
"description": "Machine specific settings that should be copied into the container."
|
||||
},
|
||||
"remoteEnv": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"description": "Remote environment variables."
|
||||
},
|
||||
"remoteUser": {
|
||||
"type": "string",
|
||||
"description": "The user VS Code Server will be started with. The default is the same user as the container."
|
||||
},
|
||||
"postCreateCommand": {
|
||||
"type": [
|
||||
"string",
|
||||
@@ -55,6 +69,21 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"containerEnv": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "Container environment variables."
|
||||
},
|
||||
"containerUser": {
|
||||
"type": "string",
|
||||
"description": "The user the container will be started with. The default is the user on the Docker image."
|
||||
},
|
||||
"updateRemoteUserUID": {
|
||||
"type": "boolean",
|
||||
"description": "Controls whether on Linux the container's user should be updated with the local user's UID and GID. On by default."
|
||||
},
|
||||
"runArgs": {
|
||||
"type": "array",
|
||||
"description": "The arguments required when starting in the container.",
|
||||
@@ -68,7 +97,7 @@
|
||||
"none",
|
||||
"stopContainer"
|
||||
],
|
||||
"description": "Action to take when VS Code is shutting down. The default is to stop the container."
|
||||
"description": "Action to take when the VS Code window is closed. The default is to stop the container."
|
||||
},
|
||||
"overrideCommand": {
|
||||
"type": "boolean",
|
||||
@@ -146,7 +175,7 @@
|
||||
"none",
|
||||
"stopCompose"
|
||||
],
|
||||
"description": "Action to take when VS Code is shutting down. The default is to stop the containers."
|
||||
"description": "Action to take when the VS Code window is closed. The default is to stop the containers."
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
|
||||
@@ -4,23 +4,11 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { getLocation, parse, visit } from 'jsonc-parser';
|
||||
import * as path from 'path';
|
||||
import * as vscode from 'vscode';
|
||||
import * as nls from 'vscode-nls';
|
||||
import { SettingsDocument } from './settingsDocumentHelper';
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
const fadedDecoration = vscode.window.createTextEditorDecorationType({
|
||||
light: {
|
||||
color: '#757575'
|
||||
},
|
||||
dark: {
|
||||
color: '#878787'
|
||||
}
|
||||
});
|
||||
|
||||
let pendingLaunchJsonDecoration: NodeJS.Timer;
|
||||
|
||||
export function activate(context: vscode.ExtensionContext): void {
|
||||
//settings.json suggestions
|
||||
context.subscriptions.push(registerSettingsCompletions());
|
||||
@@ -33,18 +21,6 @@ export function activate(context: vscode.ExtensionContext): void {
|
||||
|
||||
// task.json variable suggestions
|
||||
context.subscriptions.push(registerVariableCompletions('**/tasks.json'));
|
||||
|
||||
// launch.json decorations
|
||||
context.subscriptions.push(vscode.window.onDidChangeActiveTextEditor(editor => updateLaunchJsonDecorations(editor), null, context.subscriptions));
|
||||
context.subscriptions.push(vscode.workspace.onDidChangeTextDocument(event => {
|
||||
if (vscode.window.activeTextEditor && event.document === vscode.window.activeTextEditor.document) {
|
||||
if (pendingLaunchJsonDecoration) {
|
||||
clearTimeout(pendingLaunchJsonDecoration);
|
||||
}
|
||||
pendingLaunchJsonDecoration = setTimeout(() => updateLaunchJsonDecorations(vscode.window.activeTextEditor), 1000);
|
||||
}
|
||||
}, null, context.subscriptions));
|
||||
updateLaunchJsonDecorations(vscode.window.activeTextEditor);
|
||||
}
|
||||
|
||||
function registerSettingsCompletions(): vscode.Disposable {
|
||||
@@ -153,39 +129,6 @@ function provideInstalledExtensionProposals(extensionsContent: IExtensionsConten
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function updateLaunchJsonDecorations(editor: vscode.TextEditor | undefined): void {
|
||||
if (!editor || path.basename(editor.document.fileName) !== 'launch.json') {
|
||||
return;
|
||||
}
|
||||
|
||||
const ranges: vscode.Range[] = [];
|
||||
let addPropertyAndValue = false;
|
||||
let depthInArray = 0;
|
||||
visit(editor.document.getText(), {
|
||||
onObjectProperty: (property, offset, length) => {
|
||||
// Decorate attributes which are unlikely to be edited by the user.
|
||||
// Only decorate "configurations" if it is not inside an array (compounds have a configurations property which should not be decorated).
|
||||
addPropertyAndValue = property === 'version' || property === 'type' || property === 'request' || property === 'compounds' || (property === 'configurations' && depthInArray === 0);
|
||||
if (addPropertyAndValue) {
|
||||
ranges.push(new vscode.Range(editor.document.positionAt(offset), editor.document.positionAt(offset + length)));
|
||||
}
|
||||
},
|
||||
onLiteralValue: (_value, offset, length) => {
|
||||
if (addPropertyAndValue) {
|
||||
ranges.push(new vscode.Range(editor.document.positionAt(offset), editor.document.positionAt(offset + length)));
|
||||
}
|
||||
},
|
||||
onArrayBegin: (_offset: number, _length: number) => {
|
||||
depthInArray++;
|
||||
},
|
||||
onArrayEnd: (_offset: number, _length: number) => {
|
||||
depthInArray--;
|
||||
}
|
||||
});
|
||||
|
||||
editor.setDecorations(fadedDecoration, ranges);
|
||||
}
|
||||
|
||||
vscode.languages.registerDocumentSymbolProvider({ pattern: '**/launch.json', language: 'jsonc' }, {
|
||||
provideDocumentSymbols(document: vscode.TextDocument, _token: vscode.CancellationToken): vscode.ProviderResult<vscode.SymbolInformation[]> {
|
||||
const result: vscode.SymbolInformation[] = [];
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@types/node@^10.14.8":
|
||||
version "10.14.8"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.8.tgz#fe444203ecef1162348cd6deb76c62477b2cc6e9"
|
||||
integrity sha512-I4+DbJEhLEg4/vIy/2gkWDvXBOOtPKV9EnLhYjMoqxcRW+TTZtUftkHktz/a8suoD5mUL7m6ReLrkPvSsCQQmw==
|
||||
"@types/node@^12.11.7":
|
||||
version "12.11.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.11.7.tgz#57682a9771a3f7b09c2497f28129a0462966524a"
|
||||
integrity sha512-JNbGaHFCLwgHn/iCckiGSOZ1XYHsKFwREtzPwSGCVld1SGhOlmZw2D4ZI94HQCrBHbADzW9m4LER/8olJTRGHA==
|
||||
|
||||
jsonc-parser@^2.1.1:
|
||||
version "2.1.1"
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/mocha": "^5.2.5",
|
||||
"@types/node": "10",
|
||||
"@types/node": "^12.11.7",
|
||||
"mocha": "^5.2.0",
|
||||
"mocha-junit-reporter": "^1.17.0",
|
||||
"mocha-multi-reporters": "^1.1.7",
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-5.2.6.tgz#b8622d50557dd155e9f2f634b7d68fd38de5e94b"
|
||||
integrity sha512-1axi39YdtBI7z957vdqXI4Ac25e7YihYQtJa+Clnxg1zTJEaIRbndt71O3sP4GAMgiAm0pY26/b9BrY4MR/PMw==
|
||||
|
||||
"@types/node@10":
|
||||
version "10.17.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.4.tgz#8993a4fe3c4022fda66bf4ea660d615fc5659c6f"
|
||||
integrity sha512-F2pgg+LcIr/elguz+x+fdBX5KeZXGUOp7TV8M0TVIrDezYLFRNt8oMTyps0VQ1kj5WGGoR18RdxnRDHXrIFHMQ==
|
||||
"@types/node@^12.11.7":
|
||||
version "12.12.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.7.tgz#01e4ea724d9e3bd50d90c11fd5980ba317d8fa11"
|
||||
integrity sha512-E6Zn0rffhgd130zbCbAr/JdXfXkoOUFAKNs/rF8qnafSJ8KYaA/j3oz7dcwal+lYjLA7xvdd5J4wdYpCTlP8+w==
|
||||
|
||||
agent-base@4, agent-base@^4.3.0:
|
||||
version "4.3.0"
|
||||
|
||||
@@ -54,6 +54,6 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/markdown-it": "0.0.2",
|
||||
"@types/node": "^10.14.8"
|
||||
"@types/node": "^12.11.7"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/markdown-it/-/markdown-it-0.0.2.tgz#5d9ad19e6e6508cdd2f2596df86fd0aade598660"
|
||||
integrity sha1-XZrRnm5lCM3S8llt+G/Qqt5ZhmA=
|
||||
|
||||
"@types/node@^10.14.8":
|
||||
version "10.14.8"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.8.tgz#fe444203ecef1162348cd6deb76c62477b2cc6e9"
|
||||
integrity sha512-I4+DbJEhLEg4/vIy/2gkWDvXBOOtPKV9EnLhYjMoqxcRW+TTZtUftkHktz/a8suoD5mUL7m6ReLrkPvSsCQQmw==
|
||||
"@types/node@^12.11.7":
|
||||
version "12.11.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.11.7.tgz#57682a9771a3f7b09c2497f28129a0462966524a"
|
||||
integrity sha512-JNbGaHFCLwgHn/iCckiGSOZ1XYHsKFwREtzPwSGCVld1SGhOlmZw2D4ZI94HQCrBHbADzW9m4LER/8olJTRGHA==
|
||||
|
||||
"@types/node@^6.0.46":
|
||||
version "6.0.78"
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
"engines": {
|
||||
"vscode": "^1.5.0"
|
||||
},
|
||||
"extensionKind": "ui",
|
||||
"extensionKind": [
|
||||
"ui"
|
||||
],
|
||||
"aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217",
|
||||
"enableProposedApi": true,
|
||||
"categories": [
|
||||
@@ -23,6 +25,6 @@
|
||||
"watch": "gulp watch-extension:git-ui"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^10.14.8"
|
||||
"@types/node": "^12.11.7"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,12 +41,12 @@ export function exec(command: string, options: cp.ExecOptions & { stdin?: string
|
||||
(error ? reject : resolve)({ error, stdout, stderr });
|
||||
});
|
||||
if (options.stdin) {
|
||||
child.stdin.write(options.stdin, (err: any) => {
|
||||
child.stdin!.write(options.stdin, (err: any) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
return;
|
||||
}
|
||||
child.stdin.end((err: any) => {
|
||||
child.stdin!.end((err: any) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@types/node@^10.14.8":
|
||||
version "10.14.8"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.8.tgz#fe444203ecef1162348cd6deb76c62477b2cc6e9"
|
||||
integrity sha512-I4+DbJEhLEg4/vIy/2gkWDvXBOOtPKV9EnLhYjMoqxcRW+TTZtUftkHktz/a8suoD5mUL7m6ReLrkPvSsCQQmw==
|
||||
"@types/node@^12.11.7":
|
||||
version "12.11.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.11.7.tgz#57682a9771a3f7b09c2497f28129a0462966524a"
|
||||
integrity sha512-JNbGaHFCLwgHn/iCckiGSOZ1XYHsKFwREtzPwSGCVld1SGhOlmZw2D4ZI94HQCrBHbADzW9m4LER/8olJTRGHA==
|
||||
|
||||
+190
-16
@@ -109,6 +109,24 @@
|
||||
"dark": "resources/icons/dark/stage.svg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "git.stageAllTracked",
|
||||
"title": "%command.stageAllTracked%",
|
||||
"category": "Git",
|
||||
"icon": {
|
||||
"light": "resources/icons/light/stage.svg",
|
||||
"dark": "resources/icons/dark/stage.svg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "git.stageAllUntracked",
|
||||
"title": "%command.stageAllUntracked%",
|
||||
"category": "Git",
|
||||
"icon": {
|
||||
"light": "resources/icons/light/stage.svg",
|
||||
"dark": "resources/icons/dark/stage.svg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "git.stageSelectedRanges",
|
||||
"title": "%command.stageSelectedRanges%",
|
||||
@@ -178,6 +196,24 @@
|
||||
"dark": "resources/icons/dark/clean.svg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "git.cleanAllTracked",
|
||||
"title": "%command.cleanAllTracked%",
|
||||
"category": "Git",
|
||||
"icon": {
|
||||
"light": "resources/icons/light/clean.svg",
|
||||
"dark": "resources/icons/dark/clean.svg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "git.cleanAllUntracked",
|
||||
"title": "%command.cleanAllUntracked%",
|
||||
"category": "Git",
|
||||
"icon": {
|
||||
"light": "resources/icons/light/clean.svg",
|
||||
"dark": "resources/icons/dark/clean.svg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "git.commit",
|
||||
"title": "%command.commit%",
|
||||
@@ -267,6 +303,11 @@
|
||||
"title": "%command.createTag%",
|
||||
"category": "Git"
|
||||
},
|
||||
{
|
||||
"command": "git.deleteTag",
|
||||
"title": "%command.deleteTag%",
|
||||
"category": "Git"
|
||||
},
|
||||
{
|
||||
"command": "git.fetch",
|
||||
"title": "%command.fetch%",
|
||||
@@ -396,6 +437,11 @@
|
||||
"command": "git.stashApplyLatest",
|
||||
"title": "%command.stashApplyLatest%",
|
||||
"category": "Git"
|
||||
},
|
||||
{
|
||||
"command": "git.stashDrop",
|
||||
"title": "%command.stashDrop%",
|
||||
"category": "Git"
|
||||
}
|
||||
],
|
||||
"menus": {
|
||||
@@ -440,6 +486,14 @@
|
||||
"command": "git.stageAll",
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
},
|
||||
{
|
||||
"command": "git.stageAllTracked",
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
},
|
||||
{
|
||||
"command": "git.stageAllUntracked",
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
},
|
||||
{
|
||||
"command": "git.stageSelectedRanges",
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
@@ -564,6 +618,10 @@
|
||||
"command": "git.createTag",
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
},
|
||||
{
|
||||
"command": "git.deleteTag",
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
},
|
||||
{
|
||||
"command": "git.fetch",
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
@@ -651,6 +709,10 @@
|
||||
{
|
||||
"command": "git.stashApplyLatest",
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
},
|
||||
{
|
||||
"command": "git.stashDrop",
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
}
|
||||
],
|
||||
"scm/title": [
|
||||
@@ -804,6 +866,11 @@
|
||||
"group": "6_stash",
|
||||
"when": "scmProvider == git"
|
||||
},
|
||||
{
|
||||
"command": "git.stashDrop",
|
||||
"group": "6_stash",
|
||||
"when": "scmProvider == git"
|
||||
},
|
||||
{
|
||||
"command": "git.showOutput",
|
||||
"group": "7_repository",
|
||||
@@ -840,22 +907,62 @@
|
||||
},
|
||||
{
|
||||
"command": "git.cleanAll",
|
||||
"when": "scmProvider == git && scmResourceGroup == workingTree",
|
||||
"when": "scmProvider == git && scmResourceGroup == workingTree && config.git.untrackedChanges == mixed",
|
||||
"group": "1_modification"
|
||||
},
|
||||
{
|
||||
"command": "git.stageAll",
|
||||
"when": "scmProvider == git && scmResourceGroup == workingTree",
|
||||
"when": "scmProvider == git && scmResourceGroup == workingTree && config.git.untrackedChanges == mixed",
|
||||
"group": "1_modification"
|
||||
},
|
||||
{
|
||||
"command": "git.cleanAll",
|
||||
"when": "scmProvider == git && scmResourceGroup == workingTree",
|
||||
"when": "scmProvider == git && scmResourceGroup == workingTree && config.git.untrackedChanges == mixed",
|
||||
"group": "inline"
|
||||
},
|
||||
{
|
||||
"command": "git.stageAll",
|
||||
"when": "scmProvider == git && scmResourceGroup == workingTree",
|
||||
"when": "scmProvider == git && scmResourceGroup == workingTree && config.git.untrackedChanges == mixed",
|
||||
"group": "inline"
|
||||
},
|
||||
{
|
||||
"command": "git.cleanAllTracked",
|
||||
"when": "scmProvider == git && scmResourceGroup == workingTree && config.git.untrackedChanges != mixed",
|
||||
"group": "1_modification"
|
||||
},
|
||||
{
|
||||
"command": "git.stageAllTracked",
|
||||
"when": "scmProvider == git && scmResourceGroup == workingTree && config.git.untrackedChanges != mixed",
|
||||
"group": "1_modification"
|
||||
},
|
||||
{
|
||||
"command": "git.cleanAllTracked",
|
||||
"when": "scmProvider == git && scmResourceGroup == workingTree && config.git.untrackedChanges != mixed",
|
||||
"group": "inline"
|
||||
},
|
||||
{
|
||||
"command": "git.stageAllTracked",
|
||||
"when": "scmProvider == git && scmResourceGroup == workingTree && config.git.untrackedChanges != mixed",
|
||||
"group": "inline"
|
||||
},
|
||||
{
|
||||
"command": "git.cleanAllUntracked",
|
||||
"when": "scmProvider == git && scmResourceGroup == untracked",
|
||||
"group": "1_modification"
|
||||
},
|
||||
{
|
||||
"command": "git.stageAllUntracked",
|
||||
"when": "scmProvider == git && scmResourceGroup == untracked",
|
||||
"group": "1_modification"
|
||||
},
|
||||
{
|
||||
"command": "git.cleanAllUntracked",
|
||||
"when": "scmProvider == git && scmResourceGroup == untracked",
|
||||
"group": "inline"
|
||||
},
|
||||
{
|
||||
"command": "git.stageAllUntracked",
|
||||
"when": "scmProvider == git && scmResourceGroup == untracked",
|
||||
"group": "inline"
|
||||
}
|
||||
],
|
||||
@@ -1031,13 +1138,63 @@
|
||||
"command": "git.revealInExplorer",
|
||||
"when": "scmProvider == git && scmResourceGroup == workingTree",
|
||||
"group": "2_view"
|
||||
},
|
||||
{
|
||||
"command": "git.openChange",
|
||||
"when": "scmProvider == git && scmResourceGroup == untracked",
|
||||
"group": "navigation"
|
||||
},
|
||||
{
|
||||
"command": "git.openHEADFile",
|
||||
"when": "scmProvider == git && scmResourceGroup == untracked",
|
||||
"group": "navigation"
|
||||
},
|
||||
{
|
||||
"command": "git.openFile",
|
||||
"when": "scmProvider == git && scmResourceGroup == untracked",
|
||||
"group": "navigation"
|
||||
},
|
||||
{
|
||||
"command": "git.stage",
|
||||
"when": "scmProvider == git && scmResourceGroup == untracked",
|
||||
"group": "1_modification"
|
||||
},
|
||||
{
|
||||
"command": "git.clean",
|
||||
"when": "scmProvider == git && scmResourceGroup == untracked && !gitFreshRepository",
|
||||
"group": "1_modification"
|
||||
},
|
||||
{
|
||||
"command": "git.clean",
|
||||
"when": "scmProvider == git && scmResourceGroup == untracked && !gitFreshRepository",
|
||||
"group": "inline"
|
||||
},
|
||||
{
|
||||
"command": "git.stage",
|
||||
"when": "scmProvider == git && scmResourceGroup == untracked",
|
||||
"group": "inline"
|
||||
},
|
||||
{
|
||||
"command": "git.openFile2",
|
||||
"when": "scmProvider == git && scmResourceGroup == untracked && config.git.showInlineOpenFileAction && config.git.openDiffOnClick",
|
||||
"group": "inline0"
|
||||
},
|
||||
{
|
||||
"command": "git.openChange",
|
||||
"when": "scmProvider == git && scmResourceGroup == untracked && config.git.showInlineOpenFileAction && !config.git.openDiffOnClick",
|
||||
"group": "inline0"
|
||||
},
|
||||
{
|
||||
"command": "git.ignore",
|
||||
"when": "scmProvider == git && scmResourceGroup == untracked",
|
||||
"group": "1_modification@3"
|
||||
}
|
||||
],
|
||||
"editor/title": [
|
||||
{
|
||||
"command": "git.openFile",
|
||||
"group": "navigation",
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme =~ /^git$|^file$/"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme =~ /^gitfs$|^file$/"
|
||||
},
|
||||
{
|
||||
"command": "git.openChange",
|
||||
@@ -1047,44 +1204,44 @@
|
||||
{
|
||||
"command": "git.stageSelectedRanges",
|
||||
"group": "2_git@1",
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme =~ /^git$|^file$/"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme =~ /^gitfs$|^file$/"
|
||||
},
|
||||
{
|
||||
"command": "git.unstageSelectedRanges",
|
||||
"group": "2_git@2",
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme =~ /^git$|^file$/"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme =~ /^gitfs$|^file$/"
|
||||
},
|
||||
{
|
||||
"command": "git.revertSelectedRanges",
|
||||
"group": "2_git@3",
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme =~ /^git$|^file$/"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme =~ /^gitfs$|^file$/"
|
||||
}
|
||||
],
|
||||
"editor/context": [
|
||||
{
|
||||
"command": "git.stageSelectedRanges",
|
||||
"group": "2_git@1",
|
||||
"when": "isInDiffRightEditor && config.git.enabled && gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme =~ /^git$|^file$/"
|
||||
"when": "isInDiffRightEditor && config.git.enabled && gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme =~ /^gitfs$|^file$/"
|
||||
},
|
||||
{
|
||||
"command": "git.unstageSelectedRanges",
|
||||
"group": "2_git@2",
|
||||
"when": "isInDiffRightEditor && config.git.enabled && gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme =~ /^git$|^file$/"
|
||||
"when": "isInDiffRightEditor && config.git.enabled && gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme =~ /^gitfs$|^file$/"
|
||||
},
|
||||
{
|
||||
"command": "git.revertSelectedRanges",
|
||||
"group": "2_git@3",
|
||||
"when": "isInDiffRightEditor && config.git.enabled && gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme =~ /^git$|^file$/"
|
||||
"when": "isInDiffRightEditor && config.git.enabled && gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme =~ /^gitfs$|^file$/"
|
||||
}
|
||||
],
|
||||
"scm/change/title": [
|
||||
{
|
||||
"command": "git.stageChange",
|
||||
"when": "originalResourceScheme == git"
|
||||
"when": "originalResourceScheme == gitfs"
|
||||
},
|
||||
{
|
||||
"command": "git.revertChange",
|
||||
"when": "originalResourceScheme == git"
|
||||
"when": "originalResourceScheme == gitfs"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -1174,7 +1331,8 @@
|
||||
"%config.countBadge.off%"
|
||||
],
|
||||
"description": "%config.countBadge%",
|
||||
"default": "all"
|
||||
"default": "all",
|
||||
"scope": "resource"
|
||||
},
|
||||
"git.checkoutType": {
|
||||
"type": "string",
|
||||
@@ -1434,6 +1592,22 @@
|
||||
],
|
||||
"default": "committerdate",
|
||||
"description": "%config.branchSortOrder%"
|
||||
},
|
||||
"git.untrackedChanges": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"mixed",
|
||||
"separate",
|
||||
"hidden"
|
||||
],
|
||||
"enumDescriptions": [
|
||||
"%config.untrackedChanges.mixed%",
|
||||
"%config.untrackedChanges.separate%",
|
||||
"%config.untrackedChanges.hidden%"
|
||||
],
|
||||
"default": "mixed",
|
||||
"description": "%config.untrackedChanges%",
|
||||
"scope": "resource"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -1585,7 +1759,7 @@
|
||||
"byline": "^5.0.0",
|
||||
"file-type": "^7.2.0",
|
||||
"iconv-lite": "^0.4.24",
|
||||
"jschardet": "^1.6.0",
|
||||
"jschardet": "2.1.1",
|
||||
"vscode-extension-telemetry": "0.1.1",
|
||||
"vscode-nls": "^4.0.0",
|
||||
"vscode-uri": "^2.0.0",
|
||||
@@ -1595,7 +1769,7 @@
|
||||
"@types/byline": "4.2.31",
|
||||
"@types/file-type": "^5.2.1",
|
||||
"@types/mocha": "2.2.43",
|
||||
"@types/node": "^10.14.8",
|
||||
"@types/node": "^12.11.7",
|
||||
"@types/which": "^1.0.28",
|
||||
"mocha": "^3.2.0"
|
||||
}
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
"command.openHEADFile": "Open File (HEAD)",
|
||||
"command.stage": "Stage Changes",
|
||||
"command.stageAll": "Stage All Changes",
|
||||
"command.stageAllTracked": "Stage All Tracked Changes",
|
||||
"command.stageAllUntracked": "Stage All Untracked Changes",
|
||||
"command.stageSelectedRanges": "Stage Selected Ranges",
|
||||
"command.revertSelectedRanges": "Revert Selected Ranges",
|
||||
"command.stageChange": "Stage Change",
|
||||
@@ -20,6 +22,8 @@
|
||||
"command.unstageSelectedRanges": "Unstage Selected Ranges",
|
||||
"command.clean": "Discard Changes",
|
||||
"command.cleanAll": "Discard All Changes",
|
||||
"command.cleanAllTracked": "Discard All Tracked Changes",
|
||||
"command.cleanAllUntracked": "Discard All Untracked Changes",
|
||||
"command.commit": "Commit",
|
||||
"command.commitStaged": "Commit Staged",
|
||||
"command.commitEmpty": "Commit Empty",
|
||||
@@ -37,6 +41,7 @@
|
||||
"command.renameBranch": "Rename Branch...",
|
||||
"command.merge": "Merge Branch...",
|
||||
"command.createTag": "Create Tag",
|
||||
"command.deleteTag": "Delete Tag",
|
||||
"command.fetch": "Fetch",
|
||||
"command.fetchPrune": "Fetch (Prune)",
|
||||
"command.fetchAll": "Fetch From All Remotes",
|
||||
@@ -56,13 +61,14 @@
|
||||
"command.publish": "Publish Branch...",
|
||||
"command.showOutput": "Show Git Output",
|
||||
"command.ignore": "Add to .gitignore",
|
||||
"command.revealInExplorer": "Reveal in Explorer",
|
||||
"command.revealInExplorer": "Reveal in Side Bar",
|
||||
"command.stashIncludeUntracked": "Stash (Include Untracked)",
|
||||
"command.stash": "Stash",
|
||||
"command.stashPop": "Pop Stash...",
|
||||
"command.stashPopLatest": "Pop Latest Stash",
|
||||
"command.stashApply": "Apply Stash...",
|
||||
"command.stashApplyLatest": "Apply Latest Stash",
|
||||
"command.stashDrop": "Drop Stash...",
|
||||
"config.enabled": "Whether git is enabled.",
|
||||
"config.path": "Path and filename of the git executable, e.g. `C:\\Program Files\\Git\\bin\\git.exe` (Windows).",
|
||||
"config.autoRepositoryDetection": "Configures when repositories should be automatically detected.",
|
||||
@@ -119,7 +125,7 @@
|
||||
"config.scanRepositories": "List of paths to search for git repositories in.",
|
||||
"config.showProgress": "Controls whether git actions should show progress.",
|
||||
"config.rebaseWhenSync": "Force git to use rebase when running the sync command.",
|
||||
"config.confirmEmptyCommits": "Always confirm the creation of empty commits.",
|
||||
"config.confirmEmptyCommits": "Always confirm the creation of empty commits for the 'Git: Commit Empty' command.",
|
||||
"config.fetchOnPull": "Fetch all branches when pulling or just the current one.",
|
||||
"config.pullTags": "Fetch all tags when pulling.",
|
||||
"config.autoStash": "Stash any changes before pulling and restore them after successful pull.",
|
||||
@@ -129,6 +135,10 @@
|
||||
"config.openDiffOnClick": "Controls whether the diff editor should be opened when clicking a change. Otherwise the regular editor will be opened.",
|
||||
"config.supportCancellation": "Controls whether a notification comes up when running the Sync action, which allows the user to cancel the operation.",
|
||||
"config.branchSortOrder": "Controls the sort order for branches.",
|
||||
"config.untrackedChanges": "Controls how untracked changes behave.",
|
||||
"config.untrackedChanges.mixed": "All changes, tracked and untracked, appear together and behave equally.",
|
||||
"config.untrackedChanges.separate": "Untracked changes appear separately in the Source Control view. They are also excluded from several actions.",
|
||||
"config.untrackedChanges.hidden": "Untracked changes are hidden and excluded from several actions.",
|
||||
"colors.added": "Color for added resources.",
|
||||
"colors.modified": "Color for modified resources.",
|
||||
"colors.deleted": "Color for deleted resources.",
|
||||
|
||||
@@ -8,6 +8,7 @@ import { Repository as BaseRepository, Resource } from '../repository';
|
||||
import { InputBox, Git, API, Repository, Remote, RepositoryState, Branch, Ref, Submodule, Commit, Change, RepositoryUIState, Status, LogOptions, APIState } from './git';
|
||||
import { Event, SourceControlInputBox, Uri, SourceControl } from 'vscode';
|
||||
import { mapEvent } from '../util';
|
||||
import { toGitUri } from '../uri';
|
||||
|
||||
class ApiInputBox implements InputBox {
|
||||
set value(value: string) { this._inputBox.value = value; }
|
||||
@@ -234,5 +235,9 @@ export class ApiImpl implements API {
|
||||
return this._model.repositories.map(r => new ApiRepository(r));
|
||||
}
|
||||
|
||||
toGitUri(uri: Uri, ref: string): Uri {
|
||||
return toGitUri(uri, ref);
|
||||
}
|
||||
|
||||
constructor(private _model: Model) { }
|
||||
}
|
||||
|
||||
Vendored
+2
@@ -185,6 +185,8 @@ export interface API {
|
||||
readonly repositories: Repository[];
|
||||
readonly onDidOpenRepository: Event<Repository>;
|
||||
readonly onDidCloseRepository: Event<Repository>;
|
||||
|
||||
toGitUri(uri: Uri, ref: string): Uri;
|
||||
}
|
||||
|
||||
export interface GitExtension {
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as http from 'http';
|
||||
import * as fs from 'fs';
|
||||
import * as nls from 'vscode-nls';
|
||||
import { IPCClient } from './ipc/ipcClient';
|
||||
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
@@ -20,10 +20,6 @@ function main(argv: string[]): void {
|
||||
return fatal('Wrong number of arguments');
|
||||
}
|
||||
|
||||
if (!process.env['VSCODE_GIT_ASKPASS_HANDLE']) {
|
||||
return fatal('Missing handle');
|
||||
}
|
||||
|
||||
if (!process.env['VSCODE_GIT_ASKPASS_PIPE']) {
|
||||
return fatal('Missing pipe');
|
||||
}
|
||||
@@ -33,40 +29,14 @@ function main(argv: string[]): void {
|
||||
}
|
||||
|
||||
const output = process.env['VSCODE_GIT_ASKPASS_PIPE'] as string;
|
||||
const socketPath = process.env['VSCODE_GIT_ASKPASS_HANDLE'] as string;
|
||||
const request = argv[2];
|
||||
const host = argv[4].substring(1, argv[4].length - 2);
|
||||
const opts: http.RequestOptions = {
|
||||
socketPath,
|
||||
path: '/',
|
||||
method: 'POST'
|
||||
};
|
||||
const ipcClient = new IPCClient('askpass');
|
||||
|
||||
const req = http.request(opts, res => {
|
||||
if (res.statusCode !== 200) {
|
||||
return fatal(`Bad status code: ${res.statusCode}`);
|
||||
}
|
||||
|
||||
const chunks: string[] = [];
|
||||
res.setEncoding('utf8');
|
||||
res.on('data', (d: string) => chunks.push(d));
|
||||
res.on('end', () => {
|
||||
const raw = chunks.join('');
|
||||
|
||||
try {
|
||||
const result = JSON.parse(raw);
|
||||
fs.writeFileSync(output, result + '\n');
|
||||
} catch (err) {
|
||||
return fatal(`Error parsing response`);
|
||||
}
|
||||
|
||||
setTimeout(() => process.exit(0), 0);
|
||||
});
|
||||
});
|
||||
|
||||
req.on('error', () => fatal('Error in request'));
|
||||
req.write(JSON.stringify({ request, host }));
|
||||
req.end();
|
||||
ipcClient.call({ request, host }).then(res => {
|
||||
fs.writeFileSync(output, res + '\n');
|
||||
setTimeout(() => process.exit(0), 0);
|
||||
}).catch(err => fatal(err));
|
||||
}
|
||||
|
||||
main(process.argv);
|
||||
|
||||
@@ -3,15 +3,10 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Disposable, window, InputBoxOptions } from 'vscode';
|
||||
import { denodeify } from './util';
|
||||
import { window, InputBoxOptions } from 'vscode';
|
||||
import { IDisposable } from './util';
|
||||
import * as path from 'path';
|
||||
import * as http from 'http';
|
||||
import * as os from 'os';
|
||||
import * as fs from 'fs';
|
||||
import * as crypto from 'crypto';
|
||||
|
||||
const randomBytes = denodeify<Buffer>(crypto.randomBytes);
|
||||
import { IIPCHandler, IIPCServer } from './ipc/ipcServer';
|
||||
|
||||
export interface AskpassEnvironment {
|
||||
GIT_ASKPASS: string;
|
||||
@@ -21,68 +16,21 @@ export interface AskpassEnvironment {
|
||||
VSCODE_GIT_ASKPASS_HANDLE?: string;
|
||||
}
|
||||
|
||||
function getIPCHandlePath(nonce: string): string {
|
||||
if (process.platform === 'win32') {
|
||||
return `\\\\.\\pipe\\vscode-git-askpass-${nonce}-sock`;
|
||||
export class Askpass implements IIPCHandler {
|
||||
|
||||
private disposable: IDisposable;
|
||||
|
||||
static getDisabledEnv(): AskpassEnvironment {
|
||||
return {
|
||||
GIT_ASKPASS: path.join(__dirname, 'askpass-empty.sh')
|
||||
};
|
||||
}
|
||||
|
||||
if (process.env['XDG_RUNTIME_DIR']) {
|
||||
return path.join(process.env['XDG_RUNTIME_DIR'] as string, `vscode-git-askpass-${nonce}.sock`);
|
||||
constructor(ipc: IIPCServer) {
|
||||
this.disposable = ipc.registerHandler('askpass', this);
|
||||
}
|
||||
|
||||
return path.join(os.tmpdir(), `vscode-git-askpass-${nonce}.sock`);
|
||||
}
|
||||
|
||||
export class Askpass implements Disposable {
|
||||
|
||||
private server: http.Server;
|
||||
private ipcHandlePathPromise: Promise<string>;
|
||||
private ipcHandlePath: string | undefined;
|
||||
private enabled = true;
|
||||
|
||||
constructor() {
|
||||
this.server = http.createServer((req, res) => this.onRequest(req, res));
|
||||
this.ipcHandlePathPromise = this.setup().catch(err => {
|
||||
console.error(err);
|
||||
return '';
|
||||
});
|
||||
}
|
||||
|
||||
private async setup(): Promise<string> {
|
||||
const buffer = await randomBytes(20);
|
||||
const nonce = buffer.toString('hex');
|
||||
const ipcHandlePath = getIPCHandlePath(nonce);
|
||||
this.ipcHandlePath = ipcHandlePath;
|
||||
|
||||
try {
|
||||
this.server.listen(ipcHandlePath);
|
||||
this.server.on('error', err => console.error(err));
|
||||
} catch (err) {
|
||||
console.error('Could not launch git askpass helper.');
|
||||
this.enabled = false;
|
||||
}
|
||||
|
||||
return ipcHandlePath;
|
||||
}
|
||||
|
||||
private onRequest(req: http.IncomingMessage, res: http.ServerResponse): void {
|
||||
const chunks: string[] = [];
|
||||
req.setEncoding('utf8');
|
||||
req.on('data', (d: string) => chunks.push(d));
|
||||
req.on('end', () => {
|
||||
const { request, host } = JSON.parse(chunks.join(''));
|
||||
|
||||
this.prompt(host, request).then(result => {
|
||||
res.writeHead(200);
|
||||
res.end(JSON.stringify(result));
|
||||
}, () => {
|
||||
res.writeHead(500);
|
||||
res.end();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private async prompt(host: string, request: string): Promise<string> {
|
||||
async handle({ request, host }: { request: string, host: string }): Promise<string> {
|
||||
const options: InputBoxOptions = {
|
||||
password: /password/i.test(request),
|
||||
placeHolder: request,
|
||||
@@ -93,27 +41,16 @@ export class Askpass implements Disposable {
|
||||
return await window.showInputBox(options) || '';
|
||||
}
|
||||
|
||||
async getEnv(): Promise<AskpassEnvironment> {
|
||||
if (!this.enabled) {
|
||||
return {
|
||||
GIT_ASKPASS: path.join(__dirname, 'askpass-empty.sh')
|
||||
};
|
||||
}
|
||||
|
||||
getEnv(): AskpassEnvironment {
|
||||
return {
|
||||
ELECTRON_RUN_AS_NODE: '1',
|
||||
GIT_ASKPASS: path.join(__dirname, 'askpass.sh'),
|
||||
VSCODE_GIT_ASKPASS_NODE: process.execPath,
|
||||
VSCODE_GIT_ASKPASS_MAIN: path.join(__dirname, 'askpass-main.js'),
|
||||
VSCODE_GIT_ASKPASS_HANDLE: await this.ipcHandlePathPromise
|
||||
VSCODE_GIT_ASKPASS_MAIN: path.join(__dirname, 'askpass-main.js')
|
||||
};
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this.server.close();
|
||||
|
||||
if (this.ipcHandlePath && process.platform !== 'win32') {
|
||||
fs.unlinkSync(this.ipcHandlePath);
|
||||
}
|
||||
this.disposable.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+210
-139
@@ -3,19 +3,19 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Uri, commands, Disposable, window, workspace, QuickPickItem, OutputChannel, Range, WorkspaceEdit, Position, LineChange, SourceControlResourceState, TextDocumentShowOptions, ViewColumn, ProgressLocation, TextEditor, MessageOptions, WorkspaceFolder } from 'vscode';
|
||||
import { Git, CommitOptions, Stash, ForcePushMode } from './git';
|
||||
import { Repository, Resource, ResourceGroupType } from './repository';
|
||||
import { Model } from './model';
|
||||
import { toGitUri, fromGitUri } from './uri';
|
||||
import { grep, isDescendant, pathEquals } from './util';
|
||||
import { applyLineChanges, intersectDiffWithRange, toLineRanges, invertLineChange, getModifiedRange } from './staging';
|
||||
import * as path from 'path';
|
||||
import { lstat, Stats } from 'fs';
|
||||
import * as os from 'os';
|
||||
import * as path from 'path';
|
||||
import { commands, Disposable, LineChange, MessageOptions, OutputChannel, Position, ProgressLocation, QuickPickItem, Range, SourceControlResourceState, TextDocumentShowOptions, TextEditor, Uri, ViewColumn, window, workspace, WorkspaceEdit, WorkspaceFolder } from 'vscode';
|
||||
import TelemetryReporter from 'vscode-extension-telemetry';
|
||||
import * as nls from 'vscode-nls';
|
||||
import { Ref, RefType, Branch, GitErrorCodes, Status } from './api/git';
|
||||
import { Branch, GitErrorCodes, Ref, RefType, Status } from './api/git';
|
||||
import { CommitOptions, ForcePushMode, Git, Stash } from './git';
|
||||
import { Model } from './model';
|
||||
import { Repository, Resource, ResourceGroupType } from './repository';
|
||||
import { applyLineChanges, getModifiedRange, intersectDiffWithRange, invertLineChange, toLineRanges } from './staging';
|
||||
import { fromGitUri, toGitUri, isGitUri } from './uri';
|
||||
import { grep, isDescendant, pathEquals } from './util';
|
||||
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
@@ -99,7 +99,7 @@ class CreateBranchItem implements QuickPickItem {
|
||||
|
||||
constructor(private cc: CommandCenter) { }
|
||||
|
||||
get label(): string { return localize('create branch', '$(plus) Create new branch...'); }
|
||||
get label(): string { return '$(plus) ' + localize('create branch', 'Create new branch...'); }
|
||||
get description(): string { return ''; }
|
||||
|
||||
get alwaysShow(): boolean { return true; }
|
||||
@@ -113,7 +113,7 @@ class CreateBranchFromItem implements QuickPickItem {
|
||||
|
||||
constructor(private cc: CommandCenter) { }
|
||||
|
||||
get label(): string { return localize('create branch from', '$(plus) Create new branch from...'); }
|
||||
get label(): string { return '$(plus) ' + localize('create branch from', 'Create new branch from...'); }
|
||||
get description(): string { return ''; }
|
||||
|
||||
get alwaysShow(): boolean { return true; }
|
||||
@@ -136,7 +136,7 @@ class AddRemoteItem implements QuickPickItem {
|
||||
|
||||
constructor(private cc: CommandCenter) { }
|
||||
|
||||
get label(): string { return localize('add remote', '$(plus) Add a new remote...'); }
|
||||
get label(): string { return '$(plus) ' + localize('add remote', 'Add a new remote...'); }
|
||||
get description(): string { return ''; }
|
||||
|
||||
get alwaysShow(): boolean { return true; }
|
||||
@@ -170,14 +170,14 @@ function command(commandId: string, options: CommandOptions = {}): Function {
|
||||
};
|
||||
}
|
||||
|
||||
const ImageMimetypes = [
|
||||
'image/png',
|
||||
'image/gif',
|
||||
'image/jpeg',
|
||||
'image/webp',
|
||||
'image/tiff',
|
||||
'image/bmp'
|
||||
];
|
||||
// const ImageMimetypes = [
|
||||
// 'image/png',
|
||||
// 'image/gif',
|
||||
// 'image/jpeg',
|
||||
// 'image/webp',
|
||||
// 'image/tiff',
|
||||
// 'image/bmp'
|
||||
// ];
|
||||
|
||||
async function categorizeResourceByResolution(resources: Resource[]): Promise<{ merge: Resource[], resolved: Resource[], unresolved: Resource[], deletionConflicts: Resource[] }> {
|
||||
const selection = resources.filter(s => s instanceof Resource) as Resource[];
|
||||
@@ -213,6 +213,12 @@ function createCheckoutItems(repository: Repository): CheckoutItem[] {
|
||||
return [...heads, ...tags, ...remoteHeads];
|
||||
}
|
||||
|
||||
class TagItem implements QuickPickItem {
|
||||
get label(): string { return this.ref.name ?? ''; }
|
||||
get description(): string { return this.ref.commit?.substr(0, 8) ?? ''; }
|
||||
constructor(readonly ref: Ref) { }
|
||||
}
|
||||
|
||||
enum PushType {
|
||||
Push,
|
||||
PushTo,
|
||||
@@ -289,10 +295,10 @@ export class CommandCenter {
|
||||
}
|
||||
} else {
|
||||
if (resource.type !== Status.DELETED_BY_THEM) {
|
||||
left = await this.getLeftResource(resource);
|
||||
left = this.getLeftResource(resource);
|
||||
}
|
||||
|
||||
right = await this.getRightResource(resource);
|
||||
right = this.getRightResource(resource);
|
||||
}
|
||||
|
||||
const title = this.getTitle(resource);
|
||||
@@ -324,79 +330,40 @@ export class CommandCenter {
|
||||
}
|
||||
}
|
||||
|
||||
private async getURI(uri: Uri, ref: string): Promise<Uri | undefined> {
|
||||
const repository = this.model.getRepository(uri);
|
||||
|
||||
if (!repository) {
|
||||
return toGitUri(uri, ref);
|
||||
}
|
||||
|
||||
try {
|
||||
let gitRef = ref;
|
||||
|
||||
if (gitRef === '~') {
|
||||
const uriString = uri.toString();
|
||||
const [indexStatus] = repository.indexGroup.resourceStates.filter(r => r.resourceUri.toString() === uriString);
|
||||
gitRef = indexStatus ? '' : 'HEAD';
|
||||
}
|
||||
|
||||
const { size, object } = await repository.getObjectDetails(gitRef, uri.fsPath);
|
||||
const { mimetype } = await repository.detectObjectType(object);
|
||||
|
||||
if (mimetype === 'text/plain') {
|
||||
return toGitUri(uri, ref);
|
||||
}
|
||||
|
||||
if (size > 1000000) { // 1 MB
|
||||
return Uri.parse(`data:;label:${path.basename(uri.fsPath)};description:${gitRef},`);
|
||||
}
|
||||
|
||||
if (ImageMimetypes.indexOf(mimetype) > -1) {
|
||||
const contents = await repository.buffer(gitRef, uri.fsPath);
|
||||
return Uri.parse(`data:${mimetype};label:${path.basename(uri.fsPath)};description:${gitRef};size:${size};base64,${contents.toString('base64')}`);
|
||||
}
|
||||
|
||||
return Uri.parse(`data:;label:${path.basename(uri.fsPath)};description:${gitRef},`);
|
||||
|
||||
} catch (err) {
|
||||
return toGitUri(uri, ref);
|
||||
}
|
||||
}
|
||||
|
||||
private async getLeftResource(resource: Resource): Promise<Uri | undefined> {
|
||||
private getLeftResource(resource: Resource): Uri | undefined {
|
||||
switch (resource.type) {
|
||||
case Status.INDEX_MODIFIED:
|
||||
case Status.INDEX_RENAMED:
|
||||
case Status.INDEX_ADDED:
|
||||
return this.getURI(resource.original, 'HEAD');
|
||||
return toGitUri(resource.original, 'HEAD');
|
||||
|
||||
case Status.MODIFIED:
|
||||
case Status.UNTRACKED:
|
||||
return this.getURI(resource.resourceUri, '~');
|
||||
return toGitUri(resource.resourceUri, '~');
|
||||
|
||||
case Status.DELETED_BY_THEM:
|
||||
return this.getURI(resource.resourceUri, '');
|
||||
return toGitUri(resource.resourceUri, '');
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private async getRightResource(resource: Resource): Promise<Uri | undefined> {
|
||||
private getRightResource(resource: Resource): Uri | undefined {
|
||||
switch (resource.type) {
|
||||
case Status.INDEX_MODIFIED:
|
||||
case Status.INDEX_ADDED:
|
||||
case Status.INDEX_COPIED:
|
||||
case Status.INDEX_RENAMED:
|
||||
return this.getURI(resource.resourceUri, '');
|
||||
return toGitUri(resource.resourceUri, '');
|
||||
|
||||
case Status.INDEX_DELETED:
|
||||
case Status.DELETED:
|
||||
return this.getURI(resource.resourceUri, 'HEAD');
|
||||
return toGitUri(resource.resourceUri, 'HEAD');
|
||||
|
||||
case Status.DELETED_BY_US:
|
||||
return this.getURI(resource.resourceUri, '~3');
|
||||
return toGitUri(resource.resourceUri, '~3');
|
||||
|
||||
case Status.DELETED_BY_THEM:
|
||||
return this.getURI(resource.resourceUri, '~2');
|
||||
return toGitUri(resource.resourceUri, '~2');
|
||||
|
||||
case Status.MODIFIED:
|
||||
case Status.UNTRACKED:
|
||||
@@ -453,7 +420,7 @@ export class CommandCenter {
|
||||
}
|
||||
|
||||
@command('git.clone')
|
||||
async clone(url?: string): Promise<void> {
|
||||
async clone(url?: string, parentPath?: string): Promise<void> {
|
||||
if (!url) {
|
||||
url = await window.showInputBox({
|
||||
prompt: localize('repourl', "Repository URL"),
|
||||
@@ -473,31 +440,33 @@ export class CommandCenter {
|
||||
|
||||
url = url.trim().replace(/^git\s+clone\s+/, '');
|
||||
|
||||
const config = workspace.getConfiguration('git');
|
||||
let defaultCloneDirectory = config.get<string>('defaultCloneDirectory') || os.homedir();
|
||||
defaultCloneDirectory = defaultCloneDirectory.replace(/^~/, os.homedir());
|
||||
if (!parentPath) {
|
||||
const config = workspace.getConfiguration('git');
|
||||
let defaultCloneDirectory = config.get<string>('defaultCloneDirectory') || os.homedir();
|
||||
defaultCloneDirectory = defaultCloneDirectory.replace(/^~/, os.homedir());
|
||||
|
||||
const uris = await window.showOpenDialog({
|
||||
canSelectFiles: false,
|
||||
canSelectFolders: true,
|
||||
canSelectMany: false,
|
||||
defaultUri: Uri.file(defaultCloneDirectory),
|
||||
openLabel: localize('selectFolder', "Select Repository Location")
|
||||
});
|
||||
const uris = await window.showOpenDialog({
|
||||
canSelectFiles: false,
|
||||
canSelectFolders: true,
|
||||
canSelectMany: false,
|
||||
defaultUri: Uri.file(defaultCloneDirectory),
|
||||
openLabel: localize('selectFolder', "Select Repository Location")
|
||||
});
|
||||
|
||||
if (!uris || uris.length === 0) {
|
||||
/* __GDPR__
|
||||
"clone" : {
|
||||
"outcome" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
}
|
||||
*/
|
||||
this.telemetryReporter.sendTelemetryEvent('clone', { outcome: 'no_directory' });
|
||||
return;
|
||||
if (!uris || uris.length === 0) {
|
||||
/* __GDPR__
|
||||
"clone" : {
|
||||
"outcome" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
}
|
||||
*/
|
||||
this.telemetryReporter.sendTelemetryEvent('clone', { outcome: 'no_directory' });
|
||||
return;
|
||||
}
|
||||
|
||||
const uri = uris[0];
|
||||
parentPath = uri.fsPath;
|
||||
}
|
||||
|
||||
const uri = uris[0];
|
||||
const parentPath = uri.fsPath;
|
||||
|
||||
try {
|
||||
const opts = {
|
||||
location: ProgressLocation.Notification,
|
||||
@@ -507,7 +476,7 @@ export class CommandCenter {
|
||||
|
||||
const repositoryPath = await window.withProgress(
|
||||
opts,
|
||||
(progress, token) => this.git.clone(url!, parentPath, progress, token)
|
||||
(progress, token) => this.git.clone(url!, parentPath!, progress, token)
|
||||
);
|
||||
|
||||
let message = localize('proposeopen', "Would you like to open the cloned repository?");
|
||||
@@ -686,7 +655,7 @@ export class CommandCenter {
|
||||
let uris: Uri[] | undefined;
|
||||
|
||||
if (arg instanceof Uri) {
|
||||
if (arg.scheme === 'git') {
|
||||
if (isGitUri(arg)) {
|
||||
uris = [Uri.file(fromGitUri(arg).path)];
|
||||
} else if (arg.scheme === 'file') {
|
||||
uris = [arg];
|
||||
@@ -765,7 +734,7 @@ export class CommandCenter {
|
||||
return;
|
||||
}
|
||||
|
||||
const HEAD = await this.getLeftResource(resource);
|
||||
const HEAD = this.getLeftResource(resource);
|
||||
const basename = path.basename(resource.resourceUri.fsPath);
|
||||
const title = `${basename} (HEAD)`;
|
||||
|
||||
@@ -866,7 +835,8 @@ export class CommandCenter {
|
||||
}
|
||||
|
||||
const workingTree = selection.filter(s => s.resourceGroupType === ResourceGroupType.WorkingTree);
|
||||
const scmResources = [...workingTree, ...resolved, ...unresolved];
|
||||
const untracked = selection.filter(s => s.resourceGroupType === ResourceGroupType.Untracked);
|
||||
const scmResources = [...workingTree, ...untracked, ...resolved, ...unresolved];
|
||||
|
||||
this.outputChannel.appendLine(`git.stage.scmResources ${scmResources.length}`);
|
||||
if (!scmResources.length) {
|
||||
@@ -907,7 +877,9 @@ export class CommandCenter {
|
||||
}
|
||||
}
|
||||
|
||||
await repository.add([]);
|
||||
const config = workspace.getConfiguration('git', Uri.file(repository.root));
|
||||
const untrackedChanges = config.get<'mixed' | 'separate' | 'hidden'>('untrackedChanges');
|
||||
await repository.add([], untrackedChanges === 'mixed' ? undefined : { update: true });
|
||||
}
|
||||
|
||||
private async _stageDeletionConflict(repository: Repository, uri: Uri): Promise<void> {
|
||||
@@ -945,6 +917,24 @@ export class CommandCenter {
|
||||
}
|
||||
}
|
||||
|
||||
@command('git.stageAllTracked', { repository: true })
|
||||
async stageAllTracked(repository: Repository): Promise<void> {
|
||||
const resources = repository.workingTreeGroup.resourceStates
|
||||
.filter(r => r.type !== Status.UNTRACKED && r.type !== Status.IGNORED);
|
||||
const uris = resources.map(r => r.resourceUri);
|
||||
|
||||
await repository.add(uris);
|
||||
}
|
||||
|
||||
@command('git.stageAllUntracked', { repository: true })
|
||||
async stageAllUntracked(repository: Repository): Promise<void> {
|
||||
const resources = [...repository.workingTreeGroup.resourceStates, ...repository.untrackedGroup.resourceStates]
|
||||
.filter(r => r.type === Status.UNTRACKED || r.type === Status.IGNORED);
|
||||
const uris = resources.map(r => r.resourceUri);
|
||||
|
||||
await repository.add(uris);
|
||||
}
|
||||
|
||||
@command('git.stageChange')
|
||||
async stageChange(uri: Uri, changes: LineChange[], index: number): Promise<void> {
|
||||
const textEditor = window.visibleTextEditors.filter(e => e.document.uri.toString() === uri.toString())[0];
|
||||
@@ -1090,7 +1080,7 @@ export class CommandCenter {
|
||||
const modifiedDocument = textEditor.document;
|
||||
const modifiedUri = modifiedDocument.uri;
|
||||
|
||||
if (modifiedUri.scheme !== 'git') {
|
||||
if (!isGitUri(modifiedUri)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1131,8 +1121,8 @@ export class CommandCenter {
|
||||
resourceStates = [resource];
|
||||
}
|
||||
|
||||
const scmResources = resourceStates
|
||||
.filter(s => s instanceof Resource && s.resourceGroupType === ResourceGroupType.WorkingTree) as Resource[];
|
||||
const scmResources = resourceStates.filter(s => s instanceof Resource
|
||||
&& (s.resourceGroupType === ResourceGroupType.WorkingTree || s.resourceGroupType === ResourceGroupType.Untracked)) as Resource[];
|
||||
|
||||
if (!scmResources.length) {
|
||||
return;
|
||||
@@ -1189,41 +1179,11 @@ export class CommandCenter {
|
||||
const untrackedResources = resources.filter(r => r.type === Status.UNTRACKED || r.type === Status.IGNORED);
|
||||
|
||||
if (untrackedResources.length === 0) {
|
||||
const message = resources.length === 1
|
||||
? localize('confirm discard all single', "Are you sure you want to discard changes in {0}?", path.basename(resources[0].resourceUri.fsPath))
|
||||
: localize('confirm discard all', "Are you sure you want to discard ALL changes in {0} files?\nThis is IRREVERSIBLE!\nYour current working set will be FOREVER LOST.", resources.length);
|
||||
const yes = resources.length === 1
|
||||
? localize('discardAll multiple', "Discard 1 File")
|
||||
: localize('discardAll', "Discard All {0} Files", resources.length);
|
||||
const pick = await window.showWarningMessage(message, { modal: true }, yes);
|
||||
|
||||
if (pick !== yes) {
|
||||
return;
|
||||
}
|
||||
|
||||
await repository.clean(resources.map(r => r.resourceUri));
|
||||
return;
|
||||
await this._cleanTrackedChanges(repository, resources);
|
||||
} else if (resources.length === 1) {
|
||||
const message = localize('confirm delete', "Are you sure you want to DELETE {0}?\nThis is IRREVERSIBLE!\nThis file will be FOREVER LOST.", path.basename(resources[0].resourceUri.fsPath));
|
||||
const yes = localize('delete file', "Delete file");
|
||||
const pick = await window.showWarningMessage(message, { modal: true }, yes);
|
||||
|
||||
if (pick !== yes) {
|
||||
return;
|
||||
}
|
||||
|
||||
await repository.clean(resources.map(r => r.resourceUri));
|
||||
await this._cleanUntrackedChange(repository, resources[0]);
|
||||
} else if (trackedResources.length === 0) {
|
||||
const message = localize('confirm delete multiple', "Are you sure you want to DELETE {0} files?", resources.length);
|
||||
const yes = localize('delete files', "Delete Files");
|
||||
const pick = await window.showWarningMessage(message, { modal: true }, yes);
|
||||
|
||||
if (pick !== yes) {
|
||||
return;
|
||||
}
|
||||
|
||||
await repository.clean(resources.map(r => r.resourceUri));
|
||||
|
||||
await this._cleanUntrackedChanges(repository, resources);
|
||||
} else { // resources.length > 1 && untrackedResources.length > 0 && trackedResources.length > 0
|
||||
const untrackedMessage = untrackedResources.length === 1
|
||||
? localize('there are untracked files single', "The following untracked file will be DELETED FROM DISK if discarded: {0}.", path.basename(untrackedResources[0].resourceUri.fsPath))
|
||||
@@ -1248,6 +1208,74 @@ export class CommandCenter {
|
||||
}
|
||||
}
|
||||
|
||||
@command('git.cleanAllTracked', { repository: true })
|
||||
async cleanAllTracked(repository: Repository): Promise<void> {
|
||||
const resources = repository.workingTreeGroup.resourceStates
|
||||
.filter(r => r.type !== Status.UNTRACKED && r.type !== Status.IGNORED);
|
||||
|
||||
if (resources.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
await this._cleanTrackedChanges(repository, resources);
|
||||
}
|
||||
|
||||
@command('git.cleanAllUntracked', { repository: true })
|
||||
async cleanAllUntracked(repository: Repository): Promise<void> {
|
||||
const resources = [...repository.workingTreeGroup.resourceStates, ...repository.untrackedGroup.resourceStates]
|
||||
.filter(r => r.type === Status.UNTRACKED || r.type === Status.IGNORED);
|
||||
|
||||
if (resources.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (resources.length === 1) {
|
||||
await this._cleanUntrackedChange(repository, resources[0]);
|
||||
} else {
|
||||
await this._cleanUntrackedChanges(repository, resources);
|
||||
}
|
||||
}
|
||||
|
||||
private async _cleanTrackedChanges(repository: Repository, resources: Resource[]): Promise<void> {
|
||||
const message = resources.length === 1
|
||||
? localize('confirm discard all single', "Are you sure you want to discard changes in {0}?", path.basename(resources[0].resourceUri.fsPath))
|
||||
: localize('confirm discard all', "Are you sure you want to discard ALL changes in {0} files?\nThis is IRREVERSIBLE!\nYour current working set will be FOREVER LOST.", resources.length);
|
||||
const yes = resources.length === 1
|
||||
? localize('discardAll multiple', "Discard 1 File")
|
||||
: localize('discardAll', "Discard All {0} Files", resources.length);
|
||||
const pick = await window.showWarningMessage(message, { modal: true }, yes);
|
||||
|
||||
if (pick !== yes) {
|
||||
return;
|
||||
}
|
||||
|
||||
await repository.clean(resources.map(r => r.resourceUri));
|
||||
}
|
||||
|
||||
private async _cleanUntrackedChange(repository: Repository, resource: Resource): Promise<void> {
|
||||
const message = localize('confirm delete', "Are you sure you want to DELETE {0}?\nThis is IRREVERSIBLE!\nThis file will be FOREVER LOST.", path.basename(resource.resourceUri.fsPath));
|
||||
const yes = localize('delete file', "Delete file");
|
||||
const pick = await window.showWarningMessage(message, { modal: true }, yes);
|
||||
|
||||
if (pick !== yes) {
|
||||
return;
|
||||
}
|
||||
|
||||
await repository.clean([resource.resourceUri]);
|
||||
}
|
||||
|
||||
private async _cleanUntrackedChanges(repository: Repository, resources: Resource[]): Promise<void> {
|
||||
const message = localize('confirm delete multiple', "Are you sure you want to DELETE {0} files?", resources.length);
|
||||
const yes = localize('delete files', "Delete Files");
|
||||
const pick = await window.showWarningMessage(message, { modal: true }, yes);
|
||||
|
||||
if (pick !== yes) {
|
||||
return;
|
||||
}
|
||||
|
||||
await repository.clean(resources.map(r => r.resourceUri));
|
||||
}
|
||||
|
||||
private async smartCommit(
|
||||
repository: Repository,
|
||||
getCommitMessage: () => Promise<string | undefined>,
|
||||
@@ -1271,7 +1299,7 @@ export class CommandCenter {
|
||||
|
||||
if (promptToSaveFilesBeforeCommit === 'staged' || repository.indexGroup.resourceStates.length > 0) {
|
||||
documents = documents
|
||||
.filter(d => repository.indexGroup.resourceStates.some(s => s.resourceUri.path === d.uri.fsPath));
|
||||
.filter(d => repository.indexGroup.resourceStates.some(s => pathEquals(s.resourceUri.fsPath, d.uri.fsPath)));
|
||||
}
|
||||
|
||||
if (documents.length > 0) {
|
||||
@@ -1356,6 +1384,10 @@ export class CommandCenter {
|
||||
opts.all = 'tracked';
|
||||
}
|
||||
|
||||
if (opts.all && config.get<'mixed' | 'separate' | 'hidden'>('untrackedChanges') !== 'mixed') {
|
||||
opts.all = 'tracked';
|
||||
}
|
||||
|
||||
await repository.commit(message, opts);
|
||||
|
||||
const postCommitCommand = config.get<'none' | 'push' | 'sync'>('postCommitCommand');
|
||||
@@ -1376,6 +1408,7 @@ export class CommandCenter {
|
||||
const message = repository.inputBox.value;
|
||||
const getCommitMessage = async () => {
|
||||
let _message: string | undefined = message;
|
||||
|
||||
if (!_message) {
|
||||
let value: string | undefined = undefined;
|
||||
|
||||
@@ -1400,7 +1433,7 @@ export class CommandCenter {
|
||||
});
|
||||
}
|
||||
|
||||
return _message ? repository.cleanUpCommitEditMessage(_message) : _message;
|
||||
return _message;
|
||||
};
|
||||
|
||||
const didCommit = await this.smartCommit(repository, getCommitMessage, opts);
|
||||
@@ -1485,7 +1518,7 @@ export class CommandCenter {
|
||||
|
||||
if (commit.parents.length > 1) {
|
||||
const yes = localize('undo commit', "Undo merge commit");
|
||||
const result = await window.showWarningMessage(localize('merge commit', "The last commit was a merge commit. Are you sure you want to undo it?"), yes);
|
||||
const result = await window.showWarningMessage(localize('merge commit', "The last commit was a merge commit. Are you sure you want to undo it?"), { modal: true }, yes);
|
||||
|
||||
if (result !== yes) {
|
||||
return;
|
||||
@@ -1705,6 +1738,26 @@ export class CommandCenter {
|
||||
await repository.tag(name, message);
|
||||
}
|
||||
|
||||
@command('git.deleteTag', { repository: true })
|
||||
async deleteTag(repository: Repository): Promise<void> {
|
||||
const picks = repository.refs.filter(ref => ref.type === RefType.Tag)
|
||||
.map(ref => new TagItem(ref));
|
||||
|
||||
if (picks.length === 0) {
|
||||
window.showWarningMessage(localize('no tags', "This repository has no tags."));
|
||||
return;
|
||||
}
|
||||
|
||||
const placeHolder = localize('select a tag to delete', 'Select a tag to delete');
|
||||
const choice = await window.showQuickPick(picks, { placeHolder });
|
||||
|
||||
if (!choice) {
|
||||
return;
|
||||
}
|
||||
|
||||
await repository.deleteTag(choice.label);
|
||||
}
|
||||
|
||||
@command('git.fetch', { repository: true })
|
||||
async fetch(repository: Repository): Promise<void> {
|
||||
if (repository.remotes.length === 0) {
|
||||
@@ -2073,9 +2126,14 @@ export class CommandCenter {
|
||||
return;
|
||||
}
|
||||
|
||||
const branchName = repository.HEAD && repository.HEAD.name || '';
|
||||
|
||||
if (remotes.length === 1) {
|
||||
return await repository.pushTo(remotes[0].name, branchName, true);
|
||||
}
|
||||
|
||||
const addRemote = new AddRemoteItem(this);
|
||||
const picks = [...repository.remotes.map(r => ({ label: r.name, description: r.pushUrl })), addRemote];
|
||||
const branchName = repository.HEAD && repository.HEAD.name || '';
|
||||
const placeHolder = localize('pick remote', "Pick a remote to publish the branch '{0}' to:", branchName);
|
||||
const choice = await window.showQuickPick(picks, { placeHolder });
|
||||
|
||||
@@ -2133,7 +2191,8 @@ export class CommandCenter {
|
||||
}
|
||||
|
||||
private async _stash(repository: Repository, includeUntracked = false): Promise<void> {
|
||||
const noUnstagedChanges = repository.workingTreeGroup.resourceStates.length === 0;
|
||||
const noUnstagedChanges = repository.workingTreeGroup.resourceStates.length === 0
|
||||
&& (!includeUntracked || repository.untrackedGroup.resourceStates.length === 0);
|
||||
const noStagedChanges = repository.indexGroup.resourceStates.length === 0;
|
||||
|
||||
if (noUnstagedChanges && noStagedChanges) {
|
||||
@@ -2215,6 +2274,18 @@ export class CommandCenter {
|
||||
await repository.applyStash();
|
||||
}
|
||||
|
||||
@command('git.stashDrop', { repository: true })
|
||||
async stashDrop(repository: Repository): Promise<void> {
|
||||
const placeHolder = localize('pick stash to drop', "Pick a stash to drop");
|
||||
const stash = await this.pickStash(repository, placeHolder);
|
||||
|
||||
if (!stash) {
|
||||
return;
|
||||
}
|
||||
|
||||
await repository.dropStash(stash.index);
|
||||
}
|
||||
|
||||
private async pickStash(repository: Repository, placeHolder: string): Promise<Stash | undefined> {
|
||||
const stashes = await repository.getStashes();
|
||||
|
||||
@@ -2352,7 +2423,7 @@ export class CommandCenter {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (uri.scheme === 'git') {
|
||||
if (isGitUri(uri)) {
|
||||
const { path } = fromGitUri(uri);
|
||||
uri = Uri.file(path);
|
||||
}
|
||||
|
||||
@@ -147,4 +147,4 @@ export class GitContentProvider {
|
||||
dispose(): void {
|
||||
this.disposables.forEach(d => d.dispose());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,6 +113,7 @@ class GitDecorationProvider implements DecorationProvider {
|
||||
|
||||
this.collectSubmoduleDecorationData(newDecorations);
|
||||
this.collectDecorationData(this.repository.indexGroup, newDecorations);
|
||||
this.collectDecorationData(this.repository.untrackedGroup, newDecorations);
|
||||
this.collectDecorationData(this.repository.workingTreeGroup, newDecorations);
|
||||
this.collectDecorationData(this.repository.mergeGroup, newDecorations);
|
||||
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
|
||||
import * as jschardet from 'jschardet';
|
||||
|
||||
jschardet.Constants.MINIMUM_THRESHOLD = 0.2;
|
||||
|
||||
function detectEncodingByBOM(buffer: Buffer): string | null {
|
||||
if (!buffer || buffer.length < 2) {
|
||||
return null;
|
||||
|
||||
@@ -0,0 +1,199 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { workspace, Uri, Disposable, Event, EventEmitter, window, FileSystemProvider, FileChangeEvent, FileStat, FileType, FileChangeType, FileSystemError } from 'vscode';
|
||||
import { debounce, throttle } from './decorators';
|
||||
import { fromGitUri, toGitUri } from './uri';
|
||||
import { Model, ModelChangeEvent, OriginalResourceChangeEvent } from './model';
|
||||
import { filterEvent, eventToPromise, isDescendant, pathEquals, EmptyDisposable } from './util';
|
||||
|
||||
interface CacheRow {
|
||||
uri: Uri;
|
||||
timestamp: number;
|
||||
}
|
||||
|
||||
const THREE_MINUTES = 1000 * 60 * 3;
|
||||
const FIVE_MINUTES = 1000 * 60 * 5;
|
||||
|
||||
export class GitFileSystemProvider implements FileSystemProvider {
|
||||
|
||||
private _onDidChangeFile = new EventEmitter<FileChangeEvent[]>();
|
||||
readonly onDidChangeFile: Event<FileChangeEvent[]> = this._onDidChangeFile.event;
|
||||
|
||||
private changedRepositoryRoots = new Set<string>();
|
||||
private cache = new Map<string, CacheRow>();
|
||||
private mtime = new Date().getTime();
|
||||
private disposables: Disposable[] = [];
|
||||
|
||||
constructor(private model: Model) {
|
||||
this.disposables.push(
|
||||
model.onDidChangeRepository(this.onDidChangeRepository, this),
|
||||
model.onDidChangeOriginalResource(this.onDidChangeOriginalResource, this),
|
||||
workspace.registerFileSystemProvider('gitfs', this, { isReadonly: true, isCaseSensitive: true }),
|
||||
workspace.registerResourceLabelFormatter({
|
||||
scheme: 'gitfs',
|
||||
formatting: {
|
||||
label: '${path} (git)',
|
||||
separator: '/'
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
setInterval(() => this.cleanup(), FIVE_MINUTES);
|
||||
}
|
||||
|
||||
private onDidChangeRepository({ repository }: ModelChangeEvent): void {
|
||||
this.changedRepositoryRoots.add(repository.root);
|
||||
this.eventuallyFireChangeEvents();
|
||||
}
|
||||
|
||||
private onDidChangeOriginalResource({ uri }: OriginalResourceChangeEvent): void {
|
||||
if (uri.scheme !== 'file') {
|
||||
return;
|
||||
}
|
||||
|
||||
const gitUri = toGitUri(uri, '', { replaceFileExtension: true });
|
||||
this.mtime = new Date().getTime();
|
||||
this._onDidChangeFile.fire([{ type: FileChangeType.Changed, uri: gitUri }]);
|
||||
}
|
||||
|
||||
@debounce(1100)
|
||||
private eventuallyFireChangeEvents(): void {
|
||||
this.fireChangeEvents();
|
||||
}
|
||||
|
||||
@throttle
|
||||
private async fireChangeEvents(): Promise<void> {
|
||||
if (!window.state.focused) {
|
||||
const onDidFocusWindow = filterEvent(window.onDidChangeWindowState, e => e.focused);
|
||||
await eventToPromise(onDidFocusWindow);
|
||||
}
|
||||
|
||||
const events: FileChangeEvent[] = [];
|
||||
|
||||
for (const { uri } of this.cache.values()) {
|
||||
const fsPath = uri.fsPath;
|
||||
|
||||
for (const root of this.changedRepositoryRoots) {
|
||||
if (isDescendant(root, fsPath)) {
|
||||
events.push({ type: FileChangeType.Changed, uri });
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (events.length > 0) {
|
||||
this.mtime = new Date().getTime();
|
||||
this._onDidChangeFile.fire(events);
|
||||
}
|
||||
|
||||
this.changedRepositoryRoots.clear();
|
||||
}
|
||||
|
||||
private cleanup(): void {
|
||||
const now = new Date().getTime();
|
||||
const cache = new Map<string, CacheRow>();
|
||||
|
||||
for (const row of this.cache.values()) {
|
||||
const { path } = fromGitUri(row.uri);
|
||||
const isOpen = workspace.textDocuments
|
||||
.filter(d => d.uri.scheme === 'file')
|
||||
.some(d => pathEquals(d.uri.fsPath, path));
|
||||
|
||||
if (isOpen || now - row.timestamp < THREE_MINUTES) {
|
||||
cache.set(row.uri.toString(), row);
|
||||
} else {
|
||||
// TODO: should fire delete events?
|
||||
}
|
||||
}
|
||||
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
watch(): Disposable {
|
||||
return EmptyDisposable;
|
||||
}
|
||||
|
||||
stat(uri: Uri): FileStat {
|
||||
const { submoduleOf } = fromGitUri(uri);
|
||||
const repository = submoduleOf ? this.model.getRepository(submoduleOf) : this.model.getRepository(uri);
|
||||
|
||||
if (!repository) {
|
||||
throw FileSystemError.FileNotFound();
|
||||
}
|
||||
|
||||
return { type: FileType.File, size: 0, mtime: this.mtime, ctime: 0 };
|
||||
}
|
||||
|
||||
readDirectory(): Thenable<[string, FileType][]> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
createDirectory(): void {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
async readFile(uri: Uri): Promise<Uint8Array> {
|
||||
let { path, ref, submoduleOf } = fromGitUri(uri);
|
||||
|
||||
if (submoduleOf) {
|
||||
const repository = this.model.getRepository(submoduleOf);
|
||||
|
||||
if (!repository) {
|
||||
throw FileSystemError.FileNotFound();
|
||||
}
|
||||
|
||||
const encoder = new TextEncoder();
|
||||
|
||||
if (ref === 'index') {
|
||||
return encoder.encode(await repository.diffIndexWithHEAD(path));
|
||||
} else {
|
||||
return encoder.encode(await repository.diffWithHEAD(path));
|
||||
}
|
||||
}
|
||||
|
||||
const repository = this.model.getRepository(uri);
|
||||
|
||||
if (!repository) {
|
||||
throw FileSystemError.FileNotFound();
|
||||
}
|
||||
|
||||
const timestamp = new Date().getTime();
|
||||
const cacheValue: CacheRow = { uri, timestamp };
|
||||
|
||||
this.cache.set(uri.toString(), cacheValue);
|
||||
|
||||
if (ref === '~') {
|
||||
const fileUri = Uri.file(path);
|
||||
const uriString = fileUri.toString();
|
||||
const [indexStatus] = repository.indexGroup.resourceStates.filter(r => r.resourceUri.toString() === uriString);
|
||||
ref = indexStatus ? '' : 'HEAD';
|
||||
} else if (/^~\d$/.test(ref)) {
|
||||
ref = `:${ref[1]}`;
|
||||
}
|
||||
|
||||
try {
|
||||
return await repository.buffer(ref, path);
|
||||
} catch (err) {
|
||||
return new Uint8Array(0);
|
||||
}
|
||||
}
|
||||
|
||||
writeFile(): void {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
delete(): void {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
rename(): void {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this.disposables.forEach(d => d.dispose());
|
||||
}
|
||||
}
|
||||
+50
-29
@@ -3,7 +3,7 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as fs from 'fs';
|
||||
import { promises as fs, exists } from 'fs';
|
||||
import * as path from 'path';
|
||||
import * as os from 'os';
|
||||
import * as cp from 'child_process';
|
||||
@@ -11,7 +11,7 @@ import * as which from 'which';
|
||||
import { EventEmitter } from 'events';
|
||||
import iconv = require('iconv-lite');
|
||||
import * as filetype from 'file-type';
|
||||
import { assign, groupBy, denodeify, IDisposable, toDisposable, dispose, mkdirp, readBytes, detectUnicodeEncoding, Encoding, onceEvent, splitInChunks, Limiter } from './util';
|
||||
import { assign, groupBy, IDisposable, toDisposable, dispose, mkdirp, readBytes, detectUnicodeEncoding, Encoding, onceEvent, splitInChunks, Limiter } from './util';
|
||||
import { CancellationToken, Progress } from 'vscode';
|
||||
import { URI } from 'vscode-uri';
|
||||
import { detectEncoding } from './encoding';
|
||||
@@ -22,8 +22,6 @@ import { StringDecoder } from 'string_decoder';
|
||||
// https://github.com/microsoft/vscode/issues/65693
|
||||
const MAX_CLI_LENGTH = 30000;
|
||||
|
||||
const readfile = denodeify<string, string | null, string>(fs.readFile);
|
||||
|
||||
export interface IGit {
|
||||
path: string;
|
||||
version: string;
|
||||
@@ -196,13 +194,13 @@ async function exec(child: cp.ChildProcess, cancellationToken?: CancellationToke
|
||||
}),
|
||||
new Promise<Buffer>(c => {
|
||||
const buffers: Buffer[] = [];
|
||||
on(child.stdout, 'data', (b: Buffer) => buffers.push(b));
|
||||
once(child.stdout, 'close', () => c(Buffer.concat(buffers)));
|
||||
on(child.stdout!, 'data', (b: Buffer) => buffers.push(b));
|
||||
once(child.stdout!, 'close', () => c(Buffer.concat(buffers)));
|
||||
}),
|
||||
new Promise<string>(c => {
|
||||
const buffers: Buffer[] = [];
|
||||
on(child.stderr, 'data', (b: Buffer) => buffers.push(b));
|
||||
once(child.stderr, 'close', () => c(Buffer.concat(buffers).toString('utf8')));
|
||||
on(child.stderr!, 'data', (b: Buffer) => buffers.push(b));
|
||||
once(child.stderr!, 'close', () => c(Buffer.concat(buffers).toString('utf8')));
|
||||
})
|
||||
]) as Promise<[number, Buffer, string]>;
|
||||
|
||||
@@ -350,7 +348,7 @@ export class Git {
|
||||
let folderPath = path.join(parentPath, folderName);
|
||||
let count = 1;
|
||||
|
||||
while (count < 20 && await new Promise(c => fs.exists(folderPath, c))) {
|
||||
while (count < 20 && await new Promise(c => exists(folderPath, c))) {
|
||||
folderName = `${baseFolderName}-${count++}`;
|
||||
folderPath = path.join(parentPath, folderName);
|
||||
}
|
||||
@@ -360,7 +358,7 @@ export class Git {
|
||||
const onSpawn = (child: cp.ChildProcess) => {
|
||||
const decoder = new StringDecoder('utf8');
|
||||
const lineStream = new byline.LineStream({ encoding: 'utf8' });
|
||||
child.stderr.on('data', (buffer: Buffer) => lineStream.write(decoder.write(buffer)));
|
||||
child.stderr!.on('data', (buffer: Buffer) => lineStream.write(decoder.write(buffer)));
|
||||
|
||||
let totalProgress = 0;
|
||||
let previousProgress = 0;
|
||||
@@ -438,7 +436,7 @@ export class Git {
|
||||
}
|
||||
|
||||
if (options.input) {
|
||||
child.stdin.end(options.input, 'utf8');
|
||||
child.stdin!.end(options.input, 'utf8');
|
||||
}
|
||||
|
||||
const bufferResult = await exec(child, options.cancellationToken);
|
||||
@@ -763,9 +761,10 @@ export class Repository {
|
||||
async log(options?: LogOptions): Promise<Commit[]> {
|
||||
const maxEntries = options && typeof options.maxEntries === 'number' && options.maxEntries > 0 ? options.maxEntries : 32;
|
||||
const args = ['log', '-' + maxEntries, `--pretty=format:${COMMIT_FORMAT}%x00%x00`];
|
||||
|
||||
const gitResult = await this.run(args);
|
||||
if (gitResult.exitCode) {
|
||||
// An empty repo.
|
||||
// An empty repo
|
||||
return [];
|
||||
}
|
||||
|
||||
@@ -882,7 +881,7 @@ export class Repository {
|
||||
|
||||
async detectObjectType(object: string): Promise<{ mimetype: string, encoding?: string }> {
|
||||
const child = await this.stream(['show', object]);
|
||||
const buffer = await readBytes(child.stdout, 4100);
|
||||
const buffer = await readBytes(child.stdout!, 4100);
|
||||
|
||||
try {
|
||||
child.kill();
|
||||
@@ -1151,7 +1150,7 @@ export class Repository {
|
||||
|
||||
async stage(path: string, data: string): Promise<void> {
|
||||
const child = this.stream(['hash-object', '--stdin', '-w', '--path', path], { stdio: [null, null, null] });
|
||||
child.stdin.end(data, 'utf8');
|
||||
child.stdin!.end(data, 'utf8');
|
||||
|
||||
const { exitCode, stdout } = await exec(child);
|
||||
const hash = stdout.toString('utf8');
|
||||
@@ -1163,11 +1162,12 @@ export class Repository {
|
||||
});
|
||||
}
|
||||
|
||||
const treeish = await this.getCommit('HEAD').then(() => 'HEAD', () => '');
|
||||
let mode: string;
|
||||
let add: string = '';
|
||||
|
||||
try {
|
||||
const details = await this.getObjectDetails('HEAD', path);
|
||||
const details = await this.getObjectDetails(treeish, path);
|
||||
mode = details.mode;
|
||||
} catch (err) {
|
||||
if (err.gitErrorCode !== GitErrorCodes.UnknownPath) {
|
||||
@@ -1327,6 +1327,11 @@ export class Repository {
|
||||
await this.run(args);
|
||||
}
|
||||
|
||||
async deleteTag(name: string): Promise<void> {
|
||||
let args = ['tag', '-d', name];
|
||||
await this.run(args);
|
||||
}
|
||||
|
||||
async clean(paths: string[]): Promise<void> {
|
||||
const pathsByGroup = groupBy(paths, p => path.dirname(p));
|
||||
const groups = Object.keys(pathsByGroup).map(k => pathsByGroup[k]);
|
||||
@@ -1592,6 +1597,24 @@ export class Repository {
|
||||
}
|
||||
}
|
||||
|
||||
async dropStash(index?: number): Promise<void> {
|
||||
const args = ['stash', 'drop'];
|
||||
|
||||
if (typeof index === 'number') {
|
||||
args.push(`stash@{${index}}`);
|
||||
}
|
||||
|
||||
try {
|
||||
await this.run(args);
|
||||
} catch (err) {
|
||||
if (/No stash found/.test(err.stderr || '')) {
|
||||
err.gitErrorCode = GitErrorCodes.NoStashFound;
|
||||
}
|
||||
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
getStatus(limit = 5000): Promise<{ status: IFileStatus[]; didHitLimit: boolean; }> {
|
||||
return new Promise<{ status: IFileStatus[]; didHitLimit: boolean; }>((c, e) => {
|
||||
const parser = new GitStatusParser();
|
||||
@@ -1618,19 +1641,19 @@ export class Repository {
|
||||
|
||||
if (parser.status.length > limit) {
|
||||
child.removeListener('exit', onExit);
|
||||
child.stdout.removeListener('data', onStdoutData);
|
||||
child.stdout!.removeListener('data', onStdoutData);
|
||||
child.kill();
|
||||
|
||||
c({ status: parser.status.slice(0, limit), didHitLimit: true });
|
||||
}
|
||||
};
|
||||
|
||||
child.stdout.setEncoding('utf8');
|
||||
child.stdout.on('data', onStdoutData);
|
||||
child.stdout!.setEncoding('utf8');
|
||||
child.stdout!.on('data', onStdoutData);
|
||||
|
||||
const stderrData: string[] = [];
|
||||
child.stderr.setEncoding('utf8');
|
||||
child.stderr.on('data', raw => stderrData.push(raw as string));
|
||||
child.stderr!.setEncoding('utf8');
|
||||
child.stderr!.on('data', raw => stderrData.push(raw as string));
|
||||
|
||||
child.on('error', cpErrorHandler(e));
|
||||
child.on('exit', onExit);
|
||||
@@ -1789,18 +1812,17 @@ export class Repository {
|
||||
}
|
||||
}
|
||||
|
||||
cleanupCommitEditMessage(message: string): string {
|
||||
//TODO: Support core.commentChar
|
||||
// TODO: Support core.commentChar
|
||||
stripCommitMessageComments(message: string): string {
|
||||
return message.replace(/^\s*#.*$\n?/gm, '').trim();
|
||||
}
|
||||
|
||||
|
||||
async getMergeMessage(): Promise<string | undefined> {
|
||||
const mergeMsgPath = path.join(this.repositoryRoot, '.git', 'MERGE_MSG');
|
||||
|
||||
try {
|
||||
const raw = await readfile(mergeMsgPath, 'utf8');
|
||||
return raw.trim();
|
||||
const raw = await fs.readFile(mergeMsgPath, 'utf8');
|
||||
return this.stripCommitMessageComments(raw);
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
@@ -1823,9 +1845,8 @@ export class Repository {
|
||||
templatePath = path.join(this.repositoryRoot, templatePath);
|
||||
}
|
||||
|
||||
const raw = await readfile(templatePath, 'utf8');
|
||||
return raw.trim();
|
||||
|
||||
const raw = await fs.readFile(templatePath, 'utf8');
|
||||
return this.stripCommitMessageComments(raw);
|
||||
} catch (err) {
|
||||
return '';
|
||||
}
|
||||
@@ -1848,7 +1869,7 @@ export class Repository {
|
||||
const gitmodulesPath = path.join(this.root, '.gitmodules');
|
||||
|
||||
try {
|
||||
const gitmodulesRaw = await readfile(gitmodulesPath, 'utf8');
|
||||
const gitmodulesRaw = await fs.readFile(gitmodulesPath, 'utf8');
|
||||
return parseGitmodules(gitmodulesRaw);
|
||||
} catch (err) {
|
||||
if (/ENOENT/.test(err.message)) {
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as http from 'http';
|
||||
|
||||
export class IPCClient {
|
||||
|
||||
private ipcHandlePath: string;
|
||||
|
||||
constructor(private handlerName: string) {
|
||||
const ipcHandlePath = process.env['VSCODE_GIT_IPC_HANDLE'];
|
||||
|
||||
if (!ipcHandlePath) {
|
||||
throw new Error('Missing VSCODE_GIT_IPC_HANDLE');
|
||||
}
|
||||
|
||||
this.ipcHandlePath = ipcHandlePath;
|
||||
}
|
||||
|
||||
call(request: any): Promise<any> {
|
||||
const opts: http.RequestOptions = {
|
||||
socketPath: this.ipcHandlePath,
|
||||
path: `/${this.handlerName}`,
|
||||
method: 'POST'
|
||||
};
|
||||
|
||||
return new Promise((c, e) => {
|
||||
const req = http.request(opts, res => {
|
||||
if (res.statusCode !== 200) {
|
||||
return e(new Error(`Bad status code: ${res.statusCode}`));
|
||||
}
|
||||
|
||||
const chunks: Buffer[] = [];
|
||||
res.on('data', d => chunks.push(d));
|
||||
res.on('end', () => c(JSON.parse(Buffer.concat(chunks).toString('utf8'))));
|
||||
});
|
||||
|
||||
req.on('error', err => e(err));
|
||||
req.write(JSON.stringify(request));
|
||||
req.end();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Disposable } from 'vscode';
|
||||
import { toDisposable } from '../util';
|
||||
import * as path from 'path';
|
||||
import * as http from 'http';
|
||||
import * as os from 'os';
|
||||
import * as fs from 'fs';
|
||||
import * as crypto from 'crypto';
|
||||
|
||||
function getIPCHandlePath(nonce: string): string {
|
||||
if (process.platform === 'win32') {
|
||||
return `\\\\.\\pipe\\vscode-git-ipc-${nonce}-sock`;
|
||||
}
|
||||
|
||||
if (process.env['XDG_RUNTIME_DIR']) {
|
||||
return path.join(process.env['XDG_RUNTIME_DIR'] as string, `vscode-git-ipc-${nonce}.sock`);
|
||||
}
|
||||
|
||||
return path.join(os.tmpdir(), `vscode-git-ipc-${nonce}.sock`);
|
||||
}
|
||||
|
||||
export interface IIPCHandler {
|
||||
handle(request: any): Promise<any>;
|
||||
}
|
||||
|
||||
export async function createIPCServer(): Promise<IIPCServer> {
|
||||
const server = http.createServer();
|
||||
const buffer = await new Promise<Buffer>((c, e) => crypto.randomBytes(20, (err, buf) => err ? e(err) : c(buf)));
|
||||
const nonce = buffer.toString('hex');
|
||||
const ipcHandlePath = getIPCHandlePath(nonce);
|
||||
|
||||
return new Promise((c, e) => {
|
||||
try {
|
||||
server.on('error', err => e(err));
|
||||
server.listen(ipcHandlePath);
|
||||
c(new IPCServer(server, ipcHandlePath));
|
||||
} catch (err) {
|
||||
e(err);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export interface IIPCServer extends Disposable {
|
||||
readonly ipcHandlePath: string | undefined;
|
||||
getEnv(): any;
|
||||
registerHandler(name: string, handler: IIPCHandler): Disposable;
|
||||
}
|
||||
|
||||
class IPCServer implements IIPCServer, Disposable {
|
||||
|
||||
private handlers = new Map<string, IIPCHandler>();
|
||||
get ipcHandlePath(): string { return this._ipcHandlePath; }
|
||||
|
||||
constructor(private server: http.Server, private _ipcHandlePath: string) {
|
||||
this.server.on('request', this.onRequest.bind(this));
|
||||
}
|
||||
|
||||
registerHandler(name: string, handler: IIPCHandler): Disposable {
|
||||
this.handlers.set(`/${name}`, handler);
|
||||
return toDisposable(() => this.handlers.delete(name));
|
||||
}
|
||||
|
||||
private onRequest(req: http.IncomingMessage, res: http.ServerResponse): void {
|
||||
if (!req.url) {
|
||||
console.warn(`Request lacks url`);
|
||||
return;
|
||||
}
|
||||
|
||||
const handler = this.handlers.get(req.url);
|
||||
|
||||
if (!handler) {
|
||||
console.warn(`IPC handler for ${req.url} not found`);
|
||||
return;
|
||||
}
|
||||
|
||||
const chunks: Buffer[] = [];
|
||||
req.on('data', d => chunks.push(d));
|
||||
req.on('end', () => {
|
||||
const request = JSON.parse(Buffer.concat(chunks).toString('utf8'));
|
||||
handler.handle(request).then(result => {
|
||||
res.writeHead(200);
|
||||
res.end(JSON.stringify(result));
|
||||
}, () => {
|
||||
res.writeHead(500);
|
||||
res.end();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
getEnv(): any {
|
||||
return { VSCODE_GIT_IPC_HANDLE: this.ipcHandlePath };
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this.handlers.clear();
|
||||
this.server.close();
|
||||
|
||||
if (this._ipcHandlePath && process.platform !== 'win32') {
|
||||
fs.unlinkSync(this._ipcHandlePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import { findGit, Git, IGit } from './git';
|
||||
import { Model } from './model';
|
||||
import { CommandCenter } from './commands';
|
||||
import { GitContentProvider } from './contentProvider';
|
||||
import { GitFileSystemProvider } from './fileSystemProvider';
|
||||
import { GitDecorations } from './decorationProvider';
|
||||
import { Askpass } from './askpass';
|
||||
import { toDisposable, filterEvent, eventToPromise } from './util';
|
||||
@@ -18,9 +19,9 @@ import TelemetryReporter from 'vscode-extension-telemetry';
|
||||
import { GitExtension } from './api/git';
|
||||
import { GitProtocolHandler } from './protocolHandler';
|
||||
import { GitExtensionImpl } from './api/extension';
|
||||
// {{SQL CARBON EDIT}} - remove unused imports
|
||||
// import * as path from 'path';
|
||||
// import * as fs from 'fs';
|
||||
import { createIPCServer, IIPCServer } from './ipc/ipcServer';
|
||||
|
||||
const deactivateTasks: { (): Promise<any>; }[] = [];
|
||||
|
||||
@@ -33,10 +34,26 @@ export async function deactivate(): Promise<any> {
|
||||
async function createModel(context: ExtensionContext, outputChannel: OutputChannel, telemetryReporter: TelemetryReporter, disposables: Disposable[]): Promise<Model> {
|
||||
const pathHint = workspace.getConfiguration('git').get<string>('path');
|
||||
const info = await findGit(pathHint, path => outputChannel.appendLine(localize('looking', "Looking for git in: {0}", path)));
|
||||
const askpass = new Askpass();
|
||||
disposables.push(askpass);
|
||||
|
||||
const env = await askpass.getEnv();
|
||||
let env: any = {};
|
||||
let ipc: IIPCServer | undefined;
|
||||
|
||||
try {
|
||||
ipc = await createIPCServer();
|
||||
disposables.push(ipc);
|
||||
env = { ...env, ...ipc.getEnv() };
|
||||
} catch {
|
||||
// noop
|
||||
}
|
||||
|
||||
if (ipc) {
|
||||
const askpass = new Askpass(ipc);
|
||||
disposables.push(askpass);
|
||||
env = { ...env, ...askpass.getEnv() };
|
||||
} else {
|
||||
env = { ...env, ...Askpass.getDisabledEnv() };
|
||||
}
|
||||
|
||||
const git = new Git({ gitPath: info.path, version: info.version, env });
|
||||
const model = new Model(git, context.globalState, outputChannel);
|
||||
disposables.push(model);
|
||||
@@ -63,6 +80,7 @@ async function createModel(context: ExtensionContext, outputChannel: OutputChann
|
||||
disposables.push(
|
||||
new CommandCenter(git, model, outputChannel, telemetryReporter),
|
||||
new GitContentProvider(model),
|
||||
new GitFileSystemProvider(model),
|
||||
new GitDecorations(model),
|
||||
new GitProtocolHandler()
|
||||
);
|
||||
@@ -198,4 +216,4 @@ async function checkGitVersion(_info: IGit): Promise<void> {
|
||||
// await config.update('ignoreLegacyWarning', true, true);
|
||||
// }
|
||||
// {{SQL CARBON EDIT}} - End
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import { workspace, WorkspaceFoldersChangeEvent, Uri, window, Event, EventEmitter, QuickPickItem, Disposable, SourceControl, SourceControlResourceGroup, TextEditor, Memento, OutputChannel } from 'vscode';
|
||||
import { Repository, RepositoryState } from './repository';
|
||||
import { memoize, sequentialize, debounce } from './decorators';
|
||||
import { dispose, anyEvent, filterEvent, isDescendant, firstIndex } from './util';
|
||||
import { dispose, anyEvent, filterEvent, isDescendant, firstIndex, pathEquals } from './util';
|
||||
import { Git } from './git';
|
||||
import * as path from 'path';
|
||||
import * as fs from 'fs';
|
||||
@@ -240,10 +240,7 @@ export class Model {
|
||||
return;
|
||||
}
|
||||
|
||||
const config = workspace.getConfiguration('git');
|
||||
const ignoredRepos = new Set(config.get<Array<string>>('ignoredRepositories'));
|
||||
|
||||
if (ignoredRepos.has(rawRoot)) {
|
||||
if (this.shouldRepositoryBeIgnored(rawRoot)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -261,6 +258,27 @@ export class Model {
|
||||
}
|
||||
}
|
||||
|
||||
private shouldRepositoryBeIgnored(repositoryRoot: string): boolean {
|
||||
const config = workspace.getConfiguration('git');
|
||||
const ignoredRepos = config.get<string[]>('ignoredRepositories') || [];
|
||||
|
||||
for (const ignoredRepo of ignoredRepos) {
|
||||
if (path.isAbsolute(ignoredRepo)) {
|
||||
if (pathEquals(ignoredRepo, repositoryRoot)) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
for (const folder of workspace.workspaceFolders || []) {
|
||||
if (pathEquals(path.join(folder.uri.fsPath, ignoredRepo), repositoryRoot)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private open(repository: Repository): void {
|
||||
this.outputChannel.appendLine(`Open repository: ${repository.root}`);
|
||||
|
||||
|
||||
@@ -3,17 +3,17 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Uri, Command, EventEmitter, Event, scm, SourceControl, SourceControlInputBox, SourceControlResourceGroup, SourceControlResourceState, SourceControlResourceDecorations, SourceControlInputBoxValidation, Disposable, ProgressLocation, window, workspace, WorkspaceEdit, ThemeColor, Decoration, Memento, SourceControlInputBoxValidationType, OutputChannel, LogLevel, env, ProgressOptions, CancellationToken } from 'vscode';
|
||||
import { Repository as BaseRepository, Commit, Stash, GitError, Submodule, CommitOptions, ForcePushMode } from './git';
|
||||
import { anyEvent, filterEvent, eventToPromise, dispose, find, isDescendant, IDisposable, onceEvent, EmptyDisposable, debounceEvent, combinedDisposable } from './util';
|
||||
import { memoize, throttle, debounce } from './decorators';
|
||||
import { toGitUri } from './uri';
|
||||
import { AutoFetcher } from './autofetch';
|
||||
import * as path from 'path';
|
||||
import * as nls from 'vscode-nls';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import { CancellationToken, Command, Disposable, env, Event, EventEmitter, LogLevel, Memento, OutputChannel, ProgressLocation, ProgressOptions, scm, SourceControl, SourceControlInputBox, SourceControlInputBoxValidation, SourceControlInputBoxValidationType, SourceControlResourceDecorations, SourceControlResourceGroup, SourceControlResourceState, ThemeColor, Uri, window, workspace, WorkspaceEdit, Decoration } from 'vscode';
|
||||
import * as nls from 'vscode-nls';
|
||||
import { Branch, Change, GitErrorCodes, LogOptions, Ref, RefType, Remote, Status } from './api/git';
|
||||
import { AutoFetcher } from './autofetch';
|
||||
import { debounce, memoize, throttle } from './decorators';
|
||||
import { Commit, CommitOptions, ForcePushMode, GitError, Repository as BaseRepository, Stash, Submodule } from './git';
|
||||
import { StatusBarCommands } from './statusbar';
|
||||
import { Branch, Ref, Remote, RefType, GitErrorCodes, Status, LogOptions, Change } from './api/git';
|
||||
import { toGitUri } from './uri';
|
||||
import { anyEvent, combinedDisposable, debounceEvent, dispose, EmptyDisposable, eventToPromise, filterEvent, find, IDisposable, isDescendant, onceEvent } from './util';
|
||||
import { IFileWatcher, watch } from './watch';
|
||||
|
||||
const timeout = (millis: number) => new Promise(c => setTimeout(c, millis));
|
||||
@@ -33,7 +33,8 @@ export const enum RepositoryState {
|
||||
export const enum ResourceGroupType {
|
||||
Merge,
|
||||
Index,
|
||||
WorkingTree
|
||||
WorkingTree,
|
||||
Untracked
|
||||
}
|
||||
|
||||
export class Resource implements SourceControlResourceState {
|
||||
@@ -292,6 +293,7 @@ export const enum Operation {
|
||||
Merge = 'Merge',
|
||||
Ignore = 'Ignore',
|
||||
Tag = 'Tag',
|
||||
DeleteTag = 'DeleteTag',
|
||||
Stash = 'Stash',
|
||||
CheckIgnore = 'CheckIgnore',
|
||||
GetObjectDetails = 'GetObjectDetails',
|
||||
@@ -569,6 +571,9 @@ export class Repository implements Disposable {
|
||||
private _workingTreeGroup: SourceControlResourceGroup;
|
||||
get workingTreeGroup(): GitResourceGroup { return this._workingTreeGroup as GitResourceGroup; }
|
||||
|
||||
private _untrackedGroup: SourceControlResourceGroup;
|
||||
get untrackedGroup(): GitResourceGroup { return this._untrackedGroup as GitResourceGroup; }
|
||||
|
||||
private _HEAD: Branch | undefined;
|
||||
get HEAD(): Branch | undefined {
|
||||
return this._HEAD;
|
||||
@@ -641,6 +646,7 @@ export class Repository implements Disposable {
|
||||
this.mergeGroup.resourceStates = [];
|
||||
this.indexGroup.resourceStates = [];
|
||||
this.workingTreeGroup.resourceStates = [];
|
||||
this.untrackedGroup.resourceStates = [];
|
||||
this._sourceControl.count = 0;
|
||||
}
|
||||
|
||||
@@ -708,6 +714,7 @@ export class Repository implements Disposable {
|
||||
this._mergeGroup = this._sourceControl.createResourceGroup('merge', localize('merge changes', "MERGE CHANGES"));
|
||||
this._indexGroup = this._sourceControl.createResourceGroup('index', localize('staged changes', "STAGED CHANGES"));
|
||||
this._workingTreeGroup = this._sourceControl.createResourceGroup('workingTree', localize('changes', "CHANGES"));
|
||||
this._untrackedGroup = this._sourceControl.createResourceGroup('untracked', localize('untracked changes', "UNTRACKED CHANGES"));
|
||||
|
||||
const updateIndexGroupVisibility = () => {
|
||||
const config = workspace.getConfiguration('git', root);
|
||||
@@ -721,11 +728,16 @@ export class Repository implements Disposable {
|
||||
const onConfigListenerForBranchSortOrder = filterEvent(workspace.onDidChangeConfiguration, e => e.affectsConfiguration('git.branchSortOrder', root));
|
||||
onConfigListenerForBranchSortOrder(this.updateModelState, this, this.disposables);
|
||||
|
||||
const onConfigListenerForUntracked = filterEvent(workspace.onDidChangeConfiguration, e => e.affectsConfiguration('git.untrackedChanges', root));
|
||||
onConfigListenerForUntracked(this.updateModelState, this, this.disposables);
|
||||
|
||||
this.mergeGroup.hideWhenEmpty = true;
|
||||
this.untrackedGroup.hideWhenEmpty = true;
|
||||
|
||||
this.disposables.push(this.mergeGroup);
|
||||
this.disposables.push(this.indexGroup);
|
||||
this.disposables.push(this.workingTreeGroup);
|
||||
this.disposables.push(this.untrackedGroup);
|
||||
|
||||
this.disposables.push(new AutoFetcher(this, globalState));
|
||||
|
||||
@@ -911,8 +923,8 @@ export class Repository implements Disposable {
|
||||
return this.run(Operation.HashObject, () => this.repository.hashObject(data));
|
||||
}
|
||||
|
||||
async add(resources: Uri[]): Promise<void> {
|
||||
await this.run(Operation.Add, () => this.repository.add(resources.map(r => r.fsPath)));
|
||||
async add(resources: Uri[], opts?: { update?: boolean }): Promise<void> {
|
||||
await this.run(Operation.Add, () => this.repository.add(resources.map(r => r.fsPath), opts));
|
||||
}
|
||||
|
||||
async rm(resources: Uri[]): Promise<void> {
|
||||
@@ -957,6 +969,7 @@ export class Repository implements Disposable {
|
||||
const toClean: string[] = [];
|
||||
const toCheckout: string[] = [];
|
||||
const submodulesToUpdate: string[] = [];
|
||||
const resourceStates = [...this.workingTreeGroup.resourceStates, ...this.untrackedGroup.resourceStates];
|
||||
|
||||
resources.forEach(r => {
|
||||
const fsPath = r.fsPath;
|
||||
@@ -969,7 +982,7 @@ export class Repository implements Disposable {
|
||||
}
|
||||
|
||||
const raw = r.toString();
|
||||
const scmResource = find(this.workingTreeGroup.resourceStates, sr => sr.resourceUri.toString() === raw);
|
||||
const scmResource = find(resourceStates, sr => sr.resourceUri.toString() === raw);
|
||||
|
||||
if (!scmResource) {
|
||||
return;
|
||||
@@ -1021,6 +1034,10 @@ export class Repository implements Disposable {
|
||||
await this.run(Operation.Tag, () => this.repository.tag(name, message));
|
||||
}
|
||||
|
||||
async deleteTag(name: string): Promise<void> {
|
||||
await this.run(Operation.DeleteTag, () => this.repository.deleteTag(name));
|
||||
}
|
||||
|
||||
async checkout(treeish: string): Promise<void> {
|
||||
await this.run(Operation.Checkout, () => this.repository.checkout(treeish, []));
|
||||
}
|
||||
@@ -1249,6 +1266,10 @@ export class Repository implements Disposable {
|
||||
return await this.run(Operation.Stash, () => this.repository.popStash(index));
|
||||
}
|
||||
|
||||
async dropStash(index?: number): Promise<void> {
|
||||
return await this.run(Operation.Stash, () => this.repository.dropStash(index));
|
||||
}
|
||||
|
||||
async applyStash(index?: number): Promise<void> {
|
||||
return await this.run(Operation.Stash, () => this.repository.applyStash(index));
|
||||
}
|
||||
@@ -1257,10 +1278,6 @@ export class Repository implements Disposable {
|
||||
return await this.run(Operation.GetCommitTemplate, async () => this.repository.getCommitTemplate());
|
||||
}
|
||||
|
||||
async cleanUpCommitEditMessage(editMessage: string): Promise<string> {
|
||||
return this.repository.cleanupCommitEditMessage(editMessage);
|
||||
}
|
||||
|
||||
async ignore(files: Uri[]): Promise<void> {
|
||||
return await this.run(Operation.Ignore, async () => {
|
||||
const ignoreFile = `${this.repository.root}${path.sep}.gitignore`;
|
||||
@@ -1298,7 +1315,7 @@ export class Repository implements Disposable {
|
||||
|
||||
// https://git-scm.com/docs/git-check-ignore#git-check-ignore--z
|
||||
const child = this.repository.stream(['check-ignore', '-v', '-z', '--stdin'], { stdio: [null, null, null] });
|
||||
child.stdin.end(filePaths.join('\0'), 'utf8');
|
||||
child.stdin!.end(filePaths.join('\0'), 'utf8');
|
||||
|
||||
const onExit = (exitCode: number) => {
|
||||
if (exitCode === 1) {
|
||||
@@ -1320,12 +1337,12 @@ export class Repository implements Disposable {
|
||||
data += raw;
|
||||
};
|
||||
|
||||
child.stdout.setEncoding('utf8');
|
||||
child.stdout.on('data', onStdoutData);
|
||||
child.stdout!.setEncoding('utf8');
|
||||
child.stdout!.on('data', onStdoutData);
|
||||
|
||||
let stderr: string = '';
|
||||
child.stderr.setEncoding('utf8');
|
||||
child.stderr.on('data', raw => stderr += raw);
|
||||
child.stderr!.setEncoding('utf8');
|
||||
child.stderr!.on('data', raw => stderr += raw);
|
||||
|
||||
child.on('error', reject);
|
||||
child.on('exit', onExit);
|
||||
@@ -1427,6 +1444,7 @@ export class Repository implements Disposable {
|
||||
private async updateModelState(): Promise<void> {
|
||||
const { status, didHitLimit } = await this.repository.getStatus();
|
||||
const config = workspace.getConfiguration('git');
|
||||
const scopedConfig = workspace.getConfiguration('git', Uri.file(this.repository.root));
|
||||
const shouldIgnore = config.get<boolean>('ignoreLimitWarning') === true;
|
||||
const useIcons = !config.get<boolean>('decorations.enabled', true);
|
||||
this.isRepositoryHuge = didHitLimit;
|
||||
@@ -1487,17 +1505,29 @@ export class Repository implements Disposable {
|
||||
this._submodules = submodules!;
|
||||
this.rebaseCommit = rebaseCommit;
|
||||
|
||||
const untrackedChanges = scopedConfig.get<'mixed' | 'separate' | 'hidden'>('untrackedChanges');
|
||||
const index: Resource[] = [];
|
||||
const workingTree: Resource[] = [];
|
||||
const merge: Resource[] = [];
|
||||
const untracked: Resource[] = [];
|
||||
|
||||
status.forEach(raw => {
|
||||
const uri = Uri.file(path.join(this.repository.root, raw.path));
|
||||
const renameUri = raw.rename ? Uri.file(path.join(this.repository.root, raw.rename)) : undefined;
|
||||
const renameUri = raw.rename
|
||||
? Uri.file(path.join(this.repository.root, raw.rename))
|
||||
: undefined;
|
||||
|
||||
switch (raw.x + raw.y) {
|
||||
case '??': return workingTree.push(new Resource(ResourceGroupType.WorkingTree, uri, Status.UNTRACKED, useIcons));
|
||||
case '!!': return workingTree.push(new Resource(ResourceGroupType.WorkingTree, uri, Status.IGNORED, useIcons));
|
||||
case '??': switch (untrackedChanges) {
|
||||
case 'mixed': return workingTree.push(new Resource(ResourceGroupType.WorkingTree, uri, Status.UNTRACKED, useIcons));
|
||||
case 'separate': return untracked.push(new Resource(ResourceGroupType.Untracked, uri, Status.UNTRACKED, useIcons));
|
||||
default: return undefined;
|
||||
}
|
||||
case '!!': switch (untrackedChanges) {
|
||||
case 'mixed': return workingTree.push(new Resource(ResourceGroupType.WorkingTree, uri, Status.IGNORED, useIcons));
|
||||
case 'separate': return untracked.push(new Resource(ResourceGroupType.Untracked, uri, Status.IGNORED, useIcons));
|
||||
default: return undefined;
|
||||
}
|
||||
case 'DD': return merge.push(new Resource(ResourceGroupType.Merge, uri, Status.BOTH_DELETED, useIcons));
|
||||
case 'AU': return merge.push(new Resource(ResourceGroupType.Merge, uri, Status.ADDED_BY_US, useIcons));
|
||||
case 'UD': return merge.push(new Resource(ResourceGroupType.Merge, uri, Status.DELETED_BY_THEM, useIcons));
|
||||
@@ -1520,6 +1550,7 @@ export class Repository implements Disposable {
|
||||
case 'D': workingTree.push(new Resource(ResourceGroupType.WorkingTree, uri, Status.DELETED, useIcons, renameUri)); break;
|
||||
case 'A': workingTree.push(new Resource(ResourceGroupType.WorkingTree, uri, Status.INTENT_TO_ADD, useIcons, renameUri)); break;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
});
|
||||
|
||||
@@ -1527,6 +1558,7 @@ export class Repository implements Disposable {
|
||||
this.mergeGroup.resourceStates = merge;
|
||||
this.indexGroup.resourceStates = index;
|
||||
this.workingTreeGroup.resourceStates = workingTree;
|
||||
this.untrackedGroup.resourceStates = untracked;
|
||||
|
||||
// set count badge
|
||||
this.setCountBadge();
|
||||
@@ -1537,12 +1569,27 @@ export class Repository implements Disposable {
|
||||
}
|
||||
|
||||
private setCountBadge(): void {
|
||||
const countBadge = workspace.getConfiguration('git').get<string>('countBadge');
|
||||
let count = this.mergeGroup.resourceStates.length + this.indexGroup.resourceStates.length + this.workingTreeGroup.resourceStates.length;
|
||||
const config = workspace.getConfiguration('git', Uri.file(this.repository.root));
|
||||
const countBadge = config.get<'all' | 'tracked' | 'off'>('countBadge');
|
||||
const untrackedChanges = config.get<'mixed' | 'separate' | 'hidden'>('untrackedChanges');
|
||||
|
||||
let count =
|
||||
this.mergeGroup.resourceStates.length +
|
||||
this.indexGroup.resourceStates.length +
|
||||
this.workingTreeGroup.resourceStates.length;
|
||||
|
||||
switch (countBadge) {
|
||||
case 'off': count = 0; break;
|
||||
case 'tracked': count = count - this.workingTreeGroup.resourceStates.filter(r => r.type === Status.UNTRACKED || r.type === Status.IGNORED).length; break;
|
||||
case 'tracked':
|
||||
if (untrackedChanges === 'mixed') {
|
||||
count -= this.workingTreeGroup.resourceStates.filter(r => r.type === Status.UNTRACKED || r.type === Status.IGNORED).length;
|
||||
}
|
||||
break;
|
||||
case 'all':
|
||||
if (untrackedChanges === 'separate') {
|
||||
count += this.untrackedGroup.resourceStates.length;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
this._sourceControl.count = count;
|
||||
@@ -1644,7 +1691,7 @@ export class Repository implements Disposable {
|
||||
const head = HEAD.name || tagName || (HEAD.commit || '').substr(0, 8);
|
||||
|
||||
return head
|
||||
+ (this.workingTreeGroup.resourceStates.length > 0 ? '*' : '')
|
||||
+ (this.workingTreeGroup.resourceStates.length + this.untrackedGroup.resourceStates.length > 0 ? '*' : '')
|
||||
+ (this.indexGroup.resourceStates.length > 0 ? '+' : '')
|
||||
+ (this.mergeGroup.resourceStates.length > 0 ? '!' : '');
|
||||
}
|
||||
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
declare module 'jschardet' {
|
||||
export interface IDetectedMap {
|
||||
encoding: string,
|
||||
confidence: number
|
||||
}
|
||||
export function detect(buffer: Buffer): IDetectedMap;
|
||||
|
||||
export const Constants: {
|
||||
MINIMUM_THRESHOLD: number,
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Uri } from 'vscode';
|
||||
import * as qs from 'querystring';
|
||||
|
||||
export interface GitUriParams {
|
||||
path: string;
|
||||
@@ -11,8 +12,26 @@ export interface GitUriParams {
|
||||
submoduleOf?: string;
|
||||
}
|
||||
|
||||
export function isGitUri(uri: Uri): boolean {
|
||||
return /^git(fs)?$/.test(uri.scheme);
|
||||
}
|
||||
|
||||
export function fromGitUri(uri: Uri): GitUriParams {
|
||||
return JSON.parse(uri.query);
|
||||
const result = qs.parse(uri.query) as any;
|
||||
|
||||
if (!result) {
|
||||
throw new Error('Invalid git URI: empty query');
|
||||
}
|
||||
|
||||
if (typeof result.path !== 'string') {
|
||||
throw new Error('Invalid git URI: missing path');
|
||||
}
|
||||
|
||||
if (typeof result.ref !== 'string') {
|
||||
throw new Error('Invalid git URI: missing ref');
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
export interface GitUriOptions {
|
||||
@@ -42,8 +61,8 @@ export function toGitUri(uri: Uri, ref: string, options: GitUriOptions = {}): Ur
|
||||
}
|
||||
|
||||
return uri.with({
|
||||
scheme: 'git',
|
||||
scheme: 'gitfs',
|
||||
path,
|
||||
query: JSON.stringify(params)
|
||||
query: qs.stringify(params as any)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import { Event } from 'vscode';
|
||||
import { dirname, sep } from 'path';
|
||||
import { Readable } from 'stream';
|
||||
import * as fs from 'fs';
|
||||
import { promises as fs, createReadStream } from 'fs';
|
||||
import * as byline from 'byline';
|
||||
|
||||
export function log(...args: any[]): void {
|
||||
@@ -140,25 +140,14 @@ export function groupBy<T>(arr: T[], fn: (el: T) => string): { [key: string]: T[
|
||||
}, Object.create(null));
|
||||
}
|
||||
|
||||
export function denodeify<A, B, C, R>(fn: Function): (a: A, b: B, c: C) => Promise<R>;
|
||||
export function denodeify<A, B, R>(fn: Function): (a: A, b: B) => Promise<R>;
|
||||
export function denodeify<A, R>(fn: Function): (a: A) => Promise<R>;
|
||||
export function denodeify<R>(fn: Function): (...args: any[]) => Promise<R>;
|
||||
export function denodeify<R>(fn: Function): (...args: any[]) => Promise<R> {
|
||||
return (...args) => new Promise<R>((c, e) => fn(...args, (err: any, r: any) => err ? e(err) : c(r)));
|
||||
}
|
||||
|
||||
export function nfcall<R>(fn: Function, ...args: any[]): Promise<R> {
|
||||
return new Promise<R>((c, e) => fn(...args, (err: any, r: any) => err ? e(err) : c(r)));
|
||||
}
|
||||
|
||||
export async function mkdirp(path: string, mode?: number): Promise<boolean> {
|
||||
const mkdir = async () => {
|
||||
try {
|
||||
await nfcall(fs.mkdir, path, mode);
|
||||
await fs.mkdir(path, mode);
|
||||
} catch (err) {
|
||||
if (err.code === 'EEXIST') {
|
||||
const stat = await nfcall<fs.Stats>(fs.stat, path);
|
||||
const stat = await fs.stat(path);
|
||||
|
||||
if (stat.isDirectory()) {
|
||||
return;
|
||||
@@ -232,7 +221,7 @@ export function find<T>(array: T[], fn: (t: T) => boolean): T | undefined {
|
||||
|
||||
export async function grep(filename: string, pattern: RegExp): Promise<boolean> {
|
||||
return new Promise<boolean>((c, e) => {
|
||||
const fileStream = fs.createReadStream(filename, { encoding: 'utf8' });
|
||||
const fileStream = createReadStream(filename, { encoding: 'utf8' });
|
||||
const stream = byline(fileStream);
|
||||
stream.on('data', (line: string) => {
|
||||
if (pattern.test(line)) {
|
||||
|
||||
@@ -26,10 +26,10 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.51.tgz#b31d716fb8d58eeb95c068a039b9b6292817d5fb"
|
||||
integrity sha512-El3+WJk2D/ppWNd2X05aiP5l2k4EwF7KwheknQZls+I26eSICoWRhRIJ56jGgw2dqNGQ5LtNajmBU2ajS28EvQ==
|
||||
|
||||
"@types/node@^10.14.8":
|
||||
version "10.14.8"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.8.tgz#fe444203ecef1162348cd6deb76c62477b2cc6e9"
|
||||
integrity sha512-I4+DbJEhLEg4/vIy/2gkWDvXBOOtPKV9EnLhYjMoqxcRW+TTZtUftkHktz/a8suoD5mUL7m6ReLrkPvSsCQQmw==
|
||||
"@types/node@^12.11.7":
|
||||
version "12.11.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.11.7.tgz#57682a9771a3f7b09c2497f28129a0462966524a"
|
||||
integrity sha512-JNbGaHFCLwgHn/iCckiGSOZ1XYHsKFwREtzPwSGCVld1SGhOlmZw2D4ZI94HQCrBHbADzW9m4LER/8olJTRGHA==
|
||||
|
||||
"@types/which@^1.0.28":
|
||||
version "1.0.28"
|
||||
@@ -176,10 +176,10 @@ isexe@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
|
||||
integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=
|
||||
|
||||
jschardet@^1.6.0:
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-1.6.0.tgz#c7d1a71edcff2839db2f9ec30fc5d5ebd3c1a678"
|
||||
integrity sha512-xYuhvQ7I9PDJIGBWev9xm0+SMSed3ZDBAmvVjbFR1ZRLAF+vlXcQu6cRI9uAlj81rzikElRVteehwV7DuX2ZmQ==
|
||||
jschardet@2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-2.1.1.tgz#af6f8fd0b3b0f5d46a8fd9614a4fce490575c184"
|
||||
integrity sha512-pA5qG9Zwm8CBpGlK/lo2GE9jPxwqRgMV7Lzc/1iaPccw6v4Rhj8Zg2BTyrdmHmxlJojnbLupLeRnaPLsq03x6Q==
|
||||
|
||||
json3@3.3.2:
|
||||
version "3.3.2"
|
||||
|
||||
@@ -21,6 +21,7 @@ body img {
|
||||
.container {
|
||||
padding: 5px 0 0 10px;
|
||||
box-sizing: border-box;
|
||||
-webkit-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
|
||||
@@ -70,7 +70,8 @@
|
||||
let ctrlPressed = false;
|
||||
let altPressed = false;
|
||||
let hasLoadedImage = false;
|
||||
let consumeClick = false;
|
||||
let consumeClick = true;
|
||||
let isActive = false;
|
||||
|
||||
// Elements
|
||||
const container = document.body;
|
||||
@@ -117,10 +118,16 @@
|
||||
});
|
||||
}
|
||||
|
||||
function changeActive(value) {
|
||||
function setActive(value) {
|
||||
isActive = value;
|
||||
if (value) {
|
||||
container.classList.add('zoom-in');
|
||||
consumeClick = true;
|
||||
if (isMac ? altPressed : ctrlPressed) {
|
||||
container.classList.remove('zoom-in');
|
||||
container.classList.add('zoom-out');
|
||||
} else {
|
||||
container.classList.remove('zoom-out');
|
||||
container.classList.add('zoom-in');
|
||||
}
|
||||
} else {
|
||||
ctrlPressed = false;
|
||||
altPressed = false;
|
||||
@@ -202,7 +209,10 @@
|
||||
return;
|
||||
}
|
||||
|
||||
consumeClick = false;
|
||||
ctrlPressed = e.ctrlKey;
|
||||
altPressed = e.altKey;
|
||||
|
||||
consumeClick = !isActive;
|
||||
});
|
||||
|
||||
container.addEventListener('click', (/** @type {MouseEvent} */ e) => {
|
||||
@@ -214,14 +224,6 @@
|
||||
return;
|
||||
}
|
||||
|
||||
ctrlPressed = e.ctrlKey;
|
||||
altPressed = e.altKey;
|
||||
|
||||
if (isMac ? altPressed : ctrlPressed) {
|
||||
container.classList.remove('zoom-in');
|
||||
container.classList.add('zoom-out');
|
||||
}
|
||||
|
||||
if (consumeClick) {
|
||||
consumeClick = false;
|
||||
return;
|
||||
@@ -239,6 +241,11 @@
|
||||
});
|
||||
|
||||
container.addEventListener('wheel', (/** @type {WheelEvent} */ e) => {
|
||||
// Prevent pinch to zoom
|
||||
if (e.ctrlKey) {
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
if (!image || !hasLoadedImage) {
|
||||
return;
|
||||
}
|
||||
@@ -254,9 +261,9 @@
|
||||
|
||||
let delta = e.deltaY > 0 ? 1 : -1;
|
||||
updateScale(scale * (1 - delta * SCALE_PINCH_FACTOR));
|
||||
});
|
||||
}, { passive: false });
|
||||
|
||||
window.addEventListener('scroll', () => {
|
||||
window.addEventListener('scroll', e => {
|
||||
if (!image || !hasLoadedImage || !image.parentElement || scale === 'fit') {
|
||||
return;
|
||||
}
|
||||
@@ -265,7 +272,7 @@
|
||||
if (entry) {
|
||||
vscode.setState({ scale: entry.scale, offsetX: window.scrollX, offsetY: window.scrollY });
|
||||
}
|
||||
});
|
||||
}, { passive: true });
|
||||
|
||||
container.classList.add('image');
|
||||
|
||||
@@ -296,7 +303,7 @@
|
||||
document.body.classList.remove('loading');
|
||||
});
|
||||
|
||||
image.src = decodeURI(settings.src);
|
||||
image.src = settings.src;
|
||||
|
||||
window.addEventListener('message', e => {
|
||||
switch (e.data.type) {
|
||||
@@ -305,7 +312,7 @@
|
||||
break;
|
||||
|
||||
case 'setActive':
|
||||
changeActive(e.data.value);
|
||||
setActive(e.data.value);
|
||||
break;
|
||||
|
||||
case 'zoomIn':
|
||||
|
||||
@@ -29,8 +29,7 @@
|
||||
"priority": "builtin",
|
||||
"selector": [
|
||||
{
|
||||
"filenamePattern": "*.{jpg,jpe,jpeg,png,bmp,gif,ico,tga,webp}",
|
||||
"mime": "image/*"
|
||||
"filenamePattern": "*.{jpg,jpe,jpeg,png,bmp,gif,ico,webp}"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import * as nls from 'vscode-nls';
|
||||
import { PreviewStatusBarEntry } from './ownedStatusBarEntry';
|
||||
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
class BinarySize {
|
||||
static readonly KB = 1024;
|
||||
static readonly MB = BinarySize.KB * BinarySize.KB;
|
||||
static readonly GB = BinarySize.MB * BinarySize.KB;
|
||||
static readonly TB = BinarySize.GB * BinarySize.KB;
|
||||
|
||||
static formatSize(size: number): string {
|
||||
if (size < BinarySize.KB) {
|
||||
return localize('sizeB', "{0}B", size);
|
||||
}
|
||||
|
||||
if (size < BinarySize.MB) {
|
||||
return localize('sizeKB', "{0}KB", (size / BinarySize.KB).toFixed(2));
|
||||
}
|
||||
|
||||
if (size < BinarySize.GB) {
|
||||
return localize('sizeMB', "{0}MB", (size / BinarySize.MB).toFixed(2));
|
||||
}
|
||||
|
||||
if (size < BinarySize.TB) {
|
||||
return localize('sizeGB', "{0}GB", (size / BinarySize.GB).toFixed(2));
|
||||
}
|
||||
|
||||
return localize('sizeTB', "{0}TB", (size / BinarySize.TB).toFixed(2));
|
||||
}
|
||||
}
|
||||
|
||||
export class BinarySizeStatusBarEntry extends PreviewStatusBarEntry {
|
||||
|
||||
constructor() {
|
||||
super({
|
||||
id: 'imagePreview.binarySize',
|
||||
name: localize('sizeStatusBar.name', "Image Binary Size"),
|
||||
alignment: vscode.StatusBarAlignment.Right,
|
||||
priority: 100,
|
||||
});
|
||||
}
|
||||
|
||||
public show(owner: string, size: number | undefined) {
|
||||
if (typeof size === 'number') {
|
||||
super.showItem(owner, BinarySize.formatSize(size));
|
||||
} else {
|
||||
this.hide(owner);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@
|
||||
import * as vscode from 'vscode';
|
||||
import { PreviewManager } from './preview';
|
||||
import { SizeStatusBarEntry } from './sizeStatusBarEntry';
|
||||
import { BinarySizeStatusBarEntry } from './binarySizeStatusBarEntry';
|
||||
import { ZoomStatusBarEntry } from './zoomStatusBarEntry';
|
||||
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
@@ -14,18 +15,15 @@ export function activate(context: vscode.ExtensionContext) {
|
||||
const sizeStatusBarEntry = new SizeStatusBarEntry();
|
||||
context.subscriptions.push(sizeStatusBarEntry);
|
||||
|
||||
const binarySizeStatusBarEntry = new BinarySizeStatusBarEntry();
|
||||
context.subscriptions.push(binarySizeStatusBarEntry);
|
||||
|
||||
const zoomStatusBarEntry = new ZoomStatusBarEntry();
|
||||
context.subscriptions.push(zoomStatusBarEntry);
|
||||
|
||||
const previewManager = new PreviewManager(extensionRoot, sizeStatusBarEntry, zoomStatusBarEntry);
|
||||
const previewManager = new PreviewManager(extensionRoot, sizeStatusBarEntry, binarySizeStatusBarEntry, zoomStatusBarEntry);
|
||||
|
||||
context.subscriptions.push(vscode.window.registerWebviewEditorProvider(
|
||||
PreviewManager.viewType,
|
||||
{
|
||||
async resolveWebviewEditor(resource: vscode.Uri, editor: vscode.WebviewEditor): Promise<void> {
|
||||
previewManager.resolve(resource, editor);
|
||||
}
|
||||
}));
|
||||
context.subscriptions.push(vscode.window.registerWebviewEditorProvider(PreviewManager.viewType, previewManager));
|
||||
|
||||
context.subscriptions.push(vscode.commands.registerCommand('imagePreview.zoomIn', () => {
|
||||
previewManager.activePreview?.zoomIn();
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import { Disposable } from './dispose';
|
||||
|
||||
export abstract class PreviewStatusBarEntry extends Disposable {
|
||||
private _showOwner: string | undefined;
|
||||
|
||||
protected readonly entry: vscode.StatusBarItem;
|
||||
|
||||
constructor(options: vscode.window.StatusBarItemOptions) {
|
||||
super();
|
||||
this.entry = this._register(vscode.window.createStatusBarItem(options));
|
||||
}
|
||||
|
||||
protected showItem(owner: string, text: string) {
|
||||
this._showOwner = owner;
|
||||
this.entry.text = text;
|
||||
this.entry.show();
|
||||
}
|
||||
|
||||
public hide(owner: string) {
|
||||
if (owner === this._showOwner) {
|
||||
this.entry.hide();
|
||||
this._showOwner = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,11 +8,12 @@ import * as nls from 'vscode-nls';
|
||||
import { Disposable } from './dispose';
|
||||
import { SizeStatusBarEntry } from './sizeStatusBarEntry';
|
||||
import { Scale, ZoomStatusBarEntry } from './zoomStatusBarEntry';
|
||||
import { BinarySizeStatusBarEntry } from './binarySizeStatusBarEntry';
|
||||
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
|
||||
export class PreviewManager {
|
||||
export class PreviewManager implements vscode.WebviewEditorProvider {
|
||||
|
||||
public static readonly viewType = 'imagePreview.previewEditor';
|
||||
|
||||
@@ -22,14 +23,15 @@ export class PreviewManager {
|
||||
constructor(
|
||||
private readonly extensionRoot: vscode.Uri,
|
||||
private readonly sizeStatusBarEntry: SizeStatusBarEntry,
|
||||
private readonly binarySizeStatusBarEntry: BinarySizeStatusBarEntry,
|
||||
private readonly zoomStatusBarEntry: ZoomStatusBarEntry,
|
||||
) { }
|
||||
|
||||
public resolve(
|
||||
resource: vscode.Uri,
|
||||
webviewEditor: vscode.WebviewEditor,
|
||||
) {
|
||||
const preview = new Preview(this.extensionRoot, resource, webviewEditor, this.sizeStatusBarEntry, this.zoomStatusBarEntry);
|
||||
public async resolveWebviewEditor(
|
||||
input: { readonly resource: vscode.Uri, },
|
||||
webviewEditor: vscode.WebviewPanel,
|
||||
): Promise<vscode.WebviewEditorCapabilities> {
|
||||
const preview = new Preview(this.extensionRoot, input.resource, webviewEditor, this.sizeStatusBarEntry, this.binarySizeStatusBarEntry, this.zoomStatusBarEntry);
|
||||
this._previews.add(preview);
|
||||
this.setActivePreview(preview);
|
||||
|
||||
@@ -42,6 +44,8 @@ export class PreviewManager {
|
||||
this.setActivePreview(undefined);
|
||||
}
|
||||
});
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
public get activePreview() { return this._activePreview; }
|
||||
@@ -68,13 +72,15 @@ class Preview extends Disposable {
|
||||
|
||||
private _previewState = PreviewState.Visible;
|
||||
private _imageSize: string | undefined;
|
||||
private _imageBinarySize: number | undefined;
|
||||
private _imageZoom: Scale | undefined;
|
||||
|
||||
constructor(
|
||||
private readonly extensionRoot: vscode.Uri,
|
||||
private readonly resource: vscode.Uri,
|
||||
private readonly webviewEditor: vscode.WebviewEditor,
|
||||
private readonly webviewEditor: vscode.WebviewPanel,
|
||||
private readonly sizeStatusBarEntry: SizeStatusBarEntry,
|
||||
private readonly binarySizeStatusBarEntry: BinarySizeStatusBarEntry,
|
||||
private readonly zoomStatusBarEntry: ZoomStatusBarEntry,
|
||||
) {
|
||||
super();
|
||||
@@ -115,11 +121,13 @@ class Preview extends Disposable {
|
||||
|
||||
this._register(webviewEditor.onDidChangeViewState(() => {
|
||||
this.update();
|
||||
this.webviewEditor.webview.postMessage({ type: 'setActive', value: this.webviewEditor.active });
|
||||
}));
|
||||
|
||||
this._register(webviewEditor.onDidDispose(() => {
|
||||
if (this._previewState === PreviewState.Active) {
|
||||
this.sizeStatusBarEntry.hide(this.id);
|
||||
this.binarySizeStatusBarEntry.hide(this.id);
|
||||
this.zoomStatusBarEntry.hide(this.id);
|
||||
}
|
||||
this._previewState = PreviewState.Disposed;
|
||||
@@ -137,8 +145,14 @@ class Preview extends Disposable {
|
||||
}
|
||||
}));
|
||||
|
||||
vscode.workspace.fs.stat(resource).then(({ size }) => {
|
||||
this._imageBinarySize = size;
|
||||
this.update();
|
||||
});
|
||||
|
||||
this.render();
|
||||
this.update();
|
||||
this.webviewEditor.webview.postMessage({ type: 'setActive', value: this.webviewEditor.active });
|
||||
}
|
||||
|
||||
public zoomIn() {
|
||||
@@ -167,15 +181,16 @@ class Preview extends Disposable {
|
||||
if (this.webviewEditor.active) {
|
||||
this._previewState = PreviewState.Active;
|
||||
this.sizeStatusBarEntry.show(this.id, this._imageSize || '');
|
||||
this.binarySizeStatusBarEntry.show(this.id, this._imageBinarySize);
|
||||
this.zoomStatusBarEntry.show(this.id, this._imageZoom || 'fit');
|
||||
} else {
|
||||
if (this._previewState === PreviewState.Active) {
|
||||
this.sizeStatusBarEntry.hide(this.id);
|
||||
this.binarySizeStatusBarEntry.hide(this.id);
|
||||
this.zoomStatusBarEntry.hide(this.id);
|
||||
}
|
||||
this._previewState = PreviewState.Visible;
|
||||
}
|
||||
this.webviewEditor.webview.postMessage({ type: 'setActive', value: this.webviewEditor.active });
|
||||
}
|
||||
|
||||
private getWebiewContents(): string {
|
||||
@@ -191,8 +206,11 @@ class Preview extends Disposable {
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
|
||||
<!-- Disable pinch zooming -->
|
||||
<meta name="viewport"
|
||||
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
|
||||
|
||||
<title>Image Preview</title>
|
||||
|
||||
<link rel="stylesheet" href="${escapeAttribute(this.extensionResource('/media/main.css'))}" type="text/css" media="screen" nonce="${nonce}">
|
||||
@@ -208,18 +226,21 @@ class Preview extends Disposable {
|
||||
</html>`;
|
||||
}
|
||||
|
||||
private getResourcePath(webviewEditor: vscode.WebviewEditor, resource: vscode.Uri, version: string) {
|
||||
private getResourcePath(webviewEditor: vscode.WebviewPanel, resource: vscode.Uri, version: string) {
|
||||
switch (resource.scheme) {
|
||||
case 'data':
|
||||
return encodeURI(resource.toString(true));
|
||||
return resource.toString(true);
|
||||
|
||||
case 'git':
|
||||
// Show blank image
|
||||
return encodeURI('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAEElEQVR42gEFAPr/AP///wAI/AL+Sr4t6gAAAABJRU5ErkJggg==');
|
||||
|
||||
return 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAEElEQVR42gEFAPr/AP///wAI/AL+Sr4t6gAAAABJRU5ErkJggg==';
|
||||
|
||||
default:
|
||||
return encodeURI(webviewEditor.webview.asWebviewUri(resource).toString(true) + `?version=${version}`);
|
||||
// Avoid adding cache busting if there is already a query string
|
||||
if (resource.query) {
|
||||
return webviewEditor.webview.asWebviewUri(resource).toString(true);
|
||||
}
|
||||
return webviewEditor.webview.asWebviewUri(resource).with({ query: `version=${version}` }).toString(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,36 +4,23 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import { Disposable } from './dispose';
|
||||
import * as nls from 'vscode-nls';
|
||||
import { PreviewStatusBarEntry } from './ownedStatusBarEntry';
|
||||
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
export class SizeStatusBarEntry extends Disposable {
|
||||
private readonly _entry: vscode.StatusBarItem;
|
||||
|
||||
private _showingOwner: string | undefined;
|
||||
export class SizeStatusBarEntry extends PreviewStatusBarEntry {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this._entry = this._register(vscode.window.createStatusBarItem({
|
||||
super({
|
||||
id: 'imagePreview.size',
|
||||
name: localize('sizeStatusBar.name', "Image Size"),
|
||||
alignment: vscode.StatusBarAlignment.Right,
|
||||
priority: 101 /* to the left of editor status (100) */,
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
public show(owner: string, text: string) {
|
||||
this._showingOwner = owner;
|
||||
this._entry.text = text;
|
||||
this._entry.show();
|
||||
}
|
||||
|
||||
public hide(owner: string) {
|
||||
if (owner === this._showingOwner) {
|
||||
this._entry.hide();
|
||||
this._showingOwner = undefined;
|
||||
}
|
||||
this.showItem(owner, text);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import * as nls from 'vscode-nls';
|
||||
import { Disposable } from './dispose';
|
||||
import { PreviewStatusBarEntry as OwnedStatusBarEntry } from './ownedStatusBarEntry';
|
||||
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
@@ -13,22 +13,18 @@ const selectZoomLevelCommandId = '_imagePreview.selectZoomLevel';
|
||||
|
||||
export type Scale = number | 'fit';
|
||||
|
||||
export class ZoomStatusBarEntry extends Disposable {
|
||||
private readonly _entry: vscode.StatusBarItem;
|
||||
export class ZoomStatusBarEntry extends OwnedStatusBarEntry {
|
||||
|
||||
private readonly _onDidChangeScale = this._register(new vscode.EventEmitter<{ scale: Scale }>());
|
||||
public readonly onDidChangeScale = this._onDidChangeScale.event;
|
||||
|
||||
private _showOwner: string | undefined;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this._entry = this._register(vscode.window.createStatusBarItem({
|
||||
super({
|
||||
id: 'imagePreview.zoom',
|
||||
name: localize('zoomStatusBar.name', "Image Zoom"),
|
||||
alignment: vscode.StatusBarAlignment.Right,
|
||||
priority: 102 /* to the left of editor size entry (101) */,
|
||||
}));
|
||||
});
|
||||
|
||||
this._register(vscode.commands.registerCommand(selectZoomLevelCommandId, async () => {
|
||||
type MyPickItem = vscode.QuickPickItem & { scale: Scale };
|
||||
@@ -47,20 +43,11 @@ export class ZoomStatusBarEntry extends Disposable {
|
||||
}
|
||||
}));
|
||||
|
||||
this._entry.command = selectZoomLevelCommandId;
|
||||
this.entry.command = selectZoomLevelCommandId;
|
||||
}
|
||||
|
||||
public show(owner: string, scale: Scale) {
|
||||
this._showOwner = owner;
|
||||
this._entry.text = this.zoomLabel(scale);
|
||||
this._entry.show();
|
||||
}
|
||||
|
||||
public hide(owner: string) {
|
||||
if (owner === this._showOwner) {
|
||||
this._entry.hide();
|
||||
this._showOwner = undefined;
|
||||
}
|
||||
this.showItem(owner, this.zoomLabel(scale));
|
||||
}
|
||||
|
||||
private zoomLabel(scale: Scale): string {
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
"vscode-nls": "^3.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "10"
|
||||
"@types/node": "^12.11.7"
|
||||
},
|
||||
"__metadata": {
|
||||
"id": "23",
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@types/node@10":
|
||||
version "10.17.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.4.tgz#8993a4fe3c4022fda66bf4ea660d615fc5659c6f"
|
||||
integrity sha512-F2pgg+LcIr/elguz+x+fdBX5KeZXGUOp7TV8M0TVIrDezYLFRNt8oMTyps0VQ1kj5WGGoR18RdxnRDHXrIFHMQ==
|
||||
"@types/node@^12.11.7":
|
||||
version "12.12.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.7.tgz#01e4ea724d9e3bd50d90c11fd5980ba317d8fa11"
|
||||
integrity sha512-E6Zn0rffhgd130zbCbAr/JdXfXkoOUFAKNs/rF8qnafSJ8KYaA/j3oz7dcwal+lYjLA7xvdd5J4wdYpCTlP8+w==
|
||||
|
||||
agent-base@4:
|
||||
version "4.2.1"
|
||||
|
||||
+1
-1
@@ -14,4 +14,4 @@
|
||||
"preLaunchTask": "npm"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@ interface Settings {
|
||||
json?: {
|
||||
schemas?: JSONSchemaSettings[];
|
||||
format?: { enable: boolean; };
|
||||
resultLimit?: number;
|
||||
};
|
||||
http?: {
|
||||
proxy?: string;
|
||||
@@ -142,12 +143,6 @@ export function activate(context: ExtensionContext) {
|
||||
let disposable = client.start();
|
||||
toDispose.push(disposable);
|
||||
client.onReady().then(() => {
|
||||
disposable = client.onTelemetry(e => {
|
||||
if (telemetryReporter) {
|
||||
telemetryReporter.sendTelemetryEvent(e.key, e.data);
|
||||
}
|
||||
});
|
||||
|
||||
const schemaDocuments: { [uri: string]: boolean } = {};
|
||||
|
||||
// handle content request
|
||||
@@ -161,11 +156,23 @@ export function activate(context: ExtensionContext) {
|
||||
return Promise.reject(error);
|
||||
});
|
||||
} else {
|
||||
if (telemetryReporter && uri.authority === 'schema.management.azure.com') {
|
||||
/* __GDPR__
|
||||
"json.schema" : {
|
||||
"schemaURL" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
}
|
||||
*/
|
||||
telemetryReporter.sendTelemetryEvent('json.schema', { schemaURL: uriPath });
|
||||
}
|
||||
const headers = { 'Accept-Encoding': 'gzip, deflate' };
|
||||
return xhr({ url: uriPath, followRedirects: 5, headers }).then(response => {
|
||||
return response.responseText;
|
||||
}, (error: XHRResponse) => {
|
||||
return Promise.reject(new ResponseError(error.status, error.responseText || getErrorStatusDescription(error.status) || error.toString()));
|
||||
let extraInfo = error.responseText || error.toString();
|
||||
if (extraInfo.length > 256) {
|
||||
extraInfo = `${extraInfo.substr(0, 256)}...`;
|
||||
}
|
||||
return Promise.reject(new ResponseError(error.status, getErrorStatusDescription(error.status) + '\n' + extraInfo));
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -320,6 +327,7 @@ function getSettings(): Settings {
|
||||
},
|
||||
json: {
|
||||
schemas: [],
|
||||
resultLimit: 5000
|
||||
}
|
||||
};
|
||||
let schemaSettingsById: { [schemaId: string]: JSONSchemaSettings } = Object.create(null);
|
||||
|
||||
@@ -102,12 +102,12 @@
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"request-light": "^0.2.4",
|
||||
"request-light": "^0.2.5",
|
||||
"vscode-extension-telemetry": "0.1.1",
|
||||
"vscode-languageclient": "^6.0.0-next.1",
|
||||
"vscode-languageclient": "^6.0.0-next.3",
|
||||
"vscode-nls": "^4.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^10.14.8"
|
||||
"@types/node": "^12.11.7"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,16 +12,15 @@
|
||||
},
|
||||
"main": "./out/jsonServerMain",
|
||||
"dependencies": {
|
||||
"jsonc-parser": "^2.1.1",
|
||||
"request-light": "^0.2.4",
|
||||
"vscode-json-languageservice": "^3.3.5",
|
||||
"vscode-languageserver": "^6.0.0-next.1",
|
||||
"vscode-nls": "^4.1.1",
|
||||
"vscode-uri": "^2.0.3"
|
||||
"jsonc-parser": "^2.2.0",
|
||||
"request-light": "^0.2.5",
|
||||
"vscode-json-languageservice": "^3.4.7",
|
||||
"vscode-languageserver": "^6.0.0-next.3",
|
||||
"vscode-uri": "^2.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/mocha": "2.2.33",
|
||||
"@types/node": "^10.14.8"
|
||||
"@types/node": "^12.11.7"
|
||||
},
|
||||
"scripts": {
|
||||
"prepublishOnly": "npm run clean && npm run compile",
|
||||
|
||||
@@ -5,16 +5,18 @@
|
||||
|
||||
import {
|
||||
createConnection, IConnection,
|
||||
TextDocuments, TextDocument, InitializeParams, InitializeResult, NotificationType, RequestType,
|
||||
DocumentRangeFormattingRequest, Disposable, ServerCapabilities, Diagnostic
|
||||
TextDocuments, InitializeParams, InitializeResult, NotificationType, RequestType,
|
||||
DocumentRangeFormattingRequest, Disposable, ServerCapabilities, TextDocumentSyncKind
|
||||
} from 'vscode-languageserver';
|
||||
|
||||
import { xhr, XHRResponse, configure as configureHttpRequests, getErrorStatusDescription } from 'request-light';
|
||||
import * as fs from 'fs';
|
||||
import { URI } from 'vscode-uri';
|
||||
import * as URL from 'url';
|
||||
import { posix } from 'path';
|
||||
import { setTimeout, clearTimeout } from 'timers';
|
||||
import { formatError, runSafe, runSafeAsync } from './utils/runner';
|
||||
import { JSONDocument, JSONSchema, getLanguageService, DocumentLanguageSettings, SchemaConfiguration, ClientCapabilities } from 'vscode-json-languageservice';
|
||||
import { TextDocument, JSONDocument, JSONSchema, getLanguageService, DocumentLanguageSettings, SchemaConfiguration, ClientCapabilities, SchemaRequestService, Diagnostic } from 'vscode-json-languageservice';
|
||||
import { getLanguageModelCache } from './languageModelCache';
|
||||
|
||||
interface ISchemaAssociations {
|
||||
@@ -56,40 +58,40 @@ const workspaceContext = {
|
||||
return URL.resolve(resource, relativePath);
|
||||
}
|
||||
};
|
||||
function getSchemaRequestService(handledSchemas: { [schema: string]: boolean }) {
|
||||
|
||||
const fileRequestService: SchemaRequestService = (uri: string) => {
|
||||
const fsPath = URI.parse(uri).fsPath;
|
||||
return new Promise<string>((c, e) => {
|
||||
fs.readFile(fsPath, 'UTF-8', (err, result) => {
|
||||
err ? e(err.message || err.toString()) : c(result.toString());
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const httpRequestService: SchemaRequestService = (uri: string) => {
|
||||
const headers = { 'Accept-Encoding': 'gzip, deflate' };
|
||||
return xhr({ url: uri, followRedirects: 5, headers }).then(response => {
|
||||
return response.responseText;
|
||||
}, (error: XHRResponse) => {
|
||||
return Promise.reject(error.responseText || getErrorStatusDescription(error.status) || error.toString());
|
||||
});
|
||||
};
|
||||
|
||||
function getSchemaRequestService(handledSchemas: string[] = ['https', 'http', 'file']) {
|
||||
const builtInHandlers: { [protocol: string]: SchemaRequestService } = {};
|
||||
for (let protocol of handledSchemas) {
|
||||
if (protocol === 'file') {
|
||||
builtInHandlers[protocol] = fileRequestService;
|
||||
} else if (protocol === 'http' || protocol === 'https') {
|
||||
builtInHandlers[protocol] = httpRequestService;
|
||||
}
|
||||
}
|
||||
return (uri: string): Thenable<string> => {
|
||||
const protocol = uri.substr(0, uri.indexOf(':'));
|
||||
|
||||
if (!handledSchemas || handledSchemas[protocol]) {
|
||||
if (protocol === 'file') {
|
||||
const fsPath = URI.parse(uri).fsPath;
|
||||
return new Promise<string>((c, e) => {
|
||||
fs.readFile(fsPath, 'UTF-8', (err, result) => {
|
||||
err ? e(err.message || err.toString()) : c(result.toString());
|
||||
});
|
||||
});
|
||||
} else if (protocol === 'http' || protocol === 'https') {
|
||||
if (uri.indexOf('//schema.management.azure.com/') !== -1) {
|
||||
/* __GDPR__
|
||||
"json.schema" : {
|
||||
"schemaURL" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
}
|
||||
*/
|
||||
connection.telemetry.logEvent({
|
||||
key: 'json.schema',
|
||||
value: {
|
||||
schemaURL: uri
|
||||
}
|
||||
});
|
||||
}
|
||||
const headers = { 'Accept-Encoding': 'gzip, deflate' };
|
||||
return xhr({ url: uri, followRedirects: 5, headers }).then(response => {
|
||||
return response.responseText;
|
||||
}, (error: XHRResponse) => {
|
||||
return Promise.reject(error.responseText || getErrorStatusDescription(error.status) || error.toString());
|
||||
});
|
||||
}
|
||||
const builtInHandler = builtInHandlers[protocol];
|
||||
if (builtInHandler) {
|
||||
return builtInHandler(uri);
|
||||
}
|
||||
return connection.sendRequest(VSCodeContentRequest.type, uri).then(responseText => {
|
||||
return responseText;
|
||||
@@ -107,7 +109,7 @@ let languageService = getLanguageService({
|
||||
});
|
||||
|
||||
// Create a text document manager.
|
||||
const documents: TextDocuments = new TextDocuments();
|
||||
const documents = new TextDocuments(TextDocument);
|
||||
|
||||
// Make the text document manager listen on the connection
|
||||
// for open, change and close text document events
|
||||
@@ -115,9 +117,12 @@ documents.listen(connection);
|
||||
|
||||
let clientSnippetSupport = false;
|
||||
let dynamicFormatterRegistration = false;
|
||||
let foldingRangeLimit = Number.MAX_VALUE;
|
||||
let hierarchicalDocumentSymbolSupport = false;
|
||||
|
||||
let foldingRangeLimitDefault = Number.MAX_VALUE;
|
||||
let foldingRangeLimit = Number.MAX_VALUE;
|
||||
let resultLimit = Number.MAX_VALUE;
|
||||
|
||||
// After the server has started the client sends an initialize request. The server receives
|
||||
// in the passed params the rootPath of the workspace plus the client capabilities.
|
||||
connection.onInitialize((params: InitializeParams): InitializeResult => {
|
||||
@@ -145,11 +150,10 @@ connection.onInitialize((params: InitializeParams): InitializeResult => {
|
||||
|
||||
clientSnippetSupport = getClientCapability('textDocument.completion.completionItem.snippetSupport', false);
|
||||
dynamicFormatterRegistration = getClientCapability('textDocument.rangeFormatting.dynamicRegistration', false) && (typeof params.initializationOptions.provideFormatter !== 'boolean');
|
||||
foldingRangeLimit = getClientCapability('textDocument.foldingRange.rangeLimit', Number.MAX_VALUE);
|
||||
foldingRangeLimitDefault = getClientCapability('textDocument.foldingRange.rangeLimit', Number.MAX_VALUE);
|
||||
hierarchicalDocumentSymbolSupport = getClientCapability('textDocument.documentSymbol.hierarchicalDocumentSymbolSupport', false);
|
||||
const capabilities: ServerCapabilities = {
|
||||
// Tell the client that the server works in FULL text document sync mode
|
||||
textDocumentSync: documents.syncKind,
|
||||
textDocumentSync: TextDocumentSyncKind.Incremental,
|
||||
completionProvider: clientSnippetSupport ? { resolveProvider: true, triggerCharacters: ['"', ':'] } : undefined,
|
||||
hoverProvider: true,
|
||||
documentSymbolProvider: true,
|
||||
@@ -169,6 +173,7 @@ interface Settings {
|
||||
json: {
|
||||
schemas: JSONSchemaSettings[];
|
||||
format: { enable: boolean; };
|
||||
resultLimit?: number;
|
||||
};
|
||||
http: {
|
||||
proxy: string;
|
||||
@@ -182,6 +187,39 @@ interface JSONSchemaSettings {
|
||||
schema?: JSONSchema;
|
||||
}
|
||||
|
||||
namespace LimitExceededWarnings {
|
||||
const pendingWarnings: { [uri: string]: { features: { [name: string]: string }; timeout?: NodeJS.Timeout; } } = {};
|
||||
|
||||
export function cancel(uri: string) {
|
||||
const warning = pendingWarnings[uri];
|
||||
if (warning && warning.timeout) {
|
||||
clearTimeout(warning.timeout);
|
||||
delete pendingWarnings[uri];
|
||||
}
|
||||
}
|
||||
|
||||
export function onResultLimitExceeded(uri: string, resultLimit: number, name: string) {
|
||||
return () => {
|
||||
let warning = pendingWarnings[uri];
|
||||
if (warning) {
|
||||
if (!warning.timeout) {
|
||||
// already shown
|
||||
return;
|
||||
}
|
||||
warning.features[name] = name;
|
||||
warning.timeout.refresh();
|
||||
} else {
|
||||
warning = { features: { [name]: name } };
|
||||
warning.timeout = setTimeout(() => {
|
||||
connection.window.showInformationMessage(`${posix.basename(uri)}: For performance reasons, ${Object.keys(warning.features).join(' and ')} have been limited to ${resultLimit} items.`);
|
||||
warning.timeout = undefined;
|
||||
}, 2000);
|
||||
pendingWarnings[uri] = warning;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
let jsonConfigurationSettings: JSONSchemaSettings[] | undefined = undefined;
|
||||
let schemaAssociations: ISchemaAssociations | undefined = undefined;
|
||||
let formatterRegistration: Thenable<Disposable> | null = null;
|
||||
@@ -194,6 +232,9 @@ connection.onDidChangeConfiguration((change) => {
|
||||
jsonConfigurationSettings = settings.json && settings.json.schemas;
|
||||
updateConfiguration();
|
||||
|
||||
foldingRangeLimit = Math.trunc(Math.max(settings.json && settings.json.resultLimit || foldingRangeLimitDefault, 0));
|
||||
resultLimit = Math.trunc(Math.max(settings.json && settings.json.resultLimit || Number.MAX_VALUE, 0));
|
||||
|
||||
// dynamically enable & disable the formatter
|
||||
if (dynamicFormatterRegistration) {
|
||||
const enableFormatter = settings && settings.json && settings.json.format && settings.json.format.enable;
|
||||
@@ -270,11 +311,13 @@ function updateConfiguration() {
|
||||
// The content of a text document has changed. This event is emitted
|
||||
// when the text document first opened or when its content has changed.
|
||||
documents.onDidChangeContent((change) => {
|
||||
LimitExceededWarnings.cancel(change.document.uri);
|
||||
triggerValidation(change.document);
|
||||
});
|
||||
|
||||
// a document has closed: clear all diagnostics
|
||||
documents.onDidClose(event => {
|
||||
LimitExceededWarnings.cancel(event.document.uri);
|
||||
cleanPendingValidation(event.document);
|
||||
connection.sendDiagnostics({ uri: event.document.uri, diagnostics: [] });
|
||||
});
|
||||
@@ -383,10 +426,11 @@ connection.onDocumentSymbol((documentSymbolParams, token) => {
|
||||
const document = documents.get(documentSymbolParams.textDocument.uri);
|
||||
if (document) {
|
||||
const jsonDocument = getJSONDocument(document);
|
||||
const onResultLimitExceeded = LimitExceededWarnings.onResultLimitExceeded(document.uri, resultLimit, 'document symbols');
|
||||
if (hierarchicalDocumentSymbolSupport) {
|
||||
return languageService.findDocumentSymbols2(document, jsonDocument);
|
||||
return languageService.findDocumentSymbols2(document, jsonDocument, { resultLimit, onResultLimitExceeded });
|
||||
} else {
|
||||
return languageService.findDocumentSymbols(document, jsonDocument);
|
||||
return languageService.findDocumentSymbols(document, jsonDocument, { resultLimit, onResultLimitExceeded });
|
||||
}
|
||||
}
|
||||
return [];
|
||||
@@ -407,8 +451,9 @@ connection.onDocumentColor((params, token) => {
|
||||
return runSafeAsync(async () => {
|
||||
const document = documents.get(params.textDocument.uri);
|
||||
if (document) {
|
||||
const onResultLimitExceeded = LimitExceededWarnings.onResultLimitExceeded(document.uri, resultLimit, 'document colors');
|
||||
const jsonDocument = getJSONDocument(document);
|
||||
return languageService.findDocumentColors(document, jsonDocument);
|
||||
return languageService.findDocumentColors(document, jsonDocument, { resultLimit, onResultLimitExceeded });
|
||||
}
|
||||
return [];
|
||||
}, [], `Error while computing document colors for ${params.textDocument.uri}`, token);
|
||||
@@ -429,7 +474,8 @@ connection.onFoldingRanges((params, token) => {
|
||||
return runSafe(() => {
|
||||
const document = documents.get(params.textDocument.uri);
|
||||
if (document) {
|
||||
return languageService.getFoldingRanges(document, { rangeLimit: foldingRangeLimit });
|
||||
const onRangeLimitExceeded = LimitExceededWarnings.onResultLimitExceeded(document.uri, foldingRangeLimit, 'folding ranges');
|
||||
return languageService.getFoldingRanges(document, { rangeLimit: foldingRangeLimit, onRangeLimitExceeded });
|
||||
}
|
||||
return null;
|
||||
}, null, `Error while computing folding ranges for ${params.textDocument.uri}`, token);
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-2.2.33.tgz#d79a0061ec270379f4d9e225f4096fb436669def"
|
||||
integrity sha1-15oAYewnA3n02eIl9AlvtDZmne8=
|
||||
|
||||
"@types/node@^10.14.8":
|
||||
version "10.14.8"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.8.tgz#fe444203ecef1162348cd6deb76c62477b2cc6e9"
|
||||
integrity sha512-I4+DbJEhLEg4/vIy/2gkWDvXBOOtPKV9EnLhYjMoqxcRW+TTZtUftkHktz/a8suoD5mUL7m6ReLrkPvSsCQQmw==
|
||||
"@types/node@^12.11.7":
|
||||
version "12.11.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.11.7.tgz#57682a9771a3f7b09c2497f28129a0462966524a"
|
||||
integrity sha512-JNbGaHFCLwgHn/iCckiGSOZ1XYHsKFwREtzPwSGCVld1SGhOlmZw2D4ZI94HQCrBHbADzW9m4LER/8olJTRGHA==
|
||||
|
||||
agent-base@4:
|
||||
version "4.1.2"
|
||||
@@ -53,7 +53,7 @@ http-proxy-agent@^2.1.0:
|
||||
agent-base "4"
|
||||
debug "3.1.0"
|
||||
|
||||
https-proxy-agent@^2.2.1:
|
||||
https-proxy-agent@^2.2.3:
|
||||
version "2.2.4"
|
||||
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz#4ee7a737abd92678a293d9b34a1af4d0d08c787b"
|
||||
integrity sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==
|
||||
@@ -61,77 +61,77 @@ https-proxy-agent@^2.2.1:
|
||||
agent-base "^4.3.0"
|
||||
debug "^3.1.0"
|
||||
|
||||
jsonc-parser@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-2.1.1.tgz#83dc3d7a6e7186346b889b1280eefa04446c6d3e"
|
||||
integrity sha512-VC0CjnWJylKB1iov4u76/W/5Ef0ydDkjtYWxoZ9t3HdWlSnZQwZL5MgFikaB/EtQ4RmMEw3tmQzuYnZA2/Ja1g==
|
||||
jsonc-parser@^2.2.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-2.2.0.tgz#f206f87f9d49d644b7502052c04e82dd6392e9ef"
|
||||
integrity sha512-4fLQxW1j/5fWj6p78vAlAafoCKtuBm6ghv+Ij5W2DrDx0qE+ZdEl2c6Ko1mgJNF5ftX1iEWQQ4Ap7+3GlhjkOA==
|
||||
|
||||
ms@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
|
||||
integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
|
||||
|
||||
request-light@^0.2.4:
|
||||
version "0.2.4"
|
||||
resolved "https://registry.yarnpkg.com/request-light/-/request-light-0.2.4.tgz#3cea29c126682e6bcadf7915353322eeba01a755"
|
||||
integrity sha512-pM9Fq5jRnSb+82V7M97rp8FE9/YNeP2L9eckB4Szd7lyeclSIx02aIpPO/6e4m6Dy31+FBN/zkFMTd2HkNO3ow==
|
||||
request-light@^0.2.5:
|
||||
version "0.2.5"
|
||||
resolved "https://registry.yarnpkg.com/request-light/-/request-light-0.2.5.tgz#38a3da7b2e56f7af8cbba57e8a94930ee2380746"
|
||||
integrity sha512-eBEh+GzJAftUnex6tcL6eV2JCifY0+sZMIUpUPOVXbs2nV5hla4ZMmO3icYKGuGVuQ2zHE9evh4OrRcH4iyYYw==
|
||||
dependencies:
|
||||
http-proxy-agent "^2.1.0"
|
||||
https-proxy-agent "^2.2.1"
|
||||
vscode-nls "^4.0.0"
|
||||
|
||||
vscode-json-languageservice@^3.3.5:
|
||||
version "3.3.5"
|
||||
resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.3.5.tgz#e222e8391beeb23cfa40cf17fd57d1594d295fc7"
|
||||
integrity sha512-Le6SG5aRdrRc5jVeVMRkYbGH9rrVaZHCW0Oa8zCFQ0T8viUud9qdZ29lSv5NPNLwTB8mn4pYucFyyEPM2YWvLA==
|
||||
dependencies:
|
||||
jsonc-parser "^2.1.1"
|
||||
vscode-languageserver-types "^3.15.0-next.5"
|
||||
https-proxy-agent "^2.2.3"
|
||||
vscode-nls "^4.1.1"
|
||||
vscode-uri "^2.0.3"
|
||||
|
||||
vscode-json-languageservice@^3.4.7:
|
||||
version "3.4.7"
|
||||
resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.4.7.tgz#8d85f3c1d46a1e58e9867d747552fb8c83d934fd"
|
||||
integrity sha512-y3MN2+/yph3yoIHGmHu4ScYpm285L58XVvfGkd49xTQzLja4apxSbwzsYcP9QsqS0W7KuvoyiPhqksiudoMwjg==
|
||||
dependencies:
|
||||
jsonc-parser "^2.2.0"
|
||||
vscode-languageserver-textdocument "^1.0.0-next.4"
|
||||
vscode-languageserver-types "^3.15.0-next.6"
|
||||
vscode-nls "^4.1.1"
|
||||
vscode-uri "^2.1.0"
|
||||
|
||||
vscode-jsonrpc@^5.0.0-next.2:
|
||||
version "5.0.0-next.2"
|
||||
resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-5.0.0-next.2.tgz#a44bc03f67069e53f8d8beb88b96c0cacbfefbca"
|
||||
integrity sha512-Q3/jabZUNviCG9hhF6hHWjhrABevPF9mv0aiE2j8BYCAP2k+aHTpjMyk+04MzaAqWYwXdQuZkLSbcYCCqbzJLg==
|
||||
|
||||
vscode-languageserver-protocol@^3.15.0-next.9:
|
||||
version "3.15.0-next.9"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.15.0-next.9.tgz#e768256bd5b580b25bfbc8099bc03bc4c42ebf30"
|
||||
integrity sha512-b9PAxouMmtsLEe8ZjbIMPb7wRWPhckGfgjwZLmp/dWnaAuRPYtY3lGO0/rNbLc3jKIqCVlnEyYVFKalzDAzj0g==
|
||||
vscode-languageserver-protocol@^3.15.0-next.10:
|
||||
version "3.15.0-next.10"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.15.0-next.10.tgz#f1382f0c270ae5d0c2c7e552483285fb75810914"
|
||||
integrity sha512-TmbBhKrBoYNX+/pQGwoXmy2qlOfjGBUhwUGIzQoWpj8qtDzYuLof8bi19rGLZ9sVuSHh3anvIyVpGJEqT0QODQ==
|
||||
dependencies:
|
||||
vscode-jsonrpc "^5.0.0-next.2"
|
||||
vscode-languageserver-types "^3.15.0-next.5"
|
||||
vscode-languageserver-types "^3.15.0-next.6"
|
||||
|
||||
vscode-languageserver-types@^3.15.0-next.5:
|
||||
version "3.15.0-next.5"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.15.0-next.5.tgz#863d711bf47b338ff5e63ae19fb20d4fcd4d713b"
|
||||
integrity sha512-7hrELhTeWieUgex3+6692KjCkcmO/+V/bFItM5MHGcBotzwmjEuXjapLLYTYhIspuJ1ibRSik5MhX5YwLpsPiw==
|
||||
vscode-languageserver-textdocument@^1.0.0-next.4:
|
||||
version "1.0.0-next.4"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.0-next.4.tgz#8f7afdfe3e81411f57baaa29bb3214d1907160cd"
|
||||
integrity sha512-LJ5WfoBO54nqinjlLJKnjoo2Im4bIvPJ8bFT7R0C84ZI36iK8M29ddslfe5jUeWNSTtCda7YuKdKsDIq38HpgA==
|
||||
|
||||
vscode-languageserver@^6.0.0-next.1:
|
||||
version "6.0.0-next.1"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-6.0.0-next.1.tgz#4d71886d4a17d22eafc61b3a5fbf84e8e27c191f"
|
||||
integrity sha512-LSF6bXoFeXfMPRNyqzI3yFX/kD2DzXBemqvyj1kDWNVraiWttm4xKF4YXsvJ7Z3s9sVt/Dpu3CFU3w61PGNZMg==
|
||||
vscode-languageserver-types@^3.15.0-next.6:
|
||||
version "3.15.0-next.6"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.15.0-next.6.tgz#7a990d00c39ad4e744335afb4cc422a3e687ff25"
|
||||
integrity sha512-+4jfvmZ26oFMSX6EgPRB75PWHoT8pzyWuSSWk0erC4hTzmJq2gWxVLh20bZutZjMmiivawvPshtM3XZhX2SttA==
|
||||
|
||||
vscode-languageserver@^6.0.0-next.3:
|
||||
version "6.0.0-next.3"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-6.0.0-next.3.tgz#41e2fda6417939792f6a19fc19ecbb2f080e2072"
|
||||
integrity sha512-Q6T+KwYuoXV9KRHD6x7RfTU13pV0xAX2BtcuvSC/LBCiVAnEIOe7jKZjzya+B9gDvSk4hpfvhPefy5IdQK1mpQ==
|
||||
dependencies:
|
||||
vscode-languageserver-protocol "^3.15.0-next.9"
|
||||
vscode-textbuffer "^1.0.0"
|
||||
|
||||
vscode-nls@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-4.0.0.tgz#4001c8a6caba5cedb23a9c5ce1090395c0e44002"
|
||||
integrity sha512-qCfdzcH+0LgQnBpZA53bA32kzp9rpq/f66Som577ObeuDlFIrtbEJ+A/+CCxjIh4G8dpJYNCKIsxpRAHIfsbNw==
|
||||
vscode-languageserver-protocol "^3.15.0-next.10"
|
||||
|
||||
vscode-nls@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-4.1.1.tgz#f9916b64e4947b20322defb1e676a495861f133c"
|
||||
integrity sha512-4R+2UoUUU/LdnMnFjePxfLqNhBS8lrAFyX7pjb2ud/lqDkrUavFUTcG7wR0HBZFakae0Q6KLBFjMS6W93F403A==
|
||||
|
||||
vscode-textbuffer@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-textbuffer/-/vscode-textbuffer-1.0.0.tgz#1faee638c8e0e4131c8d5c353993a1874acda086"
|
||||
integrity sha512-zPaHo4urgpwsm+PrJWfNakolRpryNja18SUip/qIIsfhuEqEIPEXMxHOlFPjvDC4JgTaimkncNW7UMXRJTY6ow==
|
||||
vscode-uri@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-2.1.0.tgz#475a4269e63edbc13914b40c84bc1416e3398156"
|
||||
integrity sha512-3voe44nOhb6OdKlpZShVsmVvY2vFQHMe6REP3Ky9RVJuPyM/XidsjH6HncCIDdSmbcF5YQHrTC/Q+Q2loJGkOw==
|
||||
|
||||
vscode-uri@^2.0.3:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-2.0.3.tgz#25e5f37f552fbee3cec7e5f80cef8469cefc6543"
|
||||
integrity sha512-4D3DI3F4uRy09WNtDGD93H9q034OHImxiIcSq664Hq1Y1AScehlP3qqZyTkX/RWxeu0MRMHGkrxYqm2qlDF/aw==
|
||||
vscode-uri@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-2.1.1.tgz#5aa1803391b6ebdd17d047f51365cf62c38f6e90"
|
||||
integrity sha512-eY9jmGoEnVf8VE8xr5znSah7Qt1P/xsCdErz+g8HYZtJ7bZqKH5E3d+6oVNm1AC/c6IHUDokbmVXKOi4qPAC9A==
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@types/node@^10.14.8":
|
||||
version "10.14.8"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.8.tgz#fe444203ecef1162348cd6deb76c62477b2cc6e9"
|
||||
integrity sha512-I4+DbJEhLEg4/vIy/2gkWDvXBOOtPKV9EnLhYjMoqxcRW+TTZtUftkHktz/a8suoD5mUL7m6ReLrkPvSsCQQmw==
|
||||
"@types/node@^12.11.7":
|
||||
version "12.11.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.11.7.tgz#57682a9771a3f7b09c2497f28129a0462966524a"
|
||||
integrity sha512-JNbGaHFCLwgHn/iCckiGSOZ1XYHsKFwREtzPwSGCVld1SGhOlmZw2D4ZI94HQCrBHbADzW9m4LER/8olJTRGHA==
|
||||
|
||||
agent-base@4:
|
||||
version "4.2.1"
|
||||
@@ -76,7 +76,7 @@ http-proxy-agent@^2.1.0:
|
||||
agent-base "4"
|
||||
debug "3.1.0"
|
||||
|
||||
https-proxy-agent@^2.2.1:
|
||||
https-proxy-agent@^2.2.3:
|
||||
version "2.2.4"
|
||||
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz#4ee7a737abd92678a293d9b34a1af4d0d08c787b"
|
||||
integrity sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==
|
||||
@@ -94,14 +94,14 @@ ms@^2.1.1:
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a"
|
||||
integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==
|
||||
|
||||
request-light@^0.2.4:
|
||||
version "0.2.4"
|
||||
resolved "https://registry.yarnpkg.com/request-light/-/request-light-0.2.4.tgz#3cea29c126682e6bcadf7915353322eeba01a755"
|
||||
integrity sha512-pM9Fq5jRnSb+82V7M97rp8FE9/YNeP2L9eckB4Szd7lyeclSIx02aIpPO/6e4m6Dy31+FBN/zkFMTd2HkNO3ow==
|
||||
request-light@^0.2.5:
|
||||
version "0.2.5"
|
||||
resolved "https://registry.yarnpkg.com/request-light/-/request-light-0.2.5.tgz#38a3da7b2e56f7af8cbba57e8a94930ee2380746"
|
||||
integrity sha512-eBEh+GzJAftUnex6tcL6eV2JCifY0+sZMIUpUPOVXbs2nV5hla4ZMmO3icYKGuGVuQ2zHE9evh4OrRcH4iyYYw==
|
||||
dependencies:
|
||||
http-proxy-agent "^2.1.0"
|
||||
https-proxy-agent "^2.2.1"
|
||||
vscode-nls "^4.0.0"
|
||||
https-proxy-agent "^2.2.3"
|
||||
vscode-nls "^4.1.1"
|
||||
|
||||
semver@^5.3.0:
|
||||
version "5.5.0"
|
||||
@@ -125,31 +125,26 @@ vscode-jsonrpc@^5.0.0-next.2:
|
||||
resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-5.0.0-next.2.tgz#a44bc03f67069e53f8d8beb88b96c0cacbfefbca"
|
||||
integrity sha512-Q3/jabZUNviCG9hhF6hHWjhrABevPF9mv0aiE2j8BYCAP2k+aHTpjMyk+04MzaAqWYwXdQuZkLSbcYCCqbzJLg==
|
||||
|
||||
vscode-languageclient@^6.0.0-next.1:
|
||||
version "6.0.0-next.1"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-6.0.0-next.1.tgz#deca1743afd20da092e04e40ef73cedbbd978455"
|
||||
integrity sha512-eJ9VjLFNINArgRzLbQ11YlWry7dM93GEODkQBXTRfrSypksiO9qSGr4SHhWgxxP26p4FRSpzc/17+N+Egnnchg==
|
||||
vscode-languageclient@^6.0.0-next.3:
|
||||
version "6.0.0-next.3"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-6.0.0-next.3.tgz#41b701d963fc7affc01e9279532a747fcd4f3810"
|
||||
integrity sha512-SuSaG9xjqkROm4Ie0jQig0CFDuU/WxHERegl3kRsFHDbhMSK4dH45ZeBY5zMWUgZ+LrIrEbwf8qWNlrTRBlUgg==
|
||||
dependencies:
|
||||
semver "^6.3.0"
|
||||
vscode-languageserver-protocol "^3.15.0-next.9"
|
||||
vscode-languageserver-protocol "^3.15.0-next.10"
|
||||
|
||||
vscode-languageserver-protocol@^3.15.0-next.9:
|
||||
version "3.15.0-next.9"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.15.0-next.9.tgz#e768256bd5b580b25bfbc8099bc03bc4c42ebf30"
|
||||
integrity sha512-b9PAxouMmtsLEe8ZjbIMPb7wRWPhckGfgjwZLmp/dWnaAuRPYtY3lGO0/rNbLc3jKIqCVlnEyYVFKalzDAzj0g==
|
||||
vscode-languageserver-protocol@^3.15.0-next.10:
|
||||
version "3.15.0-next.10"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.15.0-next.10.tgz#f1382f0c270ae5d0c2c7e552483285fb75810914"
|
||||
integrity sha512-TmbBhKrBoYNX+/pQGwoXmy2qlOfjGBUhwUGIzQoWpj8qtDzYuLof8bi19rGLZ9sVuSHh3anvIyVpGJEqT0QODQ==
|
||||
dependencies:
|
||||
vscode-jsonrpc "^5.0.0-next.2"
|
||||
vscode-languageserver-types "^3.15.0-next.5"
|
||||
vscode-languageserver-types "^3.15.0-next.6"
|
||||
|
||||
vscode-languageserver-types@^3.15.0-next.5:
|
||||
version "3.15.0-next.5"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.15.0-next.5.tgz#863d711bf47b338ff5e63ae19fb20d4fcd4d713b"
|
||||
integrity sha512-7hrELhTeWieUgex3+6692KjCkcmO/+V/bFItM5MHGcBotzwmjEuXjapLLYTYhIspuJ1ibRSik5MhX5YwLpsPiw==
|
||||
|
||||
vscode-nls@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-4.0.0.tgz#4001c8a6caba5cedb23a9c5ce1090395c0e44002"
|
||||
integrity sha512-qCfdzcH+0LgQnBpZA53bA32kzp9rpq/f66Som577ObeuDlFIrtbEJ+A/+CCxjIh4G8dpJYNCKIsxpRAHIfsbNw==
|
||||
vscode-languageserver-types@^3.15.0-next.6:
|
||||
version "3.15.0-next.6"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.15.0-next.6.tgz#7a990d00c39ad4e744335afb4cc422a3e687ff25"
|
||||
integrity sha512-+4jfvmZ26oFMSX6EgPRB75PWHoT8pzyWuSSWk0erC4hTzmJq2gWxVLh20bZutZjMmiivawvPshtM3XZhX2SttA==
|
||||
|
||||
vscode-nls@^4.1.1:
|
||||
version "4.1.1"
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"Once accepted there, we are happy to receive an update request."
|
||||
],
|
||||
"version": "https://github.com/Microsoft/vscode-JSON.tmLanguage/commit/9bd83f1c252b375e957203f21793316203f61f70",
|
||||
"name": "JSON (JavaScript Next)",
|
||||
"name": "JSON (Javascript Next)",
|
||||
"scopeName": "source.json",
|
||||
"patterns": [
|
||||
{
|
||||
@@ -210,4 +210,4 @@
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,7 @@
|
||||
"compile": "gulp compile-extension:liveshare"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "12.0.9",
|
||||
"@types/node": "^12.11.7",
|
||||
"ts-loader": "^5.3.3",
|
||||
"tslint": "^5.12.1",
|
||||
"typescript": "^3.3.1"
|
||||
|
||||
@@ -18,10 +18,10 @@
|
||||
esutils "^2.0.2"
|
||||
js-tokens "^4.0.0"
|
||||
|
||||
"@types/node@12.0.9":
|
||||
version "12.0.9"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.0.9.tgz#18e0fc7bc6acc71f43a1a6ec9096c30d3954dd5c"
|
||||
integrity sha512-xxrghIb6jMoEkNtdzGMUezwCEGuBd4QSA/Fko1XaUYpn6P/LwVw7UGpf4NzwGZXRC96fDgBJcBX7bXU0T52nWA==
|
||||
"@types/node@^12.11.7":
|
||||
version "12.12.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.7.tgz#01e4ea724d9e3bd50d90c11fd5980ba317d8fa11"
|
||||
integrity sha512-E6Zn0rffhgd130zbCbAr/JdXfXkoOUFAKNs/rF8qnafSJ8KYaA/j3oz7dcwal+lYjLA7xvdd5J4wdYpCTlP8+w==
|
||||
|
||||
ansi-styles@^3.2.1:
|
||||
version "3.2.1"
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
|
||||
"Once accepted there, we are happy to receive an update request."
|
||||
],
|
||||
"version": "https://github.com/microsoft/vscode-markdown-tm-grammar/commit/46724e2885f9557400ed91727d75c3574ceded3a",
|
||||
"version": "https://github.com/microsoft/vscode-markdown-tm-grammar/commit/e3091a421bdcad527018c897652ded47585cbd12",
|
||||
"name": "Markdown",
|
||||
"scopeName": "text.html.markdown",
|
||||
"patterns": [
|
||||
@@ -63,7 +63,7 @@
|
||||
"while": "(^|\\G)\\s*(>) ?"
|
||||
},
|
||||
"fenced_code_block_css": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(css|css.erb)(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(css|css.erb)((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -96,7 +96,7 @@
|
||||
]
|
||||
},
|
||||
"fenced_code_block_basic": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(html|htm|shtml|xhtml|inc|tmpl|tpl)(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(html|htm|shtml|xhtml|inc|tmpl|tpl)((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -129,7 +129,7 @@
|
||||
]
|
||||
},
|
||||
"fenced_code_block_ini": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(ini|conf)(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(ini|conf)((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -162,7 +162,7 @@
|
||||
]
|
||||
},
|
||||
"fenced_code_block_java": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(java|bsh)(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(java|bsh)((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -195,7 +195,7 @@
|
||||
]
|
||||
},
|
||||
"fenced_code_block_lua": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(lua)(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(lua)((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -228,7 +228,7 @@
|
||||
]
|
||||
},
|
||||
"fenced_code_block_makefile": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(Makefile|makefile|GNUmakefile|OCamlMakefile)(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(Makefile|makefile|GNUmakefile|OCamlMakefile)((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -261,7 +261,7 @@
|
||||
]
|
||||
},
|
||||
"fenced_code_block_perl": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(perl|pl|pm|pod|t|PL|psgi|vcl)(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(perl|pl|pm|pod|t|PL|psgi|vcl)((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -294,7 +294,7 @@
|
||||
]
|
||||
},
|
||||
"fenced_code_block_r": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(R|r|s|S|Rprofile|\\{\\.r.+?\\})(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(R|r|s|S|Rprofile|\\{\\.r.+?\\})((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -327,7 +327,7 @@
|
||||
]
|
||||
},
|
||||
"fenced_code_block_ruby": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(ruby|rb|rbx|rjs|Rakefile|rake|cgi|fcgi|gemspec|irbrc|Capfile|ru|prawn|Cheffile|Gemfile|Guardfile|Hobofile|Vagrantfile|Appraisals|Rantfile|Berksfile|Berksfile.lock|Thorfile|Puppetfile)(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(ruby|rb|rbx|rjs|Rakefile|rake|cgi|fcgi|gemspec|irbrc|Capfile|ru|prawn|Cheffile|Gemfile|Guardfile|Hobofile|Vagrantfile|Appraisals|Rantfile|Berksfile|Berksfile.lock|Thorfile|Puppetfile)((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -360,7 +360,7 @@
|
||||
]
|
||||
},
|
||||
"fenced_code_block_php": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(php|php3|php4|php5|phpt|phtml|aw|ctp)(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(php|php3|php4|php5|phpt|phtml|aw|ctp)((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -396,7 +396,7 @@
|
||||
]
|
||||
},
|
||||
"fenced_code_block_sql": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(sql|ddl|dml)(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(sql|ddl|dml)((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -429,7 +429,7 @@
|
||||
]
|
||||
},
|
||||
"fenced_code_block_vs_net": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(vb)(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(vb)((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -462,7 +462,7 @@
|
||||
]
|
||||
},
|
||||
"fenced_code_block_xml": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(xml|xsd|tld|jsp|pt|cpt|dtml|rss|opml)(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(xml|xsd|tld|jsp|pt|cpt|dtml|rss|opml)((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -495,7 +495,7 @@
|
||||
]
|
||||
},
|
||||
"fenced_code_block_xsl": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(xsl|xslt)(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(xsl|xslt)((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -528,7 +528,7 @@
|
||||
]
|
||||
},
|
||||
"fenced_code_block_yaml": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(yaml|yml)(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(yaml|yml)((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -561,7 +561,7 @@
|
||||
]
|
||||
},
|
||||
"fenced_code_block_dosbatch": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(bat|batch)(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(bat|batch)((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -594,7 +594,7 @@
|
||||
]
|
||||
},
|
||||
"fenced_code_block_clojure": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(clj|cljs|clojure)(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(clj|cljs|clojure)((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -627,7 +627,7 @@
|
||||
]
|
||||
},
|
||||
"fenced_code_block_coffee": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(coffee|Cakefile|coffee.erb)(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(coffee|Cakefile|coffee.erb)((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -660,7 +660,7 @@
|
||||
]
|
||||
},
|
||||
"fenced_code_block_c": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(c|h)(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(c|h)((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -693,7 +693,7 @@
|
||||
]
|
||||
},
|
||||
"fenced_code_block_cpp": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(cpp|c\\+\\+|cxx)(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(cpp|c\\+\\+|cxx)((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -726,7 +726,7 @@
|
||||
]
|
||||
},
|
||||
"fenced_code_block_diff": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(patch|diff|rej)(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(patch|diff|rej)((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -759,7 +759,7 @@
|
||||
]
|
||||
},
|
||||
"fenced_code_block_dockerfile": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(dockerfile|Dockerfile)(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(dockerfile|Dockerfile)((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -792,7 +792,7 @@
|
||||
]
|
||||
},
|
||||
"fenced_code_block_git_commit": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(COMMIT_EDITMSG|MERGE_MSG)(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(COMMIT_EDITMSG|MERGE_MSG)((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -825,7 +825,7 @@
|
||||
]
|
||||
},
|
||||
"fenced_code_block_git_rebase": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(git-rebase-todo)(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(git-rebase-todo)((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -858,7 +858,7 @@
|
||||
]
|
||||
},
|
||||
"fenced_code_block_go": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(go|golang)(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(go|golang)((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -891,7 +891,7 @@
|
||||
]
|
||||
},
|
||||
"fenced_code_block_groovy": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(groovy|gvy)(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(groovy|gvy)((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -924,7 +924,7 @@
|
||||
]
|
||||
},
|
||||
"fenced_code_block_pug": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(jade|pug)(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(jade|pug)((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -957,7 +957,7 @@
|
||||
]
|
||||
},
|
||||
"fenced_code_block_js": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(js|jsx|javascript|es6|mjs|\\{\\.js.+?\\})(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(js|jsx|javascript|es6|mjs|cjs|\\{\\.js.+?\\})((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -990,7 +990,7 @@
|
||||
]
|
||||
},
|
||||
"fenced_code_block_js_regexp": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(regexp)(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(regexp)((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -1023,7 +1023,7 @@
|
||||
]
|
||||
},
|
||||
"fenced_code_block_json": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(json|json5|sublime-settings|sublime-menu|sublime-keymap|sublime-mousemap|sublime-theme|sublime-build|sublime-project|sublime-completions)(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(json|json5|sublime-settings|sublime-menu|sublime-keymap|sublime-mousemap|sublime-theme|sublime-build|sublime-project|sublime-completions)((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -1056,7 +1056,7 @@
|
||||
]
|
||||
},
|
||||
"fenced_code_block_jsonc": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(jsonc)(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(jsonc)((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -1089,7 +1089,7 @@
|
||||
]
|
||||
},
|
||||
"fenced_code_block_less": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(less)(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(less)((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -1122,7 +1122,7 @@
|
||||
]
|
||||
},
|
||||
"fenced_code_block_objc": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(objectivec|objective-c|mm|objc|obj-c|m|h)(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(objectivec|objective-c|mm|objc|obj-c|m|h)((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -1155,7 +1155,7 @@
|
||||
]
|
||||
},
|
||||
"fenced_code_block_swift": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(swift)(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(swift)((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -1188,7 +1188,7 @@
|
||||
]
|
||||
},
|
||||
"fenced_code_block_scss": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(scss)(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(scss)((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -1221,7 +1221,7 @@
|
||||
]
|
||||
},
|
||||
"fenced_code_block_perl6": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(perl6|p6|pl6|pm6|nqp)(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(perl6|p6|pl6|pm6|nqp)((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -1254,7 +1254,7 @@
|
||||
]
|
||||
},
|
||||
"fenced_code_block_powershell": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(powershell|ps1|psm1|psd1)(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(powershell|ps1|psm1|psd1)((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -1287,7 +1287,7 @@
|
||||
]
|
||||
},
|
||||
"fenced_code_block_python": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(python|py|py3|rpy|pyw|cpy|SConstruct|Sconstruct|sconstruct|SConscript|gyp|gypi|\\{\\.python.+?\\})(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(python|py|py3|rpy|pyw|cpy|SConstruct|Sconstruct|sconstruct|SConscript|gyp|gypi|\\{\\.python.+?\\})((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -1320,7 +1320,7 @@
|
||||
]
|
||||
},
|
||||
"fenced_code_block_regexp_python": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(re)(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(re)((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -1353,7 +1353,7 @@
|
||||
]
|
||||
},
|
||||
"fenced_code_block_rust": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(rust|rs|\\{\\.rust.+?\\})(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(rust|rs|\\{\\.rust.+?\\})((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -1386,7 +1386,7 @@
|
||||
]
|
||||
},
|
||||
"fenced_code_block_scala": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(scala|sbt)(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(scala|sbt)((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -1419,7 +1419,7 @@
|
||||
]
|
||||
},
|
||||
"fenced_code_block_shell": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(shell|sh|bash|zsh|bashrc|bash_profile|bash_login|profile|bash_logout|.textmate_init|\\{\\.bash.+?\\})(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(shell|sh|bash|zsh|bashrc|bash_profile|bash_login|profile|bash_logout|.textmate_init|\\{\\.bash.+?\\})((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -1452,7 +1452,7 @@
|
||||
]
|
||||
},
|
||||
"fenced_code_block_ts": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(typescript|ts)(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(typescript|ts)((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -1485,7 +1485,7 @@
|
||||
]
|
||||
},
|
||||
"fenced_code_block_tsx": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(tsx)(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(tsx)((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -1518,7 +1518,7 @@
|
||||
]
|
||||
},
|
||||
"fenced_code_block_csharp": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(cs|csharp|c#)(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(cs|csharp|c#)((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -1551,7 +1551,7 @@
|
||||
]
|
||||
},
|
||||
"fenced_code_block_fsharp": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(fs|fsharp|f#)(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(fs|fsharp|f#)((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -1584,7 +1584,7 @@
|
||||
]
|
||||
},
|
||||
"fenced_code_block_dart": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(dart)(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(dart)((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -1617,7 +1617,7 @@
|
||||
]
|
||||
},
|
||||
"fenced_code_block_handlebars": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(handlebars|hbs)(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(handlebars|hbs)((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -1650,7 +1650,7 @@
|
||||
]
|
||||
},
|
||||
"fenced_code_block_markdown": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(markdown|md)(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(markdown|md)((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -1683,7 +1683,7 @@
|
||||
]
|
||||
},
|
||||
"fenced_code_block_log": {
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(log)(\\s+[^`~]*)?$)",
|
||||
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(log)((\\s+|:|\\{)[^`~]*)?$)",
|
||||
"name": "markup.fenced_code.block.markdown",
|
||||
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
|
||||
"beginCaptures": {
|
||||
@@ -2623,4 +2623,4 @@
|
||||
"name": "markup.inline.raw.string.markdown"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -129,15 +129,6 @@ h1, h2, h3 {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
h1 code,
|
||||
h2 code,
|
||||
h3 code,
|
||||
h4 code,
|
||||
h5 code,
|
||||
h6 code {
|
||||
line-height: auto;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -25,7 +25,9 @@
|
||||
"onCommand:markdown.showSource",
|
||||
"onCommand:markdown.showPreviewSecuritySelector",
|
||||
"onCommand:markdown.api.render",
|
||||
"onWebviewPanel:markdown.preview"
|
||||
"onCommand:notebook.showPreview",
|
||||
"onWebviewPanel:markdown.preview",
|
||||
"onWebviewEditor:vscode.markdown.preview.editor"
|
||||
],
|
||||
"contributes": {
|
||||
"commands": [
|
||||
@@ -307,6 +309,18 @@
|
||||
],
|
||||
"markdown.previewScripts": [
|
||||
"./media/index.js"
|
||||
],
|
||||
"webviewEditors": [
|
||||
{
|
||||
"viewType": "vscode.markdown.preview.editor",
|
||||
"displayName": "(Experimental) VS Code Markdown Preview",
|
||||
"priority": "option",
|
||||
"selector": [
|
||||
{
|
||||
"filenamePattern": "*.md"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"scripts": {
|
||||
@@ -327,14 +341,14 @@
|
||||
"@types/highlight.js": "9.12.3",
|
||||
"@types/lodash.throttle": "^4.1.3",
|
||||
"@types/markdown-it": "0.0.2",
|
||||
"@types/node": "^10.14.8",
|
||||
"@types/node": "^12.11.7",
|
||||
"lodash.throttle": "^4.1.1",
|
||||
"mocha-junit-reporter": "^1.17.0",
|
||||
"mocha-multi-reporters": "^1.1.7",
|
||||
"ts-loader": "^4.0.1",
|
||||
"typescript": "^3.3.1",
|
||||
"ts-loader": "^6.2.1",
|
||||
"typescript": "^3.7.2",
|
||||
"vscode": "^1.1.10",
|
||||
"webpack": "^4.1.0",
|
||||
"webpack-cli": "^2.0.10"
|
||||
"webpack": "^4.41.2",
|
||||
"webpack-cli": "^3.3.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@ document.addEventListener('dblclick', event => {
|
||||
}
|
||||
});
|
||||
|
||||
const passThroughLinkSchemes = ['http:', 'https:', 'mailto:', 'vscode:', 'vscode-insiders'];
|
||||
const passThroughLinkSchemes = ['http:', 'https:', 'mailto:', 'vscode:', 'vscode-insiders:'];
|
||||
|
||||
document.addEventListener('click', event => {
|
||||
if (!event) {
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
import { getSettings } from './settings';
|
||||
|
||||
const codeLineClass = 'code-line';
|
||||
|
||||
function clamp(min: number, max: number, value: number) {
|
||||
return Math.min(max, Math.max(min, value));
|
||||
@@ -25,9 +26,17 @@ const getCodeLineElements = (() => {
|
||||
return () => {
|
||||
if (!elements) {
|
||||
elements = [{ element: document.body, line: 0 }];
|
||||
for (const element of document.getElementsByClassName('code-line')) {
|
||||
for (const element of document.getElementsByClassName(codeLineClass)) {
|
||||
const line = +element.getAttribute('data-line')!;
|
||||
if (!isNaN(line)) {
|
||||
if (isNaN(line)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (element.tagName === 'CODE' && element.parentElement && element.parentElement.tagName === 'PRE') {
|
||||
// Fenched code blocks are a special case since the `code-line` can only be marked on
|
||||
// the `<code>` element and not the parent `<pre>` element.
|
||||
elements.push({ element: element.parentElement as HTMLElement, line });
|
||||
} else {
|
||||
elements.push({ element: element as HTMLElement, line });
|
||||
}
|
||||
}
|
||||
@@ -67,7 +76,7 @@ export function getLineElementsAtPageOffset(offset: number): { previous: CodeLin
|
||||
let hi = lines.length - 1;
|
||||
while (lo + 1 < hi) {
|
||||
const mid = Math.floor((lo + hi) / 2);
|
||||
const bounds = lines[mid].element.getBoundingClientRect();
|
||||
const bounds = getElementBounds(lines[mid]);
|
||||
if (bounds.top + bounds.height >= position) {
|
||||
hi = mid;
|
||||
}
|
||||
@@ -76,14 +85,35 @@ export function getLineElementsAtPageOffset(offset: number): { previous: CodeLin
|
||||
}
|
||||
}
|
||||
const hiElement = lines[hi];
|
||||
const hiBounds = hiElement.element.getBoundingClientRect();
|
||||
const hiBounds = getElementBounds(hiElement);
|
||||
if (hi >= 1 && hiBounds.top > position) {
|
||||
const loElement = lines[lo];
|
||||
return { previous: loElement, next: hiElement };
|
||||
}
|
||||
if (hi > 1 && hi < lines.length && hiBounds.top + hiBounds.height > position) {
|
||||
return { previous: hiElement, next: lines[hi + 1] };
|
||||
}
|
||||
return { previous: hiElement };
|
||||
}
|
||||
|
||||
function getElementBounds({ element }: CodeLineElement): { top: number, height: number } {
|
||||
const myBounds = element.getBoundingClientRect();
|
||||
|
||||
// Some code line elements may contain other code line elements.
|
||||
// In those cases, only take the height up to that child.
|
||||
const codeLineChild = element.querySelector(`.${codeLineClass}`);
|
||||
if (codeLineChild) {
|
||||
const childBounds = codeLineChild.getBoundingClientRect();
|
||||
const height = Math.max(1, (childBounds.top - myBounds.top));
|
||||
return {
|
||||
top: myBounds.top,
|
||||
height: height
|
||||
};
|
||||
}
|
||||
|
||||
return myBounds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to reveal the element for a source line in the editor.
|
||||
*/
|
||||
@@ -102,7 +132,7 @@ export function scrollToRevealSourceLine(line: number) {
|
||||
return;
|
||||
}
|
||||
let scrollTo = 0;
|
||||
const rect = previous.element.getBoundingClientRect();
|
||||
const rect = getElementBounds(previous);
|
||||
const previousTop = rect.top;
|
||||
if (next && next.line !== previous.line) {
|
||||
// Between two elements. Go to percentage offset between them.
|
||||
@@ -119,14 +149,13 @@ export function scrollToRevealSourceLine(line: number) {
|
||||
export function getEditorLineNumberForPageOffset(offset: number) {
|
||||
const { previous, next } = getLineElementsAtPageOffset(offset);
|
||||
if (previous) {
|
||||
const previousBounds = previous.element.getBoundingClientRect();
|
||||
const previousBounds = getElementBounds(previous);
|
||||
const offsetFromPrevious = (offset - window.scrollY - previousBounds.top);
|
||||
if (next) {
|
||||
const progressBetweenElements = offsetFromPrevious / (next.element.getBoundingClientRect().top - previousBounds.top);
|
||||
const progressBetweenElements = offsetFromPrevious / (getElementBounds(next).top - previousBounds.top);
|
||||
const line = previous.line + progressBetweenElements * (next.line - previous.line);
|
||||
return clampLine(line);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
const progressWithinElement = offsetFromPrevious / (previousBounds.height);
|
||||
const line = previous.line + progressWithinElement;
|
||||
return clampLine(line);
|
||||
|
||||
@@ -6,9 +6,8 @@
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
import { Command } from '../commandManager';
|
||||
import { MarkdownPreviewManager } from '../features/previewManager';
|
||||
import { MarkdownPreviewManager, DynamicPreviewSettings } from '../features/previewManager';
|
||||
import { TelemetryReporter } from '../telemetryReporter';
|
||||
import { PreviewSettings } from '../features/preview';
|
||||
|
||||
interface ShowPreviewSettings {
|
||||
readonly sideBySide?: boolean;
|
||||
@@ -39,7 +38,7 @@ async function showPreview(
|
||||
}
|
||||
|
||||
const resourceColumn = (vscode.window.activeTextEditor && vscode.window.activeTextEditor.viewColumn) || vscode.ViewColumn.One;
|
||||
webviewManager.preview(resource, {
|
||||
webviewManager.openDynamicPreview(resource, {
|
||||
resourceColumn: resourceColumn,
|
||||
previewColumn: previewSettings.sideBySide ? resourceColumn + 1 : resourceColumn,
|
||||
locked: !!previewSettings.locked
|
||||
@@ -59,7 +58,7 @@ export class ShowPreviewCommand implements Command {
|
||||
private readonly telemetryReporter: TelemetryReporter
|
||||
) { }
|
||||
|
||||
public execute(mainUri?: vscode.Uri, allUris?: vscode.Uri[], previewSettings?: PreviewSettings) {
|
||||
public execute(mainUri?: vscode.Uri, allUris?: vscode.Uri[], previewSettings?: DynamicPreviewSettings) {
|
||||
for (const uri of Array.isArray(allUris) ? allUris : [mainUri]) {
|
||||
showPreview(this.webviewManager, this.telemetryReporter, uri, {
|
||||
sideBySide: false,
|
||||
@@ -77,7 +76,7 @@ export class ShowPreviewToSideCommand implements Command {
|
||||
private readonly telemetryReporter: TelemetryReporter
|
||||
) { }
|
||||
|
||||
public execute(uri?: vscode.Uri, previewSettings?: PreviewSettings) {
|
||||
public execute(uri?: vscode.Uri, previewSettings?: DynamicPreviewSettings) {
|
||||
showPreview(this.webviewManager, this.telemetryReporter, uri, {
|
||||
sideBySide: true,
|
||||
locked: previewSettings && previewSettings.locked
|
||||
|
||||
@@ -54,9 +54,11 @@ function registerMarkdownLanguageFeatures(
|
||||
{ language: 'markdown', scheme: 'untitled' }
|
||||
];
|
||||
|
||||
const charPattern = '(\\p{Alphabetic}|\\p{Number}|\\p{Nonspacing_Mark})';
|
||||
|
||||
return vscode.Disposable.from(
|
||||
vscode.languages.setLanguageConfiguration('markdown', {
|
||||
wordPattern: new RegExp('(\\p{Alphabetic}|\\p{Number}|\\p{Nonspacing_Mark})+', 'ug'),
|
||||
wordPattern: new RegExp(`${charPattern}((${charPattern}|[_])?${charPattern})*`, 'ug'),
|
||||
}),
|
||||
vscode.languages.registerDocumentSymbolProvider(selector, symbolProvider),
|
||||
vscode.languages.registerDocumentLinkProvider(selector, new LinkProvider()),
|
||||
|
||||
@@ -7,7 +7,7 @@ import * as path from 'path';
|
||||
import * as vscode from 'vscode';
|
||||
import * as nls from 'vscode-nls';
|
||||
import { OpenDocumentLinkCommand } from '../commands/openDocumentLink';
|
||||
import { getUriForLinkWithKnownExternalScheme } from '../util/links';
|
||||
import { getUriForLinkWithKnownExternalScheme, isOfScheme, Schemes } from '../util/links';
|
||||
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
@@ -18,6 +18,10 @@ function parseLink(
|
||||
): { uri: vscode.Uri, tooltip?: string } {
|
||||
const externalSchemeUri = getUriForLinkWithKnownExternalScheme(link);
|
||||
if (externalSchemeUri) {
|
||||
// Normalize VS Code links to target currently running version
|
||||
if (isOfScheme(Schemes.vscode, link) || isOfScheme(Schemes['vscode-insiders'], link)) {
|
||||
return { uri: vscode.Uri.parse(link).with({ scheme: vscode.env.uriScheme }) };
|
||||
}
|
||||
return { uri: externalSchemeUri };
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import { MarkdownContentProvider } from './previewContentProvider';
|
||||
import { Disposable } from '../util/dispose';
|
||||
|
||||
import * as nls from 'vscode-nls';
|
||||
import { getVisibleLine, MarkdownFileTopmostLineMonitor } from '../util/topmostLineMonitor';
|
||||
import { getVisibleLine, TopmostLineMonitor } from '../util/topmostLineMonitor';
|
||||
import { MarkdownPreviewConfigurationManager } from './previewConfig';
|
||||
import { MarkdownContributionProvider, MarkdownContributions } from '../markdownExtensions';
|
||||
import { isMarkdownFile } from '../util/file';
|
||||
@@ -72,11 +72,22 @@ export class PreviewDocumentVersion {
|
||||
}
|
||||
}
|
||||
|
||||
export class MarkdownPreview extends Disposable {
|
||||
interface DynamicPreviewInput {
|
||||
readonly resource: vscode.Uri;
|
||||
readonly resourceColumn: vscode.ViewColumn;
|
||||
readonly locked: boolean;
|
||||
readonly line?: number;
|
||||
}
|
||||
|
||||
export class DynamicMarkdownPreview extends Disposable {
|
||||
|
||||
public static readonly viewType = 'markdown.preview';
|
||||
|
||||
private readonly delay = 300;
|
||||
|
||||
private _resource: vscode.Uri;
|
||||
private readonly _resourceColumn: vscode.ViewColumn;
|
||||
|
||||
private _locked: boolean;
|
||||
|
||||
private readonly editor: vscode.WebviewPanel;
|
||||
@@ -84,92 +95,65 @@ export class MarkdownPreview extends Disposable {
|
||||
private line: number | undefined = undefined;
|
||||
private firstUpdate = true;
|
||||
private currentVersion?: PreviewDocumentVersion;
|
||||
private forceUpdate = false;
|
||||
private isScrolling = false;
|
||||
private _disposed: boolean = false;
|
||||
private imageInfo: { id: string, width: number, height: number; }[] = [];
|
||||
private scrollToFragment: string | undefined;
|
||||
|
||||
public static async revive(
|
||||
public static revive(
|
||||
input: DynamicPreviewInput,
|
||||
webview: vscode.WebviewPanel,
|
||||
state: any,
|
||||
contentProvider: MarkdownContentProvider,
|
||||
previewConfigurations: MarkdownPreviewConfigurationManager,
|
||||
logger: Logger,
|
||||
topmostLineMonitor: MarkdownFileTopmostLineMonitor,
|
||||
topmostLineMonitor: TopmostLineMonitor,
|
||||
contributionProvider: MarkdownContributionProvider,
|
||||
): Promise<MarkdownPreview> {
|
||||
const resource = vscode.Uri.parse(state.resource);
|
||||
const locked = state.locked;
|
||||
const line = state.line;
|
||||
const resourceColumn = state.resourceColumn;
|
||||
): DynamicMarkdownPreview {
|
||||
webview.webview.options = DynamicMarkdownPreview.getWebviewOptions(input.resource, contributionProvider.contributions);
|
||||
webview.title = DynamicMarkdownPreview.getPreviewTitle(input.resource, input.locked);
|
||||
|
||||
const preview = new MarkdownPreview(
|
||||
webview,
|
||||
resource,
|
||||
locked,
|
||||
resourceColumn,
|
||||
contentProvider,
|
||||
previewConfigurations,
|
||||
logger,
|
||||
topmostLineMonitor,
|
||||
contributionProvider);
|
||||
|
||||
preview.editor.webview.options = MarkdownPreview.getWebviewOptions(resource, contributionProvider.contributions);
|
||||
|
||||
if (!isNaN(line)) {
|
||||
preview.line = line;
|
||||
}
|
||||
await preview.doUpdate();
|
||||
return preview;
|
||||
return new DynamicMarkdownPreview(webview, input,
|
||||
contentProvider, previewConfigurations, logger, topmostLineMonitor, contributionProvider);
|
||||
}
|
||||
|
||||
public static create(
|
||||
resource: vscode.Uri,
|
||||
input: DynamicPreviewInput,
|
||||
previewColumn: vscode.ViewColumn,
|
||||
resourceColumn: vscode.ViewColumn,
|
||||
locked: boolean,
|
||||
contentProvider: MarkdownContentProvider,
|
||||
previewConfigurations: MarkdownPreviewConfigurationManager,
|
||||
logger: Logger,
|
||||
topmostLineMonitor: MarkdownFileTopmostLineMonitor,
|
||||
topmostLineMonitor: TopmostLineMonitor,
|
||||
contributionProvider: MarkdownContributionProvider
|
||||
): MarkdownPreview {
|
||||
): DynamicMarkdownPreview {
|
||||
const webview = vscode.window.createWebviewPanel(
|
||||
MarkdownPreview.viewType,
|
||||
MarkdownPreview.getPreviewTitle(resource, locked),
|
||||
DynamicMarkdownPreview.viewType,
|
||||
DynamicMarkdownPreview.getPreviewTitle(input.resource, input.locked),
|
||||
previewColumn, {
|
||||
enableFindWidget: true,
|
||||
...MarkdownPreview.getWebviewOptions(resource, contributionProvider.contributions)
|
||||
...DynamicMarkdownPreview.getWebviewOptions(input.resource, contributionProvider.contributions)
|
||||
});
|
||||
|
||||
return new MarkdownPreview(
|
||||
webview,
|
||||
resource,
|
||||
locked,
|
||||
resourceColumn,
|
||||
contentProvider,
|
||||
previewConfigurations,
|
||||
logger,
|
||||
topmostLineMonitor,
|
||||
contributionProvider);
|
||||
return new DynamicMarkdownPreview(webview, input,
|
||||
contentProvider, previewConfigurations, logger, topmostLineMonitor, contributionProvider);
|
||||
}
|
||||
|
||||
private constructor(
|
||||
webview: vscode.WebviewPanel,
|
||||
resource: vscode.Uri,
|
||||
locked: boolean,
|
||||
private readonly _resourceColumn: vscode.ViewColumn,
|
||||
input: DynamicPreviewInput,
|
||||
private readonly _contentProvider: MarkdownContentProvider,
|
||||
private readonly _previewConfigurations: MarkdownPreviewConfigurationManager,
|
||||
private readonly _logger: Logger,
|
||||
topmostLineMonitor: MarkdownFileTopmostLineMonitor,
|
||||
topmostLineMonitor: TopmostLineMonitor,
|
||||
private readonly _contributionProvider: MarkdownContributionProvider,
|
||||
) {
|
||||
super();
|
||||
this._resource = resource;
|
||||
this._locked = locked;
|
||||
this._resource = input.resource;
|
||||
this._resourceColumn = input.resourceColumn;
|
||||
this._locked = input.locked;
|
||||
this.editor = webview;
|
||||
if (!isNaN(input.line!)) {
|
||||
this.line = input.line;
|
||||
}
|
||||
|
||||
this._register(this.editor.onDidDispose(() => {
|
||||
this.dispose();
|
||||
@@ -190,7 +174,7 @@ export class MarkdownPreview extends Disposable {
|
||||
|
||||
switch (e.type) {
|
||||
case 'cacheImageSizes':
|
||||
this.onCacheImageSizes(e.body);
|
||||
this.imageInfo = e.body;
|
||||
break;
|
||||
|
||||
case 'revealLine':
|
||||
@@ -221,7 +205,7 @@ export class MarkdownPreview extends Disposable {
|
||||
}
|
||||
}));
|
||||
|
||||
this._register(topmostLineMonitor.onDidChangeTopmostLine(event => {
|
||||
this._register(topmostLineMonitor.onDidChanged(event => {
|
||||
if (this.isPreviewOf(event.resource)) {
|
||||
this.updateForView(event.resource, event.line);
|
||||
}
|
||||
@@ -239,9 +223,11 @@ export class MarkdownPreview extends Disposable {
|
||||
|
||||
this._register(vscode.window.onDidChangeActiveTextEditor(editor => {
|
||||
if (editor && isMarkdownFile(editor.document) && !this._locked) {
|
||||
this.update(editor.document.uri);
|
||||
this.update(editor.document.uri, false);
|
||||
}
|
||||
}));
|
||||
|
||||
this.doUpdate();
|
||||
}
|
||||
|
||||
private readonly _onDisposeEmitter = this._register(new vscode.EventEmitter<void>());
|
||||
@@ -278,7 +264,6 @@ export class MarkdownPreview extends Disposable {
|
||||
this._onDisposeEmitter.fire();
|
||||
this._onDisposeEmitter.dispose();
|
||||
|
||||
this._onDidChangeViewStateEmitter.dispose();
|
||||
this.editor.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
@@ -297,7 +282,6 @@ export class MarkdownPreview extends Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// If we have changed resources, cancel any pending updates
|
||||
const isResourceChange = resource.fsPath !== this._resource.fsPath;
|
||||
if (isResourceChange) {
|
||||
@@ -310,9 +294,9 @@ export class MarkdownPreview extends Disposable {
|
||||
// Schedule update if none is pending
|
||||
if (!this.throttleTimer) {
|
||||
if (isResourceChange || this.firstUpdate) {
|
||||
this.doUpdate();
|
||||
this.doUpdate(isRefresh);
|
||||
} else {
|
||||
this.throttleTimer = setTimeout(() => this.doUpdate(), 300);
|
||||
this.throttleTimer = setTimeout(() => this.doUpdate(isRefresh), this.delay);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -320,7 +304,6 @@ export class MarkdownPreview extends Disposable {
|
||||
}
|
||||
|
||||
public refresh() {
|
||||
this.forceUpdate = true;
|
||||
this.update(this._resource, true);
|
||||
}
|
||||
|
||||
@@ -350,7 +333,7 @@ export class MarkdownPreview extends Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
public matches(otherPreview: MarkdownPreview): boolean {
|
||||
public matches(otherPreview: DynamicMarkdownPreview): boolean {
|
||||
return this.matchesResource(otherPreview._resource, otherPreview.position, otherPreview._locked);
|
||||
}
|
||||
|
||||
@@ -360,7 +343,7 @@ export class MarkdownPreview extends Disposable {
|
||||
|
||||
public toggleLock() {
|
||||
this._locked = !this._locked;
|
||||
this.editor.title = MarkdownPreview.getPreviewTitle(this._resource, this._locked);
|
||||
this.editor.title = DynamicMarkdownPreview.getPreviewTitle(this._resource, this._locked);
|
||||
}
|
||||
|
||||
private get iconPath() {
|
||||
@@ -408,7 +391,7 @@ export class MarkdownPreview extends Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
private async doUpdate(): Promise<void> {
|
||||
private async doUpdate(forceUpdate?: boolean): Promise<void> {
|
||||
if (this._disposed) {
|
||||
return;
|
||||
}
|
||||
@@ -431,13 +414,12 @@ export class MarkdownPreview extends Disposable {
|
||||
}
|
||||
|
||||
const pendingVersion = new PreviewDocumentVersion(markdownResource, document.version);
|
||||
if (!this.forceUpdate && this.currentVersion && this.currentVersion.equals(pendingVersion)) {
|
||||
if (!forceUpdate && this.currentVersion?.equals(pendingVersion)) {
|
||||
if (this.line) {
|
||||
this.updateForView(markdownResource, this.line);
|
||||
}
|
||||
return;
|
||||
}
|
||||
this.forceUpdate = false;
|
||||
|
||||
this.currentVersion = pendingVersion;
|
||||
if (this._resource === markdownResource) {
|
||||
@@ -463,7 +445,7 @@ export class MarkdownPreview extends Disposable {
|
||||
): vscode.WebviewOptions {
|
||||
return {
|
||||
enableScripts: true,
|
||||
localResourceRoots: MarkdownPreview.getLocalResourceRoots(resource, contributions)
|
||||
localResourceRoots: DynamicMarkdownPreview.getLocalResourceRoots(resource, contributions)
|
||||
};
|
||||
}
|
||||
|
||||
@@ -508,6 +490,9 @@ export class MarkdownPreview extends Disposable {
|
||||
}
|
||||
|
||||
private async onDidClickPreview(line: number): Promise<void> {
|
||||
// fix #82457, find currently opened but unfocused source tab
|
||||
await vscode.commands.executeCommand('markdown.showSource');
|
||||
|
||||
for (const visibleEditor of vscode.window.visibleTextEditors) {
|
||||
if (this.isPreviewOf(visibleEditor.document.uri)) {
|
||||
const editor = await vscode.window.showTextDocument(visibleEditor.document, visibleEditor.viewColumn);
|
||||
@@ -529,9 +514,9 @@ export class MarkdownPreview extends Disposable {
|
||||
}
|
||||
|
||||
private setContent(html: string): void {
|
||||
this.editor.title = MarkdownPreview.getPreviewTitle(this._resource, this._locked);
|
||||
this.editor.title = DynamicMarkdownPreview.getPreviewTitle(this._resource, this._locked);
|
||||
this.editor.iconPath = this.iconPath;
|
||||
this.editor.webview.options = MarkdownPreview.getWebviewOptions(this._resource, this._contributionProvider.contributions);
|
||||
this.editor.webview.options = DynamicMarkdownPreview.getWebviewOptions(this._resource, this._contributionProvider.contributions);
|
||||
this.editor.webview.html = html;
|
||||
}
|
||||
|
||||
@@ -559,14 +544,4 @@ export class MarkdownPreview extends Disposable {
|
||||
|
||||
vscode.commands.executeCommand('_markdown.openDocumentLink', { path: hrefPath, fragment, fromResource: this.resource });
|
||||
}
|
||||
|
||||
private async onCacheImageSizes(imageInfo: { id: string, width: number, height: number; }[]) {
|
||||
this.imageInfo = imageInfo;
|
||||
}
|
||||
}
|
||||
|
||||
export interface PreviewSettings {
|
||||
readonly resourceColumn: vscode.ViewColumn;
|
||||
readonly previewColumn: vscode.ViewColumn;
|
||||
readonly locked: boolean;
|
||||
}
|
||||
|
||||
@@ -7,19 +7,61 @@ import * as vscode from 'vscode';
|
||||
import { Logger } from '../logger';
|
||||
import { MarkdownContributionProvider } from '../markdownExtensions';
|
||||
import { disposeAll, Disposable } from '../util/dispose';
|
||||
import { MarkdownFileTopmostLineMonitor } from '../util/topmostLineMonitor';
|
||||
import { MarkdownPreview, PreviewSettings } from './preview';
|
||||
import { TopmostLineMonitor } from '../util/topmostLineMonitor';
|
||||
import { DynamicMarkdownPreview } from './preview';
|
||||
import { MarkdownPreviewConfigurationManager } from './previewConfig';
|
||||
import { MarkdownContentProvider } from './previewContentProvider';
|
||||
|
||||
export interface DynamicPreviewSettings {
|
||||
readonly resourceColumn: vscode.ViewColumn;
|
||||
readonly previewColumn: vscode.ViewColumn;
|
||||
readonly locked: boolean;
|
||||
}
|
||||
|
||||
export class MarkdownPreviewManager extends Disposable implements vscode.WebviewPanelSerializer {
|
||||
class PreviewStore extends Disposable {
|
||||
|
||||
private readonly _previews = new Set<DynamicMarkdownPreview>();
|
||||
|
||||
public dispose(): void {
|
||||
super.dispose();
|
||||
for (const preview of this._previews) {
|
||||
preview.dispose();
|
||||
}
|
||||
this._previews.clear();
|
||||
}
|
||||
|
||||
[Symbol.iterator](): Iterator<DynamicMarkdownPreview> {
|
||||
return this._previews[Symbol.iterator]();
|
||||
}
|
||||
|
||||
public get(resource: vscode.Uri, previewSettings: DynamicPreviewSettings): DynamicMarkdownPreview | undefined {
|
||||
for (const preview of this._previews) {
|
||||
if (preview.matchesResource(resource, previewSettings.previewColumn, previewSettings.locked)) {
|
||||
return preview;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public add(preview: DynamicMarkdownPreview) {
|
||||
this._previews.add(preview);
|
||||
}
|
||||
|
||||
public delete(preview: DynamicMarkdownPreview) {
|
||||
this._previews.delete(preview);
|
||||
}
|
||||
}
|
||||
|
||||
export class MarkdownPreviewManager extends Disposable implements vscode.WebviewPanelSerializer, vscode.WebviewEditorProvider {
|
||||
private static readonly markdownPreviewActiveContextKey = 'markdownPreviewFocus';
|
||||
|
||||
private readonly _topmostLineMonitor = new MarkdownFileTopmostLineMonitor();
|
||||
private readonly _topmostLineMonitor = new TopmostLineMonitor();
|
||||
private readonly _previewConfigurations = new MarkdownPreviewConfigurationManager();
|
||||
private readonly _previews: MarkdownPreview[] = [];
|
||||
private _activePreview: MarkdownPreview | undefined = undefined;
|
||||
|
||||
private readonly _dynamicPreviews = this._register(new PreviewStore());
|
||||
private readonly _staticPreviews = this._register(new PreviewStore());
|
||||
|
||||
private _activePreview: DynamicMarkdownPreview | undefined = undefined;
|
||||
|
||||
public constructor(
|
||||
private readonly _contentProvider: MarkdownContentProvider,
|
||||
@@ -27,46 +69,48 @@ export class MarkdownPreviewManager extends Disposable implements vscode.Webview
|
||||
private readonly _contributions: MarkdownContributionProvider
|
||||
) {
|
||||
super();
|
||||
this._register(vscode.window.registerWebviewPanelSerializer(MarkdownPreview.viewType, this));
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
super.dispose();
|
||||
disposeAll(this._previews);
|
||||
this._register(vscode.window.registerWebviewPanelSerializer(DynamicMarkdownPreview.viewType, this));
|
||||
this._register(vscode.window.registerWebviewEditorProvider('vscode.markdown.preview.editor', this));
|
||||
}
|
||||
|
||||
public refresh() {
|
||||
for (const preview of this._previews) {
|
||||
for (const preview of this._dynamicPreviews) {
|
||||
preview.refresh();
|
||||
}
|
||||
for (const preview of this._staticPreviews) {
|
||||
preview.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
public updateConfiguration() {
|
||||
for (const preview of this._previews) {
|
||||
for (const preview of this._dynamicPreviews) {
|
||||
preview.updateConfiguration();
|
||||
}
|
||||
for (const preview of this._staticPreviews) {
|
||||
preview.updateConfiguration();
|
||||
}
|
||||
}
|
||||
|
||||
public preview(
|
||||
public openDynamicPreview(
|
||||
resource: vscode.Uri,
|
||||
previewSettings: PreviewSettings
|
||||
settings: DynamicPreviewSettings
|
||||
): void {
|
||||
let preview = this.getExistingPreview(resource, previewSettings);
|
||||
let preview = this._dynamicPreviews.get(resource, settings);
|
||||
if (preview) {
|
||||
preview.reveal(previewSettings.previewColumn);
|
||||
preview.reveal(settings.previewColumn);
|
||||
} else {
|
||||
preview = this.createNewPreview(resource, previewSettings);
|
||||
preview = this.createNewDynamicPreview(resource, settings);
|
||||
}
|
||||
|
||||
preview.update(resource);
|
||||
}
|
||||
|
||||
public get activePreviewResource() {
|
||||
return this._activePreview && this._activePreview.resource;
|
||||
return this._activePreview?.resource;
|
||||
}
|
||||
|
||||
public get activePreviewResourceColumn() {
|
||||
return this._activePreview && this._activePreview.resourceColumn;
|
||||
return this._activePreview?.resourceColumn;
|
||||
}
|
||||
|
||||
public toggleLock() {
|
||||
@@ -75,7 +119,7 @@ export class MarkdownPreviewManager extends Disposable implements vscode.Webview
|
||||
preview.toggleLock();
|
||||
|
||||
// Close any previews that are now redundant, such as having two dynamic previews in the same editor group
|
||||
for (const otherPreview of this._previews) {
|
||||
for (const otherPreview of this._dynamicPreviews) {
|
||||
if (otherPreview !== preview && preview.matches(otherPreview)) {
|
||||
otherPreview.dispose();
|
||||
}
|
||||
@@ -87,35 +131,50 @@ export class MarkdownPreviewManager extends Disposable implements vscode.Webview
|
||||
webview: vscode.WebviewPanel,
|
||||
state: any
|
||||
): Promise<void> {
|
||||
const preview = await MarkdownPreview.revive(
|
||||
const resource = vscode.Uri.parse(state.resource);
|
||||
const locked = state.locked;
|
||||
const line = state.line;
|
||||
const resourceColumn = state.resourceColumn;
|
||||
|
||||
const preview = await DynamicMarkdownPreview.revive(
|
||||
{ resource, locked, line, resourceColumn },
|
||||
webview,
|
||||
state,
|
||||
this._contentProvider,
|
||||
this._previewConfigurations,
|
||||
this._logger,
|
||||
this._topmostLineMonitor,
|
||||
this._contributions);
|
||||
|
||||
this.registerPreview(preview);
|
||||
this.registerDynamicPreview(preview);
|
||||
}
|
||||
|
||||
private getExistingPreview(
|
||||
resource: vscode.Uri,
|
||||
previewSettings: PreviewSettings
|
||||
): MarkdownPreview | undefined {
|
||||
return this._previews.find(preview =>
|
||||
preview.matchesResource(resource, previewSettings.previewColumn, previewSettings.locked));
|
||||
public async resolveWebviewEditor(
|
||||
input: { readonly resource: vscode.Uri; },
|
||||
webview: vscode.WebviewPanel
|
||||
): Promise<vscode.WebviewEditorCapabilities> {
|
||||
const preview = DynamicMarkdownPreview.revive(
|
||||
{ resource: input.resource, locked: false, resourceColumn: vscode.ViewColumn.One },
|
||||
webview,
|
||||
this._contentProvider,
|
||||
this._previewConfigurations,
|
||||
this._logger,
|
||||
this._topmostLineMonitor,
|
||||
this._contributions);
|
||||
this.registerStaticPreview(preview);
|
||||
return {};
|
||||
}
|
||||
|
||||
private createNewPreview(
|
||||
private createNewDynamicPreview(
|
||||
resource: vscode.Uri,
|
||||
previewSettings: PreviewSettings
|
||||
): MarkdownPreview {
|
||||
const preview = MarkdownPreview.create(
|
||||
resource,
|
||||
previewSettings: DynamicPreviewSettings
|
||||
): DynamicMarkdownPreview {
|
||||
const preview = DynamicMarkdownPreview.create(
|
||||
{
|
||||
resource,
|
||||
resourceColumn: previewSettings.resourceColumn,
|
||||
locked: previewSettings.locked,
|
||||
},
|
||||
previewSettings.previewColumn,
|
||||
previewSettings.resourceColumn,
|
||||
previewSettings.locked,
|
||||
this._contentProvider,
|
||||
this._previewConfigurations,
|
||||
this._logger,
|
||||
@@ -124,34 +183,48 @@ export class MarkdownPreviewManager extends Disposable implements vscode.Webview
|
||||
|
||||
this.setPreviewActiveContext(true);
|
||||
this._activePreview = preview;
|
||||
return this.registerPreview(preview);
|
||||
return this.registerDynamicPreview(preview);
|
||||
}
|
||||
|
||||
private registerPreview(
|
||||
preview: MarkdownPreview
|
||||
): MarkdownPreview {
|
||||
this._previews.push(preview);
|
||||
private registerDynamicPreview(preview: DynamicMarkdownPreview): DynamicMarkdownPreview {
|
||||
this._dynamicPreviews.add(preview);
|
||||
|
||||
preview.onDispose(() => {
|
||||
const existing = this._previews.indexOf(preview);
|
||||
if (existing === -1) {
|
||||
return;
|
||||
}
|
||||
this._dynamicPreviews.delete(preview);
|
||||
});
|
||||
|
||||
this._previews.splice(existing, 1);
|
||||
this.trackActive(preview);
|
||||
|
||||
preview.onDidChangeViewState(() => {
|
||||
// Remove other dynamic previews in our column
|
||||
disposeAll(Array.from(this._dynamicPreviews).filter(otherPreview => preview !== otherPreview && preview.matches(otherPreview)));
|
||||
});
|
||||
return preview;
|
||||
}
|
||||
|
||||
private registerStaticPreview(preview: DynamicMarkdownPreview): DynamicMarkdownPreview {
|
||||
this._staticPreviews.add(preview);
|
||||
|
||||
preview.onDispose(() => {
|
||||
this._staticPreviews.delete(preview);
|
||||
});
|
||||
|
||||
this.trackActive(preview);
|
||||
return preview;
|
||||
}
|
||||
|
||||
private trackActive(preview: DynamicMarkdownPreview): void {
|
||||
preview.onDidChangeViewState(({ webviewPanel }) => {
|
||||
this.setPreviewActiveContext(webviewPanel.active);
|
||||
this._activePreview = webviewPanel.active ? preview : undefined;
|
||||
});
|
||||
|
||||
preview.onDispose(() => {
|
||||
if (this._activePreview === preview) {
|
||||
this.setPreviewActiveContext(false);
|
||||
this._activePreview = undefined;
|
||||
}
|
||||
});
|
||||
|
||||
preview.onDidChangeViewState(({ webviewPanel }) => {
|
||||
disposeAll(this._previews.filter(otherPreview => preview !== otherPreview && preview!.matches(otherPreview)));
|
||||
this.setPreviewActiveContext(webviewPanel.active);
|
||||
this._activePreview = webviewPanel.active ? preview : undefined;
|
||||
});
|
||||
|
||||
return preview;
|
||||
}
|
||||
|
||||
private setPreviewActiveContext(value: boolean) {
|
||||
|
||||
@@ -41,13 +41,21 @@ export class Logger {
|
||||
|
||||
public log(message: string, data?: any): void {
|
||||
if (this.trace === Trace.Verbose) {
|
||||
this.appendLine(`[Log - ${(new Date().toLocaleTimeString())}] ${message}`);
|
||||
this.appendLine(`[Log - ${this.now()}] ${message}`);
|
||||
if (data) {
|
||||
this.appendLine(Logger.data2String(data));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private now(): string {
|
||||
const now = new Date();
|
||||
return padLeft(now.getUTCHours() + '', 2, '0')
|
||||
+ ':' + padLeft(now.getMinutes() + '', 2, '0')
|
||||
+ ':' + padLeft(now.getUTCSeconds() + '', 2, '0') + '.' + now.getMilliseconds();
|
||||
}
|
||||
|
||||
public updateConfiguration() {
|
||||
this.trace = this.readTrace();
|
||||
}
|
||||
@@ -73,3 +81,7 @@ export class Logger {
|
||||
return JSON.stringify(data, undefined, 2);
|
||||
}
|
||||
}
|
||||
|
||||
function padLeft(s: string, n: number, pad = ' ') {
|
||||
return pad.repeat(Math.max(0, n - s.length)) + s;
|
||||
}
|
||||
|
||||
@@ -234,6 +234,11 @@ export class MarkdownEngine {
|
||||
const normalizeLink = md.normalizeLink;
|
||||
md.normalizeLink = (link: string) => {
|
||||
try {
|
||||
// Normalize VS Code schemes to target the current version
|
||||
if (isOfScheme(Schemes.vscode, link) || isOfScheme(Schemes['vscode-insiders'], link)) {
|
||||
return normalizeLink(vscode.Uri.parse(link).with({ scheme: vscode.env.uriScheme }).toString());
|
||||
}
|
||||
|
||||
// If original link doesn't look like a url with a scheme, assume it must be a link to a file in workspace
|
||||
if (!/^[a-z\-]+:/i.test(link)) {
|
||||
// Use a fake scheme for parsing
|
||||
@@ -268,7 +273,11 @@ export class MarkdownEngine {
|
||||
const validateLink = md.validateLink;
|
||||
md.validateLink = (link: string) => {
|
||||
// support file:// links
|
||||
return validateLink(link) || isOfScheme(Schemes.file, link) || /^data:image\/.*?;/.test(link);
|
||||
return validateLink(link)
|
||||
|| isOfScheme(Schemes.file, link)
|
||||
|| isOfScheme(Schemes.vscode, link)
|
||||
|| isOfScheme(Schemes['vscode-insiders'], link)
|
||||
|| /^data:image\/.*?;/.test(link);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ const suite = 'Integration Markdown Tests';
|
||||
|
||||
const options: any = {
|
||||
ui: 'tdd',
|
||||
useColors: true,
|
||||
useColors: (!process.env.BUILD_ARTIFACTSTAGINGDIRECTORY && process.platform !== 'win32'),
|
||||
timeout: 60000
|
||||
};
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ export const Schemes = {
|
||||
data: 'data:',
|
||||
vscode: 'vscode:',
|
||||
'vscode-insiders': 'vscode-insiders:',
|
||||
'vscode-resource': 'vscode-resource',
|
||||
'vscode-resource': 'vscode-resource:',
|
||||
};
|
||||
|
||||
const knownSchemes = [
|
||||
|
||||
@@ -4,33 +4,28 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import { disposeAll } from '../util/dispose';
|
||||
import { Disposable } from '../util/dispose';
|
||||
import { isMarkdownFile } from './file';
|
||||
|
||||
export class MarkdownFileTopmostLineMonitor {
|
||||
private readonly disposables: vscode.Disposable[] = [];
|
||||
export class TopmostLineMonitor extends Disposable {
|
||||
|
||||
private readonly pendingUpdates = new Map<string, number>();
|
||||
|
||||
private readonly throttle = 50;
|
||||
|
||||
constructor() {
|
||||
vscode.window.onDidChangeTextEditorVisibleRanges(event => {
|
||||
super();
|
||||
this._register(vscode.window.onDidChangeTextEditorVisibleRanges(event => {
|
||||
if (isMarkdownFile(event.textEditor.document)) {
|
||||
const line = getVisibleLine(event.textEditor);
|
||||
if (typeof line === 'number') {
|
||||
this.updateLine(event.textEditor.document.uri, line);
|
||||
}
|
||||
}
|
||||
}, null, this.disposables);
|
||||
}));
|
||||
}
|
||||
|
||||
dispose() {
|
||||
disposeAll(this.disposables);
|
||||
}
|
||||
|
||||
private readonly _onDidChangeTopmostLineEmitter = new vscode.EventEmitter<{ resource: vscode.Uri, line: number }>();
|
||||
public readonly onDidChangeTopmostLine = this._onDidChangeTopmostLineEmitter.event;
|
||||
private readonly _onChanged = this._register(new vscode.EventEmitter<{ readonly resource: vscode.Uri, readonly line: number }>());
|
||||
public readonly onDidChanged = this._onChanged.event;
|
||||
|
||||
private updateLine(
|
||||
resource: vscode.Uri,
|
||||
@@ -41,7 +36,7 @@ export class MarkdownFileTopmostLineMonitor {
|
||||
// schedule update
|
||||
setTimeout(() => {
|
||||
if (this.pendingUpdates.has(key)) {
|
||||
this._onDidChangeTopmostLineEmitter.fire({
|
||||
this._onChanged.fire({
|
||||
resource,
|
||||
line: this.pendingUpdates.get(key) as number
|
||||
});
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -138,6 +138,6 @@
|
||||
"vscode-nls": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^10.14.8"
|
||||
"@types/node": "^12.11.7"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ export class DocumentMergeConflict implements interfaces.IDocumentMergeConflict
|
||||
public applyEdit(type: interfaces.CommitType, document: vscode.TextDocument, edit: { replace(range: vscode.Range, newText: string): void; }): void {
|
||||
|
||||
// Each conflict is a set of ranges as follows, note placements or newlines
|
||||
// which may not in in spans
|
||||
// which may not in spans
|
||||
// [ Conflict Range -- (Entire content below)
|
||||
// [ Current Header ]\n -- >>>>> Header
|
||||
// [ Current Content ] -- (content)
|
||||
@@ -75,4 +75,4 @@ export class DocumentMergeConflict implements interfaces.IDocumentMergeConflict
|
||||
private isNewlineOnly(text: string) {
|
||||
return text === '\n' || text === '\r\n';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@types/node@^10.14.8":
|
||||
version "10.14.8"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.8.tgz#fe444203ecef1162348cd6deb76c62477b2cc6e9"
|
||||
integrity sha512-I4+DbJEhLEg4/vIy/2gkWDvXBOOtPKV9EnLhYjMoqxcRW+TTZtUftkHktz/a8suoD5mUL7m6ReLrkPvSsCQQmw==
|
||||
"@types/node@^12.11.7":
|
||||
version "12.11.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.11.7.tgz#57682a9771a3f7b09c2497f28129a0462966524a"
|
||||
integrity sha512-JNbGaHFCLwgHn/iCckiGSOZ1XYHsKFwREtzPwSGCVld1SGhOlmZw2D4ZI94HQCrBHbADzW9m4LER/8olJTRGHA==
|
||||
|
||||
vscode-nls@^4.0.0:
|
||||
version "4.0.0"
|
||||
|
||||
@@ -457,7 +457,7 @@
|
||||
"@types/glob": "^7.1.1",
|
||||
"@types/js-yaml": "^3.12.1",
|
||||
"@types/mocha": "^5.2.5",
|
||||
"@types/node": "^11.9.3",
|
||||
"@types/node": "^12.11.7",
|
||||
"@types/request": "^2.48.1",
|
||||
"@types/rimraf": "^2.0.2",
|
||||
"@types/temp-write": "^3.3.0",
|
||||
|
||||
@@ -161,10 +161,10 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-11.13.4.tgz#f83ec3c3e05b174b7241fadeb6688267fe5b22ca"
|
||||
integrity sha512-+rabAZZ3Yn7tF/XPGHupKIL5EcAbrLxnTr/hgQICxbeuAfWtT0UZSfULE+ndusckBItcv4o6ZeOJplQikVcLvQ==
|
||||
|
||||
"@types/node@^11.9.3":
|
||||
version "11.9.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-11.9.3.tgz#14adbb5ab8cd563f549fbae8dbe92e0b7d6e76cc"
|
||||
integrity sha512-DMiqG51GwES/c4ScBY0u5bDlH44+oY8AeYHjY1SGCWidD7h08o1dfHue/TGK7REmif2KiJzaUskO+Q0eaeZ2fQ==
|
||||
"@types/node@^12.11.7":
|
||||
version "12.12.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.7.tgz#01e4ea724d9e3bd50d90c11fd5980ba317d8fa11"
|
||||
integrity sha512-E6Zn0rffhgd130zbCbAr/JdXfXkoOUFAKNs/rF8qnafSJ8KYaA/j3oz7dcwal+lYjLA7xvdd5J4wdYpCTlP8+w==
|
||||
|
||||
"@types/request@^2.48.1":
|
||||
version "2.48.1"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"version": "0.0.1",
|
||||
"description": "Dependencies shared by all extensions",
|
||||
"dependencies": {
|
||||
"typescript": "3.7.2"
|
||||
"typescript": "3.7.3-insiders.20191123"
|
||||
},
|
||||
"scripts": {
|
||||
"postinstall": "node ./postinstall"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"git": {
|
||||
"name": "MagicStack/MagicPython",
|
||||
"repositoryUrl": "https://github.com/MagicStack/MagicPython",
|
||||
"commitHash": "38422d302fe0b3e7716d26ce8cd7d0b9685f3a38"
|
||||
"commitHash": "c0f8d514bbe6e9d3899f2b002bcd6971aef5e34b"
|
||||
}
|
||||
},
|
||||
"license": "MIT",
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
|
||||
"Once accepted there, we are happy to receive an update request."
|
||||
],
|
||||
"version": "https://github.com/MagicStack/MagicPython/commit/38422d302fe0b3e7716d26ce8cd7d0b9685f3a38",
|
||||
"version": "https://github.com/MagicStack/MagicPython/commit/c0f8d514bbe6e9d3899f2b002bcd6971aef5e34b",
|
||||
"name": "MagicPython",
|
||||
"scopeName": "source.python",
|
||||
"patterns": [
|
||||
@@ -374,6 +374,7 @@
|
||||
]
|
||||
},
|
||||
"member-access": {
|
||||
"name": "meta.member.access.python",
|
||||
"begin": "(\\.)\\s*(?!\\.)",
|
||||
"end": "(?x)\n # stop when you've just read non-whitespace followed by non-word\n # i.e. when finished reading an identifier or function call\n (?<=\\S)(?=\\W) |\n # stop when seeing the start of something that's not a word,\n # i.e. when seeing a non-identifier\n (^|(?<=\\s))(?=[^\\\\\\w\\s]) |\n $\n",
|
||||
"beginCaptures": {
|
||||
@@ -1067,6 +1068,7 @@
|
||||
}
|
||||
},
|
||||
"member-access-class": {
|
||||
"name": "meta.member.access.python",
|
||||
"begin": "(\\.)\\s*(?!\\.)",
|
||||
"end": "(?<=\\S)(?=\\W)|$",
|
||||
"beginCaptures": {
|
||||
|
||||
@@ -287,7 +287,7 @@
|
||||
},
|
||||
{
|
||||
"c": ".",
|
||||
"t": "source.python punctuation.separator.period.python",
|
||||
"t": "source.python meta.member.access.python punctuation.separator.period.python",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -298,7 +298,7 @@
|
||||
},
|
||||
{
|
||||
"c": "request",
|
||||
"t": "source.python",
|
||||
"t": "source.python meta.member.access.python",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -309,7 +309,7 @@
|
||||
},
|
||||
{
|
||||
"c": ".",
|
||||
"t": "source.python punctuation.separator.period.python",
|
||||
"t": "source.python meta.member.access.python punctuation.separator.period.python",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -320,7 +320,7 @@
|
||||
},
|
||||
{
|
||||
"c": "META",
|
||||
"t": "source.python constant.other.caps.python",
|
||||
"t": "source.python meta.member.access.python constant.other.caps.python",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -331,7 +331,7 @@
|
||||
},
|
||||
{
|
||||
"c": ".",
|
||||
"t": "source.python punctuation.separator.period.python",
|
||||
"t": "source.python meta.member.access.python punctuation.separator.period.python",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -342,7 +342,7 @@
|
||||
},
|
||||
{
|
||||
"c": "items",
|
||||
"t": "source.python meta.function-call.python meta.function-call.generic.python",
|
||||
"t": "source.python meta.member.access.python meta.function-call.python meta.function-call.generic.python",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -353,7 +353,7 @@
|
||||
},
|
||||
{
|
||||
"c": "(",
|
||||
"t": "source.python meta.function-call.python punctuation.definition.arguments.begin.python",
|
||||
"t": "source.python meta.member.access.python meta.function-call.python punctuation.definition.arguments.begin.python",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -364,7 +364,7 @@
|
||||
},
|
||||
{
|
||||
"c": ")",
|
||||
"t": "source.python meta.function-call.python punctuation.definition.arguments.end.python",
|
||||
"t": "source.python meta.member.access.python meta.function-call.python punctuation.definition.arguments.end.python",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -408,7 +408,7 @@
|
||||
},
|
||||
{
|
||||
"c": ".",
|
||||
"t": "source.python punctuation.separator.period.python",
|
||||
"t": "source.python meta.member.access.python punctuation.separator.period.python",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -419,7 +419,7 @@
|
||||
},
|
||||
{
|
||||
"c": "startswith",
|
||||
"t": "source.python meta.function-call.python meta.function-call.generic.python",
|
||||
"t": "source.python meta.member.access.python meta.function-call.python meta.function-call.generic.python",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -430,7 +430,7 @@
|
||||
},
|
||||
{
|
||||
"c": "(",
|
||||
"t": "source.python meta.function-call.python punctuation.definition.arguments.begin.python",
|
||||
"t": "source.python meta.member.access.python meta.function-call.python punctuation.definition.arguments.begin.python",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -441,7 +441,7 @@
|
||||
},
|
||||
{
|
||||
"c": "'",
|
||||
"t": "source.python meta.function-call.python meta.function-call.arguments.python string.quoted.single.python punctuation.definition.string.begin.python",
|
||||
"t": "source.python meta.member.access.python meta.function-call.python meta.function-call.arguments.python string.quoted.single.python punctuation.definition.string.begin.python",
|
||||
"r": {
|
||||
"dark_plus": "string: #CE9178",
|
||||
"light_plus": "string: #A31515",
|
||||
@@ -452,7 +452,7 @@
|
||||
},
|
||||
{
|
||||
"c": "HTTP_",
|
||||
"t": "source.python meta.function-call.python meta.function-call.arguments.python string.quoted.single.python",
|
||||
"t": "source.python meta.member.access.python meta.function-call.python meta.function-call.arguments.python string.quoted.single.python",
|
||||
"r": {
|
||||
"dark_plus": "string: #CE9178",
|
||||
"light_plus": "string: #A31515",
|
||||
@@ -463,7 +463,7 @@
|
||||
},
|
||||
{
|
||||
"c": "'",
|
||||
"t": "source.python meta.function-call.python meta.function-call.arguments.python string.quoted.single.python punctuation.definition.string.end.python",
|
||||
"t": "source.python meta.member.access.python meta.function-call.python meta.function-call.arguments.python string.quoted.single.python punctuation.definition.string.end.python",
|
||||
"r": {
|
||||
"dark_plus": "string: #CE9178",
|
||||
"light_plus": "string: #A31515",
|
||||
@@ -474,7 +474,7 @@
|
||||
},
|
||||
{
|
||||
"c": ")",
|
||||
"t": "source.python meta.function-call.python punctuation.definition.arguments.end.python",
|
||||
"t": "source.python meta.member.access.python meta.function-call.python punctuation.definition.arguments.end.python",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
|
||||
@@ -419,7 +419,7 @@
|
||||
},
|
||||
{
|
||||
"c": ".",
|
||||
"t": "source.python punctuation.separator.period.python",
|
||||
"t": "source.python meta.member.access.python punctuation.separator.period.python",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -430,7 +430,7 @@
|
||||
},
|
||||
{
|
||||
"c": "size",
|
||||
"t": "source.python",
|
||||
"t": "source.python meta.member.access.python",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -2223,7 +2223,7 @@
|
||||
},
|
||||
{
|
||||
"c": ".",
|
||||
"t": "source.python punctuation.separator.period.python",
|
||||
"t": "source.python meta.member.access.python punctuation.separator.period.python",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -2234,7 +2234,7 @@
|
||||
},
|
||||
{
|
||||
"c": "next",
|
||||
"t": "source.python meta.function-call.python meta.function-call.generic.python",
|
||||
"t": "source.python meta.member.access.python meta.function-call.python meta.function-call.generic.python",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -2245,7 +2245,7 @@
|
||||
},
|
||||
{
|
||||
"c": "(",
|
||||
"t": "source.python meta.function-call.python punctuation.definition.arguments.begin.python",
|
||||
"t": "source.python meta.member.access.python meta.function-call.python punctuation.definition.arguments.begin.python",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -2256,7 +2256,7 @@
|
||||
},
|
||||
{
|
||||
"c": ")",
|
||||
"t": "source.python meta.function-call.python punctuation.definition.arguments.end.python",
|
||||
"t": "source.python meta.member.access.python meta.function-call.python punctuation.definition.arguments.end.python",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -4533,7 +4533,7 @@
|
||||
},
|
||||
{
|
||||
"c": ".",
|
||||
"t": "source.python punctuation.separator.period.python",
|
||||
"t": "source.python meta.member.access.python punctuation.separator.period.python",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -4543,7 +4543,18 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "fn ",
|
||||
"c": "fn",
|
||||
"t": "source.python meta.member.access.python",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": " ",
|
||||
"t": "source.python",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
@@ -4599,7 +4610,7 @@
|
||||
},
|
||||
{
|
||||
"c": ".",
|
||||
"t": "source.python punctuation.separator.period.python",
|
||||
"t": "source.python meta.member.access.python punctuation.separator.period.python",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -4609,7 +4620,18 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "memo ",
|
||||
"c": "memo",
|
||||
"t": "source.python meta.member.access.python",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": " ",
|
||||
"t": "source.python",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
@@ -4885,7 +4907,7 @@
|
||||
},
|
||||
{
|
||||
"c": ".",
|
||||
"t": "source.python punctuation.separator.period.python",
|
||||
"t": "source.python meta.member.access.python punctuation.separator.period.python",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -4896,7 +4918,7 @@
|
||||
},
|
||||
{
|
||||
"c": "memo",
|
||||
"t": "source.python",
|
||||
"t": "source.python meta.member.access.python",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -4940,7 +4962,7 @@
|
||||
},
|
||||
{
|
||||
"c": ".",
|
||||
"t": "source.python punctuation.separator.period.python",
|
||||
"t": "source.python meta.member.access.python punctuation.separator.period.python",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -4951,7 +4973,7 @@
|
||||
},
|
||||
{
|
||||
"c": "memo",
|
||||
"t": "source.python meta.item-access.python",
|
||||
"t": "source.python meta.member.access.python meta.item-access.python",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -4962,7 +4984,7 @@
|
||||
},
|
||||
{
|
||||
"c": "[",
|
||||
"t": "source.python meta.item-access.python punctuation.definition.arguments.begin.python",
|
||||
"t": "source.python meta.member.access.python meta.item-access.python punctuation.definition.arguments.begin.python",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -4973,7 +4995,7 @@
|
||||
},
|
||||
{
|
||||
"c": "args",
|
||||
"t": "source.python meta.item-access.python meta.item-access.arguments.python",
|
||||
"t": "source.python meta.member.access.python meta.item-access.python meta.item-access.arguments.python",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -4984,7 +5006,7 @@
|
||||
},
|
||||
{
|
||||
"c": "]",
|
||||
"t": "source.python meta.item-access.python punctuation.definition.arguments.end.python",
|
||||
"t": "source.python meta.member.access.python meta.item-access.python punctuation.definition.arguments.end.python",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -5039,7 +5061,7 @@
|
||||
},
|
||||
{
|
||||
"c": ".",
|
||||
"t": "source.python punctuation.separator.period.python",
|
||||
"t": "source.python meta.member.access.python punctuation.separator.period.python",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -5050,7 +5072,7 @@
|
||||
},
|
||||
{
|
||||
"c": "fn",
|
||||
"t": "source.python meta.function-call.python meta.function-call.generic.python",
|
||||
"t": "source.python meta.member.access.python meta.function-call.python meta.function-call.generic.python",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -5061,7 +5083,7 @@
|
||||
},
|
||||
{
|
||||
"c": "(",
|
||||
"t": "source.python meta.function-call.python punctuation.definition.arguments.begin.python",
|
||||
"t": "source.python meta.member.access.python meta.function-call.python punctuation.definition.arguments.begin.python",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -5072,7 +5094,7 @@
|
||||
},
|
||||
{
|
||||
"c": "*",
|
||||
"t": "source.python meta.function-call.python meta.function-call.arguments.python keyword.operator.unpacking.arguments.python",
|
||||
"t": "source.python meta.member.access.python meta.function-call.python meta.function-call.arguments.python keyword.operator.unpacking.arguments.python",
|
||||
"r": {
|
||||
"dark_plus": "keyword.operator: #D4D4D4",
|
||||
"light_plus": "keyword.operator: #000000",
|
||||
@@ -5083,7 +5105,7 @@
|
||||
},
|
||||
{
|
||||
"c": "args",
|
||||
"t": "source.python meta.function-call.python meta.function-call.arguments.python",
|
||||
"t": "source.python meta.member.access.python meta.function-call.python meta.function-call.arguments.python",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -5094,7 +5116,7 @@
|
||||
},
|
||||
{
|
||||
"c": ")",
|
||||
"t": "source.python meta.function-call.python punctuation.definition.arguments.end.python",
|
||||
"t": "source.python meta.member.access.python meta.function-call.python punctuation.definition.arguments.end.python",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -5149,7 +5171,7 @@
|
||||
},
|
||||
{
|
||||
"c": ".",
|
||||
"t": "source.python punctuation.separator.period.python",
|
||||
"t": "source.python meta.member.access.python punctuation.separator.period.python",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -5160,7 +5182,7 @@
|
||||
},
|
||||
{
|
||||
"c": "memo",
|
||||
"t": "source.python meta.item-access.python",
|
||||
"t": "source.python meta.member.access.python meta.item-access.python",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -5171,7 +5193,7 @@
|
||||
},
|
||||
{
|
||||
"c": "[",
|
||||
"t": "source.python meta.item-access.python punctuation.definition.arguments.begin.python",
|
||||
"t": "source.python meta.member.access.python meta.item-access.python punctuation.definition.arguments.begin.python",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -5182,7 +5204,7 @@
|
||||
},
|
||||
{
|
||||
"c": "args",
|
||||
"t": "source.python meta.item-access.python meta.item-access.arguments.python",
|
||||
"t": "source.python meta.member.access.python meta.item-access.python meta.item-access.arguments.python",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -5193,7 +5215,7 @@
|
||||
},
|
||||
{
|
||||
"c": "]",
|
||||
"t": "source.python meta.item-access.python punctuation.definition.arguments.end.python",
|
||||
"t": "source.python meta.member.access.python meta.item-access.python punctuation.definition.arguments.end.python",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -5237,7 +5259,7 @@
|
||||
},
|
||||
{
|
||||
"c": ".",
|
||||
"t": "source.python punctuation.separator.period.python",
|
||||
"t": "source.python meta.member.access.python punctuation.separator.period.python",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -5248,7 +5270,7 @@
|
||||
},
|
||||
{
|
||||
"c": "search",
|
||||
"t": "source.python meta.function-call.python meta.function-call.generic.python",
|
||||
"t": "source.python meta.member.access.python meta.function-call.python meta.function-call.generic.python",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -5259,7 +5281,7 @@
|
||||
},
|
||||
{
|
||||
"c": "(",
|
||||
"t": "source.python meta.function-call.python punctuation.definition.arguments.begin.python",
|
||||
"t": "source.python meta.member.access.python meta.function-call.python punctuation.definition.arguments.begin.python",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -5270,7 +5292,7 @@
|
||||
},
|
||||
{
|
||||
"c": "r",
|
||||
"t": "source.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python storage.type.string.python",
|
||||
"t": "source.python meta.member.access.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python storage.type.string.python",
|
||||
"r": {
|
||||
"dark_plus": "storage.type: #569CD6",
|
||||
"light_plus": "storage.type: #0000FF",
|
||||
@@ -5281,7 +5303,7 @@
|
||||
},
|
||||
{
|
||||
"c": "\"",
|
||||
"t": "source.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python punctuation.definition.string.begin.python",
|
||||
"t": "source.python meta.member.access.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python punctuation.definition.string.begin.python",
|
||||
"r": {
|
||||
"dark_plus": "string.regexp: #D16969",
|
||||
"light_plus": "string.regexp: #811F3F",
|
||||
@@ -5292,7 +5314,7 @@
|
||||
},
|
||||
{
|
||||
"c": "(",
|
||||
"t": "source.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python support.other.parenthesis.regexp punctuation.parenthesis.begin.regexp",
|
||||
"t": "source.python meta.member.access.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python support.other.parenthesis.regexp punctuation.parenthesis.begin.regexp",
|
||||
"r": {
|
||||
"dark_plus": "support.other.parenthesis.regexp: #CE9178",
|
||||
"light_plus": "support.other.parenthesis.regexp: #D16969",
|
||||
@@ -5303,7 +5325,7 @@
|
||||
},
|
||||
{
|
||||
"c": "[",
|
||||
"t": "source.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python meta.character.set.regexp punctuation.character.set.begin.regexp constant.other.set.regexp",
|
||||
"t": "source.python meta.member.access.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python meta.character.set.regexp punctuation.character.set.begin.regexp constant.other.set.regexp",
|
||||
"r": {
|
||||
"dark_plus": "punctuation.character.set.begin.regexp: #CE9178",
|
||||
"light_plus": "punctuation.character.set.begin.regexp: #D16969",
|
||||
@@ -5314,7 +5336,7 @@
|
||||
},
|
||||
{
|
||||
"c": "0-9-",
|
||||
"t": "source.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python meta.character.set.regexp constant.character.set.regexp",
|
||||
"t": "source.python meta.member.access.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python meta.character.set.regexp constant.character.set.regexp",
|
||||
"r": {
|
||||
"dark_plus": "constant.character.set.regexp: #D16969",
|
||||
"light_plus": "constant.character.set.regexp: #811F3F",
|
||||
@@ -5325,7 +5347,7 @@
|
||||
},
|
||||
{
|
||||
"c": "]",
|
||||
"t": "source.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python meta.character.set.regexp punctuation.character.set.end.regexp constant.other.set.regexp",
|
||||
"t": "source.python meta.member.access.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python meta.character.set.regexp punctuation.character.set.end.regexp constant.other.set.regexp",
|
||||
"r": {
|
||||
"dark_plus": "punctuation.character.set.end.regexp: #CE9178",
|
||||
"light_plus": "punctuation.character.set.end.regexp: #D16969",
|
||||
@@ -5336,7 +5358,7 @@
|
||||
},
|
||||
{
|
||||
"c": "*",
|
||||
"t": "source.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python keyword.operator.quantifier.regexp",
|
||||
"t": "source.python meta.member.access.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python keyword.operator.quantifier.regexp",
|
||||
"r": {
|
||||
"dark_plus": "keyword.operator.quantifier.regexp: #D7BA7D",
|
||||
"light_plus": "keyword.operator.quantifier.regexp: #000000",
|
||||
@@ -5347,7 +5369,7 @@
|
||||
},
|
||||
{
|
||||
"c": ")",
|
||||
"t": "source.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python support.other.parenthesis.regexp punctuation.parenthesis.end.regexp",
|
||||
"t": "source.python meta.member.access.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python support.other.parenthesis.regexp punctuation.parenthesis.end.regexp",
|
||||
"r": {
|
||||
"dark_plus": "support.other.parenthesis.regexp: #CE9178",
|
||||
"light_plus": "support.other.parenthesis.regexp: #D16969",
|
||||
@@ -5358,7 +5380,7 @@
|
||||
},
|
||||
{
|
||||
"c": "\\s",
|
||||
"t": "source.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python support.other.escape.special.regexp",
|
||||
"t": "source.python meta.member.access.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python support.other.escape.special.regexp",
|
||||
"r": {
|
||||
"dark_plus": "string.regexp: #D16969",
|
||||
"light_plus": "string.regexp: #811F3F",
|
||||
@@ -5369,7 +5391,7 @@
|
||||
},
|
||||
{
|
||||
"c": "*",
|
||||
"t": "source.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python keyword.operator.quantifier.regexp",
|
||||
"t": "source.python meta.member.access.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python keyword.operator.quantifier.regexp",
|
||||
"r": {
|
||||
"dark_plus": "keyword.operator.quantifier.regexp: #D7BA7D",
|
||||
"light_plus": "keyword.operator.quantifier.regexp: #000000",
|
||||
@@ -5380,7 +5402,7 @@
|
||||
},
|
||||
{
|
||||
"c": "(",
|
||||
"t": "source.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python support.other.parenthesis.regexp punctuation.parenthesis.begin.regexp",
|
||||
"t": "source.python meta.member.access.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python support.other.parenthesis.regexp punctuation.parenthesis.begin.regexp",
|
||||
"r": {
|
||||
"dark_plus": "support.other.parenthesis.regexp: #CE9178",
|
||||
"light_plus": "support.other.parenthesis.regexp: #D16969",
|
||||
@@ -5391,7 +5413,7 @@
|
||||
},
|
||||
{
|
||||
"c": "[",
|
||||
"t": "source.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python meta.character.set.regexp punctuation.character.set.begin.regexp constant.other.set.regexp",
|
||||
"t": "source.python meta.member.access.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python meta.character.set.regexp punctuation.character.set.begin.regexp constant.other.set.regexp",
|
||||
"r": {
|
||||
"dark_plus": "punctuation.character.set.begin.regexp: #CE9178",
|
||||
"light_plus": "punctuation.character.set.begin.regexp: #D16969",
|
||||
@@ -5402,7 +5424,7 @@
|
||||
},
|
||||
{
|
||||
"c": "A-Za-z",
|
||||
"t": "source.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python meta.character.set.regexp constant.character.set.regexp",
|
||||
"t": "source.python meta.member.access.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python meta.character.set.regexp constant.character.set.regexp",
|
||||
"r": {
|
||||
"dark_plus": "constant.character.set.regexp: #D16969",
|
||||
"light_plus": "constant.character.set.regexp: #811F3F",
|
||||
@@ -5413,7 +5435,7 @@
|
||||
},
|
||||
{
|
||||
"c": "]",
|
||||
"t": "source.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python meta.character.set.regexp punctuation.character.set.end.regexp constant.other.set.regexp",
|
||||
"t": "source.python meta.member.access.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python meta.character.set.regexp punctuation.character.set.end.regexp constant.other.set.regexp",
|
||||
"r": {
|
||||
"dark_plus": "punctuation.character.set.end.regexp: #CE9178",
|
||||
"light_plus": "punctuation.character.set.end.regexp: #D16969",
|
||||
@@ -5424,7 +5446,7 @@
|
||||
},
|
||||
{
|
||||
"c": "+",
|
||||
"t": "source.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python keyword.operator.quantifier.regexp",
|
||||
"t": "source.python meta.member.access.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python keyword.operator.quantifier.regexp",
|
||||
"r": {
|
||||
"dark_plus": "keyword.operator.quantifier.regexp: #D7BA7D",
|
||||
"light_plus": "keyword.operator.quantifier.regexp: #000000",
|
||||
@@ -5435,7 +5457,7 @@
|
||||
},
|
||||
{
|
||||
"c": ")",
|
||||
"t": "source.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python support.other.parenthesis.regexp punctuation.parenthesis.end.regexp",
|
||||
"t": "source.python meta.member.access.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python support.other.parenthesis.regexp punctuation.parenthesis.end.regexp",
|
||||
"r": {
|
||||
"dark_plus": "support.other.parenthesis.regexp: #CE9178",
|
||||
"light_plus": "support.other.parenthesis.regexp: #D16969",
|
||||
@@ -5446,7 +5468,7 @@
|
||||
},
|
||||
{
|
||||
"c": ",",
|
||||
"t": "source.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python",
|
||||
"t": "source.python meta.member.access.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python",
|
||||
"r": {
|
||||
"dark_plus": "string.regexp: #D16969",
|
||||
"light_plus": "string.regexp: #811F3F",
|
||||
@@ -5457,7 +5479,7 @@
|
||||
},
|
||||
{
|
||||
"c": "\\s",
|
||||
"t": "source.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python support.other.escape.special.regexp",
|
||||
"t": "source.python meta.member.access.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python support.other.escape.special.regexp",
|
||||
"r": {
|
||||
"dark_plus": "string.regexp: #D16969",
|
||||
"light_plus": "string.regexp: #811F3F",
|
||||
@@ -5468,7 +5490,7 @@
|
||||
},
|
||||
{
|
||||
"c": "+",
|
||||
"t": "source.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python keyword.operator.quantifier.regexp",
|
||||
"t": "source.python meta.member.access.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python keyword.operator.quantifier.regexp",
|
||||
"r": {
|
||||
"dark_plus": "keyword.operator.quantifier.regexp: #D7BA7D",
|
||||
"light_plus": "keyword.operator.quantifier.regexp: #000000",
|
||||
@@ -5479,7 +5501,7 @@
|
||||
},
|
||||
{
|
||||
"c": "(",
|
||||
"t": "source.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python support.other.parenthesis.regexp punctuation.parenthesis.begin.regexp",
|
||||
"t": "source.python meta.member.access.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python support.other.parenthesis.regexp punctuation.parenthesis.begin.regexp",
|
||||
"r": {
|
||||
"dark_plus": "support.other.parenthesis.regexp: #CE9178",
|
||||
"light_plus": "support.other.parenthesis.regexp: #D16969",
|
||||
@@ -5490,7 +5512,7 @@
|
||||
},
|
||||
{
|
||||
"c": ".",
|
||||
"t": "source.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python support.other.match.any.regexp",
|
||||
"t": "source.python meta.member.access.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python support.other.match.any.regexp",
|
||||
"r": {
|
||||
"dark_plus": "string.regexp: #D16969",
|
||||
"light_plus": "string.regexp: #811F3F",
|
||||
@@ -5501,7 +5523,7 @@
|
||||
},
|
||||
{
|
||||
"c": "*",
|
||||
"t": "source.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python keyword.operator.quantifier.regexp",
|
||||
"t": "source.python meta.member.access.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python keyword.operator.quantifier.regexp",
|
||||
"r": {
|
||||
"dark_plus": "keyword.operator.quantifier.regexp: #D7BA7D",
|
||||
"light_plus": "keyword.operator.quantifier.regexp: #000000",
|
||||
@@ -5512,7 +5534,7 @@
|
||||
},
|
||||
{
|
||||
"c": ")",
|
||||
"t": "source.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python support.other.parenthesis.regexp punctuation.parenthesis.end.regexp",
|
||||
"t": "source.python meta.member.access.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python support.other.parenthesis.regexp punctuation.parenthesis.end.regexp",
|
||||
"r": {
|
||||
"dark_plus": "support.other.parenthesis.regexp: #CE9178",
|
||||
"light_plus": "support.other.parenthesis.regexp: #D16969",
|
||||
@@ -5523,7 +5545,7 @@
|
||||
},
|
||||
{
|
||||
"c": "\"",
|
||||
"t": "source.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python punctuation.definition.string.end.python",
|
||||
"t": "source.python meta.member.access.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python punctuation.definition.string.end.python",
|
||||
"r": {
|
||||
"dark_plus": "string.regexp: #D16969",
|
||||
"light_plus": "string.regexp: #811F3F",
|
||||
@@ -5534,7 +5556,7 @@
|
||||
},
|
||||
{
|
||||
"c": ",",
|
||||
"t": "source.python meta.function-call.python meta.function-call.arguments.python punctuation.separator.arguments.python",
|
||||
"t": "source.python meta.member.access.python meta.function-call.python meta.function-call.arguments.python punctuation.separator.arguments.python",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -5545,7 +5567,7 @@
|
||||
},
|
||||
{
|
||||
"c": " i",
|
||||
"t": "source.python meta.function-call.python meta.function-call.arguments.python",
|
||||
"t": "source.python meta.member.access.python meta.function-call.python meta.function-call.arguments.python",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -5556,7 +5578,7 @@
|
||||
},
|
||||
{
|
||||
"c": ")",
|
||||
"t": "source.python meta.function-call.python punctuation.definition.arguments.end.python",
|
||||
"t": "source.python meta.member.access.python meta.function-call.python punctuation.definition.arguments.end.python",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
|
||||
@@ -356,7 +356,7 @@
|
||||
"dependencies": {
|
||||
"linux-release-info": "^2.0.0",
|
||||
"promisify-child-process": "^3.1.1",
|
||||
"sudo-prompt": "^9.0.0",
|
||||
"sudo-prompt": "9.1.1",
|
||||
"vscode-nls": "^4.0.0",
|
||||
"yamljs": "^0.3.0"
|
||||
},
|
||||
|
||||
@@ -182,7 +182,7 @@ export class PlatformService implements IPlatformService {
|
||||
}
|
||||
}
|
||||
|
||||
private sudoExec(command: string, options: sudo.SudoOptions): Promise<CommandOutput> {
|
||||
private sudoExec(command: string, options: { [key: string]: any }): Promise<CommandOutput> {
|
||||
return new Promise<CommandOutput>((resolve, reject) => {
|
||||
sudo.exec(command, options, (error, stdout, stderr) => {
|
||||
if (error) {
|
||||
|
||||
@@ -6,5 +6,4 @@
|
||||
/// <reference path='../../../../src/vs/vscode.d.ts'/>
|
||||
/// <reference path='../../../../src/sql/azdata.d.ts'/>
|
||||
/// <reference path='../../../../src/sql/azdata.proposed.d.ts'/>
|
||||
/// <reference path='../../../../src/typings/sudo-prompt.d.ts'/>
|
||||
/// <reference types='@types/node'/>
|
||||
|
||||
@@ -643,10 +643,10 @@ strip-ansi@^4.0.0:
|
||||
dependencies:
|
||||
ansi-regex "^3.0.0"
|
||||
|
||||
sudo-prompt@^9.0.0:
|
||||
version "9.0.0"
|
||||
resolved "https://registry.yarnpkg.com/sudo-prompt/-/sudo-prompt-9.0.0.tgz#eebedeee9fcd6f661324e6bb46335e3288e8dc8a"
|
||||
integrity sha512-kUn5fiOk0nhY2oKD9onIkcNCE4Zt85WTsvOfSmqCplmlEvXCcPOmp1npH5YWuf8Bmyy9wLWkIxx+D+8cThBORQ==
|
||||
sudo-prompt@9.1.1:
|
||||
version "9.1.1"
|
||||
resolved "https://registry.yarnpkg.com/sudo-prompt/-/sudo-prompt-9.1.1.tgz#73853d729770392caec029e2470db9c221754db0"
|
||||
integrity sha512-es33J1g2HjMpyAhz8lOR+ICmXXAqTuKbuXuUWLhOLew20oN9oUCgCJx615U/v7aioZg7IX5lIh9x34vwneu4pA==
|
||||
|
||||
supports-color@4.4.0:
|
||||
version "4.4.0"
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/mocha": "^5.2.5",
|
||||
"@types/node": "^10.14.8",
|
||||
"@types/node": "^12.11.7",
|
||||
"mocha": "^5.2.0",
|
||||
"mocha-junit-reporter": "^1.17.0",
|
||||
"mocha-multi-reporters": "^1.1.7",
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-5.2.6.tgz#b8622d50557dd155e9f2f634b7d68fd38de5e94b"
|
||||
integrity sha512-1axi39YdtBI7z957vdqXI4Ac25e7YihYQtJa+Clnxg1zTJEaIRbndt71O3sP4GAMgiAm0pY26/b9BrY4MR/PMw==
|
||||
|
||||
"@types/node@^10.14.8":
|
||||
version "10.14.17"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.17.tgz#b96d4dd3e427382482848948041d3754d40fd5ce"
|
||||
integrity sha512-p/sGgiPaathCfOtqu2fx5Mu1bcjuP8ALFg4xpGgNkcin7LwRyzUKniEHBKdcE1RPsenq5JVPIpMTJSygLboygQ==
|
||||
"@types/node@^12.11.7":
|
||||
version "12.12.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.7.tgz#01e4ea724d9e3bd50d90c11fd5980ba317d8fa11"
|
||||
integrity sha512-E6Zn0rffhgd130zbCbAr/JdXfXkoOUFAKNs/rF8qnafSJ8KYaA/j3oz7dcwal+lYjLA7xvdd5J4wdYpCTlP8+w==
|
||||
|
||||
ajv@^6.5.5:
|
||||
version "6.10.0"
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
# Language Features for Search Result files
|
||||
|
||||
**Notice:** This extension is bundled with Visual Studio Code. It can be disabled but not uninstalled.
|
||||
@@ -0,0 +1,20 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
//@ts-check
|
||||
|
||||
'use strict';
|
||||
|
||||
const withDefaults = require('../shared.webpack.config');
|
||||
|
||||
module.exports = withDefaults({
|
||||
context: __dirname,
|
||||
resolve: {
|
||||
mainFields: ['module', 'main']
|
||||
},
|
||||
entry: {
|
||||
extension: './src/extension.ts',
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,64 @@
|
||||
{
|
||||
"name": "search-result",
|
||||
"displayName": "%displayName%",
|
||||
"description": "%description%",
|
||||
"version": "1.0.0",
|
||||
"publisher": "vscode",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"vscode": "^1.39.0"
|
||||
},
|
||||
"categories": [
|
||||
"Programming Languages"
|
||||
],
|
||||
"main": "./out/extension.js",
|
||||
"activationEvents": [
|
||||
"*"
|
||||
],
|
||||
"scripts": {
|
||||
"vscode:prepublish": "node ../../node_modules/gulp/bin/gulp.js --gulpfile ../../build/gulpfile.extensions.js compile-extension:search-result ./tsconfig.json"
|
||||
},
|
||||
"contributes": {
|
||||
"commands": [
|
||||
{
|
||||
"command": "searchResult.rerunSearch",
|
||||
"title": "%searchResult.rerunSearch.title%",
|
||||
"category": "Search Result",
|
||||
"icon": {
|
||||
"light": "./src/media/refresh-light.svg",
|
||||
"dark": "./src/media/refresh-dark.svg"
|
||||
}
|
||||
}
|
||||
],
|
||||
"menus": {
|
||||
"editor/title": [
|
||||
{
|
||||
"command": "searchResult.rerunSearch",
|
||||
"when": "editorLangId == search-result",
|
||||
"group": "navigation"
|
||||
}
|
||||
]
|
||||
},
|
||||
"languages": [
|
||||
{
|
||||
"id": "search-result",
|
||||
"extensions": [
|
||||
".code-search"
|
||||
],
|
||||
"aliases": [
|
||||
"Search Result"
|
||||
]
|
||||
}
|
||||
],
|
||||
"grammars": [
|
||||
{
|
||||
"language": "search-result",
|
||||
"scopeName": "text.searchResult",
|
||||
"path": "./syntaxes/searchResult.tmLanguage.json"
|
||||
}
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"vscode": "^1.1.36"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"displayName": "Search Result",
|
||||
"description": "Provides syntax highlighting and language features for tabbed search results.",
|
||||
"searchResult.rerunSearch.title": "Search Again"
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user