Compare commits

..

22 Commits
1.5.2 ... 1.5.1

Author SHA1 Message Date
Karl Burtram
0160901060 Update readme\changelog for March (#4575) 2019-03-18 10:23:28 -07:00
Chris LaFreniere
9313140c59 Fix install packages not always showing on startup (#4566) 2019-03-18 10:18:03 -07:00
Raj
25b1d4b673 #4565: Open notebook from Dashboard - can't close dirty notebook (#4568)
* #4565:"Don't save" doesn't close editor -Dashboard

* Misc change
2019-03-17 08:03:43 -07:00
Chris LaFreniere
b9d0602f55 Only show filename for notebook titlebar when opening from Open Notebook (#4556) 2019-03-15 17:45:06 -07:00
Charles Gagnon
ec0a3bbc95 Fix recent connections list to use <default> DB if no DB is specified by the user when a connection is made (#4564) 2019-03-15 17:28:56 -07:00
Matt Irvine
50f63a2f72 Fix extension bugs from VS Code merge (#4563) 2019-03-15 17:22:56 -07:00
Raj
cb47cb7dbf #4365: Make notebook dirty when changing kernel (#4547) 2019-03-15 17:02:00 -07:00
Cory Rivera
c9ac49c758 Check error in webhdfs.sendRequest before trying to check response code. (#4561) 2019-03-15 16:52:08 -07:00
Karl Burtram
c4e8aba1c9 Fix missing Azure account name (#4555)
* Fix Azure account picker row height

* Remove unneeded styles
2019-03-15 15:37:00 -07:00
Karl Burtram
ba6b8b1f69 Fix Azure account picker row height 2019-03-15 15:29:25 -07:00
Anthony Dresser
09af2fc2cb Add needs repro closer bot (#4517)
* change message of needs repro and enable

* update needs repro to needs info

* update to needs more info
2019-03-15 14:53:15 -07:00
Alan Ren
5caf0b02f0 make connectiondialog react to provider event (#4544)
* make connectiondialog react to provider event

* fix unit test error

* code review comments
2019-03-15 14:47:23 -07:00
Matt Irvine
86bac90001 Merge VS Code 1.31.1 (#4283) 2019-03-15 13:09:45 -07:00
Charles Gagnon
7d31575149 Fix dropdowns flickering every other time they're opened. The hide message code was being invoked which called hideContextView (the actual dropdown part) even if no message was ever displayed. Now we'll delay setting the message to null and only call hideContextView if we actually had a message to display. (#4528)
Also fixed small issue where messages that didn't have a container would throw an error when trying to call removeClass (since this.element is pulled from the container and thus was undefined.

Tested that the flicker is gone and that messages still show up correctly
2019-03-15 11:19:14 -07:00
Charles Gagnon
7223b28829 Add config for running extension tests (#4495)
* Add .bat for running extension tests (currently only Notebook) and set up launch.json with 2 new launch configs for running & debugging extension tests.

* Rename files to make it clear these aren't the integration tests

* Update launch.config too

* Fix spacing and missed file name update
2019-03-15 09:12:04 -07:00
Anthony Dresser
4014c1d0ab Small strict null checking pass on a few files (#4293)
* fix some null checking

* fix various null strict checks

* move location fo sql files in json

* fix compile and more unused properties

* formatting

* small formatting changes

* readd types

* add comments for angular components

* formatting

* remove any decl
2019-03-14 18:18:32 -07:00
Anthony Dresser
0bf0e795ca More data explorer actions (#4307)
* adding context

* apply extension changes

* shimming disconnect

* add data explorer context menu and add disconnect to it

* clean up shim code; better handle errors

* remove tpromise

* simplify code

* add node context on data explorer

* formatting

* add new Query action

* fix various errors with how the context menus work

* add manage and new query

* add refresh command

* formatting
2019-03-14 17:19:37 -07:00
Kevin Cunnane
0bc3716f74 FIX #4513 Notebook stuck at changing kernel (#4518)
* FIX #4513 Notebook stuck at changing kernel
- Intra-provider kernel change didn't happen because we only tried changing kernel on new session creation.
- Inverted the logic (e.g. did the right thing) and renamed the method so it's clearer what we're doing & what the boolean value should be
- Manually tested all the known scenarios
2019-03-14 15:49:14 -07:00
Alan Ren
ca23ea0f69 use the new dataprotocol client (#4515) 2019-03-14 15:48:49 -07:00
Kevin Cunnane
efaa2c0e3f Fix #4505 Notebooks: New Notebook will not work if existing untitled notebooks are rehydrated (#4506)
* Fix #4505 Notebooks: New Notebook will not work if existing untitled notebooks are rehydrated
* Also fixes #4508
* Unify behavior across New Notebook entry points
- Use Notebook-{n} as the standard in both entry points
- Use SQL as default provider in both
- Ensure both check for other names and only use free number
2019-03-14 14:27:08 -07:00
udeeshagautam
d91f4d5748 Fix for : 4471 Backup/Restore shows in Context Menu for Azure DB (#4498)
* Remove Back Restore from Cloud db's Context menu

* checking for null

* Cleaning up the check
2019-03-14 14:06:11 -07:00
Kevin Cunnane
6f1a03587a Fix #4029 Ensure changeKernels always resolves, even in error states (#4488)
* Fix #4029 Ensure changeKernels always resolves, even in error states
This is necessary to unblock reverting the kernel on canceling  Python install
- startSession now correctly sets up kernel information, since a kernel is loaded there.
- Remove call to change kernel on session initialize. This isn't needed due to refactor
- Handle kernel change failure by attempting to fall back to old kernel
- ExtensionHost $startNewSession now ensures errors are sent across the wire.
- Update AttachTo and Kernel dropdowns so they handle kernel being available. This is needed since other changes mean the session is likely ready before these get going

* Fix to handle python cancel and load existing scenarios
- Made changes to handle failure flow when Python dialog is canceled
- Made changes to handle initial load fail. Kernel and Attach To dropdowns show No Kernel / None and you can choose a kernel
- Added error wrapping in ext host so that string errors make it across and aren't lost.
2019-03-14 13:07:08 -07:00
1752 changed files with 54219 additions and 49444 deletions

View File

@@ -1,4 +1,4 @@
# EditorConfig is awesome: http://EditorConfig.org
# EditorConfig is awesome: https://EditorConfig.org
# top-most EditorConfig file
root = true
@@ -6,7 +6,6 @@ root = true
# Tab indentation
[*]
indent_style = tab
indent_size = 4
trim_trailing_whitespace = true
# The indent size used in the `package.json` file cannot be changed

View File

@@ -1,6 +1,6 @@
{
daysUntilClose: 7,
needsMoreInfoLabel: 'more info',
perform: false,
closeComment: "This issue has been closed automatically because it needs more information and has not had recent activity. See also our [issue reporting](https://aka.ms/vscodeissuereporting) guidelines.\n\nHappy Coding!"
needsMoreInfoLabel: 'needs more info',
perform: true,
closeComment: "This issue has been closed automatically because it needs more information and has not had recent activity in the last 7 days. If you have more info to help resolve the issue, leave a comment"
}

2
.nvmrc
View File

@@ -1 +1 @@
8.9.2
8

48
.vscode/launch.json vendored
View File

@@ -66,7 +66,8 @@
"request": "launch",
"name": "Launch azuredatastudio",
"windows": {
"runtimeExecutable": "${workspaceFolder}/scripts/sql.bat"
"runtimeExecutable": "${workspaceFolder}/scripts/sql.bat",
"timeout": 20000
},
"osx": {
"runtimeExecutable": "${workspaceFolder}/scripts/sql.sh"
@@ -74,15 +75,25 @@
"linux": {
"runtimeExecutable": "${workspaceFolder}/scripts/sql.sh"
},
"breakOnLoad": false,
"urlFilter": "*workbench.html*",
"runtimeArgs": [
"--inspect=5875", "--no-cached-data"
"--inspect=5875",
"--no-cached-data"
],
"skipFiles": [
"**/winjs*.js"
"webRoot": "${workspaceFolder}"
},
{
"type": "node",
"request": "launch",
"name": "Launch ADS (Main Process)",
"runtimeExecutable": "${workspaceFolder}/scripts/sql.sh",
"runtimeArgs": [
"--no-cached-data"
],
"webRoot": "${workspaceFolder}",
"timeout": 45000
"outFiles": [
"${workspaceFolder}/out/**/*.js"
]
},
{
"type": "chrome",
@@ -147,7 +158,23 @@
"outFiles": [
"${workspaceFolder}/out/**/*.js"
]
}
},
{
"type": "chrome",
"request": "launch",
"name": "Run Extension Unit Tests",
"windows": {
"runtimeExecutable": "${workspaceFolder}/scripts/test-extensions-unit.bat"
},
"osx": {
"runtimeExecutable": "${workspaceFolder}/scripts/test-extensions-unit.sh"
},
"linux": {
"runtimeExecutable": "${workspaceFolder}/scripts/test-extensions-unit.sh"
},
"webRoot": "${workspaceFolder}",
"timeout": 45000
},
],
"compounds": [
{
@@ -157,6 +184,13 @@
"Run Unit Tests"
]
},
{
"name": "Debug Extension Unit Tests",
"configurations": [
"Attach to Extension Host",
"Run Extension Unit Tests"
]
},
{
"name": "Debug azuredatastudio Main and Renderer",
"configurations": [

View File

@@ -50,5 +50,7 @@
}, {
"fileMatch": [ "cglicenses.json" ],
"url": "./.vscode/cglicenses.schema.json"
}]
}
],
"git.ignoreLimitWarning": true
}

View File

@@ -23,11 +23,13 @@
"description": "Insert Copyright Statement"
},
"TS -> Inject Service": {
"scope": "typescript",
"description": "Constructor Injection Pattern",
"prefix": "@inject",
"body": "@$1 private readonly _$2: ${1},$0"
},
"TS -> Event & Emitter": {
"scope": "typescript",
"prefix": "emitter",
"description": "Add emitter and event properties",
"body": [

View File

@@ -1,3 +1,3 @@
disturl "https://atom.io/download/electron"
target "2.0.12"
target "3.1.2"
runtime "electron"

View File

@@ -1,5 +1,20 @@
# Change Log
## Version 1.5.1
* Release date: March 18, 2019
* Release status: General Availability
## What's new in this version
* Announcing T-SQL Notebooks
* Announcing PostgreSQL extension
* Announcing SQL Server Dacpac extension
* Resolved [bugs and issues](https://github.com/Microsoft/azuredatastudio/milestone/25?closed=1).
## Contributions and "thank you"
We would like to thank all our users who raised issues, and in particular the following users who helped contribute fixes:
* GeoffYoung for `Fix sqlDropColumn description #4422`
## Version 1.4.5
* Release date: February 13, 2019
* Release status: General Availability

View File

@@ -24,7 +24,9 @@ The built-in tool for reporting an issue, which you can access by using `Report
Please include the following with each issue.
* Version of Azure Data Studio (formerly SQL Operations Studio).
* Version of Azure Data Studio (formerly SQL Operations Studio)
* Your operating system
> **Tip:** You can easily create an issue using `Report Issues` from Azure Data Studio Help menu.

View File

@@ -9,13 +9,13 @@ Azure Data Studio is a data management tool that enables you to work with SQL Se
Platform | Link
-- | --
Windows User Installer | https://go.microsoft.com/fwlink/?linkid=2072725
Windows System Installer | https://go.microsoft.com/fwlink/?linkid=2072728
Windows ZIP | https://go.microsoft.com/fwlink/?linkid=2072354
macOS ZIP | https://go.microsoft.com/fwlink/?linkid=2072737
Linux TAR.GZ | https://go.microsoft.com/fwlink/?linkid=2072360
Linux RPM | https://go.microsoft.com/fwlink/?linkid=2072741
Linux DEB | https://go.microsoft.com/fwlink/?linkid=2072744
Windows User Installer | https://go.microsoft.com/fwlink/?linkid=2083322
Windows System Installer | https://go.microsoft.com/fwlink/?linkid=2083323
Windows ZIP | https://go.microsoft.com/fwlink/?linkid=2083324
macOS ZIP | https://go.microsoft.com/fwlink/?linkid=2083325
Linux TAR.GZ | https://go.microsoft.com/fwlink/?linkid=2083424
Linux RPM | https://go.microsoft.com/fwlink/?linkid=2083326
Linux DEB | https://go.microsoft.com/fwlink/?linkid=2083327
Go to our [download page](https://aka.ms/azuredatastudio) for more specific instructions.
@@ -68,6 +68,7 @@ The [Microsoft Enterprise and Developer Privacy Statement](https://privacy.micro
## Contributions and "Thank You"
We would like to thank all our users who raised issues, and in particular the following users who helped contribute fixes:
* GeoffYoung for `Fix sqlDropColumn description #4422`
* AlexFsmn for `Added context menu for DBs in explorer view to backup & restore db. #2277`
* sadedil for `Missing feature request: Save as XML #3729`
* gbritton1 for `Removed reference to object explorer #3463`

View File

@@ -2440,7 +2440,6 @@ General Public License.
-------------------------------START OF THIRD-PARTY NOTICES-------------------------------------------
===================================ExcelDataReader (BEGIN)
The MIT License (MIT)
Copyright (c) 2014 ExcelDataReader

View File

@@ -2,7 +2,7 @@ steps:
- script: |
set -e
sudo apt-get update
sudo apt-get install -y libxkbfile-dev pkg-config libsecret-1-dev libxss1 libgconf-2-4 dbus xvfb libgtk-3-0
sudo apt-get install -y libxkbfile-dev pkg-config libsecret-1-dev libxss1 dbus xvfb libgtk-3-0
sudo cp build/azure-pipelines/linux/xvfb.init /etc/init.d/xvfb
sudo chmod +x /etc/init.d/xvfb
sudo update-rc.d xvfb defaults

View File

@@ -95,7 +95,7 @@ gulp.task('extract-editor-src', ['clean-editor-src'], function () {
'vs/base/browser/ui/octiconLabel/octiconLabel': 'vs/base/browser/ui/octiconLabel/octiconLabel.mock',
},
shakeLevel: 2, // 0-Files, 1-InnerFile, 2-ClassMembers
importIgnorePattern: /^vs\/css!/,
importIgnorePattern: /(^vs\/css!)|(promise-polyfill\/polyfill)/,
destRoot: path.join(root, 'out-editor-src')
});
});

View File

@@ -50,7 +50,6 @@ const indentationFilter = [
'!src/vs/css.build.js',
'!src/vs/loader.js',
'!src/vs/base/common/marked/marked.js',
'!src/vs/base/common/winjs.base.js',
'!src/vs/base/node/terminateProcess.sh',
'!src/vs/base/node/cpuUsage.sh',
'!test/assert.js',
@@ -110,10 +109,12 @@ const copyrightFilter = [
'!**/*.opts',
'!**/*.disabled',
'!**/*.code-workspace',
'!**/promise-polyfill/polyfill.js',
'!build/**/*.init',
'!resources/linux/snap/snapcraft.yaml',
'!resources/linux/snap/electron-launch',
'!resources/win32/bin/code.js',
'!resources/completions/**',
'!extensions/markdown-language-features/media/highlight.css',
'!extensions/html-language-features/server/src/modes/typescript/*',
'!extensions/*/server/bin/*'
@@ -127,7 +128,6 @@ const eslintFilter = [
'!src/vs/nls.js',
'!src/vs/css.build.js',
'!src/vs/nls.build.js',
'!src/**/winjs.base.js',
'!src/**/marked.js',
'!**/test/**'
];

View File

@@ -135,7 +135,7 @@ gulp.task('optimize-vscode', ['clean-optimized-vscode', 'compile-build', 'compil
gulp.task('optimize-index-js', ['optimize-vscode'], () => {
const fullpath = path.join(process.cwd(), 'out-vscode/vs/code/electron-browser/workbench/workbench.js');
const fullpath = path.join(process.cwd(), 'out-vscode/bootstrap-window.js');
const contents = fs.readFileSync(fullpath).toString();
const newContents = contents.replace('[/*BUILD->INSERT_NODE_MODULES*/]', JSON.stringify(nodeModules));
fs.writeFileSync(fullpath, newContents);
@@ -164,7 +164,7 @@ const config = {
version: getElectronVersion(),
productAppName: product.nameLong,
companyName: 'Microsoft Corporation',
copyright: 'Copyright (C) 2018 Microsoft. All rights reserved',
copyright: 'Copyright (C) 2019 Microsoft. All rights reserved',
darwinIcon: 'resources/darwin/code.icns',
darwinBundleIdentifier: product.darwinBundleIdentifier,
darwinApplicationCategoryType: 'public.app-category.developer-tools',
@@ -180,13 +180,13 @@ const config = {
urlSchemes: [product.urlProtocol]
}],
darwinForceDarkModeSupport: true,
darwinCredits: darwinCreditsTemplate ? Buffer.from(darwinCreditsTemplate({ commit: commit, date: new Date().toISOString() })) : void 0,
darwinCredits: darwinCreditsTemplate ? Buffer.from(darwinCreditsTemplate({ commit: commit, date: new Date().toISOString() })) : undefined,
linuxExecutableName: product.applicationName,
winIcon: 'resources/win32/code.ico',
token: process.env['VSCODE_MIXIN_PASSWORD'] || process.env['GITHUB_TOKEN'] || void 0,
token: process.env['VSCODE_MIXIN_PASSWORD'] || process.env['GITHUB_TOKEN'] || undefined,
// @ts-ignore JSON checking: electronRepository is optional
repo: product.electronRepository || void 0
repo: product.electronRepository || undefined
};
function getElectron(arch) {
@@ -423,6 +423,8 @@ function packageTask(platform, arch, opts) {
.pipe(electron(_.extend({}, config, { platform, arch, ffmpegChromium: true })))
.pipe(filter(['**', '!LICENSE', '!LICENSES.chromium.html', '!version']));
// result = es.merge(result, gulp.src('resources/completions/**', { base: '.' }));
if (platform === 'win32') {
result = es.merge(result, gulp.src('resources/win32/bin/code.js', { base: 'resources/win32' }));

View File

@@ -15,6 +15,9 @@ const util = require('./lib/util');
const packageJson = require('../package.json');
const product = require('../product.json');
const rpmDependencies = require('../resources/linux/rpm/dependencies.json');
const path = require('path');
const root = path.dirname(__dirname);
const commit = util.getVersion(root);
const linuxPackageRevision = Math.floor(new Date().getTime() / 1000);
@@ -51,6 +54,12 @@ function prepareDebPackage(arch) {
const icon = gulp.src('resources/linux/code.png', { base: '.' })
.pipe(rename('usr/share/pixmaps/' + product.applicationName + '.png'));
// const bash_completion = gulp.src('resources/completions/bash/code')
// .pipe(rename('usr/share/bash-completion/completions/code'));
// const zsh_completion = gulp.src('resources/completions/zsh/_code')
// .pipe(rename('usr/share/zsh/vendor-completions/_code'));
const code = gulp.src(binaryDir + '/**/*', { base: binaryDir })
.pipe(rename(function (p) { p.dirname = 'usr/share/' + product.applicationName + '/' + p.dirname; }));
@@ -85,7 +94,7 @@ function prepareDebPackage(arch) {
.pipe(replace('@@UPDATEURL@@', product.updateUrl || '@@UPDATEURL@@'))
.pipe(rename('DEBIAN/postinst'));
const all = es.merge(control, postinst, postrm, prerm, desktops, appdata, icon, code);
const all = es.merge(control, postinst, postrm, prerm, desktops, appdata, icon, /* bash_completion, zsh_completion, */ code);
return all.pipe(vfs.dest(destination));
};
@@ -136,6 +145,12 @@ function prepareRpmPackage(arch) {
const icon = gulp.src('resources/linux/code.png', { base: '.' })
.pipe(rename('BUILD/usr/share/pixmaps/' + product.applicationName + '.png'));
// const bash_completion = gulp.src('resources/completions/bash/code')
// .pipe(rename('BUILD/usr/share/bash-completion/completions/code'));
// const zsh_completion = gulp.src('resources/completions/zsh/_code')
// .pipe(rename('BUILD/usr/share/zsh/site-functions/_code'));
const code = gulp.src(binaryDir + '/**/*', { base: binaryDir })
.pipe(rename(function (p) { p.dirname = 'BUILD/usr/share/' + product.applicationName + '/' + p.dirname; }));
@@ -156,7 +171,7 @@ function prepareRpmPackage(arch) {
const specIcon = gulp.src('resources/linux/rpm/code.xpm', { base: '.' })
.pipe(rename('SOURCES/' + product.applicationName + '.xpm'));
const all = es.merge(code, desktops, appdata, icon, spec, specIcon);
const all = es.merge(code, desktops, appdata, icon, /* bash_completion, zsh_completion, */ spec, specIcon);
return all.pipe(vfs.dest(getRpmBuildPath(rpmArch)));
};
@@ -199,17 +214,13 @@ function prepareSnapPackage(arch) {
const snapcraft = gulp.src('resources/linux/snap/snapcraft.yaml', { base: '.' })
.pipe(replace('@@NAME@@', product.applicationName))
.pipe(replace('@@VERSION@@', `${packageJson.version}-${linuxPackageRevision}`))
.pipe(replace('@@VERSION@@', commit.substr(0, 8)))
.pipe(rename('snap/snapcraft.yaml'));
const snapUpdate = gulp.src('resources/linux/snap/snapUpdate.sh', { base: '.' })
.pipe(replace('@@NAME@@', product.applicationName))
.pipe(rename(`usr/share/${product.applicationName}/snapUpdate.sh`));
const electronLaunch = gulp.src('resources/linux/snap/electron-launch', { base: '.' })
.pipe(rename('electron-launch'));
const all = es.merge(desktop, icon, code, snapcraft, electronLaunch, snapUpdate);
const all = es.merge(desktop, icon, code, snapcraft, electronLaunch);
return all.pipe(vfs.dest(destination));
};

View File

@@ -126,6 +126,20 @@ class MonacoGenerator {
this._declarationResolver.invalidateCache(moduleId);
this._executeSoon();
});
watcher.addListener('error', (err) => {
console.error(`Encountered error while watching ${filePath}.`);
console.log(err);
delete this._watchedFiles[filePath];
for (let i = 0; i < this._watchers.length; i++) {
if (this._watchers[i] === watcher) {
this._watchers.splice(i, 1);
break;
}
}
watcher.close();
this._declarationResolver.invalidateCache(moduleId);
this._executeSoon();
});
this._watchers.push(watcher);
};
this._fsProvider = new class extends monacodts.FSProvider {

View File

@@ -159,6 +159,20 @@ class MonacoGenerator {
this._declarationResolver.invalidateCache(moduleId);
this._executeSoon();
});
watcher.addListener('error', (err) => {
console.error(`Encountered error while watching ${filePath}.`);
console.log(err);
delete this._watchedFiles[filePath];
for (let i = 0; i < this._watchers.length; i++) {
if (this._watchers[i] === watcher) {
this._watchers.splice(i, 1);
break;
}
}
watcher.close();
this._declarationResolver.invalidateCache(moduleId);
this._executeSoon();
});
this._watchers.push(watcher);
};
this._fsProvider = new class extends monacodts.FSProvider {

View File

@@ -17,14 +17,14 @@ function getVersion(repo) {
head = fs.readFileSync(headPath, 'utf8').trim();
}
catch (e) {
return void 0;
return undefined;
}
if (/^[0-9a-f]{40}$/i.test(head)) {
return head;
}
const refMatch = /^ref: (.*)$/.exec(head);
if (!refMatch) {
return void 0;
return undefined;
}
const ref = refMatch[1];
const refPath = path.join(git, ref);
@@ -40,7 +40,7 @@ function getVersion(repo) {
refsRaw = fs.readFileSync(packedRefsPath, 'utf8').trim();
}
catch (e) {
return void 0;
return undefined;
}
const refsRegex = /^([0-9a-f]{40})\s+(.+)$/gm;
let refsMatch;

View File

@@ -18,7 +18,7 @@ export function getVersion(repo: string): string | undefined {
try {
head = fs.readFileSync(headPath, 'utf8').trim();
} catch (e) {
return void 0;
return undefined;
}
if (/^[0-9a-f]{40}$/i.test(head)) {
@@ -28,7 +28,7 @@ export function getVersion(repo: string): string | undefined {
const refMatch = /^ref: (.*)$/.exec(head);
if (!refMatch) {
return void 0;
return undefined;
}
const ref = refMatch[1];
@@ -46,7 +46,7 @@ export function getVersion(repo: string): string | undefined {
try {
refsRaw = fs.readFileSync(packedRefsPath, 'utf8').trim();
} catch (e) {
return void 0;
return undefined;
}
const refsRegex = /^([0-9a-f]{40})\s+(.+)$/gm;

View File

@@ -238,6 +238,10 @@
"name": "vs/workbench/services/decorations",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/services/label",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/services/preferences",
"project": "vscode-preferences"

View File

@@ -119,8 +119,7 @@ function createESMSourcesAndResources2(options) {
return path.join(OUT_RESOURCES_FOLDER, dest);
};
const allFiles = walkDirRecursive(SRC_FOLDER);
for (let i = 0; i < allFiles.length; i++) {
const file = allFiles[i];
for (const file of allFiles) {
if (options.ignores.indexOf(file.replace(/\\/g, '/')) >= 0) {
continue;
}

View File

@@ -139,8 +139,7 @@ export function createESMSourcesAndResources2(options: IOptions2): void {
};
const allFiles = walkDirRecursive(SRC_FOLDER);
for (let i = 0; i < allFiles.length; i++) {
const file = allFiles[i];
for (const file of allFiles) {
if (options.ignores.indexOf(file.replace(/\\/g, '/')) >= 0) {
continue;
@@ -244,7 +243,6 @@ export function createESMSourcesAndResources2(options: IOptions2): void {
let mode = 0;
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
if (mode === 0) {
if (/\/\/ ESM-comment-begin/.test(line)) {
mode = 1;

View File

@@ -15,8 +15,7 @@ var ShakeLevel;
ShakeLevel[ShakeLevel["ClassMembers"] = 2] = "ClassMembers";
})(ShakeLevel = exports.ShakeLevel || (exports.ShakeLevel = {}));
function printDiagnostics(diagnostics) {
for (let i = 0; i < diagnostics.length; i++) {
const diag = diagnostics[i];
for (const diag of diagnostics) {
let result = '';
if (diag.file) {
result += `${diag.file.fileName}: `;
@@ -97,6 +96,11 @@ function discoverAndReadFiles(options) {
FILES[`${moduleId}.d.ts`] = dts_filecontents;
continue;
}
const js_filename = path.join(options.sourcesRoot, moduleId + '.js');
if (fs.existsSync(js_filename)) {
// This is an import for a .js file, so ignore it...
continue;
}
let ts_filename;
if (options.redirects[moduleId]) {
ts_filename = path.join(options.sourcesRoot, options.redirects[moduleId] + '.ts');
@@ -475,8 +479,7 @@ function generateResult(languageService, shakeLevel) {
}
else {
let survivingImports = [];
for (let i = 0; i < node.importClause.namedBindings.elements.length; i++) {
const importNode = node.importClause.namedBindings.elements[i];
for (const importNode of node.importClause.namedBindings.elements) {
if (getColor(importNode) === 2 /* Black */) {
survivingImports.push(importNode.getFullText(sourceFile));
}

View File

@@ -61,15 +61,14 @@ export interface ITreeShakingResult {
}
function printDiagnostics(diagnostics: ReadonlyArray<ts.Diagnostic>): void {
for (let i = 0; i < diagnostics.length; i++) {
const diag = diagnostics[i];
for (const diag of diagnostics) {
let result = '';
if (diag.file) {
result += `${diag.file.fileName}: `;
}
if (diag.file && diag.start) {
let location = diag.file.getLineAndCharacterOfPosition(diag.start);
result += `- ${location.line + 1},${location.character} - `
result += `- ${location.line + 1},${location.character} - `;
}
result += JSON.stringify(diag.messageText);
console.log(result);
@@ -160,6 +159,12 @@ function discoverAndReadFiles(options: ITreeShakingOptions): IFileMap {
continue;
}
const js_filename = path.join(options.sourcesRoot, moduleId + '.js');
if (fs.existsSync(js_filename)) {
// This is an import for a .js file, so ignore it...
continue;
}
let ts_filename: string;
if (options.redirects[moduleId]) {
ts_filename = path.join(options.sourcesRoot, options.redirects[moduleId] + '.ts');
@@ -459,7 +464,7 @@ function markNodes(languageService: ts.LanguageService, options: ITreeShakingOpt
}
if (black_queue.length === 0) {
for (let i = 0; i < gray_queue.length; i++) {
for (let i = 0; i< gray_queue.length; i++) {
const node = gray_queue[i];
const nodeParent = node.parent;
if ((ts.isClassDeclaration(nodeParent) || ts.isInterfaceDeclaration(nodeParent)) && nodeOrChildIsBlack(nodeParent)) {
@@ -604,8 +609,7 @@ function generateResult(languageService: ts.LanguageService, shakeLevel: ShakeLe
}
} else {
let survivingImports: string[] = [];
for (let i = 0; i < node.importClause.namedBindings.elements.length; i++) {
const importNode = node.importClause.namedBindings.elements[i];
for (const importNode of node.importClause.namedBindings.elements) {
if (getColor(importNode) === NodeColor.Black) {
survivingImports.push(importNode.getFullText(sourceFile));
}

View File

@@ -109,8 +109,7 @@ class NoUnexternalizedStringsRuleWalker extends Lint.RuleWalker {
this.recordKey(keyArg, this.messageIndex && callInfo ? callInfo.callExpression.arguments[this.messageIndex] : undefined);
}
else if (isObjectLiteral(keyArg)) {
for (let i = 0; i < keyArg.properties.length; i++) {
const property = keyArg.properties[i];
for (const property of keyArg.properties) {
if (isPropertyAssignment(property)) {
const name = property.name.getText();
if (name === 'key') {

View File

@@ -148,8 +148,7 @@ class NoUnexternalizedStringsRuleWalker extends Lint.RuleWalker {
if (isStringLiteral(keyArg)) {
this.recordKey(keyArg, this.messageIndex && callInfo ? callInfo.callExpression.arguments[this.messageIndex] : undefined);
} else if (isObjectLiteral(keyArg)) {
for (let i = 0; i < keyArg.properties.length; i++) {
const property = keyArg.properties[i];
for (const property of keyArg.properties) {
if (isPropertyAssignment(property)) {
const name = property.name.getText();
if (name === 'key') {

View File

@@ -17,7 +17,7 @@ function handleDeletions() {
});
}
let watch = void 0;
let watch = undefined;
if (!watch) {
watch = process.platform === 'win32' ? require('./watch-win32') : require('gulp-watch');

View File

@@ -8,22 +8,28 @@ herein, whether by implication, estoppel or otherwise.
%% winjs version 4.4.0 (https://github.com/winjs/winjs)
%% promise-polyfill version 8.1.0 (https://github.com/taylorhakes/promise-polyfill)
=========================================
WinJS
Copyright (c) 2014 Taylor Hakes
Copyright (c) 2014 Forbes Lindesay
Copyright (c) Microsoft Corporation
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
All rights reserved.
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
=========================================
END OF winjs NOTICES AND INFORMATION

View File

@@ -456,11 +456,20 @@ class FSProvider {
existsSync(filePath) {
return fs.existsSync(filePath);
}
statSync(filePath) {
return fs.statSync(filePath);
}
readFileSync(_moduleId, filePath) {
return fs.readFileSync(filePath);
}
}
exports.FSProvider = FSProvider;
class CacheEntry {
constructor(sourceFile, mtime) {
this.sourceFile = sourceFile;
this.mtime = mtime;
}
}
class DeclarationResolver {
constructor(_fsProvider) {
this._fsProvider = _fsProvider;
@@ -470,31 +479,43 @@ class DeclarationResolver {
this._sourceFileCache[moduleId] = null;
}
getDeclarationSourceFile(moduleId) {
if (this._sourceFileCache[moduleId]) {
// Since we cannot trust file watching to invalidate the cache, check also the mtime
const fileName = this._getFileName(moduleId);
const mtime = this._fsProvider.statSync(fileName).mtime.getTime();
if (this._sourceFileCache[moduleId].mtime !== mtime) {
this._sourceFileCache[moduleId] = null;
}
}
if (!this._sourceFileCache[moduleId]) {
this._sourceFileCache[moduleId] = this._getDeclarationSourceFile(moduleId);
}
return this._sourceFileCache[moduleId];
return this._sourceFileCache[moduleId] ? this._sourceFileCache[moduleId].sourceFile : null;
}
_getFileName(moduleId) {
if (/\.d\.ts$/.test(moduleId)) {
return path.join(SRC, moduleId);
}
return path.join(SRC, `${moduleId}.ts`);
}
_getDeclarationSourceFile(moduleId) {
if (/\.d\.ts$/.test(moduleId)) {
const fileName = path.join(SRC, moduleId);
if (!this._fsProvider.existsSync(fileName)) {
return null;
}
const fileContents = this._fsProvider.readFileSync(moduleId, fileName).toString();
return ts.createSourceFile(fileName, fileContents, ts.ScriptTarget.ES5);
}
const fileName = path.join(SRC, `${moduleId}.ts`);
const fileName = this._getFileName(moduleId);
if (!this._fsProvider.existsSync(fileName)) {
return null;
}
const mtime = this._fsProvider.statSync(fileName).mtime.getTime();
if (/\.d\.ts$/.test(moduleId)) {
// const mtime = this._fsProvider.statFileSync()
const fileContents = this._fsProvider.readFileSync(moduleId, fileName).toString();
return new CacheEntry(ts.createSourceFile(fileName, fileContents, ts.ScriptTarget.ES5), mtime);
}
const fileContents = this._fsProvider.readFileSync(moduleId, fileName).toString();
const fileMap = {
'file.ts': fileContents
};
const service = ts.createLanguageService(new TypeScriptLanguageServiceHost({}, fileMap, {}));
const text = service.getEmitOutput('file.ts', true).outputFiles[0].text;
return ts.createSourceFile(fileName, text, ts.ScriptTarget.ES5);
return new CacheEntry(ts.createSourceFile(fileName, text, ts.ScriptTarget.ES5), mtime);
}
}
exports.DeclarationResolver = DeclarationResolver;

View File

@@ -547,14 +547,24 @@ export class FSProvider {
public existsSync(filePath: string): boolean {
return fs.existsSync(filePath);
}
public statSync(filePath: string): fs.Stats {
return fs.statSync(filePath);
}
public readFileSync(_moduleId: string, filePath: string): Buffer {
return fs.readFileSync(filePath);
}
}
class CacheEntry {
constructor(
public readonly sourceFile: ts.SourceFile,
public readonly mtime: number
) {}
}
export class DeclarationResolver {
private _sourceFileCache: { [moduleId: string]: ts.SourceFile | null; };
private _sourceFileCache: { [moduleId: string]: CacheEntry | null; };
constructor(private readonly _fsProvider: FSProvider) {
this._sourceFileCache = Object.create(null);
@@ -565,32 +575,51 @@ export class DeclarationResolver {
}
public getDeclarationSourceFile(moduleId: string): ts.SourceFile | null {
if (this._sourceFileCache[moduleId]) {
// Since we cannot trust file watching to invalidate the cache, check also the mtime
const fileName = this._getFileName(moduleId);
const mtime = this._fsProvider.statSync(fileName).mtime.getTime();
if (this._sourceFileCache[moduleId]!.mtime !== mtime) {
this._sourceFileCache[moduleId] = null;
}
}
if (!this._sourceFileCache[moduleId]) {
this._sourceFileCache[moduleId] = this._getDeclarationSourceFile(moduleId);
}
return this._sourceFileCache[moduleId];
return this._sourceFileCache[moduleId] ? this._sourceFileCache[moduleId]!.sourceFile : null;
}
private _getDeclarationSourceFile(moduleId: string): ts.SourceFile | null {
private _getFileName(moduleId: string): string {
if (/\.d\.ts$/.test(moduleId)) {
const fileName = path.join(SRC, moduleId);
if (!this._fsProvider.existsSync(fileName)) {
return null;
}
const fileContents = this._fsProvider.readFileSync(moduleId, fileName).toString();
return ts.createSourceFile(fileName, fileContents, ts.ScriptTarget.ES5);
return path.join(SRC, moduleId);
}
const fileName = path.join(SRC, `${moduleId}.ts`);
return path.join(SRC, `${moduleId}.ts`);
}
private _getDeclarationSourceFile(moduleId: string): CacheEntry | null {
const fileName = this._getFileName(moduleId);
if (!this._fsProvider.existsSync(fileName)) {
return null;
}
const mtime = this._fsProvider.statSync(fileName).mtime.getTime();
if (/\.d\.ts$/.test(moduleId)) {
// const mtime = this._fsProvider.statFileSync()
const fileContents = this._fsProvider.readFileSync(moduleId, fileName).toString();
return new CacheEntry(
ts.createSourceFile(fileName, fileContents, ts.ScriptTarget.ES5),
mtime
);
}
const fileContents = this._fsProvider.readFileSync(moduleId, fileName).toString();
const fileMap: IFileMap = {
'file.ts': fileContents
};
const service = ts.createLanguageService(new TypeScriptLanguageServiceHost({}, fileMap, {}));
const text = service.getEmitOutput('file.ts', true).outputFiles[0].text;
return ts.createSourceFile(fileName, text, ts.ScriptTarget.ES5);
return new CacheEntry(
ts.createSourceFile(fileName, text, ts.ScriptTarget.ES5),
mtime
);
}
}

View File

@@ -21,12 +21,11 @@ declare namespace monaco {
export class Emitter<T> {
constructor();
readonly event: Event<T>;
fire(event?: T): void;
fire(event: T): void;
dispose(): void;
}
#include(vs/platform/markers/common/markers): MarkerTag, MarkerSeverity
#include(vs/base/common/winjs.base.d.ts): Promise
#include(vs/base/common/cancellation): CancellationTokenSource, CancellationToken
#include(vs/base/common/uri): URI, UriComponents
#include(vs/base/common/keyCodes): KeyCode
@@ -86,4 +85,4 @@ declare namespace monaco.worker {
}
//dtsv=2
//dtsv=2

View File

@@ -11,7 +11,6 @@ import { SimpleWorkerClient, create as create1 } from './vs/base/common/worker/s
import { create as create2 } from './vs/editor/common/services/editorSimpleWorker';
import { QuickOpenWidget } from './vs/base/parts/quickopen/browser/quickOpenWidget';
import { SyncDescriptor0, SyncDescriptor1, SyncDescriptor2, SyncDescriptor3, SyncDescriptor4, SyncDescriptor5, SyncDescriptor6, SyncDescriptor7, SyncDescriptor8 } from './vs/platform/instantiation/common/descriptors';
import { PolyfillPromise } from './vs/base/common/winjs.polyfill.promise';
import { DiffNavigator } from './vs/editor/browser/widget/diffNavigator';
import * as editorAPI from './vs/editor/editor.api';
@@ -32,14 +31,6 @@ import * as editorAPI from './vs/editor/editor.api';
a = create1;
a = create2;
// promise polyfill
a = PolyfillPromise.all;
a = PolyfillPromise.race;
a = PolyfillPromise.resolve;
a = PolyfillPromise.reject;
a = (<PolyfillPromise>b).then;
a = (<PolyfillPromise>b).catch;
// injection madness
a = (<SyncDescriptor0<any>>b).ctor;
a = (<SyncDescriptor0<any>>b).bind;
@@ -73,7 +64,6 @@ import * as editorAPI from './vs/editor/editor.api';
a = editorAPI.SelectionDirection;
a = editorAPI.MarkerSeverity;
a = editorAPI.MarkerTag;
a = editorAPI.Promise;
a = editorAPI.Uri;
a = editorAPI.Token;
a = editorAPI.editor;

View File

@@ -17,6 +17,7 @@ function yarnInstall(location, opts) {
opts.cwd = location;
opts.stdio = 'inherit';
console.log('Installing dependencies in \'%s\'.', location);
const result = cp.spawnSync(yarn, ['install'], opts);
if (result.error || result.status !== 0) {

View File

@@ -7,8 +7,8 @@ let err = false;
const majorNodeVersion = parseInt(/^(\d+)\./.exec(process.versions.node)[1]);
if (majorNodeVersion < 8 || majorNodeVersion >= 9) {
console.error('\033[1;31m*** Please use node >=8 and <9.\033[0;0m');
if (majorNodeVersion < 8 || majorNodeVersion >= 11) {
console.error('\033[1;31m*** Please use node >=8 and <11.\033[0;0m');
err = true;
}

View File

@@ -120,6 +120,28 @@ exports.update = function (repoId, repoPath, dest, modifyGrammar, version = 'mas
try {
fs.writeFileSync(dest, JSON.stringify(result, null, '\t').replace(/\n/g, '\r\n'));
// Add commit sha to cgmanifest
let cgmanifestRead = JSON.parse(fs.readFileSync('./cgmanifest.json').toString());
let promises = new Array();
let packageJsonPath = 'https://raw.githubusercontent.com/' + repoId + `/${info.commitSha}/package.json`;
for (let i = 0; i < cgmanifestRead.registrations.length; i++) {
if (cgmanifestRead.registrations[i].component.git.repositoryUrl.substr(cgmanifestRead.registrations[i].component.git.repositoryUrl.length - repoId.length, repoId.length) === repoId) {
cgmanifestRead.registrations[i].component.git.commitHash = info.commitSha;
promises.push(download(packageJsonPath).then(function (packageJson) {
if (packageJson) {
try {
cgmanifestRead.registrations[i].version = JSON.parse(packageJson).version;
} catch (e) {
console.log('File does not exist at' + packageJsonPath);
}
}
}));
break;
}
}
Promise.all(promises).then(function (allResult) {
fs.writeFileSync('./cgmanifest.json', JSON.stringify(cgmanifestRead, null, '\t').replace(/\n/g, '\r\n'));
});
if (info) {
console.log('Updated ' + path.basename(dest) + ' to ' + repoId + '@' + info.commitSha.substr(0, 7) + ' (' + info.commitDate.substr(0, 10) + ')');
} else {

View File

@@ -42,7 +42,7 @@
"request": "^2.85.0",
"tslint": "^5.9.1",
"service-downloader": "github:anthonydresser/service-downloader#0.1.5",
"typescript": "3.1.4",
"typescript": "3.2.2",
"vsce": "1.48.0",
"xml2js": "^0.4.17"
},

View File

@@ -2084,10 +2084,10 @@ typed-rest-client@^0.9.0:
tunnel "0.0.4"
underscore "1.8.3"
typescript@3.1.4:
version "3.1.4"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.1.4.tgz#c74ef7b3c2da65beff548b903022cb8c3cd997ed"
integrity sha512-JZHJtA6ZL15+Q3Dqkbh8iCUmvxD3iJ7ujXS+fVkKnwIVAdHc5BJTDNM0aTrnr2luKulFjU7W+SRhDZvi66Ru7Q==
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==
uc.micro@^1.0.1, uc.micro@^1.0.5:
version "1.0.6"

View File

@@ -6,7 +6,7 @@
"git": {
"name": "chromium",
"repositoryUrl": "https://chromium.googlesource.com/chromium/src",
"commitHash": "7accc8730b0f99b5e7c0702ea89d1fa7c17bfe33"
"commitHash": "164c37e3f235134c88e80fac2a182cfba3f07f00"
}
},
"licenseDetail": [
@@ -40,7 +40,7 @@
"SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
],
"isOnlyProductionDependency": true,
"version": "61.0.3163.100"
"version": "66.0.3359.181"
},
{
"component": {
@@ -48,12 +48,12 @@
"git": {
"name": "libchromiumcontent",
"repositoryUrl": "https://github.com/electron/libchromiumcontent",
"commitHash": "ccdb085454b0a387ee96e0f81a7ca9a8ce07a710"
"commitHash": "7ea271f92018b1eeb8e70ec6de8c29f9758a0c05"
}
},
"isOnlyProductionDependency": true,
"license": "MIT",
"version": "61.0.3163.100"
"version": "66.0.3359.181"
},
{
"component": {
@@ -61,11 +61,11 @@
"git": {
"name": "nodejs",
"repositoryUrl": "https://github.com/nodejs/node",
"commitHash": "8a44289089a08b7b19fa3c4651b5f1f5d1edd71b"
"commitHash": "5cbb905c1af7cea2d709932d59827d7c6d03ef4a"
}
},
"isOnlyProductionDependency": true,
"version": "8.9.3"
"version": "10.2.0"
},
{
"component": {
@@ -73,12 +73,12 @@
"git": {
"name": "electron",
"repositoryUrl": "https://github.com/electron/electron",
"commitHash": "d281859cf59f12c7107a540a9f4cba0ecf5eff41"
"commitHash": "bb28fa8e8e797db249a66405146ad0501eaf411a"
}
},
"isOnlyProductionDependency": true,
"license": "MIT",
"version": "2.0.12"
"version": "3.1.2"
},
{
"component": {
@@ -105,6 +105,30 @@
"license": "MIT",
"version": "0.14.0"
},
{
"component": {
"type": "git",
"git": {
"name": "vscode-octicons-font",
"repositoryUrl": "https://github.com/Microsoft/vscode-octicons-font",
"commitHash": "5095860bb929919670646e2dfa0ee47d9b93bcb9"
}
},
"license": "MIT",
"version": "1.0.0"
},
{
"component": {
"type": "git",
"git": {
"name": "octicons",
"repositoryUrl": "https://github.com/primer/octicons",
"commitHash": "d120bf97bc9a12fb415f69fedaf31fe58427ca56"
}
},
"license": "MIT",
"version": "8.3.0"
},
{
"component": {
"type": "npm",
@@ -493,6 +517,19 @@
" defined by the Mozilla Public License, v. 2.0."
],
"license": "MPL"
},
{
"component": {
"type": "git",
"git": {
"name": "ripgrep",
"repositoryUrl": "https://github.com/BurntSushi/ripgrep",
"commitHash": "8a7db1a918e969b85cd933d8ed9fa5285b281ba4"
}
},
"isOnlyProductionDependency": true,
"license": "MIT",
"version": "0.10.0"
}
],
"version": 1

View File

@@ -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"
}
}

View File

@@ -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"
}
}

View File

@@ -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...');
}

View File

@@ -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();

View File

@@ -10,8 +10,8 @@
}
},
"license": "MIT",
"version": "0.0.0"
"version": "0.7.4"
}
],
"version": 1
}
}

View File

@@ -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)")));

View File

@@ -41,6 +41,14 @@
"fileMatch": "*color-theme.json",
"url": "vscode://schemas/color-theme"
}
],
"languages": [
{
"id": "ignore",
"filenames": [
".vscodeignore"
]
}
]
},
"devDependencies": {

View File

@@ -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"
},

View File

@@ -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.",

View File

@@ -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

View File

@@ -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

View File

@@ -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 {

View File

@@ -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'
}

View File

@@ -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]);
}
}

View File

@@ -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 })

View File

@@ -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');
}

View File

@@ -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');

View File

@@ -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
};
}
}

View File

@@ -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',
});
});
});

View File

@@ -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> {

View File

@@ -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"

View File

@@ -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"
}
}

View File

@@ -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) {

View File

@@ -4,3 +4,4 @@
*--------------------------------------------------------------------------------------------*/
/// <reference path='../../../../../src/vs/vscode.d.ts'/>
/// <reference path="../../../../../src/vs/vscode.proposed.d.ts" />

View File

@@ -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"
}
}
}

View File

@@ -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"

View File

@@ -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();

View File

@@ -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;
}

View File

@@ -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"

View File

@@ -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"

View File

@@ -29,4 +29,4 @@
}
],
"version": 1
}
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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",

View File

@@ -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",

View File

@@ -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();

View File

@@ -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));
}

View File

@@ -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);
});
}

View File

@@ -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)));

View File

@@ -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;
}
}
}

View File

@@ -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];

View File

@@ -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);

View File

@@ -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>

View File

@@ -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>`;
}
};
}

View File

@@ -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);

View File

@@ -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 -
);

View File

@@ -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>();

View File

@@ -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('[![alt text](image.jpg)](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('[![a]( whitespace.jpg )]( 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('[![a](img1.jpg)](file1.txt) text [![a](img2.jpg)](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));
}
});
});

View File

@@ -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;

View File

@@ -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');

View File

@@ -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"

View File

@@ -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
};
}
}

View File

@@ -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;
});

View File

@@ -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();
}

View File

@@ -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);
}
}
}

View File

@@ -10,9 +10,9 @@ agent-base@4, agent-base@^4.1.0:
es6-promisify "^5.0.0"
ajv@^6.5.5:
version "6.8.1"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.8.1.tgz#0890b93742985ebf8973cd365c5b23920ce3cb20"
integrity sha512-eqxCp82P+JfqL683wwsL73XmFs1eG6qjw+RD3YHx+Jll1r0jNd4dh8QG9NYAeNGA/hnZjeEDgtTskgJULbxpWQ==
version "6.10.0"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.0.tgz#90d0d54439da587cd7e843bfb7045f50bd22bdf1"
integrity sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==
dependencies:
fast-deep-equal "^2.0.1"
fast-json-stable-stringify "^2.0.0"
@@ -562,17 +562,17 @@ make-dir@^1.0.0:
dependencies:
pify "^3.0.0"
mime-db@~1.37.0:
version "1.37.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.37.0.tgz#0b6a0ce6fdbe9576e25f1f2d2fde8830dc0ad0d8"
integrity sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==
mime-db@~1.38.0:
version "1.38.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.38.0.tgz#1a2aab16da9eb167b49c6e4df2d9c68d63d8e2ad"
integrity sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg==
mime-types@^2.1.12, mime-types@~2.1.19:
version "2.1.21"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.21.tgz#28995aa1ecb770742fe6ae7e58f9181c744b3f96"
integrity sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==
version "2.1.22"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.22.tgz#fe6b355a190926ab7698c9a0556a11199b2199bd"
integrity sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog==
dependencies:
mime-db "~1.37.0"
mime-db "~1.38.0"
minimist@0.0.8:
version "0.0.8"

View File

@@ -14,6 +14,7 @@ export class MockExtensionContext implements vscode.ExtensionContext {
return relativePath;
}
storagePath: string;
globalStoragePath: string;
constructor() {
this.subscriptions = [];

View File

@@ -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"
}
}
}

View File

@@ -14,4 +14,4 @@
}
],
"version": 1
}
}

View File

@@ -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"
}
}

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