Archived
Merge VS Code 1.31.1 (#4283)
This commit is contained in:
@@ -1,24 +1,29 @@
|
||||
{
|
||||
"name": "admin-pack",
|
||||
"displayName": "Admin Pack for SQL Server",
|
||||
"description": "",
|
||||
"version": "0.0.2",
|
||||
"publisher": "Microsoft",
|
||||
"engines": {
|
||||
"vscode": "*",
|
||||
"azdata": "*"
|
||||
},
|
||||
"extensionPack": [
|
||||
"Microsoft.agent",
|
||||
"Microsoft.profiler",
|
||||
"Microsoft.import",
|
||||
"Microsoft.dacpac"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Microsoft/azuredatastudio.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/Microsoft/azuredatastudio/issues"
|
||||
}
|
||||
"name": "admin-pack",
|
||||
"displayName": "Admin Pack for SQL Server",
|
||||
"description": "",
|
||||
"version": "0.0.2",
|
||||
"publisher": "Microsoft",
|
||||
"engines": {
|
||||
"vscode": "*",
|
||||
"azdata": "*"
|
||||
},
|
||||
"extensionPack": [
|
||||
"Microsoft.agent",
|
||||
"Microsoft.profiler",
|
||||
"Microsoft.import",
|
||||
"Microsoft.dacpac"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Microsoft/azuredatastudio.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/Microsoft/azuredatastudio/issues"
|
||||
},
|
||||
"__metadata": {
|
||||
"id": "32",
|
||||
"publisherDisplayName": "Microsoft",
|
||||
"publisherId": "Microsoft"
|
||||
}
|
||||
}
|
||||
@@ -1,51 +1,56 @@
|
||||
{
|
||||
"name": "agent",
|
||||
"displayName": "SQL Server Agent",
|
||||
"description": "Manage and troubleshoot SQL Server Agent jobs",
|
||||
"version": "0.37.0",
|
||||
"publisher": "Microsoft",
|
||||
"preview": true,
|
||||
"license": "https://raw.githubusercontent.com/Microsoft/azuredatastudio/master/LICENSE.txt",
|
||||
"icon": "images/sqlserver.png",
|
||||
"aiKey": "AIF-5574968e-856d-40d2-af67-c89a14e76412",
|
||||
"engines": {
|
||||
"vscode": "0.10.x"
|
||||
},
|
||||
"activationEvents": [
|
||||
"*"
|
||||
],
|
||||
"main": "./out/main",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Microsoft/azuredatastudio.git"
|
||||
},
|
||||
"extensionDependencies": [
|
||||
"Microsoft.mssql"
|
||||
],
|
||||
"contributes": {
|
||||
"outputChannels": [
|
||||
"sqlagent"
|
||||
],
|
||||
"dashboard.tabs": [
|
||||
{
|
||||
"id": "data-management-agent",
|
||||
"description": "Manage and troubleshoot SQL Agent jobs",
|
||||
"provider": "MSSQL",
|
||||
"title": "SQL Agent",
|
||||
"when": "connectionProvider == 'MSSQL' && !mssql:iscloud",
|
||||
"container": {
|
||||
"controlhost-container": {
|
||||
"type": "agent"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"vscode-nls": "^3.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"mocha-junit-reporter": "^1.17.0",
|
||||
"mocha-multi-reporters": "^1.1.7"
|
||||
}
|
||||
}
|
||||
"name": "agent",
|
||||
"displayName": "SQL Server Agent",
|
||||
"description": "Manage and troubleshoot SQL Server Agent jobs",
|
||||
"version": "0.37.0",
|
||||
"publisher": "Microsoft",
|
||||
"preview": true,
|
||||
"license": "https://raw.githubusercontent.com/Microsoft/azuredatastudio/master/LICENSE.txt",
|
||||
"icon": "images/sqlserver.png",
|
||||
"aiKey": "AIF-5574968e-856d-40d2-af67-c89a14e76412",
|
||||
"engines": {
|
||||
"vscode": "0.10.x"
|
||||
},
|
||||
"activationEvents": [
|
||||
"*"
|
||||
],
|
||||
"main": "./out/main",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Microsoft/azuredatastudio.git"
|
||||
},
|
||||
"extensionDependencies": [
|
||||
"Microsoft.mssql"
|
||||
],
|
||||
"contributes": {
|
||||
"outputChannels": [
|
||||
"sqlagent"
|
||||
],
|
||||
"dashboard.tabs": [
|
||||
{
|
||||
"id": "data-management-agent",
|
||||
"description": "Manage and troubleshoot SQL Agent jobs",
|
||||
"provider": "MSSQL",
|
||||
"title": "SQL Agent",
|
||||
"when": "connectionProvider == 'MSSQL' && !mssql:iscloud",
|
||||
"container": {
|
||||
"controlhost-container": {
|
||||
"type": "agent"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"vscode-nls": "^3.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"mocha-junit-reporter": "^1.17.0",
|
||||
"mocha-multi-reporters": "^1.1.7"
|
||||
},
|
||||
"__metadata": {
|
||||
"id": "10",
|
||||
"publisherDisplayName": "Microsoft",
|
||||
"publisherId": "Microsoft"
|
||||
}
|
||||
}
|
||||
@@ -47,5 +47,5 @@ export class AzureResourceAccountNotSignedInTreeNode extends TreeNode {
|
||||
return 'message_accountNotSignedIn';
|
||||
}
|
||||
|
||||
private static readonly signInLabel = localize('azure.resource.tree.accountNotSignedInTreeNode.signInLabel', 'Sign in to Azure ...');
|
||||
private static readonly signInLabel = localize('azure.resource.tree.accountNotSignedInTreeNode.signInLabel', 'Sign in to Azure...');
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ import { AzureResourceAccountNotSignedInTreeNode } from '../../../azureResource/
|
||||
|
||||
describe('AzureResourceAccountNotSignedInTreeNode.info', function(): void {
|
||||
it('Should be correct.', async function(): Promise<void> {
|
||||
const label = 'Sign in to Azure ...';
|
||||
const label = 'Sign in to Azure...';
|
||||
|
||||
const treeNode = new AzureResourceAccountNotSignedInTreeNode();
|
||||
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
}
|
||||
},
|
||||
"license": "MIT",
|
||||
"version": "0.0.0"
|
||||
"version": "0.7.4"
|
||||
}
|
||||
],
|
||||
"version": 1
|
||||
}
|
||||
}
|
||||
@@ -44,8 +44,11 @@ export class SettingsDocument {
|
||||
const completions: vscode.CompletionItem[] = [];
|
||||
|
||||
completions.push(this.newSimpleCompletionItem('${activeEditorShort}', range, localize('activeEditorShort', "the file name (e.g. myFile.txt)")));
|
||||
completions.push(this.newSimpleCompletionItem('${activeEditorMedium}', range, localize('activeEditorMedium', "the path of the file relative to the workspace folder (e.g. myFolder/myFile.txt)")));
|
||||
completions.push(this.newSimpleCompletionItem('${activeEditorLong}', range, localize('activeEditorLong', "the full path of the file (e.g. /Users/Development/myProject/myFolder/myFile.txt)")));
|
||||
completions.push(this.newSimpleCompletionItem('${activeEditorMedium}', range, localize('activeEditorMedium', "the path of the file relative to the workspace folder (e.g. myFolder/myFileFolder/myFile.txt)")));
|
||||
completions.push(this.newSimpleCompletionItem('${activeEditorLong}', range, localize('activeEditorLong', "the full path of the file (e.g. /Users/Development/myFolder/myFileFolder/myFile.txt)")));
|
||||
completions.push(this.newSimpleCompletionItem('${activeFolderShort}', range, localize('activeFolderShort', "the name of the folder the file is contained in (e.g. myFileFolder)")));
|
||||
completions.push(this.newSimpleCompletionItem('${activeFolderMedium}', range, localize('activeFolderMedium', "the path of the folder the file is contained in, relative to the workspace folder (e.g. myFolder/myFileFolder)")));
|
||||
completions.push(this.newSimpleCompletionItem('${activeFolderLong}', range, localize('activeFolderLong', "the full path of the folder the file is contained in (e.g. /Users/Development/myFolder/myFileFolder)")));
|
||||
completions.push(this.newSimpleCompletionItem('${rootName}', range, localize('rootName', "name of the workspace (e.g. myFolder or myWorkspace)")));
|
||||
completions.push(this.newSimpleCompletionItem('${rootPath}', range, localize('rootPath', "file path of the workspace (e.g. /Users/Development/myWorkspace)")));
|
||||
completions.push(this.newSimpleCompletionItem('${folderName}', range, localize('folderName', "name of the workspace folder the file is contained in (e.g. myFolder)")));
|
||||
|
||||
@@ -41,6 +41,14 @@
|
||||
"fileMatch": "*color-theme.json",
|
||||
"url": "vscode://schemas/color-theme"
|
||||
}
|
||||
],
|
||||
"languages": [
|
||||
{
|
||||
"id": "ignore",
|
||||
"filenames": [
|
||||
".vscodeignore"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -661,11 +661,21 @@
|
||||
"group": "1_sync",
|
||||
"when": "scmProvider == git"
|
||||
},
|
||||
{
|
||||
"command": "git.pushForce",
|
||||
"group": "1_sync",
|
||||
"when": "scmProvider == git && config.git.allowForcePush"
|
||||
},
|
||||
{
|
||||
"command": "git.pushTo",
|
||||
"group": "1_sync",
|
||||
"when": "scmProvider == git"
|
||||
},
|
||||
{
|
||||
"command": "git.pushToForce",
|
||||
"group": "1_sync",
|
||||
"when": "scmProvider == git && config.git.allowForcePush"
|
||||
},
|
||||
{
|
||||
"command": "git.publish",
|
||||
"group": "2_publish",
|
||||
@@ -1018,12 +1028,19 @@
|
||||
},
|
||||
"git.autofetch": {
|
||||
"type": "boolean",
|
||||
"scope": "resource",
|
||||
"description": "%config.autofetch%",
|
||||
"default": false,
|
||||
"tags": [
|
||||
"usesOnlineServices"
|
||||
]
|
||||
},
|
||||
"git.autofetchPeriod": {
|
||||
"type": "number",
|
||||
"scope": "resource",
|
||||
"description": "%config.autofetchPeriod%",
|
||||
"default": 180
|
||||
},
|
||||
"git.branchValidationRegex": {
|
||||
"type": "string",
|
||||
"description": "%config.branchValidationRegex%",
|
||||
@@ -1160,6 +1177,14 @@
|
||||
"default": 72,
|
||||
"description": "%config.inputValidationLength%"
|
||||
},
|
||||
"git.inputValidationSubjectLength": {
|
||||
"type": [
|
||||
"number",
|
||||
"null"
|
||||
],
|
||||
"default": null,
|
||||
"description": "%config.inputValidationSubjectLength%"
|
||||
},
|
||||
"git.detectSubmodules": {
|
||||
"type": "boolean",
|
||||
"scope": "resource",
|
||||
@@ -1214,6 +1239,12 @@
|
||||
"default": false,
|
||||
"description": "%config.fetchOnPull%"
|
||||
},
|
||||
"git.autoStash": {
|
||||
"type": "boolean",
|
||||
"scope": "resource",
|
||||
"default": false,
|
||||
"description": "%config.autoStash%"
|
||||
},
|
||||
"git.allowForcePush": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
@@ -1231,6 +1262,7 @@
|
||||
},
|
||||
"git.openDiffOnClick": {
|
||||
"type": "boolean",
|
||||
"scope": "resource",
|
||||
"default": true,
|
||||
"description": "%config.openDiffOnClick%"
|
||||
}
|
||||
@@ -1385,7 +1417,7 @@
|
||||
"file-type": "^7.2.0",
|
||||
"iconv-lite": "^0.4.24",
|
||||
"jschardet": "^1.6.0",
|
||||
"vscode-extension-telemetry": "0.1.0",
|
||||
"vscode-extension-telemetry": "0.1.1",
|
||||
"vscode-nls": "^4.0.0",
|
||||
"which": "^1.3.0"
|
||||
},
|
||||
|
||||
@@ -68,6 +68,7 @@
|
||||
"config.autoRepositoryDetection.openEditors": "Scan for parent folders of open files.",
|
||||
"config.autorefresh": "Whether auto refreshing is enabled.",
|
||||
"config.autofetch": "When enabled, commits will automatically be fetched from the default remote of the current Git repository.",
|
||||
"config.autofetchPeriod": "Duration in seconds between each automatic git fetch, when `git.autofetch` is enabled.",
|
||||
"config.confirmSync": "Confirm before synchronizing git repositories.",
|
||||
"config.countBadge": "Controls the git badge counter.",
|
||||
"config.countBadge.all": "Count all changes.",
|
||||
@@ -97,6 +98,7 @@
|
||||
"config.showPushSuccessNotification": "Controls whether to show a notification when a push is successful.",
|
||||
"config.inputValidation": "Controls when to show commit message input validation.",
|
||||
"config.inputValidationLength": "Controls the commit message length threshold for showing a warning.",
|
||||
"config.inputValidationSubjectLength": "Controls the commit message subject length threshold for showing a warning. Unset it to inherit the value of `config.inputValidationLength`.",
|
||||
"config.detectSubmodules": "Controls whether to automatically detect git submodules.",
|
||||
"config.detectSubmodulesLimit": "Controls the limit of git submodules detected.",
|
||||
"config.alwaysShowStagedChangesResourceGroup": "Always show the Staged Changes resource group.",
|
||||
@@ -107,6 +109,7 @@
|
||||
"config.rebaseWhenSync": "Force git to use rebase when running the sync command.",
|
||||
"config.confirmEmptyCommits": "Always confirm the creation of empty commits.",
|
||||
"config.fetchOnPull": "Fetch all branches when pulling or just the current one.",
|
||||
"config.autoStash": "Stash any changes before pulling and restore them after successful pull.",
|
||||
"config.allowForcePush": "Controls whether force push (with or without lease) is enabled.",
|
||||
"config.useForcePushWithLease": "Controls whether force pushing uses the safer force-with-lease variant.",
|
||||
"config.confirmForcePush": "Controls whether to ask for confirmation before force-pushing.",
|
||||
|
||||
@@ -1 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.icon-canvas-transparent,.icon-vs-out{fill:#252526;}.icon-canvas-transparent{opacity:0;}.icon-vs-bg{fill:#c5c5c5;}.icon-vs-action-blue{fill:#75beff;}</style></defs><title>Compare_16x</title><g id="canvas"><path class="icon-canvas-transparent" d="M16,0V16H0V0Z"/></g><g id="outline" style="display: none;"><path class="icon-vs-out" d="M16,11H12.121l1.939,1.94a1.5,1.5,0,1,1-2.12,2.12L9.433,12.554A4.4,4.4,0,0,1,9,12.735V16H0V5H4.706A4.445,4.445,0,0,1,7,4.051V0h5.621L16,3.379Z" style="display: none;"/></g><g id="iconBg"><path class="icon-vs-bg" d="M15,3.793V10H11.735a4.4,4.4,0,0,0,.237-1H14V4.207L11.793,2H9V4.276a4.485,4.485,0,0,0-1-.225V1h4.207ZM7,12.949V14H2V7H3.276a4.493,4.493,0,0,1,.486-1H1v9H8V12.972A4.612,4.612,0,0,1,7.5,13,4.342,4.342,0,0,1,7,12.949Z"/></g><g id="colorAction"><path class="icon-vs-action-blue" d="M13.354,13.646l-3-3a.545.545,0,0,0-.071-.047A3.462,3.462,0,0,0,11,8.5,3.5,3.5,0,1,0,7.5,12a3.462,3.462,0,0,0,2.1-.717.57.57,0,0,0,.047.07l3,3a.5.5,0,1,0,.708-.707ZM7.5,11A2.5,2.5,0,1,1,10,8.5,2.5,2.5,0,0,1,7.5,11Z"/></g></svg>
|
||||
<svg fill="none" height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path clip-rule="evenodd" d="m6 12h-1c-.27-.02-.48-.11-.69-.31s-.3-.42-.31-.69v-6.28c.59-.34 1-.98 1-1.72 0-1.11-.89-2-2-2s-2 .89-2 2c0 .73.41 1.38 1 1.72v6.28c.03.78.34 1.47.94 2.06s1.28.91 2.06.94c0 0 1.02 0 1 0v2l3-3-3-3zm-3-10.2c.66 0 1.2.55 1.2 1.2s-.55 1.2-1.2 1.2-1.2-.55-1.2-1.2.55-1.2 1.2-1.2zm11 9.48c0-1.73 0-6.28 0-6.28-.03-.78-.34-1.47-.94-2.06s-1.28-.91-2.06-.94h-1v-2l-3 3 3 3v-2h1c.27.02.48.11.69.31s.3.42.31.69v6.28c-.59.34-1 .98-1 1.72 0 1.11.89 2 2 2s2-.89 2-2c0-.73-.41-1.38-1-1.72zm-1 2.92c-.66 0-1.2-.55-1.2-1.2s.55-1.2 1.2-1.2 1.2.55 1.2 1.2-.55 1.2-1.2 1.2z" fill="#c5c5c5" fill-rule="evenodd"/></svg>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 720 B |
@@ -1 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.icon-canvas-transparent,.icon-vs-out{fill:#f6f6f6;}.icon-canvas-transparent{opacity:0;}.icon-vs-bg{fill:#424242;}.icon-vs-action-blue{fill:#00539c;}</style></defs><title>Compare_16x</title><g id="canvas"><path class="icon-canvas-transparent" d="M16,0V16H0V0Z"/></g><g id="outline" style="display: none;"><path class="icon-vs-out" d="M16,11H12.121l1.939,1.94a1.5,1.5,0,1,1-2.12,2.12L9.433,12.554A4.4,4.4,0,0,1,9,12.735V16H0V5H4.706A4.445,4.445,0,0,1,7,4.051V0h5.621L16,3.379Z" style="display: none;"/></g><g id="iconBg"><path class="icon-vs-bg" d="M15,3.793V10H11.735a4.4,4.4,0,0,0,.237-1H14V4.207L11.793,2H9V4.276a4.485,4.485,0,0,0-1-.225V1h4.207ZM7,12.949V14H2V7H3.276a4.493,4.493,0,0,1,.486-1H1v9H8V12.972A4.612,4.612,0,0,1,7.5,13,4.342,4.342,0,0,1,7,12.949Z"/></g><g id="colorAction"><path class="icon-vs-action-blue" d="M13.354,13.646l-3-3a.545.545,0,0,0-.071-.047A3.462,3.462,0,0,0,11,8.5,3.5,3.5,0,1,0,7.5,12a3.462,3.462,0,0,0,2.1-.717.57.57,0,0,0,.047.07l3,3a.5.5,0,1,0,.708-.707ZM7.5,11A2.5,2.5,0,1,1,10,8.5,2.5,2.5,0,0,1,7.5,11Z"/></g></svg>
|
||||
<svg fill="none" height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path clip-rule="evenodd" d="m6 12h-1c-.27-.02-.48-.11-.69-.31s-.3-.42-.31-.69v-6.28c.59-.34 1-.98 1-1.72 0-1.11-.89-2-2-2s-2 .89-2 2c0 .73.41 1.38 1 1.72v6.28c.03.78.34 1.47.94 2.06s1.28.91 2.06.94c0 0 1.02 0 1 0v2l3-3-3-3zm-3-10.2c.66 0 1.2.55 1.2 1.2s-.55 1.2-1.2 1.2-1.2-.55-1.2-1.2.55-1.2 1.2-1.2zm11 9.48c0-1.73 0-6.28 0-6.28-.03-.78-.34-1.47-.94-2.06s-1.28-.91-2.06-.94h-1v-2l-3 3 3 3v-2h1c.27.02.48.11.69.31s.3.42.31.69v6.28c-.59.34-1 .98-1 1.72 0 1.11.89 2 2 2s2-.89 2-2c0-.73-.41-1.38-1-1.72zm-1 2.92c-.66 0-1.2-.55-1.2-1.2s.55-1.2 1.2-1.2 1.2.55 1.2 1.2-.55 1.2-1.2 1.2z" fill="#424242" fill-rule="evenodd"/></svg>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 720 B |
@@ -5,7 +5,7 @@
|
||||
|
||||
import { Model } from '../model';
|
||||
import { Repository as BaseRepository, Resource } from '../repository';
|
||||
import { InputBox, Git, API, Repository, Remote, RepositoryState, Branch, Ref, Submodule, Commit, Change, RepositoryUIState, Status } from './git';
|
||||
import { InputBox, Git, API, Repository, Remote, RepositoryState, Branch, Ref, Submodule, Commit, Change, RepositoryUIState, Status, LogOptions } from './git';
|
||||
import { Event, SourceControlInputBox, Uri, SourceControl } from 'vscode';
|
||||
import { mapEvent } from '../util';
|
||||
|
||||
@@ -76,6 +76,10 @@ export class ApiRepository implements Repository {
|
||||
return this._repository.setConfig(key, value);
|
||||
}
|
||||
|
||||
getGlobalConfig(key: string): Promise<string> {
|
||||
return this._repository.getGlobalConfig(key);
|
||||
}
|
||||
|
||||
getObjectDetails(treeish: string, path: string): Promise<{ mode: string; object: string; size: number; }> {
|
||||
return this._repository.getObjectDetails(treeish, path);
|
||||
}
|
||||
@@ -104,19 +108,27 @@ export class ApiRepository implements Repository {
|
||||
return this._repository.diff(cached);
|
||||
}
|
||||
|
||||
diffWithHEAD(path: string): Promise<string> {
|
||||
diffWithHEAD(): Promise<Change[]>;
|
||||
diffWithHEAD(path: string): Promise<string>;
|
||||
diffWithHEAD(path?: string): Promise<string | Change[]> {
|
||||
return this._repository.diffWithHEAD(path);
|
||||
}
|
||||
|
||||
diffWith(ref: string, path: string): Promise<string> {
|
||||
diffWith(ref: string): Promise<Change[]>;
|
||||
diffWith(ref: string, path: string): Promise<string>;
|
||||
diffWith(ref: string, path?: string): Promise<string | Change[]> {
|
||||
return this._repository.diffWith(ref, path);
|
||||
}
|
||||
|
||||
diffIndexWithHEAD(path: string): Promise<string> {
|
||||
diffIndexWithHEAD(): Promise<Change[]>;
|
||||
diffIndexWithHEAD(path: string): Promise<string>;
|
||||
diffIndexWithHEAD(path?: string): Promise<string | Change[]> {
|
||||
return this._repository.diffIndexWithHEAD(path);
|
||||
}
|
||||
|
||||
diffIndexWith(ref: string, path: string): Promise<string> {
|
||||
diffIndexWith(ref: string): Promise<Change[]>;
|
||||
diffIndexWith(ref: string, path: string): Promise<string>;
|
||||
diffIndexWith(ref: string, path?: string): Promise<string | Change[]> {
|
||||
return this._repository.diffIndexWith(ref, path);
|
||||
}
|
||||
|
||||
@@ -124,7 +136,9 @@ export class ApiRepository implements Repository {
|
||||
return this._repository.diffBlobs(object1, object2);
|
||||
}
|
||||
|
||||
diffBetween(ref1: string, ref2: string, path: string): Promise<string> {
|
||||
diffBetween(ref1: string, ref2: string): Promise<Change[]>;
|
||||
diffBetween(ref1: string, ref2: string, path: string): Promise<string>;
|
||||
diffBetween(ref1: string, ref2: string, path?: string): Promise<string | Change[]> {
|
||||
return this._repository.diffBetween(ref1, ref2, path);
|
||||
}
|
||||
|
||||
@@ -168,17 +182,25 @@ export class ApiRepository implements Repository {
|
||||
return this._repository.removeRemote(name);
|
||||
}
|
||||
|
||||
fetch(remote?: string | undefined, ref?: string | undefined): Promise<void> {
|
||||
return this._repository.fetch(remote, ref);
|
||||
fetch(remote?: string | undefined, ref?: string | undefined, depth?: number | undefined): Promise<void> {
|
||||
return this._repository.fetch(remote, ref, depth);
|
||||
}
|
||||
|
||||
pull(): Promise<void> {
|
||||
return this._repository.pull();
|
||||
pull(unshallow?: boolean): Promise<void> {
|
||||
return this._repository.pull(undefined, unshallow);
|
||||
}
|
||||
|
||||
push(remoteName?: string, branchName?: string, setUpstream: boolean = false): Promise<void> {
|
||||
return this._repository.pushTo(remoteName, branchName, setUpstream);
|
||||
}
|
||||
|
||||
blame(path: string): Promise<string> {
|
||||
return this._repository.blame(path);
|
||||
}
|
||||
|
||||
log(options?: LogOptions): Promise<Commit[]> {
|
||||
return this._repository.log(options);
|
||||
}
|
||||
}
|
||||
|
||||
export class ApiGit implements Git {
|
||||
|
||||
Vendored
+23
-2
@@ -41,6 +41,7 @@ export interface Commit {
|
||||
readonly hash: string;
|
||||
readonly message: string;
|
||||
readonly parents: string[];
|
||||
readonly authorEmail?: string | undefined;
|
||||
}
|
||||
|
||||
export interface Submodule {
|
||||
@@ -67,6 +68,7 @@ export const enum Status {
|
||||
DELETED,
|
||||
UNTRACKED,
|
||||
IGNORED,
|
||||
INTENT_TO_ADD,
|
||||
|
||||
ADDED_BY_US,
|
||||
ADDED_BY_THEM,
|
||||
@@ -109,6 +111,14 @@ export interface RepositoryUIState {
|
||||
readonly onDidChange: Event<void>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Log options.
|
||||
*/
|
||||
export interface LogOptions {
|
||||
/** Max number of log entries to retrieve. If not specified, the default is 32. */
|
||||
readonly maxEntries?: number;
|
||||
}
|
||||
|
||||
export interface Repository {
|
||||
|
||||
readonly rootUri: Uri;
|
||||
@@ -119,6 +129,7 @@ export interface Repository {
|
||||
getConfigs(): Promise<{ key: string; value: string; }[]>;
|
||||
getConfig(key: string): Promise<string>;
|
||||
setConfig(key: string, value: string): Promise<string>;
|
||||
getGlobalConfig(key: string): Promise<string>;
|
||||
|
||||
getObjectDetails(treeish: string, path: string): Promise<{ mode: string, object: string, size: number }>;
|
||||
detectObjectType(object: string): Promise<{ mimetype: string, encoding?: string }>;
|
||||
@@ -130,11 +141,16 @@ export interface Repository {
|
||||
|
||||
apply(patch: string, reverse?: boolean): Promise<void>;
|
||||
diff(cached?: boolean): Promise<string>;
|
||||
diffWithHEAD(): Promise<Change[]>;
|
||||
diffWithHEAD(path: string): Promise<string>;
|
||||
diffWith(ref: string): Promise<Change[]>;
|
||||
diffWith(ref: string, path: string): Promise<string>;
|
||||
diffIndexWithHEAD(): Promise<Change[]>;
|
||||
diffIndexWithHEAD(path: string): Promise<string>;
|
||||
diffIndexWith(ref: string): Promise<Change[]>;
|
||||
diffIndexWith(ref: string, path: string): Promise<string>;
|
||||
diffBlobs(object1: string, object2: string): Promise<string>;
|
||||
diffBetween(ref1: string, ref2: string): Promise<Change[]>;
|
||||
diffBetween(ref1: string, ref2: string, path: string): Promise<string>;
|
||||
|
||||
hashObject(data: string): Promise<string>;
|
||||
@@ -152,9 +168,12 @@ export interface Repository {
|
||||
addRemote(name: string, url: string): Promise<void>;
|
||||
removeRemote(name: string): Promise<void>;
|
||||
|
||||
fetch(remote?: string, ref?: string): Promise<void>;
|
||||
pull(): Promise<void>;
|
||||
fetch(remote?: string, ref?: string, depth?: number): Promise<void>;
|
||||
pull(unshallow?: boolean): Promise<void>;
|
||||
push(remoteName?: string, branchName?: string, setUpstream?: boolean): Promise<void>;
|
||||
|
||||
blame(path: string): Promise<string>;
|
||||
log(options?: LogOptions): Promise<Commit[]>;
|
||||
}
|
||||
|
||||
export interface API {
|
||||
@@ -214,4 +233,6 @@ export const enum GitErrorCodes {
|
||||
WrongCase = 'WrongCase',
|
||||
CantLockRef = 'CantLockRef',
|
||||
CantRebaseMultipleBranches = 'CantRebaseMultipleBranches',
|
||||
PatchDoesNotApply = 'PatchDoesNotApply',
|
||||
NoPathFound = 'NoPathFound'
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { workspace, Disposable, EventEmitter, Memento, window, MessageItem, ConfigurationTarget } from 'vscode';
|
||||
import { workspace, Disposable, EventEmitter, Memento, window, MessageItem, ConfigurationTarget, Uri } from 'vscode';
|
||||
import { Repository, Operation } from './repository';
|
||||
import { eventToPromise, filterEvent, onceEvent } from './util';
|
||||
import * as nls from 'vscode-nls';
|
||||
@@ -17,7 +17,6 @@ function isRemoteOperation(operation: Operation): boolean {
|
||||
|
||||
export class AutoFetcher {
|
||||
|
||||
private static readonly Period = 3 * 60 * 1000 /* three minutes */;
|
||||
private static DidInformUser = 'autofetch.didInformUser';
|
||||
|
||||
private _onDidChange = new EventEmitter<boolean>();
|
||||
@@ -62,7 +61,7 @@ export class AutoFetcher {
|
||||
}
|
||||
|
||||
if (result === yes) {
|
||||
const gitConfig = workspace.getConfiguration('git');
|
||||
const gitConfig = workspace.getConfiguration('git', Uri.file(this.repository.root));
|
||||
gitConfig.update('autofetch', true, ConfigurationTarget.Global);
|
||||
}
|
||||
|
||||
@@ -70,7 +69,7 @@ export class AutoFetcher {
|
||||
}
|
||||
|
||||
private onConfiguration(): void {
|
||||
const gitConfig = workspace.getConfiguration('git');
|
||||
const gitConfig = workspace.getConfiguration('git', Uri.file(this.repository.root));
|
||||
|
||||
if (gitConfig.get<boolean>('autofetch') === false) {
|
||||
this.disable();
|
||||
@@ -112,8 +111,10 @@ export class AutoFetcher {
|
||||
return;
|
||||
}
|
||||
|
||||
const timeout = new Promise(c => setTimeout(c, AutoFetcher.Period));
|
||||
const period = workspace.getConfiguration('git', Uri.file(this.repository.root)).get<number>('autofetchPeriod', 180) * 1000;
|
||||
const timeout = new Promise(c => setTimeout(c, period));
|
||||
const whenDisabled = eventToPromise(filterEvent(this.onDidChange, enabled => !enabled));
|
||||
|
||||
await Promise.race([timeout, whenDisabled]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,6 +103,15 @@ class CreateBranchItem implements QuickPickItem {
|
||||
}
|
||||
}
|
||||
|
||||
class HEADItem implements QuickPickItem {
|
||||
|
||||
constructor(private repository: Repository) { }
|
||||
|
||||
get label(): string { return 'HEAD'; }
|
||||
get description(): string { return (this.repository.HEAD && this.repository.HEAD.commit || '').substr(0, 8); }
|
||||
get alwaysShow(): boolean { return true; }
|
||||
}
|
||||
|
||||
interface CommandOptions {
|
||||
repository?: boolean;
|
||||
diff?: boolean;
|
||||
@@ -154,6 +163,22 @@ async function categorizeResourceByResolution(resources: Resource[]): Promise<{
|
||||
return { merge, resolved, unresolved, deletionConflicts };
|
||||
}
|
||||
|
||||
function createCheckoutItems(repository: Repository): CheckoutItem[] {
|
||||
const config = workspace.getConfiguration('git');
|
||||
const checkoutType = config.get<string>('checkoutType') || 'all';
|
||||
const includeTags = checkoutType === 'all' || checkoutType === 'tags';
|
||||
const includeRemotes = checkoutType === 'all' || checkoutType === 'remote';
|
||||
|
||||
const heads = repository.refs.filter(ref => ref.type === RefType.Head)
|
||||
.map(ref => new CheckoutItem(ref));
|
||||
const tags = (includeTags ? repository.refs.filter(ref => ref.type === RefType.Tag) : [])
|
||||
.map(ref => new CheckoutTagItem(ref));
|
||||
const remoteHeads = (includeRemotes ? repository.refs.filter(ref => ref.type === RefType.RemoteHead) : [])
|
||||
.map(ref => new CheckoutRemoteHeadItem(ref));
|
||||
|
||||
return [...heads, ...tags, ...remoteHeads];
|
||||
}
|
||||
|
||||
enum PushType {
|
||||
Push,
|
||||
PushTo,
|
||||
@@ -340,6 +365,7 @@ export class CommandCenter {
|
||||
case Status.MODIFIED:
|
||||
case Status.UNTRACKED:
|
||||
case Status.IGNORED:
|
||||
case Status.INTENT_TO_ADD:
|
||||
const repository = this.model.getRepository(resource.resourceUri);
|
||||
|
||||
if (!repository) {
|
||||
@@ -1393,56 +1419,52 @@ export class CommandCenter {
|
||||
await repository.checkout(treeish);
|
||||
return true;
|
||||
}
|
||||
|
||||
const config = workspace.getConfiguration('git');
|
||||
const checkoutType = config.get<string>('checkoutType') || 'all';
|
||||
const includeTags = checkoutType === 'all' || checkoutType === 'tags';
|
||||
const includeRemotes = checkoutType === 'all' || checkoutType === 'remote';
|
||||
|
||||
const createBranch = new CreateBranchItem(this);
|
||||
|
||||
const heads = repository.refs.filter(ref => ref.type === RefType.Head)
|
||||
.map(ref => new CheckoutItem(ref));
|
||||
|
||||
const tags = (includeTags ? repository.refs.filter(ref => ref.type === RefType.Tag) : [])
|
||||
.map(ref => new CheckoutTagItem(ref));
|
||||
|
||||
const remoteHeads = (includeRemotes ? repository.refs.filter(ref => ref.type === RefType.RemoteHead) : [])
|
||||
.map(ref => new CheckoutRemoteHeadItem(ref));
|
||||
|
||||
const picks = [createBranch, ...heads, ...tags, ...remoteHeads];
|
||||
const picks = [createBranch, ...createCheckoutItems(repository)];
|
||||
const placeHolder = localize('select a ref to checkout', 'Select a ref to checkout');
|
||||
const choice = await window.showQuickPick(picks, { placeHolder });
|
||||
|
||||
const quickpick = window.createQuickPick();
|
||||
quickpick.items = picks;
|
||||
quickpick.placeholder = placeHolder;
|
||||
quickpick.show();
|
||||
|
||||
const choice = await new Promise<QuickPickItem | undefined>(c => quickpick.onDidAccept(() => c(quickpick.activeItems[0])));
|
||||
quickpick.hide();
|
||||
|
||||
if (!choice) {
|
||||
return false;
|
||||
}
|
||||
|
||||
await choice.run(repository);
|
||||
if (choice === createBranch) {
|
||||
await this._branch(repository, quickpick.value);
|
||||
} else {
|
||||
await (choice as CheckoutItem).run(repository);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@command('git.branch', { repository: true })
|
||||
async branch(repository: Repository): Promise<void> {
|
||||
await this._branch(repository);
|
||||
}
|
||||
|
||||
private async _branch(repository: Repository, defaultName?: string): Promise<void> {
|
||||
const config = workspace.getConfiguration('git');
|
||||
const branchValidationRegex = config.get<string>('branchValidationRegex')!;
|
||||
const branchWhitespaceChar = config.get<string>('branchWhitespaceChar')!;
|
||||
const validateName = new RegExp(branchValidationRegex);
|
||||
const sanitize = (name: string) => {
|
||||
name = name.trim();
|
||||
const branchValidationRegex = config.get<string>('branchValidationRegex')!;
|
||||
const sanitize = (name: string) => name ?
|
||||
name.trim().replace(/^\.|\/\.|\.\.|~|\^|:|\/$|\.lock$|\.lock\/|\\|\*|\s|^\s*$|\.$|\[|\]$/g, branchWhitespaceChar)
|
||||
: name;
|
||||
|
||||
if (!name) {
|
||||
return name;
|
||||
}
|
||||
|
||||
return name.replace(/^\.|\/\.|\.\.|~|\^|:|\/$|\.lock$|\.lock\/|\\|\*|\s|^\s*$|\.$|\[|\]$/g, branchWhitespaceChar);
|
||||
};
|
||||
|
||||
const result = await window.showInputBox({
|
||||
const rawBranchName = await window.showInputBox({
|
||||
value: defaultName,
|
||||
placeHolder: localize('branch name', "Branch name"),
|
||||
prompt: localize('provide branch name', "Please provide a branch name"),
|
||||
ignoreFocusOut: true,
|
||||
validateInput: (name: string) => {
|
||||
const validateName = new RegExp(branchValidationRegex);
|
||||
if (validateName.test(sanitize(name))) {
|
||||
return null;
|
||||
}
|
||||
@@ -1451,13 +1473,21 @@ export class CommandCenter {
|
||||
}
|
||||
});
|
||||
|
||||
const name = sanitize(result || '');
|
||||
const branchName = sanitize(rawBranchName || '');
|
||||
|
||||
if (!name) {
|
||||
if (!branchName) {
|
||||
return;
|
||||
}
|
||||
|
||||
await repository.branch(name, true);
|
||||
const picks = [new HEADItem(repository), ...createCheckoutItems(repository)];
|
||||
const placeHolder = localize('select a ref to create a new branch from', 'Select a ref to create a new branch from');
|
||||
const target = await window.showQuickPick(picks, { placeHolder });
|
||||
|
||||
if (!target) {
|
||||
return;
|
||||
}
|
||||
|
||||
await repository.branch(branchName, true, target.label);
|
||||
}
|
||||
|
||||
@command('git.deleteBranch', { repository: true })
|
||||
|
||||
+215
-24
@@ -12,9 +12,9 @@ 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 } from './util';
|
||||
import { CancellationToken } from 'vscode';
|
||||
import { CancellationToken, Uri } from 'vscode';
|
||||
import { detectEncoding } from './encoding';
|
||||
import { Ref, RefType, Branch, Remote, GitErrorCodes } from './api/git';
|
||||
import { Ref, RefType, Branch, Remote, GitErrorCodes, LogOptions, Change, Status } from './api/git';
|
||||
|
||||
const readfile = denodeify<string, string | null, string>(fs.readFile);
|
||||
|
||||
@@ -114,17 +114,17 @@ function findGitWin32InPath(onLookup: (path: string) => void): Promise<IGit> {
|
||||
|
||||
function findGitWin32(onLookup: (path: string) => void): Promise<IGit> {
|
||||
return findSystemGitWin32(process.env['ProgramW6432'] as string, onLookup)
|
||||
.then(void 0, () => findSystemGitWin32(process.env['ProgramFiles(x86)'] as string, onLookup))
|
||||
.then(void 0, () => findSystemGitWin32(process.env['ProgramFiles'] as string, onLookup))
|
||||
.then(void 0, () => findSystemGitWin32(path.join(process.env['LocalAppData'] as string, 'Programs'), onLookup))
|
||||
.then(void 0, () => findGitWin32InPath(onLookup));
|
||||
.then(undefined, () => findSystemGitWin32(process.env['ProgramFiles(x86)'] as string, onLookup))
|
||||
.then(undefined, () => findSystemGitWin32(process.env['ProgramFiles'] as string, onLookup))
|
||||
.then(undefined, () => findSystemGitWin32(path.join(process.env['LocalAppData'] as string, 'Programs'), onLookup))
|
||||
.then(undefined, () => findGitWin32InPath(onLookup));
|
||||
}
|
||||
|
||||
export function findGit(hint: string | undefined, onLookup: (path: string) => void): Promise<IGit> {
|
||||
const first = hint ? findSpecificGit(hint, onLookup) : Promise.reject<IGit>(null);
|
||||
|
||||
return first
|
||||
.then(void 0, () => {
|
||||
.then(undefined, () => {
|
||||
switch (process.platform) {
|
||||
case 'darwin': return findGitDarwin(onLookup);
|
||||
case 'win32': return findGitWin32(onLookup);
|
||||
@@ -248,7 +248,7 @@ export class GitError {
|
||||
this.error = data.error;
|
||||
this.message = data.error.message;
|
||||
} else {
|
||||
this.error = void 0;
|
||||
this.error = undefined;
|
||||
this.message = '';
|
||||
}
|
||||
|
||||
@@ -308,9 +308,11 @@ function getGitErrorCode(stderr: string): string | undefined {
|
||||
return GitErrorCodes.InvalidBranchName;
|
||||
}
|
||||
|
||||
return void 0;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const COMMIT_FORMAT = '%H\n%ae\n%P\n%B';
|
||||
|
||||
export class Git {
|
||||
|
||||
readonly path: string;
|
||||
@@ -450,6 +452,7 @@ export interface Commit {
|
||||
hash: string;
|
||||
message: string;
|
||||
parents: string[];
|
||||
authorEmail?: string | undefined;
|
||||
}
|
||||
|
||||
export class GitStatusParser {
|
||||
@@ -581,13 +584,13 @@ export function parseGitmodules(raw: string): Submodule[] {
|
||||
}
|
||||
|
||||
export function parseGitCommit(raw: string): Commit | null {
|
||||
const match = /^([0-9a-f]{40})\n(.*)\n([^]*)$/m.exec(raw.trim());
|
||||
const match = /^([0-9a-f]{40})\n(.*)\n(.*)\n([^]*)$/m.exec(raw.trim());
|
||||
if (!match) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const parents = match[2] ? match[2].split(' ') : [];
|
||||
return { hash: match[1], message: match[3], parents };
|
||||
const parents = match[3] ? match[3].split(' ') : [];
|
||||
return { hash: match[1], message: match[4], parents, authorEmail: match[2] };
|
||||
}
|
||||
|
||||
interface LsTreeElement {
|
||||
@@ -629,6 +632,10 @@ export interface CommitOptions {
|
||||
empty?: boolean;
|
||||
}
|
||||
|
||||
export interface PullOptions {
|
||||
unshallow?: boolean;
|
||||
}
|
||||
|
||||
export enum ForcePushMode {
|
||||
Force,
|
||||
ForceWithLease
|
||||
@@ -697,6 +704,41 @@ 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.
|
||||
return [];
|
||||
}
|
||||
|
||||
const s = gitResult.stdout;
|
||||
const result: Commit[] = [];
|
||||
let index = 0;
|
||||
while (index < s.length) {
|
||||
let nextIndex = s.indexOf('\x00\x00', index);
|
||||
if (nextIndex === -1) {
|
||||
nextIndex = s.length;
|
||||
}
|
||||
|
||||
let entry = s.substr(index, nextIndex - index);
|
||||
if (entry.startsWith('\n')) {
|
||||
entry = entry.substring(1);
|
||||
}
|
||||
|
||||
const commit = parseGitCommit(entry);
|
||||
if (!commit) {
|
||||
break;
|
||||
}
|
||||
|
||||
result.push(commit);
|
||||
index = nextIndex + 2;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
async bufferString(object: string, encoding: string = 'utf8', autoGuessEncoding = false): Promise<string> {
|
||||
const stdout = await this.buffer(object);
|
||||
|
||||
@@ -829,7 +871,15 @@ export class Repository {
|
||||
args.push('-R');
|
||||
}
|
||||
|
||||
await this.run(args);
|
||||
try {
|
||||
await this.run(args);
|
||||
} catch (err) {
|
||||
if (/patch does not apply/.test(err.stderr)) {
|
||||
err.gitErrorCode = GitErrorCodes.PatchDoesNotApply;
|
||||
}
|
||||
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
async diff(cached = false): Promise<string> {
|
||||
@@ -843,25 +893,53 @@ export class Repository {
|
||||
return result.stdout;
|
||||
}
|
||||
|
||||
async diffWithHEAD(path: string): Promise<string> {
|
||||
diffWithHEAD(): Promise<Change[]>;
|
||||
diffWithHEAD(path: string): Promise<string>;
|
||||
diffWithHEAD(path?: string | undefined): Promise<string | Change[]>;
|
||||
async diffWithHEAD(path?: string | undefined): Promise<string | Change[]> {
|
||||
if (!path) {
|
||||
return await this.diffFiles(false);
|
||||
}
|
||||
|
||||
const args = ['diff', '--', path];
|
||||
const result = await this.run(args);
|
||||
return result.stdout;
|
||||
}
|
||||
|
||||
async diffWith(ref: string, path: string): Promise<string> {
|
||||
diffWith(ref: string): Promise<Change[]>;
|
||||
diffWith(ref: string, path: string): Promise<string>;
|
||||
diffWith(ref: string, path?: string | undefined): Promise<string | Change[]>;
|
||||
async diffWith(ref: string, path?: string): Promise<string | Change[]> {
|
||||
if (!path) {
|
||||
return await this.diffFiles(false, ref);
|
||||
}
|
||||
|
||||
const args = ['diff', ref, '--', path];
|
||||
const result = await this.run(args);
|
||||
return result.stdout;
|
||||
}
|
||||
|
||||
async diffIndexWithHEAD(path: string): Promise<string> {
|
||||
diffIndexWithHEAD(): Promise<Change[]>;
|
||||
diffIndexWithHEAD(path: string): Promise<string>;
|
||||
diffIndexWithHEAD(path?: string | undefined): Promise<string | Change[]>;
|
||||
async diffIndexWithHEAD(path?: string): Promise<string | Change[]> {
|
||||
if (!path) {
|
||||
return await this.diffFiles(true);
|
||||
}
|
||||
|
||||
const args = ['diff', '--cached', '--', path];
|
||||
const result = await this.run(args);
|
||||
return result.stdout;
|
||||
}
|
||||
|
||||
async diffIndexWith(ref: string, path: string): Promise<string> {
|
||||
diffIndexWith(ref: string): Promise<Change[]>;
|
||||
diffIndexWith(ref: string, path: string): Promise<string>;
|
||||
diffIndexWith(ref: string, path?: string | undefined): Promise<string | Change[]>;
|
||||
async diffIndexWith(ref: string, path?: string): Promise<string | Change[]> {
|
||||
if (!path) {
|
||||
return await this.diffFiles(true, ref);
|
||||
}
|
||||
|
||||
const args = ['diff', '--cached', ref, '--', path];
|
||||
const result = await this.run(args);
|
||||
return result.stdout;
|
||||
@@ -873,13 +951,102 @@ export class Repository {
|
||||
return result.stdout;
|
||||
}
|
||||
|
||||
async diffBetween(ref1: string, ref2: string, path: string): Promise<string> {
|
||||
const args = ['diff', `${ref1}...${ref2}`, '--', path];
|
||||
diffBetween(ref1: string, ref2: string): Promise<Change[]>;
|
||||
diffBetween(ref1: string, ref2: string, path: string): Promise<string>;
|
||||
diffBetween(ref1: string, ref2: string, path?: string | undefined): Promise<string | Change[]>;
|
||||
async diffBetween(ref1: string, ref2: string, path?: string): Promise<string | Change[]> {
|
||||
const range = `${ref1}...${ref2}`;
|
||||
if (!path) {
|
||||
return await this.diffFiles(false, range);
|
||||
}
|
||||
|
||||
const args = ['diff', range, '--', path];
|
||||
const result = await this.run(args);
|
||||
|
||||
return result.stdout.trim();
|
||||
}
|
||||
|
||||
private async diffFiles(cached: boolean, ref?: string): Promise<Change[]> {
|
||||
const args = ['diff', '--name-status', '-z', '--diff-filter=ADMR'];
|
||||
if (cached) {
|
||||
args.push('--cached');
|
||||
}
|
||||
|
||||
if (ref) {
|
||||
args.push(ref);
|
||||
}
|
||||
|
||||
const gitResult = await this.run(args);
|
||||
if (gitResult.exitCode) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const entries = gitResult.stdout.split('\x00');
|
||||
let index = 0;
|
||||
const result: Change[] = [];
|
||||
|
||||
entriesLoop:
|
||||
while (index < entries.length - 1) {
|
||||
const change = entries[index++];
|
||||
const resourcePath = entries[index++];
|
||||
if (!change || !resourcePath) {
|
||||
break;
|
||||
}
|
||||
|
||||
const originalUri = Uri.file(path.isAbsolute(resourcePath) ? resourcePath : path.join(this.repositoryRoot, resourcePath));
|
||||
let status: Status = Status.UNTRACKED;
|
||||
|
||||
// Copy or Rename status comes with a number, e.g. 'R100'. We don't need the number, so we use only first character of the status.
|
||||
switch (change[0]) {
|
||||
case 'M':
|
||||
status = Status.MODIFIED;
|
||||
break;
|
||||
|
||||
case 'A':
|
||||
status = Status.INDEX_ADDED;
|
||||
break;
|
||||
|
||||
case 'D':
|
||||
status = Status.DELETED;
|
||||
break;
|
||||
|
||||
// Rename contains two paths, the second one is what the file is renamed/copied to.
|
||||
case 'R':
|
||||
if (index >= entries.length) {
|
||||
break;
|
||||
}
|
||||
|
||||
const newPath = entries[index++];
|
||||
if (!newPath) {
|
||||
break;
|
||||
}
|
||||
|
||||
const uri = Uri.file(path.isAbsolute(newPath) ? newPath : path.join(this.repositoryRoot, newPath));
|
||||
result.push({
|
||||
uri,
|
||||
renameUri: uri,
|
||||
originalUri,
|
||||
status: Status.INDEX_RENAMED
|
||||
});
|
||||
|
||||
continue;
|
||||
|
||||
default:
|
||||
// Unknown status
|
||||
break entriesLoop;
|
||||
}
|
||||
|
||||
result.push({
|
||||
status,
|
||||
originalUri,
|
||||
uri: originalUri,
|
||||
renameUri: originalUri,
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
async getMergeBase(ref1: string, ref2: string): Promise<string> {
|
||||
const args = ['merge-base', ref1, ref2];
|
||||
const result = await this.run(args);
|
||||
@@ -1158,7 +1325,7 @@ export class Repository {
|
||||
await this.run(args);
|
||||
}
|
||||
|
||||
async fetch(options: { remote?: string, ref?: string, all?: boolean, prune?: boolean } = {}): Promise<void> {
|
||||
async fetch(options: { remote?: string, ref?: string, all?: boolean, prune?: boolean, depth?: number } = {}): Promise<void> {
|
||||
const args = ['fetch'];
|
||||
|
||||
if (options.remote) {
|
||||
@@ -1175,6 +1342,9 @@ export class Repository {
|
||||
args.push('--prune');
|
||||
}
|
||||
|
||||
if (typeof options.depth === 'number') {
|
||||
args.push(`--depth=${options.depth}`);
|
||||
}
|
||||
|
||||
try {
|
||||
await this.run(args);
|
||||
@@ -1189,9 +1359,13 @@ export class Repository {
|
||||
}
|
||||
}
|
||||
|
||||
async pull(rebase?: boolean, remote?: string, branch?: string): Promise<void> {
|
||||
async pull(rebase?: boolean, remote?: string, branch?: string, options: PullOptions = {}): Promise<void> {
|
||||
const args = ['pull', '--tags'];
|
||||
|
||||
if (options.unshallow) {
|
||||
args.push('--unshallow');
|
||||
}
|
||||
|
||||
if (rebase) {
|
||||
args.push('-r');
|
||||
}
|
||||
@@ -1263,6 +1437,23 @@ export class Repository {
|
||||
}
|
||||
}
|
||||
|
||||
async blame(path: string): Promise<string> {
|
||||
try {
|
||||
const args = ['blame'];
|
||||
args.push(path);
|
||||
|
||||
let result = await this.run(args);
|
||||
|
||||
return result.stdout.trim();
|
||||
} catch (err) {
|
||||
if (/^fatal: no such path/.test(err.stderr || '')) {
|
||||
err.gitErrorCode = GitErrorCodes.NoPathFound;
|
||||
}
|
||||
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
async createStash(message?: string, includeUntracked?: boolean): Promise<void> {
|
||||
try {
|
||||
const args = ['stash', 'save'];
|
||||
@@ -1368,7 +1559,7 @@ export class Repository {
|
||||
throw new Error('Not in a branch');
|
||||
}
|
||||
|
||||
return { name: result.stdout.trim(), commit: void 0, type: RefType.Head };
|
||||
return { name: result.stdout.trim(), commit: undefined, type: RefType.Head };
|
||||
} catch (err) {
|
||||
const result = await this.run(['rev-parse', 'HEAD']);
|
||||
|
||||
@@ -1376,7 +1567,7 @@ export class Repository {
|
||||
throw new Error('Error parsing HEAD');
|
||||
}
|
||||
|
||||
return { name: void 0, commit: result.stdout.trim(), type: RefType.Head };
|
||||
return { name: undefined, commit: result.stdout.trim(), type: RefType.Head };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1521,7 +1712,7 @@ export class Repository {
|
||||
}
|
||||
|
||||
async getCommit(ref: string): Promise<Commit> {
|
||||
const result = await this.run(['show', '-s', '--format=%H\n%P\n%B', ref]);
|
||||
const result = await this.run(['show', '-s', `--format=${COMMIT_FORMAT}`, ref]);
|
||||
return parseGitCommit(result.stdout) || Promise.reject<Commit>('bad commit format');
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ import * as path from 'path';
|
||||
import * as nls from 'vscode-nls';
|
||||
import * as fs from 'fs';
|
||||
import { StatusBarCommands } from './statusbar';
|
||||
import { Branch, Ref, Remote, RefType, GitErrorCodes, Status } from './api/git';
|
||||
import { Branch, Ref, Remote, RefType, GitErrorCodes, Status, LogOptions, Change } from './api/git';
|
||||
|
||||
const timeout = (millis: number) => new Promise(c => setTimeout(c, millis));
|
||||
|
||||
@@ -94,6 +94,7 @@ export class Resource implements SourceControlResourceState {
|
||||
case Status.INDEX_COPIED: return Resource.Icons[theme].Copied;
|
||||
case Status.UNTRACKED: return Resource.Icons[theme].Untracked;
|
||||
case Status.IGNORED: return Resource.Icons[theme].Ignored;
|
||||
case Status.INTENT_TO_ADD: return Resource.Icons[theme].Added;
|
||||
case Status.BOTH_DELETED: return Resource.Icons[theme].Conflict;
|
||||
case Status.ADDED_BY_US: return Resource.Icons[theme].Conflict;
|
||||
case Status.DELETED_BY_THEM: return Resource.Icons[theme].Conflict;
|
||||
@@ -116,6 +117,7 @@ export class Resource implements SourceControlResourceState {
|
||||
case Status.INDEX_COPIED: return localize('index copied', "Index Copied");
|
||||
case Status.UNTRACKED: return localize('untracked', "Untracked");
|
||||
case Status.IGNORED: return localize('ignored', "Ignored");
|
||||
case Status.INTENT_TO_ADD: return localize('intent to add', "Intent to Add");
|
||||
case Status.BOTH_DELETED: return localize('both deleted', "Both Deleted");
|
||||
case Status.ADDED_BY_US: return localize('added by us', "Added By Us");
|
||||
case Status.DELETED_BY_THEM: return localize('deleted by them', "Deleted By Them");
|
||||
@@ -166,6 +168,7 @@ export class Resource implements SourceControlResourceState {
|
||||
case Status.MODIFIED:
|
||||
return 'M';
|
||||
case Status.INDEX_ADDED:
|
||||
case Status.INTENT_TO_ADD:
|
||||
return 'A';
|
||||
case Status.INDEX_DELETED:
|
||||
case Status.DELETED:
|
||||
@@ -201,6 +204,7 @@ export class Resource implements SourceControlResourceState {
|
||||
case Status.DELETED:
|
||||
return new ThemeColor('gitDecoration.deletedResourceForeground');
|
||||
case Status.INDEX_ADDED:
|
||||
case Status.INTENT_TO_ADD:
|
||||
return new ThemeColor('gitDecoration.addedResourceForeground');
|
||||
case Status.INDEX_RENAMED: // todo@joh - special color?
|
||||
case Status.UNTRACKED:
|
||||
@@ -295,7 +299,9 @@ export const enum Operation {
|
||||
GetObjectDetails = 'GetObjectDetails',
|
||||
SubmoduleUpdate = 'SubmoduleUpdate',
|
||||
RebaseContinue = 'RebaseContinue',
|
||||
Apply = 'Apply'
|
||||
Apply = 'Apply',
|
||||
Blame = 'Blame',
|
||||
Log = 'Log',
|
||||
}
|
||||
|
||||
function isReadOnly(operation: Operation): boolean {
|
||||
@@ -643,18 +649,43 @@ export class Repository implements Disposable {
|
||||
};
|
||||
}
|
||||
|
||||
let lineNumber = 0;
|
||||
let start = 0, end;
|
||||
let match: RegExpExecArray | null;
|
||||
const regex = /\r?\n/g;
|
||||
|
||||
while ((match = regex.exec(text)) && position > match.index) {
|
||||
start = match.index + match[0].length;
|
||||
lineNumber++;
|
||||
}
|
||||
|
||||
end = match ? match.index : text.length;
|
||||
|
||||
const line = text.substring(start, end);
|
||||
const threshold = Math.max(config.get<number>('inputValidationLength') || 72, 0) || 72;
|
||||
|
||||
let threshold = config.get<number>('inputValidationLength', 50);
|
||||
|
||||
if (lineNumber === 0) {
|
||||
const inputValidationSubjectLength = config.get<number | null>('inputValidationSubjectLength', null);
|
||||
|
||||
if (inputValidationSubjectLength !== null) {
|
||||
threshold = inputValidationSubjectLength;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// const subjectThreshold =
|
||||
|
||||
|
||||
// Math.max(config.get<number>('inputValidationLength') || 50, config.get<number>('subjectValidationLength') || 50, 0) || 50;
|
||||
|
||||
if (line.length <= threshold) {
|
||||
if (setting !== 'always') {
|
||||
@@ -697,10 +728,18 @@ export class Repository implements Disposable {
|
||||
return this.run(Operation.Config, () => this.repository.config('local', key));
|
||||
}
|
||||
|
||||
getGlobalConfig(key: string): Promise<string> {
|
||||
return this.run(Operation.Config, () => this.repository.config('global', key));
|
||||
}
|
||||
|
||||
setConfig(key: string, value: string): Promise<string> {
|
||||
return this.run(Operation.Config, () => this.repository.config('local', key, value));
|
||||
}
|
||||
|
||||
log(options?: LogOptions): Promise<Commit[]> {
|
||||
return this.run(Operation.Log, () => this.repository.log(options));
|
||||
}
|
||||
|
||||
@throttle
|
||||
async status(): Promise<void> {
|
||||
await this.run(Operation.Status);
|
||||
@@ -710,19 +749,31 @@ export class Repository implements Disposable {
|
||||
return this.run(Operation.Diff, () => this.repository.diff(cached));
|
||||
}
|
||||
|
||||
diffWithHEAD(path: string): Promise<string> {
|
||||
diffWithHEAD(): Promise<Change[]>;
|
||||
diffWithHEAD(path: string): Promise<string>;
|
||||
diffWithHEAD(path?: string | undefined): Promise<string | Change[]>;
|
||||
diffWithHEAD(path?: string | undefined): Promise<string | Change[]> {
|
||||
return this.run(Operation.Diff, () => this.repository.diffWithHEAD(path));
|
||||
}
|
||||
|
||||
diffWith(ref: string, path: string): Promise<string> {
|
||||
diffWith(ref: string): Promise<Change[]>;
|
||||
diffWith(ref: string, path: string): Promise<string>;
|
||||
diffWith(ref: string, path?: string | undefined): Promise<string | Change[]>;
|
||||
diffWith(ref: string, path?: string): Promise<string | Change[]> {
|
||||
return this.run(Operation.Diff, () => this.repository.diffWith(ref, path));
|
||||
}
|
||||
|
||||
diffIndexWithHEAD(path: string): Promise<string> {
|
||||
diffIndexWithHEAD(): Promise<Change[]>;
|
||||
diffIndexWithHEAD(path: string): Promise<string>;
|
||||
diffIndexWithHEAD(path?: string | undefined): Promise<string | Change[]>;
|
||||
diffIndexWithHEAD(path?: string): Promise<string | Change[]> {
|
||||
return this.run(Operation.Diff, () => this.repository.diffIndexWithHEAD(path));
|
||||
}
|
||||
|
||||
diffIndexWith(ref: string, path: string): Promise<string> {
|
||||
diffIndexWith(ref: string): Promise<Change[]>;
|
||||
diffIndexWith(ref: string, path: string): Promise<string>;
|
||||
diffIndexWith(ref: string, path?: string | undefined): Promise<string | Change[]>;
|
||||
diffIndexWith(ref: string, path?: string): Promise<string | Change[]> {
|
||||
return this.run(Operation.Diff, () => this.repository.diffIndexWith(ref, path));
|
||||
}
|
||||
|
||||
@@ -730,7 +781,10 @@ export class Repository implements Disposable {
|
||||
return this.run(Operation.Diff, () => this.repository.diffBlobs(object1, object2));
|
||||
}
|
||||
|
||||
diffBetween(ref1: string, ref2: string, path: string): Promise<string> {
|
||||
diffBetween(ref1: string, ref2: string): Promise<Change[]>;
|
||||
diffBetween(ref1: string, ref2: string, path: string): Promise<string>;
|
||||
diffBetween(ref1: string, ref2: string, path?: string | undefined): Promise<string | Change[]>;
|
||||
diffBetween(ref1: string, ref2: string, path?: string): Promise<string | Change[]> {
|
||||
return this.run(Operation.Diff, () => this.repository.diffBetween(ref1, ref2, path));
|
||||
}
|
||||
|
||||
@@ -904,8 +958,8 @@ export class Repository implements Disposable {
|
||||
await this.run(Operation.Fetch, () => this.repository.fetch({ all: true }));
|
||||
}
|
||||
|
||||
async fetch(remote?: string, ref?: string): Promise<void> {
|
||||
await this.run(Operation.Fetch, () => this.repository.fetch({ remote, ref }));
|
||||
async fetch(remote?: string, ref?: string, depth?: number): Promise<void> {
|
||||
await this.run(Operation.Fetch, () => this.repository.fetch({ remote, ref, depth }));
|
||||
}
|
||||
|
||||
@throttle
|
||||
@@ -918,18 +972,11 @@ export class Repository implements Disposable {
|
||||
branch = `${head.upstream.name}`;
|
||||
}
|
||||
|
||||
const config = workspace.getConfiguration('git', Uri.file(this.root));
|
||||
const fetchOnPull = config.get<boolean>('fetchOnPull');
|
||||
|
||||
if (fetchOnPull) {
|
||||
await this.run(Operation.Pull, () => this.repository.pull(true));
|
||||
} else {
|
||||
await this.run(Operation.Pull, () => this.repository.pull(true, remote, branch));
|
||||
}
|
||||
return this.pullFrom(true, remote, branch);
|
||||
}
|
||||
|
||||
@throttle
|
||||
async pull(head?: Branch): Promise<void> {
|
||||
async pull(head?: Branch, unshallow?: boolean): Promise<void> {
|
||||
let remote: string | undefined;
|
||||
let branch: string | undefined;
|
||||
|
||||
@@ -938,25 +985,22 @@ export class Repository implements Disposable {
|
||||
branch = `${head.upstream.name}`;
|
||||
}
|
||||
|
||||
const config = workspace.getConfiguration('git', Uri.file(this.root));
|
||||
const fetchOnPull = config.get<boolean>('fetchOnPull');
|
||||
|
||||
if (fetchOnPull) {
|
||||
await this.run(Operation.Pull, () => this.repository.pull(false));
|
||||
} else {
|
||||
await this.run(Operation.Pull, () => this.repository.pull(false, remote, branch));
|
||||
}
|
||||
return this.pullFrom(false, remote, branch, unshallow);
|
||||
}
|
||||
|
||||
async pullFrom(rebase?: boolean, remote?: string, branch?: string): Promise<void> {
|
||||
const config = workspace.getConfiguration('git', Uri.file(this.root));
|
||||
const fetchOnPull = config.get<boolean>('fetchOnPull');
|
||||
async pullFrom(rebase?: boolean, remote?: string, branch?: string, unshallow?: boolean): Promise<void> {
|
||||
await this.run(Operation.Pull, async () => {
|
||||
await this.maybeAutoStash(async () => {
|
||||
const config = workspace.getConfiguration('git', Uri.file(this.root));
|
||||
const fetchOnPull = config.get<boolean>('fetchOnPull');
|
||||
|
||||
if (fetchOnPull) {
|
||||
await this.run(Operation.Pull, () => this.repository.pull(rebase));
|
||||
} else {
|
||||
await this.run(Operation.Pull, () => this.repository.pull(rebase, remote, branch));
|
||||
}
|
||||
if (fetchOnPull) {
|
||||
await this.repository.pull(rebase, undefined, undefined, { unshallow });
|
||||
} else {
|
||||
await this.repository.pull(rebase, remote, branch, { unshallow });
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@throttle
|
||||
@@ -980,6 +1024,10 @@ export class Repository implements Disposable {
|
||||
await this.run(Operation.Push, () => this.repository.push(remote, undefined, false, true, forcePushMode));
|
||||
}
|
||||
|
||||
async blame(path: string): Promise<string> {
|
||||
return await this.run(Operation.Blame, () => this.repository.blame(path));
|
||||
}
|
||||
|
||||
@throttle
|
||||
sync(head: Branch): Promise<void> {
|
||||
return this._sync(head, false);
|
||||
@@ -1002,26 +1050,28 @@ export class Repository implements Disposable {
|
||||
}
|
||||
|
||||
await this.run(Operation.Sync, async () => {
|
||||
const config = workspace.getConfiguration('git', Uri.file(this.root));
|
||||
const fetchOnPull = config.get<boolean>('fetchOnPull');
|
||||
await this.maybeAutoStash(async () => {
|
||||
const config = workspace.getConfiguration('git', Uri.file(this.root));
|
||||
const fetchOnPull = config.get<boolean>('fetchOnPull');
|
||||
|
||||
if (fetchOnPull) {
|
||||
await this.repository.pull(rebase);
|
||||
} else {
|
||||
await this.repository.pull(rebase, remoteName, pullBranch);
|
||||
}
|
||||
if (fetchOnPull) {
|
||||
await this.repository.pull(rebase);
|
||||
} else {
|
||||
await this.repository.pull(rebase, remoteName, pullBranch);
|
||||
}
|
||||
|
||||
const remote = this.remotes.find(r => r.name === remoteName);
|
||||
const remote = this.remotes.find(r => r.name === remoteName);
|
||||
|
||||
if (remote && remote.isReadOnly) {
|
||||
return;
|
||||
}
|
||||
if (remote && remote.isReadOnly) {
|
||||
return;
|
||||
}
|
||||
|
||||
const shouldPush = this.HEAD && (typeof this.HEAD.ahead === 'number' ? this.HEAD.ahead > 0 : true);
|
||||
const shouldPush = this.HEAD && (typeof this.HEAD.ahead === 'number' ? this.HEAD.ahead > 0 : true);
|
||||
|
||||
if (shouldPush) {
|
||||
await this.repository.push(remoteName, pushBranch);
|
||||
}
|
||||
if (shouldPush) {
|
||||
await this.repository.push(remoteName, pushBranch);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1102,7 +1152,8 @@ export class Repository implements Disposable {
|
||||
const text = lastLine.isEmptyOrWhitespace ? `${textToAppend}\n` : `\n${textToAppend}\n`;
|
||||
|
||||
edit.insert(document.uri, lastLine.range.end, text);
|
||||
workspace.applyEdit(edit);
|
||||
await workspace.applyEdit(edit);
|
||||
await document.save();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1211,6 +1262,24 @@ export class Repository implements Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
private static KnownHugeFolderNames = ['node_modules'];
|
||||
|
||||
private async findKnownHugeFolderPathsToIgnore(): Promise<string[]> {
|
||||
const folderPaths: string[] = [];
|
||||
|
||||
for (const folderName of Repository.KnownHugeFolderNames) {
|
||||
const folderPath = path.join(this.repository.root, folderName);
|
||||
|
||||
if (await new Promise<boolean>(c => fs.exists(folderPath, c))) {
|
||||
folderPaths.push(folderPath);
|
||||
}
|
||||
}
|
||||
|
||||
const ignored = await this.checkIgnore(folderPaths);
|
||||
|
||||
return folderPaths.filter(p => !ignored.has(p));
|
||||
}
|
||||
|
||||
@throttle
|
||||
private async updateModelState(): Promise<void> {
|
||||
const { status, didHitLimit } = await this.repository.getStatus();
|
||||
@@ -1221,15 +1290,34 @@ export class Repository implements Disposable {
|
||||
this.isRepositoryHuge = didHitLimit;
|
||||
|
||||
if (didHitLimit && !shouldIgnore && !this.didWarnAboutLimit) {
|
||||
const knownHugeFolderPaths = await this.findKnownHugeFolderPathsToIgnore();
|
||||
const gitWarn = localize('huge', "The git repository at '{0}' has too many active changes, only a subset of Git features will be enabled.", this.repository.root);
|
||||
const neverAgain = { title: localize('neveragain', "Don't Show Again") };
|
||||
|
||||
window.showWarningMessage(localize('huge', "The git repository at '{0}' has too many active changes, only a subset of Git features will be enabled.", this.repository.root), neverAgain).then(result => {
|
||||
if (knownHugeFolderPaths.length > 0) {
|
||||
const folderPath = knownHugeFolderPaths[0];
|
||||
const folderName = path.basename(folderPath);
|
||||
|
||||
const addKnown = localize('add known', "Would you like to add '{0}' to .gitignore?", folderName);
|
||||
const yes = { title: localize('yes', "Yes") };
|
||||
|
||||
const result = await window.showWarningMessage(`${gitWarn} ${addKnown}`, yes, neverAgain);
|
||||
|
||||
if (result === neverAgain) {
|
||||
config.update('ignoreLimitWarning', true, false);
|
||||
this.didWarnAboutLimit = true;
|
||||
} else if (result === yes) {
|
||||
this.ignore([Uri.file(folderPath)]);
|
||||
}
|
||||
} else {
|
||||
const result = await window.showWarningMessage(gitWarn, neverAgain);
|
||||
|
||||
if (result === neverAgain) {
|
||||
config.update('ignoreLimitWarning', true, false);
|
||||
}
|
||||
});
|
||||
|
||||
this.didWarnAboutLimit = true;
|
||||
this.didWarnAboutLimit = true;
|
||||
}
|
||||
}
|
||||
|
||||
let HEAD: Branch | undefined;
|
||||
@@ -1287,6 +1375,7 @@ export class Repository implements Disposable {
|
||||
switch (raw.y) {
|
||||
case 'M': workingTree.push(new Resource(ResourceGroupType.WorkingTree, uri, Status.MODIFIED, useIcons, renameUri)); break;
|
||||
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;
|
||||
});
|
||||
@@ -1339,6 +1428,22 @@ export class Repository implements Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
private async maybeAutoStash<T>(runOperation: () => Promise<T>): Promise<T> {
|
||||
const config = workspace.getConfiguration('git', Uri.file(this.root));
|
||||
const shouldAutoStash = config.get<boolean>('autoStash')
|
||||
&& this.workingTreeGroup.resourceStates.some(r => r.type !== Status.UNTRACKED && r.type !== Status.IGNORED);
|
||||
|
||||
if (!shouldAutoStash) {
|
||||
return await runOperation();
|
||||
}
|
||||
|
||||
await this.repository.createStash(undefined, true);
|
||||
const result = await runOperation();
|
||||
await this.repository.popStash();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private onFSChange(_uri: Uri): void {
|
||||
const config = workspace.getConfiguration('git');
|
||||
const autorefresh = config.get<boolean>('autorefresh');
|
||||
|
||||
@@ -13,7 +13,18 @@ export function applyLineChanges(original: TextDocument, modified: TextDocument,
|
||||
const isInsertion = diff.originalEndLineNumber === 0;
|
||||
const isDeletion = diff.modifiedEndLineNumber === 0;
|
||||
|
||||
result.push(original.getText(new Range(currentLine, 0, isInsertion ? diff.originalStartLineNumber : diff.originalStartLineNumber - 1, 0)));
|
||||
let endLine = isInsertion ? diff.originalStartLineNumber : diff.originalStartLineNumber - 1;
|
||||
let endCharacter = 0;
|
||||
|
||||
// if this is a deletion at the very end of the document,then we need to account
|
||||
// for a newline at the end of the last line which may have been deleted
|
||||
// https://github.com/Microsoft/vscode/issues/59670
|
||||
if (isDeletion && diff.originalStartLineNumber === original.lineCount) {
|
||||
endLine -= 1;
|
||||
endCharacter = original.lineAt(endLine).range.end.character;
|
||||
}
|
||||
|
||||
result.push(original.getText(new Range(currentLine, 0, endLine, endCharacter)));
|
||||
|
||||
if (!isDeletion) {
|
||||
let fromLine = diff.modifiedStartLineNumber - 1;
|
||||
@@ -114,4 +125,4 @@ export function invertLineChange(diff: LineChange): LineChange {
|
||||
originalStartLineNumber: diff.modifiedStartLineNumber,
|
||||
originalEndLineNumber: diff.modifiedEndLineNumber
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,37 +177,43 @@ suite('git', () => {
|
||||
suite('parseGitCommit', () => {
|
||||
test('single parent commit', function () {
|
||||
const GIT_OUTPUT_SINGLE_PARENT = `52c293a05038d865604c2284aa8698bd087915a1
|
||||
john.doe@mail.com
|
||||
8e5a374372b8393906c7e380dbb09349c5385554
|
||||
This is a commit message.`;
|
||||
|
||||
assert.deepEqual(parseGitCommit(GIT_OUTPUT_SINGLE_PARENT), {
|
||||
hash: '52c293a05038d865604c2284aa8698bd087915a1',
|
||||
message: 'This is a commit message.',
|
||||
parents: ['8e5a374372b8393906c7e380dbb09349c5385554']
|
||||
parents: ['8e5a374372b8393906c7e380dbb09349c5385554'],
|
||||
authorEmail: 'john.doe@mail.com',
|
||||
});
|
||||
});
|
||||
|
||||
test('multiple parent commits', function () {
|
||||
const GIT_OUTPUT_MULTIPLE_PARENTS = `52c293a05038d865604c2284aa8698bd087915a1
|
||||
john.doe@mail.com
|
||||
8e5a374372b8393906c7e380dbb09349c5385554 df27d8c75b129ab9b178b386077da2822101b217
|
||||
This is a commit message.`;
|
||||
|
||||
assert.deepEqual(parseGitCommit(GIT_OUTPUT_MULTIPLE_PARENTS), {
|
||||
hash: '52c293a05038d865604c2284aa8698bd087915a1',
|
||||
message: 'This is a commit message.',
|
||||
parents: ['8e5a374372b8393906c7e380dbb09349c5385554', 'df27d8c75b129ab9b178b386077da2822101b217']
|
||||
parents: ['8e5a374372b8393906c7e380dbb09349c5385554', 'df27d8c75b129ab9b178b386077da2822101b217'],
|
||||
authorEmail: 'john.doe@mail.com',
|
||||
});
|
||||
});
|
||||
|
||||
test('no parent commits', function () {
|
||||
const GIT_OUTPUT_NO_PARENTS = `52c293a05038d865604c2284aa8698bd087915a1
|
||||
john.doe@mail.com
|
||||
|
||||
This is a commit message.`;
|
||||
|
||||
assert.deepEqual(parseGitCommit(GIT_OUTPUT_NO_PARENTS), {
|
||||
hash: '52c293a05038d865604c2284aa8698bd087915a1',
|
||||
message: 'This is a commit message.',
|
||||
parents: []
|
||||
parents: [],
|
||||
authorEmail: 'john.doe@mail.com',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -69,7 +69,7 @@ export function anyEvent<T>(...events: Event<T>[]): Event<T> {
|
||||
}
|
||||
|
||||
export function done<T>(promise: Promise<T>): Promise<void> {
|
||||
return promise.then<void>(() => void 0);
|
||||
return promise.then<void>(() => undefined);
|
||||
}
|
||||
|
||||
export function onceEvent<T>(event: Event<T>): Event<T> {
|
||||
|
||||
@@ -36,10 +36,10 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/which/-/which-1.0.28.tgz#016e387629b8817bed653fe32eab5d11279c8df6"
|
||||
integrity sha1-AW44dim4gXvtZT/jLqtdESecjfY=
|
||||
|
||||
applicationinsights@1.0.6:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-1.0.6.tgz#bc201810de91cea910dab34e8ad35ecde488edeb"
|
||||
integrity sha512-VQT3kBpJVPw5fCO5n+WUeSx0VHjxFtD7znYbILBlVgOS9/cMDuGFmV2Br3ObzFyZUDGNbEfW36fD1y2/vAiCKw==
|
||||
applicationinsights@1.0.8:
|
||||
version "1.0.8"
|
||||
resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-1.0.8.tgz#db6e3d983cf9f9405fe1ee5ba30ac6e1914537b5"
|
||||
integrity sha512-KzOOGdphOS/lXWMFZe5440LUdFbrLpMvh2SaRxn7BmiI550KAoSb2gIhiq6kJZ9Ir3AxRRztjhzif+e5P5IXIg==
|
||||
dependencies:
|
||||
diagnostic-channel "0.2.0"
|
||||
diagnostic-channel-publishers "0.2.1"
|
||||
@@ -313,12 +313,12 @@ supports-color@3.1.2:
|
||||
dependencies:
|
||||
has-flag "^1.0.0"
|
||||
|
||||
vscode-extension-telemetry@0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.0.tgz#3cdcb61d03829966bd04b5f11471a1e40d6abaad"
|
||||
integrity sha512-WVCnP+uLxlqB6UD98yQNV47mR5Rf79LFxpuZhSPhEf0Sb4tPZed3a63n003/dchhOwyCTCBuNN4n8XKJkLEI1Q==
|
||||
vscode-extension-telemetry@0.1.1:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.1.tgz#91387e06b33400c57abd48979b0e790415ae110b"
|
||||
integrity sha512-TkKKG/B/J94DP5qf6xWB4YaqlhWDg6zbbqVx7Bz//stLQNnfE9XS1xm3f6fl24c5+bnEK0/wHgMgZYKIKxPeUA==
|
||||
dependencies:
|
||||
applicationinsights "1.0.6"
|
||||
applicationinsights "1.0.8"
|
||||
|
||||
vscode-nls@^4.0.0:
|
||||
version "4.0.0"
|
||||
|
||||
@@ -1,64 +1,69 @@
|
||||
{
|
||||
"name": "import",
|
||||
"displayName": "SQL Server Import",
|
||||
"description": "SQL Server Import for Azure Data Studio supports importing CSV or JSON files into SQL Server.",
|
||||
"version": "0.7.0",
|
||||
"publisher": "Microsoft",
|
||||
"preview": true,
|
||||
"engines": {
|
||||
"vscode": "^1.25.0",
|
||||
"azdata": "*"
|
||||
},
|
||||
"license": "https://raw.githubusercontent.com/Microsoft/azuredatastudio/master/extensions/import/Microsoft_SQL_Server_Import_Extension_and_Tools_Import_Flat_File_Preview.docx",
|
||||
"icon": "images/sqlserver.png",
|
||||
"aiKey": "AIF-5574968e-856d-40d2-af67-c89a14e76412",
|
||||
"activationEvents": [
|
||||
"*"
|
||||
],
|
||||
"main": "./out/main",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Microsoft/azuredatastudio.git"
|
||||
},
|
||||
"extensionDependencies": [
|
||||
"Microsoft.mssql"
|
||||
],
|
||||
"contributes": {
|
||||
"commands": [
|
||||
{
|
||||
"command": "flatFileImport.start",
|
||||
"title": "Import wizard",
|
||||
"category": "Flat File Import",
|
||||
"icon": {
|
||||
"light": "./images/light_icon.svg",
|
||||
"dark": "./images/dark_icon.svg"
|
||||
}
|
||||
}
|
||||
],
|
||||
"keybindings": [
|
||||
{
|
||||
"command": "flatFileImport.start",
|
||||
"key": "ctrl+i",
|
||||
"mac": "ctrl+i"
|
||||
}
|
||||
],
|
||||
"menus": {
|
||||
"objectExplorer/item/context": [
|
||||
{
|
||||
"command": "flatFileImport.start",
|
||||
"when": "connectionProvider == MSSQL && nodeType && nodeType == Database",
|
||||
"group": "import"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"dataprotocol-client": "github:Microsoft/sqlops-dataprotocolclient#0.2.15",
|
||||
"htmlparser2": "^3.10.1",
|
||||
"opener": "^1.4.3",
|
||||
"service-downloader": "github:anthonydresser/service-downloader#0.1.5",
|
||||
"vscode-extension-telemetry": "0.0.18",
|
||||
"vscode-nls": "^3.2.1"
|
||||
},
|
||||
"devDependencies": {}
|
||||
}
|
||||
"name": "import",
|
||||
"displayName": "SQL Server Import",
|
||||
"description": "SQL Server Import for Azure Data Studio supports importing CSV or JSON files into SQL Server.",
|
||||
"version": "0.7.0",
|
||||
"publisher": "Microsoft",
|
||||
"preview": true,
|
||||
"engines": {
|
||||
"vscode": "^1.25.0",
|
||||
"azdata": "*"
|
||||
},
|
||||
"license": "https://raw.githubusercontent.com/Microsoft/azuredatastudio/master/extensions/import/Microsoft_SQL_Server_Import_Extension_and_Tools_Import_Flat_File_Preview.docx",
|
||||
"icon": "images/sqlserver.png",
|
||||
"aiKey": "AIF-5574968e-856d-40d2-af67-c89a14e76412",
|
||||
"activationEvents": [
|
||||
"*"
|
||||
],
|
||||
"main": "./out/main",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Microsoft/azuredatastudio.git"
|
||||
},
|
||||
"extensionDependencies": [
|
||||
"Microsoft.mssql"
|
||||
],
|
||||
"contributes": {
|
||||
"commands": [
|
||||
{
|
||||
"command": "flatFileImport.start",
|
||||
"title": "Import wizard",
|
||||
"category": "Flat File Import",
|
||||
"icon": {
|
||||
"light": "./images/light_icon.svg",
|
||||
"dark": "./images/dark_icon.svg"
|
||||
}
|
||||
}
|
||||
],
|
||||
"keybindings": [
|
||||
{
|
||||
"command": "flatFileImport.start",
|
||||
"key": "ctrl+i",
|
||||
"mac": "ctrl+i"
|
||||
}
|
||||
],
|
||||
"menus": {
|
||||
"objectExplorer/item/context": [
|
||||
{
|
||||
"command": "flatFileImport.start",
|
||||
"when": "connectionProvider == MSSQL && nodeType && nodeType == Database",
|
||||
"group": "import"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"dataprotocol-client": "github:Microsoft/sqlops-dataprotocolclient#0.2.15",
|
||||
"htmlparser2": "^3.10.1",
|
||||
"opener": "^1.4.3",
|
||||
"service-downloader": "github:anthonydresser/service-downloader#0.1.5",
|
||||
"vscode-extension-telemetry": "0.0.18",
|
||||
"vscode-nls": "^3.2.1"
|
||||
},
|
||||
"devDependencies": {},
|
||||
"__metadata": {
|
||||
"id": "23",
|
||||
"publisherDisplayName": "Microsoft",
|
||||
"publisherId": "Microsoft"
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ import * as fs from 'fs';
|
||||
import * as nls from 'vscode-nls';
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
import { workspace, window, languages, commands, ExtensionContext, extensions, Uri, LanguageConfiguration, Diagnostic, StatusBarAlignment, TextEditor } from 'vscode';
|
||||
import { workspace, window, languages, commands, ExtensionContext, extensions, Uri, LanguageConfiguration, Diagnostic, StatusBarAlignment, TextEditor, TextDocument, Position, SelectionRange, Range, SelectionRangeKind } from 'vscode';
|
||||
import { LanguageClient, LanguageClientOptions, RequestType, ServerOptions, TransportKind, NotificationType, DidChangeConfigurationNotification, HandleDiagnosticsSignature } from 'vscode-languageclient';
|
||||
import TelemetryReporter from 'vscode-extension-telemetry';
|
||||
|
||||
@@ -193,8 +193,32 @@ export function activate(context: ExtensionContext) {
|
||||
toDispose.push(commands.registerCommand('_json.retryResolveSchema', handleRetryResolveSchemaCommand));
|
||||
|
||||
client.sendNotification(SchemaAssociationNotification.type, getSchemaAssociation(context));
|
||||
|
||||
extensions.onDidChange(_ => {
|
||||
client.sendNotification(SchemaAssociationNotification.type, getSchemaAssociation(context));
|
||||
});
|
||||
|
||||
documentSelector.forEach(selector => {
|
||||
toDispose.push(languages.registerSelectionRangeProvider(selector, {
|
||||
async provideSelectionRanges(document: TextDocument, position: Position): Promise<SelectionRange[]> {
|
||||
const textDocument = client.code2ProtocolConverter.asTextDocumentIdentifier(document);
|
||||
const rawRanges = await client.sendRequest<Range[]>('$/textDocument/selectionRange', { textDocument, position });
|
||||
if (Array.isArray(rawRanges)) {
|
||||
return rawRanges.map(r => {
|
||||
return {
|
||||
range: client.protocol2CodeConverter.asRange(r),
|
||||
kind: SelectionRangeKind.Declaration
|
||||
};
|
||||
});
|
||||
}
|
||||
return [];
|
||||
}
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
let languageConfiguration: LanguageConfiguration = {
|
||||
wordPattern: /("(?:[^\\\"]*(?:\\.)?)*"?)|[^\s{}\[\],:]+/,
|
||||
indentationRules: {
|
||||
@@ -338,7 +362,7 @@ function getPackageInfo(context: ExtensionContext): IPackageInfo | undefined {
|
||||
aiKey: extensionPackage.aiKey
|
||||
};
|
||||
}
|
||||
return void 0;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function readJSONFile(location: string) {
|
||||
|
||||
@@ -4,3 +4,4 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
/// <reference path='../../../../../src/vs/vscode.d.ts'/>
|
||||
/// <reference path="../../../../../src/vs/vscode.proposed.d.ts" />
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
"onLanguage:jsonc"
|
||||
],
|
||||
"main": "./client/out/jsonMain",
|
||||
"enableProposedApi": true,
|
||||
"scripts": {
|
||||
"compile": "gulp compile-extension:json-language-features-client compile-extension:json-language-features-server",
|
||||
"watch": "gulp watch-extension:json-language-features-client watch-extension:json-language-features-server",
|
||||
@@ -100,11 +101,11 @@
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"vscode-extension-telemetry": "0.1.0",
|
||||
"vscode-extension-telemetry": "0.1.1",
|
||||
"vscode-languageclient": "^5.1.0",
|
||||
"vscode-nls": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^8.10.25"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@
|
||||
"dependencies": {
|
||||
"jsonc-parser": "^2.0.2",
|
||||
"request-light": "^0.2.4",
|
||||
"vscode-json-languageservice": "^3.2.1",
|
||||
"vscode-json-languageservice": "^3.3.0-next.0",
|
||||
"vscode-languageserver": "^5.1.0",
|
||||
"vscode-nls": "^4.0.0",
|
||||
"vscode-uri": "^1.0.6"
|
||||
|
||||
@@ -143,7 +143,7 @@ connection.onInitialize((params: InitializeParams): InitializeResult => {
|
||||
const capabilities: ServerCapabilities = {
|
||||
// Tell the client that the server works in FULL text document sync mode
|
||||
textDocumentSync: documents.syncKind,
|
||||
completionProvider: clientSnippetSupport ? { resolveProvider: true, triggerCharacters: ['"', ':'] } : void 0,
|
||||
completionProvider: clientSnippetSupport ? { resolveProvider: true, triggerCharacters: ['"', ':'] } : undefined,
|
||||
hoverProvider: true,
|
||||
documentSymbolProvider: true,
|
||||
documentRangeFormattingProvider: false,
|
||||
@@ -174,13 +174,13 @@ interface JSONSchemaSettings {
|
||||
schema?: JSONSchema;
|
||||
}
|
||||
|
||||
let jsonConfigurationSettings: JSONSchemaSettings[] | undefined = void 0;
|
||||
let schemaAssociations: ISchemaAssociations | undefined = void 0;
|
||||
let jsonConfigurationSettings: JSONSchemaSettings[] | undefined = undefined;
|
||||
let schemaAssociations: ISchemaAssociations | undefined = undefined;
|
||||
let formatterRegistration: Thenable<Disposable> | null = null;
|
||||
|
||||
// The settings have changed. Is send on server activation as well.
|
||||
connection.onDidChangeConfiguration((change) => {
|
||||
var settings = <Settings>change.settings;
|
||||
let settings = <Settings>change.settings;
|
||||
configureHttpRequests(settings.http && settings.http.proxy, settings.http && settings.http.proxyStrictSSL);
|
||||
|
||||
jsonConfigurationSettings = settings.json && settings.json.schemas;
|
||||
@@ -233,7 +233,7 @@ function updateConfiguration() {
|
||||
schemas: new Array<SchemaConfiguration>()
|
||||
};
|
||||
if (schemaAssociations) {
|
||||
for (var pattern in schemaAssociations) {
|
||||
for (const pattern in schemaAssociations) {
|
||||
const association = schemaAssociations[pattern];
|
||||
if (Array.isArray(association)) {
|
||||
association.forEach(uri => {
|
||||
@@ -427,5 +427,16 @@ connection.onFoldingRanges((params, token) => {
|
||||
}, null, `Error while computing folding ranges for ${params.textDocument.uri}`, token);
|
||||
});
|
||||
|
||||
connection.onRequest('$/textDocument/selectionRange', async (params, token) => {
|
||||
return runSafe(() => {
|
||||
const document = documents.get(params.textDocument.uri);
|
||||
if (document) {
|
||||
const jsonDocument = getJSONDocument(document);
|
||||
return languageService.getSelectionRanges(document, params.position, jsonDocument);
|
||||
}
|
||||
return [];
|
||||
}, [], `Error while computing selection ranges for ${params.textDocument.uri}`, token);
|
||||
});
|
||||
|
||||
// Listen on the connection
|
||||
connection.listen();
|
||||
|
||||
@@ -15,7 +15,7 @@ export function getLanguageModelCache<T>(maxEntries: number, cleanupIntervalTime
|
||||
let languageModels: { [uri: string]: { version: number, languageId: string, cTime: number, languageModel: T } } = {};
|
||||
let nModels = 0;
|
||||
|
||||
let cleanupInterval: NodeJS.Timer | undefined = void 0;
|
||||
let cleanupInterval: NodeJS.Timer | undefined = undefined;
|
||||
if (cleanupIntervalTimeInSec > 0) {
|
||||
cleanupInterval = setInterval(() => {
|
||||
let cutoffTime = Date.now() - cleanupIntervalTimeInSec * 1000;
|
||||
@@ -73,7 +73,7 @@ export function getLanguageModelCache<T>(maxEntries: number, cleanupIntervalTime
|
||||
dispose() {
|
||||
if (typeof cleanupInterval !== 'undefined') {
|
||||
clearInterval(cleanupInterval);
|
||||
cleanupInterval = void 0;
|
||||
cleanupInterval = undefined;
|
||||
languageModels = {};
|
||||
nModels = 0;
|
||||
}
|
||||
|
||||
@@ -73,10 +73,10 @@ request-light@^0.2.4:
|
||||
https-proxy-agent "^2.2.1"
|
||||
vscode-nls "^4.0.0"
|
||||
|
||||
vscode-json-languageservice@^3.2.1:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.2.1.tgz#991d51128ebd81c5525d0578cabfa5b03e3cba2a"
|
||||
integrity sha512-ee9MJ70/xR55ywvm0bZsDLhA800HCRE27AYgMNTU14RSg20Y+ngHdQnUt6OmiTXrQDI/7sne6QUOtHIN0hPQYA==
|
||||
vscode-json-languageservice@^3.3.0-next.0:
|
||||
version "3.3.0-next.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.3.0-next.0.tgz#c17db95d0eacc24f80d3b3f120ab5e03943769a0"
|
||||
integrity sha512-YZXL3yHzbr0/Ar5dGdeM/f5Y0l41z/Y4QSQTdL3Hl3ScuY76IPcDEnf7iuk9yx+QoPfEHFCBDv5Rg6XVcMl8Tg==
|
||||
dependencies:
|
||||
jsonc-parser "^2.0.2"
|
||||
vscode-languageserver-types "^3.13.0"
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.25.tgz#801fe4e39372cef18f268db880a5fbfcf71adc7e"
|
||||
integrity sha512-WXvAXaknB0c2cJ7N44e1kUrVu5K90mSfPPaT5XxfuSMxEWva86EYIwxUZM3jNZ2P1CIC9e2z4WJqpAF69PQxeA==
|
||||
|
||||
applicationinsights@1.0.6:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-1.0.6.tgz#bc201810de91cea910dab34e8ad35ecde488edeb"
|
||||
integrity sha512-VQT3kBpJVPw5fCO5n+WUeSx0VHjxFtD7znYbILBlVgOS9/cMDuGFmV2Br3ObzFyZUDGNbEfW36fD1y2/vAiCKw==
|
||||
applicationinsights@1.0.8:
|
||||
version "1.0.8"
|
||||
resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-1.0.8.tgz#db6e3d983cf9f9405fe1ee5ba30ac6e1914537b5"
|
||||
integrity sha512-KzOOGdphOS/lXWMFZe5440LUdFbrLpMvh2SaRxn7BmiI550KAoSb2gIhiq6kJZ9Ir3AxRRztjhzif+e5P5IXIg==
|
||||
dependencies:
|
||||
diagnostic-channel "0.2.0"
|
||||
diagnostic-channel-publishers "0.2.1"
|
||||
@@ -38,12 +38,12 @@ semver@^5.5.0:
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.1.tgz#7dfdd8814bdb7cabc7be0fb1d734cfb66c940477"
|
||||
integrity sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw==
|
||||
|
||||
vscode-extension-telemetry@0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.0.tgz#3cdcb61d03829966bd04b5f11471a1e40d6abaad"
|
||||
integrity sha512-WVCnP+uLxlqB6UD98yQNV47mR5Rf79LFxpuZhSPhEf0Sb4tPZed3a63n003/dchhOwyCTCBuNN4n8XKJkLEI1Q==
|
||||
vscode-extension-telemetry@0.1.1:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.1.tgz#91387e06b33400c57abd48979b0e790415ae110b"
|
||||
integrity sha512-TkKKG/B/J94DP5qf6xWB4YaqlhWDg6zbbqVx7Bz//stLQNnfE9XS1xm3f6fl24c5+bnEK0/wHgMgZYKIKxPeUA==
|
||||
dependencies:
|
||||
applicationinsights "1.0.6"
|
||||
applicationinsights "1.0.8"
|
||||
|
||||
vscode-jsonrpc@^4.0.0:
|
||||
version "4.0.0"
|
||||
|
||||
@@ -29,4 +29,4 @@
|
||||
}
|
||||
],
|
||||
"version": 1
|
||||
}
|
||||
}
|
||||
@@ -17,13 +17,13 @@
|
||||
],
|
||||
"extensions": [
|
||||
".md",
|
||||
".mkd",
|
||||
".mdwn",
|
||||
".mkd",
|
||||
".mdwn",
|
||||
".mdown",
|
||||
".markdown",
|
||||
".markdn",
|
||||
".mdtxt",
|
||||
".mdtext",
|
||||
".mdtxt",
|
||||
".mdtext",
|
||||
".workbook"
|
||||
],
|
||||
"configuration": "./language-configuration.json"
|
||||
@@ -91,4 +91,4 @@
|
||||
"scripts": {
|
||||
"update-grammar": "node ../../build/npm/update-grammar.js microsoft/vscode-markdown-tm-grammar syntaxes/markdown.tmLanguage ./syntaxes/markdown.tmLanguage.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
body {
|
||||
font-family: "Segoe WPC", "Segoe UI", "SFUIText-Light", "HelveticaNeue-Light", sans-serif, "Droid Sans Fallback";
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "Ubuntu", "Droid Sans", sans-serif;
|
||||
font-size: 14px;
|
||||
padding: 0 26px;
|
||||
line-height: 22px;
|
||||
|
||||
@@ -191,16 +191,6 @@
|
||||
"description": "%markdown.styles.dec%",
|
||||
"scope": "resource"
|
||||
},
|
||||
"markdown.previewFrontMatter": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"hide",
|
||||
"show"
|
||||
],
|
||||
"default": "hide",
|
||||
"description": "%markdown.previewFrontMatter.dec%",
|
||||
"scope": "resource"
|
||||
},
|
||||
"markdown.preview.breaks": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
@@ -215,7 +205,7 @@
|
||||
},
|
||||
"markdown.preview.fontFamily": {
|
||||
"type": "string",
|
||||
"default": "-apple-system, BlinkMacSystemFont, 'Segoe WPC', 'Segoe UI', 'HelveticaNeue-Light', 'Ubuntu', 'Droid Sans', sans-serif",
|
||||
"default": "-apple-system, BlinkMacSystemFont, 'Segoe WPC', 'Segoe UI', 'Ubuntu', 'Droid Sans', sans-serif",
|
||||
"description": "%markdown.preview.fontFamily.desc%",
|
||||
"scope": "resource"
|
||||
},
|
||||
@@ -315,13 +305,14 @@
|
||||
"build-preview": "webpack --mode development"
|
||||
},
|
||||
"dependencies": {
|
||||
"highlight.js": "9.12.0",
|
||||
"markdown-it": "^8.4.1",
|
||||
"vscode-extension-telemetry": "0.1.0",
|
||||
"highlight.js": "9.13.1",
|
||||
"markdown-it": "^8.4.2",
|
||||
"markdown-it-front-matter": "^0.1.2",
|
||||
"vscode-extension-telemetry": "0.1.1",
|
||||
"vscode-nls": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/highlight.js": "9.1.10",
|
||||
"@types/highlight.js": "9.12.3",
|
||||
"@types/lodash.throttle": "^4.1.3",
|
||||
"@types/markdown-it": "0.0.2",
|
||||
"@types/node": "^8.10.25",
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
"markdown.preview.scrollPreviewWithEditorSelection.desc": "[Deprecated] Scrolls the markdown preview to reveal the currently selected line from the editor.",
|
||||
"markdown.preview.scrollPreviewWithEditorSelection.deprecationMessage": "This setting has been replaced by 'markdown.preview.scrollPreviewWithEditor' and no longer has any effect.",
|
||||
"markdown.preview.title": "Open Preview",
|
||||
"markdown.previewFrontMatter.dec": "Sets how YAML front matter should be rendered in the markdown preview. 'hide' removes the front matter. Otherwise, the front matter is treated as markdown content.",
|
||||
"markdown.previewSide.title": "Open Preview to the Side",
|
||||
"markdown.showLockedPreviewToSide.title": "Open Locked Preview to the Side",
|
||||
"markdown.showSource.title": "Show Source",
|
||||
|
||||
@@ -12,7 +12,7 @@ import throttle = require('lodash.throttle');
|
||||
|
||||
declare var acquireVsCodeApi: any;
|
||||
|
||||
var scrollDisabled = true;
|
||||
let scrollDisabled = true;
|
||||
const marker = new ActiveLineMarker();
|
||||
const settings = getSettings();
|
||||
|
||||
|
||||
@@ -110,7 +110,8 @@ export function scrollToRevealSourceLine(line: number) {
|
||||
const elementOffset = next.element.getBoundingClientRect().top - previousTop;
|
||||
scrollTo = previousTop + betweenProgress * elementOffset;
|
||||
} else {
|
||||
scrollTo = previousTop;
|
||||
const progressInElement = line - Math.floor(line);
|
||||
scrollTo = previousTop + (rect.height * progressInElement);
|
||||
}
|
||||
window.scroll(window.scrollX, Math.max(1, window.scrollY + scrollTo));
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ export class OpenDocumentLinkCommand implements Command {
|
||||
path: string,
|
||||
fragment: string
|
||||
): vscode.Uri {
|
||||
return vscode.Uri.parse(`command:${OpenDocumentLinkCommand.id}?${encodeURIComponent(JSON.stringify({ path, fragment }))}`);
|
||||
return vscode.Uri.parse(`command:${OpenDocumentLinkCommand.id}?${encodeURIComponent(JSON.stringify({ path: encodeURIComponent(path), fragment }))}`);
|
||||
}
|
||||
|
||||
public constructor(
|
||||
@@ -39,9 +39,9 @@ export class OpenDocumentLinkCommand implements Command {
|
||||
return this.tryOpen(p + '.md', args);
|
||||
}
|
||||
const resource = vscode.Uri.file(p);
|
||||
return Promise.resolve(void 0)
|
||||
return Promise.resolve(undefined)
|
||||
.then(() => vscode.commands.executeCommand('vscode.open', resource))
|
||||
.then(() => void 0);
|
||||
.then(() => undefined);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,9 @@ export function activate(context: vscode.ExtensionContext) {
|
||||
const previewManager = new MarkdownPreviewManager(contentProvider, logger, contributions);
|
||||
context.subscriptions.push(previewManager);
|
||||
|
||||
context.subscriptions.push(vscode.languages.setLanguageConfiguration('markdown', {
|
||||
wordPattern: new RegExp('(\\p{Alphabetic}|\\p{Number})+', 'ug'),
|
||||
}));
|
||||
context.subscriptions.push(vscode.languages.registerDocumentSymbolProvider(selector, symbolProvider));
|
||||
context.subscriptions.push(vscode.languages.registerDocumentLinkProvider(selector, new LinkProvider()));
|
||||
context.subscriptions.push(vscode.languages.registerFoldingRangeProvider(selector, new MarkdownFoldingProvider(engine)));
|
||||
|
||||
@@ -50,8 +50,27 @@ function matchAll(
|
||||
return out;
|
||||
}
|
||||
|
||||
function extractDocumentLink(
|
||||
document: vscode.TextDocument,
|
||||
base: string,
|
||||
pre: number,
|
||||
link: string,
|
||||
matchIndex: number | undefined
|
||||
): vscode.DocumentLink | undefined {
|
||||
const offset = (matchIndex || 0) + pre;
|
||||
const linkStart = document.positionAt(offset);
|
||||
const linkEnd = document.positionAt(offset + link.length);
|
||||
try {
|
||||
return new vscode.DocumentLink(
|
||||
new vscode.Range(linkStart, linkEnd),
|
||||
normalizeLink(document, link, base));
|
||||
} catch (e) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
export default class LinkProvider implements vscode.DocumentLinkProvider {
|
||||
private readonly linkPattern = /(\[[^\]]*\]\(\s*)((([^\s\(\)]|\(\S*?\))+))\s*(".*?")?\)/g;
|
||||
private readonly linkPattern = /(\[((!\[[^\]]*?\]\(\s*)([^\s\(\)]+?)\s*\)\]|[^\]]*\])\(\s*)(([^\s\(\)]|\(\S*?\))+)\s*(".*?")?\)/g;
|
||||
private readonly referenceLinkPattern = /(\[([^\]]+)\]\[\s*?)([^\s\]]*?)\]/g;
|
||||
private readonly definitionPattern = /^([\t ]*\[([^\]]+)\]:\s*)(\S+)/gm;
|
||||
|
||||
@@ -73,20 +92,15 @@ export default class LinkProvider implements vscode.DocumentLinkProvider {
|
||||
): vscode.DocumentLink[] {
|
||||
const results: vscode.DocumentLink[] = [];
|
||||
for (const match of matchAll(this.linkPattern, text)) {
|
||||
const pre = match[1];
|
||||
const link = match[2];
|
||||
const offset = (match.index || 0) + pre.length;
|
||||
const linkStart = document.positionAt(offset);
|
||||
const linkEnd = document.positionAt(offset + link.length);
|
||||
try {
|
||||
results.push(new vscode.DocumentLink(
|
||||
new vscode.Range(linkStart, linkEnd),
|
||||
normalizeLink(document, link, base)));
|
||||
} catch (e) {
|
||||
// noop
|
||||
const matchImage = match[4] && extractDocumentLink(document, base, match[3].length + 1, match[4], match.index);
|
||||
if (matchImage) {
|
||||
results.push(matchImage);
|
||||
}
|
||||
const matchLink = extractDocumentLink(document, base, match[1].length, match[5], match.index);
|
||||
if (matchLink) {
|
||||
results.push(matchLink);
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
@@ -159,4 +173,4 @@ export default class LinkProvider implements vscode.DocumentLinkProvider {
|
||||
}
|
||||
return out;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,7 @@ export default class MarkdownFoldingProvider implements vscode.FoldingRangeProvi
|
||||
(isStartRegion(token.content) || isEndRegion(token.content));
|
||||
|
||||
|
||||
const tokens = await this.engine.parse(document.uri, document.getText());
|
||||
const tokens = await this.engine.parse(document);
|
||||
const regionMarkers = tokens.filter(isRegionMarker)
|
||||
.map(token => ({ line: token.map[0], isStart: isStartRegion(token.content) }));
|
||||
|
||||
@@ -84,7 +84,7 @@ export default class MarkdownFoldingProvider implements vscode.FoldingRangeProvi
|
||||
}
|
||||
};
|
||||
|
||||
const tokens = await this.engine.parse(document.uri, document.getText());
|
||||
const tokens = await this.engine.parse(document);
|
||||
const multiLineListItems = tokens.filter(isFoldableToken);
|
||||
return multiLineListItems.map(listItem => {
|
||||
const start = listItem.map[0];
|
||||
|
||||
@@ -12,7 +12,6 @@ export class MarkdownPreviewConfiguration {
|
||||
|
||||
public readonly scrollBeyondLastLine: boolean;
|
||||
public readonly wordWrap: boolean;
|
||||
public readonly previewFrontMatter: string;
|
||||
public readonly lineBreaks: boolean;
|
||||
public readonly doubleClickToSwitchToEditor: boolean;
|
||||
public readonly scrollEditorWithPreview: boolean;
|
||||
@@ -36,7 +35,6 @@ export class MarkdownPreviewConfiguration {
|
||||
this.wordWrap = markdownEditorConfig['editor.wordWrap'] !== 'off';
|
||||
}
|
||||
|
||||
this.previewFrontMatter = markdownConfig.get<string>('previewFrontMatter', 'hide');
|
||||
this.scrollPreviewWithEditor = !!markdownConfig.get<boolean>('preview.scrollPreviewWithEditor', true);
|
||||
this.scrollEditorWithPreview = !!markdownConfig.get<boolean>('preview.scrollEditorWithPreview', true);
|
||||
this.lineBreaks = !!markdownConfig.get<boolean>('preview.breaks', false);
|
||||
|
||||
@@ -68,7 +68,7 @@ export class MarkdownContentProvider {
|
||||
const nonce = new Date().getTime() + '' + new Date().getMilliseconds();
|
||||
const csp = this.getCspForResource(sourceUri, nonce);
|
||||
|
||||
const body = await this.engine.render(sourceUri, config.previewFrontMatter === 'hide', markdownDocument.getText());
|
||||
const body = await this.engine.render(markdownDocument);
|
||||
return `<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
|
||||
@@ -3,132 +3,158 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as crypto from 'crypto';
|
||||
import { MarkdownIt, Token } from 'markdown-it';
|
||||
import * as path from 'path';
|
||||
import * as vscode from 'vscode';
|
||||
import * as crypto from 'crypto';
|
||||
import { MarkdownContributions } from './markdownExtensions';
|
||||
import { Slugifier } from './slugify';
|
||||
import { SkinnyTextDocument } from './tableOfContentsProvider';
|
||||
import { getUriForLinkWithKnownExternalScheme } from './util/links';
|
||||
|
||||
const FrontMatterRegex = /^---\s*[^]*?(-{3}|\.{3})\s*/;
|
||||
const UNICODE_NEWLINE_REGEX = /\u2028|\u2029/g;
|
||||
|
||||
interface MarkdownItConfig {
|
||||
readonly breaks: boolean;
|
||||
readonly linkify: boolean;
|
||||
}
|
||||
|
||||
class TokenCache {
|
||||
private cachedDocument?: {
|
||||
readonly uri: vscode.Uri;
|
||||
readonly version: number;
|
||||
readonly config: MarkdownItConfig;
|
||||
};
|
||||
private tokens?: Token[];
|
||||
|
||||
public tryGetCached(document: SkinnyTextDocument, config: MarkdownItConfig): Token[] | undefined {
|
||||
if (this.cachedDocument
|
||||
&& this.cachedDocument.uri.toString() === document.uri.toString()
|
||||
&& this.cachedDocument.version === document.version
|
||||
&& this.cachedDocument.config.breaks === config.breaks
|
||||
&& this.cachedDocument.config.linkify === config.linkify
|
||||
) {
|
||||
return this.tokens;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public update(document: SkinnyTextDocument, config: MarkdownItConfig, tokens: Token[]) {
|
||||
this.cachedDocument = {
|
||||
uri: document.uri,
|
||||
version: document.version,
|
||||
config,
|
||||
};
|
||||
this.tokens = tokens;
|
||||
}
|
||||
}
|
||||
|
||||
export class MarkdownEngine {
|
||||
private md?: MarkdownIt;
|
||||
private md?: Promise<MarkdownIt>;
|
||||
|
||||
private firstLine?: number;
|
||||
private currentDocument?: vscode.Uri;
|
||||
private _slugCount = new Map<string, number>();
|
||||
private _tokenCache = new TokenCache();
|
||||
|
||||
public constructor(
|
||||
private readonly extensionPreviewResourceProvider: MarkdownContributions,
|
||||
private readonly slugifier: Slugifier,
|
||||
) { }
|
||||
|
||||
private usePlugin(factory: (md: any) => any): void {
|
||||
try {
|
||||
this.md = factory(this.md);
|
||||
} catch (e) {
|
||||
// noop
|
||||
private async getEngine(config: MarkdownItConfig): Promise<MarkdownIt> {
|
||||
if (!this.md) {
|
||||
this.md = import('markdown-it').then(async markdownIt => {
|
||||
let md: MarkdownIt = markdownIt(await getMarkdownOptions(() => md));
|
||||
|
||||
for (const plugin of this.extensionPreviewResourceProvider.markdownItPlugins) {
|
||||
try {
|
||||
md = (await plugin)(md);
|
||||
} catch {
|
||||
// noop
|
||||
}
|
||||
}
|
||||
|
||||
const frontMatterPlugin = require('markdown-it-front-matter');
|
||||
// Extract rules from front matter plugin and apply at a lower precedence
|
||||
let fontMatterRule: any;
|
||||
frontMatterPlugin({
|
||||
block: {
|
||||
ruler: {
|
||||
before: (_id: any, _id2: any, rule: any) => { fontMatterRule = rule; }
|
||||
}
|
||||
}
|
||||
}, () => { /* noop */ });
|
||||
|
||||
md.block.ruler.before('fence', 'front_matter', fontMatterRule, {
|
||||
alt: ['paragraph', 'reference', 'blockquote', 'list']
|
||||
});
|
||||
|
||||
for (const renderName of ['paragraph_open', 'heading_open', 'image', 'code_block', 'fence', 'blockquote_open', 'list_item_open']) {
|
||||
this.addLineNumberRenderer(md, renderName);
|
||||
}
|
||||
|
||||
this.addImageStabilizer(md);
|
||||
this.addFencedRenderer(md);
|
||||
|
||||
this.addLinkNormalizer(md);
|
||||
this.addLinkValidator(md);
|
||||
this.addNamedHeaders(md);
|
||||
return md;
|
||||
});
|
||||
}
|
||||
|
||||
const md = await this.md!;
|
||||
md.set(config);
|
||||
return md;
|
||||
}
|
||||
|
||||
private async getEngine(resource: vscode.Uri): Promise<MarkdownIt> {
|
||||
if (!this.md) {
|
||||
const hljs = await import('highlight.js');
|
||||
this.md = (await import('markdown-it'))({
|
||||
html: true,
|
||||
highlight: (str: string, lang?: string) => {
|
||||
// Workaround for highlight not supporting tsx: https://github.com/isagalaev/highlight.js/issues/1155
|
||||
if (lang && ['tsx', 'typescriptreact'].indexOf(lang.toLocaleLowerCase()) >= 0) {
|
||||
lang = 'jsx';
|
||||
}
|
||||
if (lang && lang.toLocaleLowerCase() === 'json5') {
|
||||
lang = 'json';
|
||||
}
|
||||
if (lang && lang.toLocaleLowerCase() === 'c#') {
|
||||
lang = 'cs';
|
||||
}
|
||||
if (lang && hljs.getLanguage(lang)) {
|
||||
try {
|
||||
return `<div>${hljs.highlight(lang, str, true).value}</div>`;
|
||||
} catch (error) { }
|
||||
}
|
||||
return `<code><div>${this.md!.utils.escapeHtml(str)}</div></code>`;
|
||||
}
|
||||
});
|
||||
|
||||
for (const plugin of this.extensionPreviewResourceProvider.markdownItPlugins) {
|
||||
this.usePlugin(await plugin);
|
||||
}
|
||||
|
||||
for (const renderName of ['paragraph_open', 'heading_open', 'image', 'code_block', 'fence', 'blockquote_open', 'list_item_open']) {
|
||||
this.addLineNumberRenderer(this.md, renderName);
|
||||
}
|
||||
|
||||
this.addImageStabilizer(this.md);
|
||||
this.addFencedRenderer(this.md);
|
||||
|
||||
this.addLinkNormalizer(this.md);
|
||||
this.addLinkValidator(this.md);
|
||||
this.addNamedHeaders(this.md);
|
||||
private tokenize(
|
||||
document: SkinnyTextDocument,
|
||||
config: MarkdownItConfig,
|
||||
engine: MarkdownIt
|
||||
): Token[] {
|
||||
const cached = this._tokenCache.tryGetCached(document, config);
|
||||
if (cached) {
|
||||
return cached;
|
||||
}
|
||||
|
||||
this.currentDocument = document.uri;
|
||||
this._slugCount = new Map<string, number>();
|
||||
|
||||
const text = document.getText();
|
||||
const tokens = engine.parse(text.replace(UNICODE_NEWLINE_REGEX, ''), {});
|
||||
this._tokenCache.update(document, config, tokens);
|
||||
return tokens;
|
||||
}
|
||||
|
||||
// {{SQL CARBON EDIT}} - Add renderText method
|
||||
public async renderText(document: vscode.Uri, text: string): Promise<string> {
|
||||
const engine = await this.getEngine(this.getConfig(document));
|
||||
return engine.render(text);
|
||||
}
|
||||
// {{SQL CARBON EDIT}} - End
|
||||
|
||||
public async render(document: SkinnyTextDocument): Promise<string> {
|
||||
const config = this.getConfig(document.uri);
|
||||
const engine = await this.getEngine(config);
|
||||
return engine.renderer.render(this.tokenize(document, config, engine), {
|
||||
...(engine as any).options,
|
||||
...config
|
||||
}, {});
|
||||
}
|
||||
|
||||
public async parse(document: SkinnyTextDocument): Promise<Token[]> {
|
||||
const config = this.getConfig(document.uri);
|
||||
const engine = await this.getEngine(config);
|
||||
return this.tokenize(document, config, engine);
|
||||
}
|
||||
|
||||
private getConfig(resource: vscode.Uri): MarkdownItConfig {
|
||||
const config = vscode.workspace.getConfiguration('markdown', resource);
|
||||
this.md.set({
|
||||
return {
|
||||
breaks: config.get<boolean>('preview.breaks', false),
|
||||
linkify: config.get<boolean>('preview.linkify', true)
|
||||
});
|
||||
return this.md;
|
||||
}
|
||||
|
||||
private stripFrontmatter(text: string): { text: string, offset: number } {
|
||||
let offset = 0;
|
||||
const frontMatterMatch = FrontMatterRegex.exec(text);
|
||||
if (frontMatterMatch) {
|
||||
const frontMatter = frontMatterMatch[0];
|
||||
offset = frontMatter.split(/\r\n|\n|\r/g).length - 1;
|
||||
text = text.substr(frontMatter.length);
|
||||
}
|
||||
return { text, offset };
|
||||
}
|
||||
|
||||
// {{SQL CARBON EDIT}}
|
||||
public async renderText(document: vscode.Uri, text: string): Promise<string> {
|
||||
const engine = await this.getEngine(document);
|
||||
return engine.render(text);
|
||||
}
|
||||
|
||||
public async render(document: vscode.Uri, stripFrontmatter: boolean, text: string): Promise<string> {
|
||||
let offset = 0;
|
||||
if (stripFrontmatter) {
|
||||
const markdownContent = this.stripFrontmatter(text);
|
||||
offset = markdownContent.offset;
|
||||
text = markdownContent.text;
|
||||
}
|
||||
this.currentDocument = document;
|
||||
this.firstLine = offset;
|
||||
this._slugCount = new Map<string, number>();
|
||||
|
||||
const engine = await this.getEngine(document);
|
||||
return engine.render(text);
|
||||
}
|
||||
|
||||
public async parse(document: vscode.Uri, source: string): Promise<Token[]> {
|
||||
const UNICODE_NEWLINE_REGEX = /\u2028|\u2029/g;
|
||||
const { text, offset } = this.stripFrontmatter(source);
|
||||
this.currentDocument = document;
|
||||
this._slugCount = new Map<string, number>();
|
||||
|
||||
const engine = await this.getEngine(document);
|
||||
|
||||
return engine.parse(text.replace(UNICODE_NEWLINE_REGEX, ''), {}).map(token => {
|
||||
if (token.map) {
|
||||
token.map[0] += offset;
|
||||
token.map[1] += offset;
|
||||
}
|
||||
return token;
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
private addLineNumberRenderer(md: any, ruleName: string): void {
|
||||
@@ -136,7 +162,7 @@ export class MarkdownEngine {
|
||||
md.renderer.rules[ruleName] = (tokens: any, idx: number, options: any, env: any, self: any) => {
|
||||
const token = tokens[idx];
|
||||
if (token.map && token.map.length) {
|
||||
token.attrSet('data-line', this.firstLine + token.map[0]);
|
||||
token.attrSet('data-line', token.map[0]);
|
||||
token.attrJoin('class', 'code-line');
|
||||
}
|
||||
|
||||
@@ -257,4 +283,30 @@ export class MarkdownEngine {
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function getMarkdownOptions(md: () => MarkdownIt) {
|
||||
const hljs = await import('highlight.js');
|
||||
return {
|
||||
html: true,
|
||||
highlight: (str: string, lang?: string) => {
|
||||
// Workaround for highlight not supporting tsx: https://github.com/isagalaev/highlight.js/issues/1155
|
||||
if (lang && ['tsx', 'typescriptreact'].indexOf(lang.toLocaleLowerCase()) >= 0) {
|
||||
lang = 'jsx';
|
||||
}
|
||||
if (lang && lang.toLocaleLowerCase() === 'json5') {
|
||||
lang = 'json';
|
||||
}
|
||||
if (lang && lang.toLocaleLowerCase() === 'c#') {
|
||||
lang = 'cs';
|
||||
}
|
||||
if (lang && hljs.getLanguage(lang)) {
|
||||
try {
|
||||
return `<div>${hljs.highlight(lang, str, true).value}</div>`;
|
||||
}
|
||||
catch (error) { }
|
||||
}
|
||||
return `<code><div>${md().utils.escapeHtml(str)}</div></code>`;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -149,6 +149,7 @@ export class PreviewSecuritySelector {
|
||||
|
||||
if (selection.type === 'toggle') {
|
||||
this.cspArbiter.setShouldDisableSecurityWarning(!this.cspArbiter.shouldDisableSecurityWarnings());
|
||||
this.webviewManager.refresh();
|
||||
return;
|
||||
} else {
|
||||
await this.cspArbiter.setSecurityLevelForResource(resource, selection.type);
|
||||
|
||||
@@ -23,7 +23,7 @@ export const githubSlugifier: Slugifier = new class implements Slugifier {
|
||||
heading.trim()
|
||||
.toLowerCase()
|
||||
.replace(/\s+/g, '-') // Replace whitespace with -
|
||||
.replace(/[\]\[\!\'\#\$\%\&\'\(\)\*\+\,\.\/\:\;\<\=\>\?\@\\\^\_\{\|\}\~\`。,、;:?!…—·ˉ¨‘’“”々~‖∶"'`|〃〔〕〈〉《》「」『』.〖〗【】()[]{}]/g, '') // Remove known punctuators
|
||||
.replace(/[\]\[\!\'\#\$\%\&\(\)\*\+\,\.\/\:\;\<\=\>\?\@\\\^\_\{\|\}\~\`。,、;:?!…—·ˉ¨‘’“”々~‖∶"'`|〃〔〕〈〉《》「」『』.〖〗【】()[]{}]/g, '') // Remove known punctuators
|
||||
.replace(/^\-+/, '') // Remove leading -
|
||||
.replace(/\-+$/, '') // Remove trailing -
|
||||
);
|
||||
|
||||
@@ -17,6 +17,7 @@ export interface TocEntry {
|
||||
|
||||
export interface SkinnyTextDocument {
|
||||
readonly uri: vscode.Uri;
|
||||
readonly version: number;
|
||||
readonly lineCount: number;
|
||||
getText(): string;
|
||||
lineAt(line: number): vscode.TextLine;
|
||||
@@ -49,7 +50,7 @@ export class TableOfContentsProvider {
|
||||
|
||||
private async buildToc(document: SkinnyTextDocument): Promise<TocEntry[]> {
|
||||
const toc: TocEntry[] = [];
|
||||
const tokens = await this.engine.parse(document.uri, document.getText());
|
||||
const tokens = await this.engine.parse(document);
|
||||
|
||||
const slugCount = new Map<string, number>();
|
||||
|
||||
|
||||
@@ -103,6 +103,33 @@ suite('markdown.DocumentLinkProvider', () => {
|
||||
assertRangeEqual(link1.range, new vscode.Range(0, 10, 0, 14));
|
||||
assertRangeEqual(link2.range, new vscode.Range(0, 23, 0, 28));
|
||||
});
|
||||
|
||||
// #49238
|
||||
test('should handle hyperlinked images', () => {
|
||||
{
|
||||
const links = getLinksForFile('[](https://example.com)');
|
||||
assert.strictEqual(links.length, 2);
|
||||
const [link1, link2] = links;
|
||||
assertRangeEqual(link1.range, new vscode.Range(0,13,0,22));
|
||||
assertRangeEqual(link2.range, new vscode.Range(0,25,0,44));
|
||||
}
|
||||
{
|
||||
const links = getLinksForFile('[]( https://whitespace.com )');
|
||||
assert.strictEqual(links.length, 2);
|
||||
const [link1, link2] = links;
|
||||
assertRangeEqual(link1.range, new vscode.Range(0,7,0,21));
|
||||
assertRangeEqual(link2.range, new vscode.Range(0,26,0,48));
|
||||
}
|
||||
{
|
||||
const links = getLinksForFile('[](file1.txt) text [](file2.txt)');
|
||||
assert.strictEqual(links.length, 4);
|
||||
const [link1, link2, link3, link4] = links;
|
||||
assertRangeEqual(link1.range, new vscode.Range(0,6,0,14));
|
||||
assertRangeEqual(link2.range, new vscode.Range(0,17,0,26));
|
||||
assertRangeEqual(link3.range, new vscode.Range(0,39,0,47));
|
||||
assertRangeEqual(link4.range, new vscode.Range(0,50,0,59));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -10,7 +10,8 @@ export class InMemoryDocument implements vscode.TextDocument {
|
||||
|
||||
constructor(
|
||||
public readonly uri: vscode.Uri,
|
||||
private readonly _contents: string
|
||||
private readonly _contents: string,
|
||||
public readonly version = 1,
|
||||
) {
|
||||
this._lines = this._contents.split(/\n/g);
|
||||
}
|
||||
@@ -18,7 +19,6 @@ export class InMemoryDocument implements vscode.TextDocument {
|
||||
|
||||
isUntitled: boolean = false;
|
||||
languageId: string = '';
|
||||
version: number = 1;
|
||||
isDirty: boolean = false;
|
||||
isClosed: boolean = false;
|
||||
eol: vscode.EndOfLine = vscode.EndOfLine.LF;
|
||||
|
||||
@@ -52,7 +52,7 @@ suite('markdown.WorkspaceSymbolProvider', () => {
|
||||
const testFileName = vscode.Uri.file('test.md');
|
||||
|
||||
const workspaceFileProvider = new InMemoryWorkspaceMarkdownDocumentProvider([
|
||||
new InMemoryDocument(testFileName, `# header1`)
|
||||
new InMemoryDocument(testFileName, `# header1`, 1 /* version */)
|
||||
]);
|
||||
|
||||
const provider = new MarkdownWorkspaceSymbolProvider(symbolProvider, workspaceFileProvider);
|
||||
@@ -60,7 +60,7 @@ suite('markdown.WorkspaceSymbolProvider', () => {
|
||||
assert.strictEqual((await provider.provideWorkspaceSymbols('')).length, 1);
|
||||
|
||||
// Update file
|
||||
workspaceFileProvider.updateDocument(new InMemoryDocument(testFileName, `# new header\nabc\n## header2`));
|
||||
workspaceFileProvider.updateDocument(new InMemoryDocument(testFileName, `# new header\nabc\n## header2`, 2 /* version */));
|
||||
const newSymbols = await provider.provideWorkspaceSymbols('');
|
||||
assert.strictEqual(newSymbols.length, 2);
|
||||
assert.strictEqual(newSymbols[0].name, '# new header');
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd"
|
||||
integrity sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==
|
||||
|
||||
"@types/highlight.js@9.1.10":
|
||||
version "9.1.10"
|
||||
resolved "https://registry.yarnpkg.com/@types/highlight.js/-/highlight.js-9.1.10.tgz#b621f809cd9573b80992b90cffc5788208e3069c"
|
||||
integrity sha512-3uQgLVw3ukDjrgi1h2qxSgsg2W7Sp/BN/P+IBgi8D019FdCcetJzJIxk0Wp1Qfcxzy3EreUnPI7/1HXhFNCRTg==
|
||||
"@types/highlight.js@9.12.3":
|
||||
version "9.12.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/highlight.js/-/highlight.js-9.12.3.tgz#b672cfaac25cbbc634a0fd92c515f66faa18dbca"
|
||||
integrity sha512-pGF/zvYOACZ/gLGWdQH8zSwteQS1epp68yRcVLJMgUck/MjEn/FBYmPub9pXT8C1e4a8YZfHo1CKyV8q1vKUnQ==
|
||||
|
||||
"@types/lodash.throttle@^4.1.3":
|
||||
version "4.1.3"
|
||||
@@ -159,10 +159,10 @@ anymatch@^2.0.0:
|
||||
micromatch "^3.1.4"
|
||||
normalize-path "^2.1.1"
|
||||
|
||||
applicationinsights@1.0.6:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-1.0.6.tgz#bc201810de91cea910dab34e8ad35ecde488edeb"
|
||||
integrity sha512-VQT3kBpJVPw5fCO5n+WUeSx0VHjxFtD7znYbILBlVgOS9/cMDuGFmV2Br3ObzFyZUDGNbEfW36fD1y2/vAiCKw==
|
||||
applicationinsights@1.0.8:
|
||||
version "1.0.8"
|
||||
resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-1.0.8.tgz#db6e3d983cf9f9405fe1ee5ba30ac6e1914537b5"
|
||||
integrity sha512-KzOOGdphOS/lXWMFZe5440LUdFbrLpMvh2SaRxn7BmiI550KAoSb2gIhiq6kJZ9Ir3AxRRztjhzif+e5P5IXIg==
|
||||
dependencies:
|
||||
diagnostic-channel "0.2.0"
|
||||
diagnostic-channel-publishers "0.2.1"
|
||||
@@ -2933,10 +2933,10 @@ he@1.1.1:
|
||||
resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd"
|
||||
integrity sha1-k0EP0hsAlzUVH4howvJx80J+I/0=
|
||||
|
||||
highlight.js@9.12.0:
|
||||
version "9.12.0"
|
||||
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.12.0.tgz#e6d9dbe57cbefe60751f02af336195870c90c01e"
|
||||
integrity sha1-5tnb5Xy+/mB1HwKvM2GVhwyQwB4=
|
||||
highlight.js@9.13.1:
|
||||
version "9.13.1"
|
||||
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.13.1.tgz#054586d53a6863311168488a0f58d6c505ce641e"
|
||||
integrity sha512-Sc28JNQNDzaH6PORtRLMvif9RSn1mYuOoX3omVjnb0+HbpPygU2ALBI0R/wsiqCb4/fcp07Gdo8g+fhtFrQl6A==
|
||||
|
||||
hmac-drbg@^1.0.0:
|
||||
version "1.0.1"
|
||||
@@ -3895,10 +3895,15 @@ map-visit@^1.0.0:
|
||||
dependencies:
|
||||
object-visit "^1.0.0"
|
||||
|
||||
markdown-it@^8.4.1:
|
||||
version "8.4.1"
|
||||
resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-8.4.1.tgz#206fe59b0e4e1b78a7c73250af9b34a4ad0aaf44"
|
||||
integrity sha512-CzzqSSNkFRUf9vlWvhK1awpJreMRqdCrBvZ8DIoDWTOkESMIF741UPAhuAmbyWmdiFPA6WARNhnu2M6Nrhwa+A==
|
||||
markdown-it-front-matter@^0.1.2:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/markdown-it-front-matter/-/markdown-it-front-matter-0.1.2.tgz#e50bf56e77e6a4f5ac4ffa894d4d45ccd9896b20"
|
||||
integrity sha1-5Qv1bnfmpPWsT/qJTU1FzNmJayA=
|
||||
|
||||
markdown-it@^8.4.2:
|
||||
version "8.4.2"
|
||||
resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-8.4.2.tgz#386f98998dc15a37722aa7722084f4020bdd9b54"
|
||||
integrity sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ==
|
||||
dependencies:
|
||||
argparse "^1.0.7"
|
||||
entities "~1.1.1"
|
||||
@@ -6308,12 +6313,12 @@ vm-browserify@0.0.4:
|
||||
dependencies:
|
||||
indexof "0.0.1"
|
||||
|
||||
vscode-extension-telemetry@0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.0.tgz#3cdcb61d03829966bd04b5f11471a1e40d6abaad"
|
||||
integrity sha512-WVCnP+uLxlqB6UD98yQNV47mR5Rf79LFxpuZhSPhEf0Sb4tPZed3a63n003/dchhOwyCTCBuNN4n8XKJkLEI1Q==
|
||||
vscode-extension-telemetry@0.1.1:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.1.tgz#91387e06b33400c57abd48979b0e790415ae110b"
|
||||
integrity sha512-TkKKG/B/J94DP5qf6xWB4YaqlhWDg6zbbqVx7Bz//stLQNnfE9XS1xm3f6fl24c5+bnEK0/wHgMgZYKIKxPeUA==
|
||||
dependencies:
|
||||
applicationinsights "1.0.6"
|
||||
applicationinsights "1.0.8"
|
||||
|
||||
vscode-nls@^4.0.0:
|
||||
version "4.0.0"
|
||||
|
||||
@@ -237,9 +237,9 @@ export default class CommandHandler implements vscode.Disposable {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (let i = 0; i < conflicts.length; i++) {
|
||||
if (conflicts[i].range.contains(editor.selection.active)) {
|
||||
return conflicts[i];
|
||||
for (const conflict of conflicts) {
|
||||
if (conflict.range.contains(editor.selection.active)) {
|
||||
return conflict;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -282,11 +282,11 @@ export default class CommandHandler implements vscode.Disposable {
|
||||
throw new Error(`Unsupported direction ${direction}`);
|
||||
}
|
||||
|
||||
for (let i = 0; i < conflicts.length; i++) {
|
||||
if (predicate(conflicts[i]) && !conflicts[i].range.contains(selection)) {
|
||||
for (const conflict of conflicts) {
|
||||
if (predicate(conflict) && !conflict.range.contains(selection)) {
|
||||
return {
|
||||
canNavigate: true,
|
||||
conflict: conflicts[i]
|
||||
conflict: conflict
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ export class Delayer<T> {
|
||||
}).then(() => {
|
||||
this.completionPromise = null;
|
||||
this.onSuccess = null;
|
||||
var result = this.task!();
|
||||
let result = this.task!();
|
||||
this.task = null;
|
||||
return result;
|
||||
});
|
||||
|
||||
@@ -91,8 +91,7 @@ export default class DocumentMergeConflictTracker implements vscode.Disposable,
|
||||
return false;
|
||||
}
|
||||
|
||||
var task = this.cache.get(key);
|
||||
|
||||
const task = this.cache.get(key);
|
||||
if (!task) {
|
||||
return false;
|
||||
}
|
||||
@@ -128,7 +127,7 @@ export default class DocumentMergeConflictTracker implements vscode.Disposable,
|
||||
}
|
||||
|
||||
private getCacheKey(document: vscode.TextDocument): string | null {
|
||||
if (document.uri && document.uri) {
|
||||
if (document.uri) {
|
||||
return document.uri.toString();
|
||||
}
|
||||
|
||||
|
||||
@@ -153,10 +153,10 @@ export default class MergeDecorator implements vscode.Disposable {
|
||||
}
|
||||
|
||||
private applyDecorationsFromEvent(eventDocument: vscode.TextDocument) {
|
||||
for (var i = 0; i < vscode.window.visibleTextEditors.length; i++) {
|
||||
if (vscode.window.visibleTextEditors[i].document === eventDocument) {
|
||||
for (const editor of vscode.window.visibleTextEditors) {
|
||||
if (editor.document === eventDocument) {
|
||||
// Attempt to apply
|
||||
this.applyDecorations(vscode.window.visibleTextEditors[i]);
|
||||
this.applyDecorations(editor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ export class MockExtensionContext implements vscode.ExtensionContext {
|
||||
return relativePath;
|
||||
}
|
||||
storagePath: string;
|
||||
globalStoragePath: string;
|
||||
|
||||
constructor() {
|
||||
this.subscriptions = [];
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
"version": "0.0.1",
|
||||
"description": "Dependencies shared by all extensions",
|
||||
"dependencies": {
|
||||
"typescript": "3.2.2"
|
||||
"typescript": "3.3.1"
|
||||
},
|
||||
"scripts": {
|
||||
"postinstall": "node ./postinstall"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,4 +14,4 @@
|
||||
}
|
||||
],
|
||||
"version": 1
|
||||
}
|
||||
}
|
||||
@@ -1,84 +1,89 @@
|
||||
{
|
||||
"name": "profiler",
|
||||
"displayName": "SQL Server Profiler",
|
||||
"description": "SQL Server Profiler for Azure Data Studio",
|
||||
"version": "0.7.0",
|
||||
"publisher": "Microsoft",
|
||||
"preview": true,
|
||||
"license": "https://raw.githubusercontent.com/Microsoft/azuredatastudio/master/LICENSE.txt",
|
||||
"icon": "images/sqlserver.png",
|
||||
"aiKey": "AIF-5574968e-856d-40d2-af67-c89a14e76412",
|
||||
"engines": {
|
||||
"vscode": "0.10.x"
|
||||
},
|
||||
"activationEvents": [
|
||||
"*"
|
||||
],
|
||||
"main": "./client/out/main",
|
||||
"scripts": {
|
||||
"compile": "gulp compile-extension:profiler-client"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Microsoft/azuredatastudio.git"
|
||||
},
|
||||
"extensionDependencies": [
|
||||
"Microsoft.mssql"
|
||||
],
|
||||
"contributes": {
|
||||
"commands": [
|
||||
{
|
||||
"command": "profiler.newProfiler",
|
||||
"title": "Launch Profiler",
|
||||
"category": "Profiler"
|
||||
},
|
||||
{
|
||||
"command": "profiler.start",
|
||||
"title": "Start",
|
||||
"category": "Profiler"
|
||||
},
|
||||
{
|
||||
"command": "profiler.stop",
|
||||
"title": "Stop",
|
||||
"category": "Profiler"
|
||||
},
|
||||
{
|
||||
"command": "profiler.openCreateSessionDialog",
|
||||
"title": "Create Profiler Session",
|
||||
"category": "Profiler"
|
||||
}
|
||||
],
|
||||
"menus": {
|
||||
"commandPalette": [
|
||||
{
|
||||
"command": "profiler.start",
|
||||
"when": "False"
|
||||
},
|
||||
{
|
||||
"command": "profiler.stop",
|
||||
"when": "False"
|
||||
},
|
||||
{
|
||||
"command": "profiler.openCreateSessionDialog",
|
||||
"when": "False"
|
||||
}
|
||||
],
|
||||
"objectExplorer/item/context": [
|
||||
{
|
||||
"command": "profiler.newProfiler",
|
||||
"when": "connectionProvider == MSSQL && nodeType && nodeType == Server",
|
||||
"group": "profiler"
|
||||
}
|
||||
]
|
||||
},
|
||||
"outputChannels": [
|
||||
"sqlprofiler"
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"vscode-nls": "^3.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"vscode": "1.0.1"
|
||||
}
|
||||
}
|
||||
"name": "profiler",
|
||||
"displayName": "SQL Server Profiler",
|
||||
"description": "SQL Server Profiler for Azure Data Studio",
|
||||
"version": "0.7.0",
|
||||
"publisher": "Microsoft",
|
||||
"preview": true,
|
||||
"license": "https://raw.githubusercontent.com/Microsoft/azuredatastudio/master/LICENSE.txt",
|
||||
"icon": "images/sqlserver.png",
|
||||
"aiKey": "AIF-5574968e-856d-40d2-af67-c89a14e76412",
|
||||
"engines": {
|
||||
"vscode": "0.10.x"
|
||||
},
|
||||
"activationEvents": [
|
||||
"*"
|
||||
],
|
||||
"main": "./client/out/main",
|
||||
"scripts": {
|
||||
"compile": "gulp compile-extension:profiler-client"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Microsoft/azuredatastudio.git"
|
||||
},
|
||||
"extensionDependencies": [
|
||||
"Microsoft.mssql"
|
||||
],
|
||||
"contributes": {
|
||||
"commands": [
|
||||
{
|
||||
"command": "profiler.newProfiler",
|
||||
"title": "Launch Profiler",
|
||||
"category": "Profiler"
|
||||
},
|
||||
{
|
||||
"command": "profiler.start",
|
||||
"title": "Start",
|
||||
"category": "Profiler"
|
||||
},
|
||||
{
|
||||
"command": "profiler.stop",
|
||||
"title": "Stop",
|
||||
"category": "Profiler"
|
||||
},
|
||||
{
|
||||
"command": "profiler.openCreateSessionDialog",
|
||||
"title": "Create Profiler Session",
|
||||
"category": "Profiler"
|
||||
}
|
||||
],
|
||||
"menus": {
|
||||
"commandPalette": [
|
||||
{
|
||||
"command": "profiler.start",
|
||||
"when": "False"
|
||||
},
|
||||
{
|
||||
"command": "profiler.stop",
|
||||
"when": "False"
|
||||
},
|
||||
{
|
||||
"command": "profiler.openCreateSessionDialog",
|
||||
"when": "False"
|
||||
}
|
||||
],
|
||||
"objectExplorer/item/context": [
|
||||
{
|
||||
"command": "profiler.newProfiler",
|
||||
"when": "connectionProvider == MSSQL && nodeType && nodeType == Server",
|
||||
"group": "profiler"
|
||||
}
|
||||
]
|
||||
},
|
||||
"outputChannels": [
|
||||
"sqlprofiler"
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"vscode-nls": "^3.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"vscode": "1.0.1"
|
||||
},
|
||||
"__metadata": {
|
||||
"id": "18",
|
||||
"publisherDisplayName": "Microsoft",
|
||||
"publisherId": "Microsoft"
|
||||
}
|
||||
}
|
||||
@@ -10,8 +10,8 @@
|
||||
}
|
||||
},
|
||||
"license": "MIT",
|
||||
"version": "0.0.0"
|
||||
"version": "1.1.1"
|
||||
}
|
||||
],
|
||||
"version": 1
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@
|
||||
"contributes": {
|
||||
"languages": [{
|
||||
"id": "python",
|
||||
"extensions": [ ".py", ".rpy", ".pyw", ".cpy", ".gyp", ".gypi", ".snakefile", ".smk"],
|
||||
"extensions": [ ".py", ".rpy", ".pyw", ".cpy", ".gyp", ".gypi", ".snakefile", ".smk", ".pyi"],
|
||||
"aliases": [ "Python", "py" ],
|
||||
"firstLine": "^#!\\s*/.*\\bpython[0-9.-]*\\b",
|
||||
"configuration": "./language-configuration.json"
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
}
|
||||
},
|
||||
"license": "MIT",
|
||||
"version": "0.0.0"
|
||||
"version": "0.5.5"
|
||||
}
|
||||
],
|
||||
"version": 1
|
||||
}
|
||||
}
|
||||
@@ -6,12 +6,12 @@
|
||||
"git": {
|
||||
"name": "Microsoft/vscode-mssql",
|
||||
"repositoryUrl": "https://github.com/Microsoft/vscode-mssql",
|
||||
"commitHash": "68d4b740b6a9e12592a32f1c0c8a0dd987f19da8"
|
||||
"commitHash": "3aa44d04b04d219ad5fa8f411ca9dd32294a7a06"
|
||||
}
|
||||
},
|
||||
"license": "MIT",
|
||||
"version": "0.0.0"
|
||||
"version": "1.4.0"
|
||||
}
|
||||
],
|
||||
"version": 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-mssql/commit/68d4b740b6a9e12592a32f1c0c8a0dd987f19da8",
|
||||
"version": "https://github.com/Microsoft/vscode-mssql/commit/3aa44d04b04d219ad5fa8f411ca9dd32294a7a06",
|
||||
"name": "SQL",
|
||||
"scopeName": "source.sql",
|
||||
"patterns": [
|
||||
@@ -223,7 +223,7 @@
|
||||
"name": "support.function.mathematical.sql"
|
||||
},
|
||||
{
|
||||
"match": "(?i)\\b(app_name|applock_mode|applock_test|assemblyproperty|col_length|col_name|columnproperty|database_principal_id|databasepropertyex|db_id|db_name|file_id|file_idex|file_name|filegroup_id|filegroup_name|filegroupproperty|fileproperty|fulltextcatalogproperty|fulltextserviceproperty|index_col|indexkey_property|indexproperty|object_definition|object_id|object_name|object_schema_name|objectproperty|objectpropertyex|original_db_name|parsename|schema_id|schema_name|scope_identity|severeproperty|stats_date|type_id|type_name|typeproperty)\\b",
|
||||
"match": "(?i)\\b(app_name|applock_mode|applock_test|assemblyproperty|col_length|col_name|columnproperty|database_principal_id|databasepropertyex|db_id|db_name|file_id|file_idex|file_name|filegroup_id|filegroup_name|filegroupproperty|fileproperty|fulltextcatalogproperty|fulltextserviceproperty|index_col|indexkey_property|indexproperty|object_definition|object_id|object_name|object_schema_name|objectproperty|objectpropertyex|original_db_name|parsename|schema_id|schema_name|scope_identity|serverproperty|stats_date|type_id|type_name|typeproperty)\\b",
|
||||
"name": "support.function.metadata.sql"
|
||||
},
|
||||
{
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"git": {
|
||||
"name": "Colorsublime-Themes",
|
||||
"repositoryUrl": "https://github.com/Colorsublime/Colorsublime-Themes",
|
||||
"commitHash": "d7401929c97c5fe78319b424f575ddce3f05da81"
|
||||
"commitHash": "c10fdd8b144486b7a4f3cb4e2251c66df222a825"
|
||||
}
|
||||
},
|
||||
"description": "The themes in this folders are copied from colorsublime.com. <<<TODO check the licenses, we can easily drop the themes>>>",
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"git": {
|
||||
"name": "Colorsublime-Themes",
|
||||
"repositoryUrl": "https://github.com/Colorsublime/Colorsublime-Themes",
|
||||
"commitHash": "d7401929c97c5fe78319b424f575ddce3f05da81"
|
||||
"commitHash": "c10fdd8b144486b7a4f3cb4e2251c66df222a825"
|
||||
}
|
||||
},
|
||||
"version": "0.1.0"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"git": {
|
||||
"name": "Colorsublime-Themes",
|
||||
"repositoryUrl": "https://github.com/Colorsublime/Colorsublime-Themes",
|
||||
"commitHash": "d7401929c97c5fe78319b424f575ddce3f05da81"
|
||||
"commitHash": "c10fdd8b144486b7a4f3cb4e2251c66df222a825"
|
||||
}
|
||||
},
|
||||
"version": "0.1.0"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"git": {
|
||||
"name": "Colorsublime-Themes",
|
||||
"repositoryUrl": "https://github.com/Colorsublime/Colorsublime-Themes",
|
||||
"commitHash": "d7401929c97c5fe78319b424f575ddce3f05da81"
|
||||
"commitHash": "c10fdd8b144486b7a4f3cb4e2251c66df222a825"
|
||||
}
|
||||
},
|
||||
"version": "0.1.0"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"git": {
|
||||
"name": "Colorsublime-Themes",
|
||||
"repositoryUrl": "https://github.com/Colorsublime/Colorsublime-Themes",
|
||||
"commitHash": "d7401929c97c5fe78319b424f575ddce3f05da81"
|
||||
"commitHash": "c10fdd8b144486b7a4f3cb4e2251c66df222a825"
|
||||
}
|
||||
},
|
||||
"version": "0.1.0"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"git": {
|
||||
"name": "Colorsublime-Themes",
|
||||
"repositoryUrl": "https://github.com/Colorsublime/Colorsublime-Themes",
|
||||
"commitHash": "d7401929c97c5fe78319b424f575ddce3f05da81"
|
||||
"commitHash": "c10fdd8b144486b7a4f3cb4e2251c66df222a825"
|
||||
}
|
||||
},
|
||||
"version": "0.1.0"
|
||||
|
||||
@@ -35,16 +35,32 @@ let nonBuiltInLanguages = { // { fileNames, extensions }
|
||||
"todo": { fileNames: ['todo'] }
|
||||
};
|
||||
|
||||
function getCommitSha(repoId, repoPath) {
|
||||
let commitInfo = 'https://api.github.com/repos/' + repoId + '/commits?path=' + repoPath;
|
||||
let FROM_DISK = false; // set to true to take content from a repo checkedout next to the vscode repo
|
||||
|
||||
let font, fontMappingsFile, fileAssociationFile, colorsFile;
|
||||
if (!FROM_DISK) {
|
||||
font = 'https://raw.githubusercontent.com/jesseweed/seti-ui/master/styles/_fonts/seti/seti.woff';
|
||||
fontMappingsFile = 'https://raw.githubusercontent.com/jesseweed/seti-ui/master/styles/_fonts/seti.less';
|
||||
fileAssociationFile = 'https://raw.githubusercontent.com/jesseweed/seti-ui/master/styles/components/icons/mapping.less';
|
||||
colorsFile = 'https://raw.githubusercontent.com/jesseweed/seti-ui/master/styles/ui-variables.less';
|
||||
} else {
|
||||
font = '../../../seti-ui/styles/_fonts/seti/seti.woff';
|
||||
fontMappingsFile = '../../../seti-ui/styles/_fonts/seti.less';
|
||||
fileAssociationFile = '../../../seti-ui/styles/components/icons/mapping.less';
|
||||
colorsFile = '../../../seti-ui/styles/ui-variables.less';
|
||||
}
|
||||
|
||||
function getCommitSha(repoId) {
|
||||
let commitInfo = 'https://api.github.com/repos/' + repoId + '/commits/master';
|
||||
return download(commitInfo).then(function (content) {
|
||||
try {
|
||||
let lastCommit = JSON.parse(content)[0];
|
||||
let lastCommit = JSON.parse(content);
|
||||
return Promise.resolve({
|
||||
commitSha: lastCommit.sha,
|
||||
commitDate: lastCommit.commit.author.date
|
||||
});
|
||||
} catch (e) {
|
||||
console.error('Failed parsing ' + content);
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
}, function () {
|
||||
@@ -189,21 +205,10 @@ function getLanguageMappings() {
|
||||
return langMappings;
|
||||
}
|
||||
|
||||
//let font = 'https://raw.githubusercontent.com/jesseweed/seti-ui/master/styles/_fonts/seti/seti.woff';
|
||||
let font = '../../../seti-ui/styles/_fonts/seti/seti.woff';
|
||||
|
||||
exports.copyFont = function () {
|
||||
return downloadBinary(font, './icons/seti.woff');
|
||||
};
|
||||
|
||||
//let fontMappings = 'https://raw.githubusercontent.com/jesseweed/seti-ui/master/styles/_fonts/seti.less';
|
||||
//let mappings = 'https://raw.githubusercontent.com/jesseweed/seti-ui/master/styles/components/icons/mapping.less';
|
||||
//let colors = 'https://raw.githubusercontent.com/jesseweed/seti-ui/master/styles/ui-variables.less';
|
||||
|
||||
let fontMappingsFile = '../../../seti-ui/styles/_fonts/seti.less';
|
||||
let fileAssociationFile = '../../../seti-ui/styles/components/icons/mapping.less';
|
||||
let colorsFile = '../../../seti-ui/styles/ui-variables.less';
|
||||
|
||||
exports.update = function () {
|
||||
|
||||
console.log('Reading from ' + fontMappingsFile);
|
||||
@@ -358,12 +363,18 @@ exports.update = function () {
|
||||
while ((match = regex3.exec(content)) !== null) {
|
||||
colorId2Value[match[1]] = match[2];
|
||||
}
|
||||
return getCommitSha('jesseweed/seti-ui', 'styles/_fonts/seti.less').then(function (info) {
|
||||
return getCommitSha('jesseweed/seti-ui').then(function (info) {
|
||||
try {
|
||||
writeFileIconContent(info);
|
||||
if (info) {
|
||||
console.log('Updated to jesseweed/seti-ui@' + info.commitSha.substr(0, 7) + ' (' + info.commitDate.substr(0, 10) + ')');
|
||||
}
|
||||
|
||||
let cgmanifestPath = './cgmanifest.json';
|
||||
let cgmanifest = fs.readFileSync(cgmanifestPath).toString();
|
||||
let cgmanifestContent = JSON.parse(cgmanifest);
|
||||
cgmanifestContent['registrations'][0]['component']['git']['commitHash'] = info.commitSha;
|
||||
fs.writeFileSync(cgmanifestPath, JSON.stringify(cgmanifestContent, null, '\t'));
|
||||
console.log('updated ' + cgmanifestPath);
|
||||
|
||||
console.log('Updated to jesseweed/seti-ui@' + info.commitSha.substr(0, 7) + ' (' + info.commitDate.substr(0, 10) + ')');
|
||||
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
"git": {
|
||||
"name": "seti-ui",
|
||||
"repositoryUrl": "https://github.com/jesseweed/seti-ui",
|
||||
"commitHash": "0b576faae405d3cd8df6ac1a397f287aa6d8b3fe"
|
||||
"commitHash": "89175d7f9e0c70cd325b80a18a3c77fc8eb7c798"
|
||||
}
|
||||
},
|
||||
"version": "0.1.0"
|
||||
}
|
||||
],
|
||||
"version": 1
|
||||
}
|
||||
}
|
||||
@@ -1839,5 +1839,5 @@
|
||||
"profiler": "_csv_light"
|
||||
}
|
||||
},
|
||||
"version": "https://github.com/jesseweed/seti-ui/commit/7714a720646300bb8f6d1690752cd71f50991414"
|
||||
"version": "https://github.com/jesseweed/seti-ui/commit/89175d7f9e0c70cd325b80a18a3c77fc8eb7c798"
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
"git": {
|
||||
"name": "Colorsublime-Themes",
|
||||
"repositoryUrl": "https://github.com/Colorsublime/Colorsublime-Themes",
|
||||
"commitHash": "d7401929c97c5fe78319b424f575ddce3f05da81"
|
||||
"commitHash": "c10fdd8b144486b7a4f3cb4e2251c66df222a825"
|
||||
}
|
||||
},
|
||||
"version": "0.1.0"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"git": {
|
||||
"name": "Colorsublime-Themes",
|
||||
"repositoryUrl": "https://github.com/Colorsublime/Colorsublime-Themes",
|
||||
"commitHash": "d7401929c97c5fe78319b424f575ddce3f05da81"
|
||||
"commitHash": "c10fdd8b144486b7a4f3cb4e2251c66df222a825"
|
||||
}
|
||||
},
|
||||
"version": "0.1.0"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"git": {
|
||||
"name": "Colorsublime-Themes",
|
||||
"repositoryUrl": "https://github.com/Colorsublime/Colorsublime-Themes",
|
||||
"commitHash": "d7401929c97c5fe78319b424f575ddce3f05da81"
|
||||
"commitHash": "c10fdd8b144486b7a4f3cb4e2251c66df222a825"
|
||||
}
|
||||
},
|
||||
"version": "0.1.0"
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
},
|
||||
"license": "MIT",
|
||||
"description": "The files syntaxes/xml.json and syntaxes/xsl.json were derived from the Atom package https://github.com/atom/language-xml which were originally converted from the TextMate bundle https://github.com/textmate/xml.tmbundle.",
|
||||
"version": "0.0.0"
|
||||
"version": "0.35.2"
|
||||
}
|
||||
],
|
||||
"version": 1
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,6 @@
|
||||
".atom",
|
||||
".axml",
|
||||
".bpmn",
|
||||
".config",
|
||||
".cpt",
|
||||
".csl",
|
||||
".csproj",
|
||||
@@ -36,7 +35,7 @@
|
||||
".opml",
|
||||
".owl",
|
||||
".proj",
|
||||
".props",
|
||||
".props",
|
||||
".pt",
|
||||
".publishsettings",
|
||||
".pubxml",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
typescript@3.2.2:
|
||||
version "3.2.2"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.2.2.tgz#fe8101c46aa123f8353523ebdcf5730c2ae493e5"
|
||||
integrity sha512-VCj5UiSyHBjwfYacmDuc/NOk4QQixbE+Wn7MFJuS0nRuPQbof132Pw4u53dm264O8LPc2MVsc7RJNml5szurkg==
|
||||
typescript@3.3.1:
|
||||
version "3.3.1"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.3.1.tgz#6de14e1db4b8a006ac535e482c8ba018c55f750b"
|
||||
integrity sha512-cTmIDFW7O0IHbn1DPYjkiebHxwtCMU+eTy30ZtJNBPF9j2O1ITu5XH2YnBeVRKWHqF+3JQwWJv0Q0aUgX8W7IA==
|
||||
|
||||
Reference in New Issue
Block a user