mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-04-11 06:01:46 -04:00
Merge from vscode 1a81711a85e38ccf784110568ebf3784ab9094a5 (#9161)
* Merge from vscode 1a81711a85e38ccf784110568ebf3784ab9094a5 * small spacing fix
This commit is contained in:
@@ -447,6 +447,22 @@
|
|||||||
"command": "git.stashDrop",
|
"command": "git.stashDrop",
|
||||||
"title": "%command.stashDrop%",
|
"title": "%command.stashDrop%",
|
||||||
"category": "Git"
|
"category": "Git"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "git.timeline.openDiff",
|
||||||
|
"title": "%command.timelineOpenDiff%",
|
||||||
|
"icon": "$(compare-changes)",
|
||||||
|
"category": "Git"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "git.timeline.copyCommitId",
|
||||||
|
"title": "%command.timelineCopyCommitId%",
|
||||||
|
"category": "Git"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "git.timeline.copyCommitMessage",
|
||||||
|
"title": "%command.timelineCopyCommitMessage%",
|
||||||
|
"category": "Git"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"menus": {
|
"menus": {
|
||||||
@@ -718,6 +734,18 @@
|
|||||||
{
|
{
|
||||||
"command": "git.stashDrop",
|
"command": "git.stashDrop",
|
||||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "git.timeline.openDiff",
|
||||||
|
"when": "false"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "git.timeline.copyCommitId",
|
||||||
|
"when": "false"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "git.timeline.copyCommitMessage",
|
||||||
|
"when": "false"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"scm/title": [
|
"scm/title": [
|
||||||
@@ -1248,6 +1276,28 @@
|
|||||||
"command": "git.revertChange",
|
"command": "git.revertChange",
|
||||||
"when": "originalResourceScheme == git"
|
"when": "originalResourceScheme == git"
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"timeline/item/context": [
|
||||||
|
{
|
||||||
|
"command": "git.timeline.openDiff",
|
||||||
|
"group": "inline",
|
||||||
|
"when": "timelineItem =~ /git:file\\b/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "git.timeline.openDiff",
|
||||||
|
"group": "1_timeline",
|
||||||
|
"when": "timelineItem =~ /git:file\\b/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "git.timeline.copyCommitId",
|
||||||
|
"group": "2_timeline@1",
|
||||||
|
"when": "timelineItem =~ /git:file:commit\\b/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "git.timeline.copyCommitMessage",
|
||||||
|
"group": "2_timeline@2",
|
||||||
|
"when": "timelineItem =~ /git:file:commit\\b/"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"configuration": {
|
"configuration": {
|
||||||
@@ -1779,10 +1829,11 @@
|
|||||||
"@types/file-type": "^5.2.1",
|
"@types/file-type": "^5.2.1",
|
||||||
"@types/mocha": "2.2.43",
|
"@types/mocha": "2.2.43",
|
||||||
"@types/node": "^12.11.7",
|
"@types/node": "^12.11.7",
|
||||||
|
"@types/vscode": "^1.42",
|
||||||
"@types/which": "^1.0.28",
|
"@types/which": "^1.0.28",
|
||||||
"mocha": "^3.2.0",
|
"mocha": "^3.2.0",
|
||||||
"mocha-junit-reporter": "^1.23.3",
|
"mocha-junit-reporter": "^1.23.3",
|
||||||
"mocha-multi-reporters": "^1.1.7",
|
"mocha-multi-reporters": "^1.1.7",
|
||||||
"vscode": "^1.1.36"
|
"vscode-test": "^1.3.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,6 +70,9 @@
|
|||||||
"command.stashApply": "Apply Stash...",
|
"command.stashApply": "Apply Stash...",
|
||||||
"command.stashApplyLatest": "Apply Latest Stash",
|
"command.stashApplyLatest": "Apply Latest Stash",
|
||||||
"command.stashDrop": "Drop Stash...",
|
"command.stashDrop": "Drop Stash...",
|
||||||
|
"command.timelineOpenDiff": "Open Changes",
|
||||||
|
"command.timelineCopyCommitId": "Copy Commit ID",
|
||||||
|
"command.timelineCopyCommitMessage": "Copy Commit Message",
|
||||||
"config.enabled": "Whether git is enabled.",
|
"config.enabled": "Whether git is enabled.",
|
||||||
"config.path": "Path and filename of the git executable, e.g. `C:\\Program Files\\Git\\bin\\git.exe` (Windows).",
|
"config.path": "Path and filename of the git executable, e.g. `C:\\Program Files\\Git\\bin\\git.exe` (Windows).",
|
||||||
"config.autoRepositoryDetection": "Configures when repositories should be automatically detected.",
|
"config.autoRepositoryDetection": "Configures when repositories should be automatically detected.",
|
||||||
@@ -127,7 +130,7 @@
|
|||||||
"config.showProgress": "Controls whether git actions should show progress.",
|
"config.showProgress": "Controls whether git actions should show progress.",
|
||||||
"config.rebaseWhenSync": "Force git to use rebase when running the sync command.",
|
"config.rebaseWhenSync": "Force git to use rebase when running the sync command.",
|
||||||
"config.confirmEmptyCommits": "Always confirm the creation of empty commits for the 'Git: Commit Empty' command.",
|
"config.confirmEmptyCommits": "Always confirm the creation of empty commits for the 'Git: Commit Empty' command.",
|
||||||
"config.fetchOnPull": "Fetch all branches when pulling or just the current one.",
|
"config.fetchOnPull": "When enabled, fetch all branches when pulling. Otherwise, fetch just the current one.",
|
||||||
"config.pullTags": "Fetch all tags when pulling.",
|
"config.pullTags": "Fetch all tags when pulling.",
|
||||||
"config.autoStash": "Stash any changes before pulling and restore them after successful pull.",
|
"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.allowForcePush": "Controls whether force push (with or without lease) is enabled.",
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
import { lstat, Stats } from 'fs';
|
import { lstat, Stats } from 'fs';
|
||||||
import * as os from 'os';
|
import * as os from 'os';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import { commands, Disposable, LineChange, MessageOptions, OutputChannel, Position, ProgressLocation, QuickPickItem, Range, SourceControlResourceState, TextDocumentShowOptions, TextEditor, Uri, ViewColumn, window, workspace, WorkspaceEdit, WorkspaceFolder } from 'vscode';
|
import { commands, Disposable, LineChange, MessageOptions, OutputChannel, Position, ProgressLocation, QuickPickItem, Range, SourceControlResourceState, TextDocumentShowOptions, TextEditor, Uri, ViewColumn, window, workspace, WorkspaceEdit, WorkspaceFolder, TimelineItem, env } from 'vscode';
|
||||||
import TelemetryReporter from 'vscode-extension-telemetry';
|
import TelemetryReporter from 'vscode-extension-telemetry';
|
||||||
import * as nls from 'vscode-nls';
|
import * as nls from 'vscode-nls';
|
||||||
import { Branch, GitErrorCodes, Ref, RefType, Status, CommitOptions } from './api/git';
|
import { Branch, GitErrorCodes, Ref, RefType, Status, CommitOptions } from './api/git';
|
||||||
@@ -17,6 +17,7 @@ import { applyLineChanges, getModifiedRange, intersectDiffWithRange, invertLineC
|
|||||||
import { fromGitUri, toGitUri, isGitUri } from './uri';
|
import { fromGitUri, toGitUri, isGitUri } from './uri';
|
||||||
import { grep, isDescendant, pathEquals } from './util';
|
import { grep, isDescendant, pathEquals } from './util';
|
||||||
import { Log, LogLevel } from './log';
|
import { Log, LogLevel } from './log';
|
||||||
|
import { GitTimelineItem } from './timelineProvider';
|
||||||
|
|
||||||
const localize = nls.loadMessageBundle();
|
const localize = nls.loadMessageBundle();
|
||||||
|
|
||||||
@@ -2331,23 +2332,47 @@ export class CommandCenter {
|
|||||||
return result && result.stash;
|
return result && result.stash;
|
||||||
}
|
}
|
||||||
|
|
||||||
@command('git.openDiff', { repository: false })
|
@command('git.timeline.openDiff', { repository: false })
|
||||||
async openDiff(uri: Uri, lhs: string, rhs: string) {
|
async timelineOpenDiff(item: TimelineItem, uri: Uri | undefined, _source: string) {
|
||||||
|
// eslint-disable-next-line eqeqeq
|
||||||
|
if (uri == null || !GitTimelineItem.is(item)) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
const basename = path.basename(uri.fsPath);
|
const basename = path.basename(uri.fsPath);
|
||||||
|
|
||||||
let title;
|
let title;
|
||||||
if ((lhs === 'HEAD' || lhs === '~') && rhs === '') {
|
if ((item.previousRef === 'HEAD' || item.previousRef === '~') && item.ref === '') {
|
||||||
title = `${basename} (Working Tree)`;
|
title = `${basename} (Working Tree)`;
|
||||||
}
|
}
|
||||||
else if (lhs === 'HEAD' && rhs === '~') {
|
else if (item.previousRef === 'HEAD' && item.ref === '~') {
|
||||||
title = `${basename} (Index)`;
|
title = `${basename} (Index)`;
|
||||||
} else {
|
} else {
|
||||||
title = `${basename} (${lhs.endsWith('^') ? `${lhs.substr(0, 8)}^` : lhs.substr(0, 8)}) \u27f7 ${basename} (${rhs.endsWith('^') ? `${rhs.substr(0, 8)}^` : rhs.substr(0, 8)})`;
|
title = `${basename} (${item.shortPreviousRef}) \u27f7 ${basename} (${item.shortRef})`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return commands.executeCommand('vscode.diff', toGitUri(uri, lhs), rhs === '' ? uri : toGitUri(uri, rhs), title);
|
return commands.executeCommand('vscode.diff', toGitUri(uri, item.previousRef), item.ref === '' ? uri : toGitUri(uri, item.ref), title);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@command('git.timeline.copyCommitId', { repository: false })
|
||||||
|
async timelineCopyCommitId(item: TimelineItem, _uri: Uri | undefined, _source: string) {
|
||||||
|
if (!GitTimelineItem.is(item)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
env.clipboard.writeText(item.ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
@command('git.timeline.copyCommitMessage', { repository: false })
|
||||||
|
async timelineCopyCommitMessage(item: TimelineItem, _uri: Uri | undefined, _source: string) {
|
||||||
|
if (!GitTimelineItem.is(item)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
env.clipboard.writeText(item.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private createCommand(id: string, key: string, method: Function, options: CommandOptions): (...args: any[]) => any {
|
private createCommand(id: string, key: string, method: Function, options: CommandOptions): (...args: any[]) => any {
|
||||||
const result = (...args: any[]) => {
|
const result = (...args: any[]) => {
|
||||||
let result: Promise<any>;
|
let result: Promise<any>;
|
||||||
|
|||||||
@@ -5,19 +5,62 @@
|
|||||||
|
|
||||||
import * as dayjs from 'dayjs';
|
import * as dayjs from 'dayjs';
|
||||||
import * as advancedFormat from 'dayjs/plugin/advancedFormat';
|
import * as advancedFormat from 'dayjs/plugin/advancedFormat';
|
||||||
import * as relativeTime from 'dayjs/plugin/relativeTime';
|
import { CancellationToken, Disposable, Event, EventEmitter, ThemeIcon, Timeline, TimelineChangeEvent, TimelineCursor, TimelineItem, TimelineProvider, Uri, workspace } from 'vscode';
|
||||||
import { CancellationToken, Disposable, Event, EventEmitter, ThemeIcon, TimelineItem, TimelineProvider, Uri, workspace, TimelineChangeEvent } from 'vscode';
|
|
||||||
import { Model } from './model';
|
import { Model } from './model';
|
||||||
import { Repository } from './repository';
|
import { Repository } from './repository';
|
||||||
import { debounce } from './decorators';
|
import { debounce } from './decorators';
|
||||||
import { Status } from './api/git';
|
import { Status } from './api/git';
|
||||||
|
|
||||||
dayjs.extend(advancedFormat);
|
dayjs.extend(advancedFormat);
|
||||||
dayjs.extend(relativeTime);
|
|
||||||
|
|
||||||
// TODO[ECA]: Localize all the strings
|
// TODO[ECA]: Localize all the strings
|
||||||
// TODO[ECA]: Localize or use a setting for date format
|
// TODO[ECA]: Localize or use a setting for date format
|
||||||
|
|
||||||
|
export class GitTimelineItem extends TimelineItem {
|
||||||
|
static is(item: TimelineItem): item is GitTimelineItem {
|
||||||
|
return item instanceof GitTimelineItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly ref: string;
|
||||||
|
readonly previousRef: string;
|
||||||
|
readonly message: string;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
ref: string,
|
||||||
|
previousRef: string,
|
||||||
|
message: string,
|
||||||
|
timestamp: number,
|
||||||
|
id: string,
|
||||||
|
contextValue: string
|
||||||
|
) {
|
||||||
|
const index = message.indexOf('\n');
|
||||||
|
const label = index !== -1 ? `${message.substring(0, index)} \u2026` : message;
|
||||||
|
|
||||||
|
super(label, timestamp);
|
||||||
|
|
||||||
|
this.ref = ref;
|
||||||
|
this.previousRef = previousRef;
|
||||||
|
this.message = message;
|
||||||
|
this.id = id;
|
||||||
|
this.contextValue = contextValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
get shortRef() {
|
||||||
|
return this.shortenRef(this.ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
get shortPreviousRef() {
|
||||||
|
return this.shortenRef(this.previousRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
private shortenRef(ref: string): string {
|
||||||
|
if (ref === '' || ref === '~' || ref === 'HEAD') {
|
||||||
|
return ref;
|
||||||
|
}
|
||||||
|
return ref.endsWith('^') ? `${ref.substr(0, 8)}^` : ref.substr(0, 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class GitTimelineProvider implements TimelineProvider {
|
export class GitTimelineProvider implements TimelineProvider {
|
||||||
private _onDidChange = new EventEmitter<TimelineChangeEvent>();
|
private _onDidChange = new EventEmitter<TimelineChangeEvent>();
|
||||||
get onDidChange(): Event<TimelineChangeEvent> {
|
get onDidChange(): Event<TimelineChangeEvent> {
|
||||||
@@ -44,7 +87,7 @@ export class GitTimelineProvider implements TimelineProvider {
|
|||||||
this._disposable.dispose();
|
this._disposable.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
async provideTimeline(uri: Uri, _token: CancellationToken): Promise<TimelineItem[]> {
|
async provideTimeline(uri: Uri, _cursor: TimelineCursor, _token: CancellationToken): Promise<Timeline> {
|
||||||
// console.log(`GitTimelineProvider.provideTimeline: uri=${uri} state=${this._model.state}`);
|
// console.log(`GitTimelineProvider.provideTimeline: uri=${uri} state=${this._model.state}`);
|
||||||
|
|
||||||
const repo = this._model.getRepository(uri);
|
const repo = this._model.getRepository(uri);
|
||||||
@@ -53,7 +96,7 @@ export class GitTimelineProvider implements TimelineProvider {
|
|||||||
this._repoStatusDate = undefined;
|
this._repoStatusDate = undefined;
|
||||||
this._repo = undefined;
|
this._repo = undefined;
|
||||||
|
|
||||||
return [];
|
return { items: [] };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._repo?.root !== repo.root) {
|
if (this._repo?.root !== repo.root) {
|
||||||
@@ -72,25 +115,17 @@ export class GitTimelineProvider implements TimelineProvider {
|
|||||||
const commits = await repo.logFile(uri);
|
const commits = await repo.logFile(uri);
|
||||||
|
|
||||||
let dateFormatter: dayjs.Dayjs;
|
let dateFormatter: dayjs.Dayjs;
|
||||||
const items = commits.map<TimelineItem>(c => {
|
const items = commits.map<GitTimelineItem>(c => {
|
||||||
let message = c.message;
|
|
||||||
|
|
||||||
const index = message.indexOf('\n');
|
|
||||||
if (index !== -1) {
|
|
||||||
message = `${message.substring(0, index)} \u2026`;
|
|
||||||
}
|
|
||||||
|
|
||||||
dateFormatter = dayjs(c.authorDate);
|
dateFormatter = dayjs(c.authorDate);
|
||||||
|
|
||||||
const item = new TimelineItem(message, c.authorDate?.getTime() ?? 0);
|
const item = new GitTimelineItem(c.hash, `${c.hash}^`, c.message, c.authorDate?.getTime() ?? 0, c.hash, 'git:file:commit');
|
||||||
item.id = c.hash;
|
|
||||||
item.iconPath = new (ThemeIcon as any)('git-commit');
|
item.iconPath = new (ThemeIcon as any)('git-commit');
|
||||||
item.description = `${dateFormatter.fromNow()} \u2022 ${c.authorName}`;
|
item.description = c.authorName;
|
||||||
item.detail = `${c.authorName} (${c.authorEmail}) \u2014 ${c.hash.substr(0, 8)}\n${dateFormatter.fromNow()} (${dateFormatter.format('MMMM Do, YYYY h:mma')})\n\n${c.message}`;
|
item.detail = `${c.authorName} (${c.authorEmail}) \u2014 ${c.hash.substr(0, 8)}\n${dateFormatter.format('MMMM Do, YYYY h:mma')}\n\n${c.message}`;
|
||||||
item.command = {
|
item.command = {
|
||||||
title: 'Open Diff',
|
title: 'Open Comparison',
|
||||||
command: 'git.openDiff',
|
command: 'git.timeline.openDiff',
|
||||||
arguments: [uri, `${c.hash}^`, c.hash]
|
arguments: [uri, this.id, item]
|
||||||
};
|
};
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
@@ -123,16 +158,15 @@ export class GitTimelineProvider implements TimelineProvider {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const item = new TimelineItem('Staged Changes', date.getTime());
|
const item = new GitTimelineItem('~', 'HEAD', 'Staged Changes', date.getTime(), 'index', 'git:file:index');
|
||||||
item.id = 'index';
|
|
||||||
// TODO[ECA]: Replace with a better icon -- reflecting its status maybe?
|
// TODO[ECA]: Replace with a better icon -- reflecting its status maybe?
|
||||||
item.iconPath = new (ThemeIcon as any)('git-commit');
|
item.iconPath = new (ThemeIcon as any)('git-commit');
|
||||||
item.description = `${dateFormatter.fromNow()} \u2022 You`;
|
item.description = 'You';
|
||||||
item.detail = `You \u2014 Index\n${dateFormatter.fromNow()} (${dateFormatter.format('MMMM Do, YYYY h:mma')})\n${status}`;
|
item.detail = `You \u2014 Index\n${dateFormatter.format('MMMM Do, YYYY h:mma')}\n${status}`;
|
||||||
item.command = {
|
item.command = {
|
||||||
title: 'Open Comparison',
|
title: 'Open Comparison',
|
||||||
command: 'git.openDiff',
|
command: 'git.timeline.openDiff',
|
||||||
arguments: [uri, 'HEAD', '~']
|
arguments: [uri, this.id, item]
|
||||||
};
|
};
|
||||||
|
|
||||||
items.push(item);
|
items.push(item);
|
||||||
@@ -166,22 +200,21 @@ export class GitTimelineProvider implements TimelineProvider {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const item = new TimelineItem('Uncommited Changes', date.getTime());
|
const item = new GitTimelineItem('', index ? '~' : 'HEAD', 'Uncommited Changes', date.getTime(), 'working', 'git:file:working');
|
||||||
item.id = 'working';
|
|
||||||
// TODO[ECA]: Replace with a better icon -- reflecting its status maybe?
|
// TODO[ECA]: Replace with a better icon -- reflecting its status maybe?
|
||||||
item.iconPath = new (ThemeIcon as any)('git-commit');
|
item.iconPath = new (ThemeIcon as any)('git-commit');
|
||||||
item.description = `${dateFormatter.fromNow()} \u2022 You`;
|
item.description = 'You';
|
||||||
item.detail = `You \u2014 Working Tree\n${dateFormatter.fromNow()} (${dateFormatter.format('MMMM Do, YYYY h:mma')})\n${status}`;
|
item.detail = `You \u2014 Working Tree\n${dateFormatter.format('MMMM Do, YYYY h:mma')}\n${status}`;
|
||||||
item.command = {
|
item.command = {
|
||||||
title: 'Open Comparison',
|
title: 'Open Comparison',
|
||||||
command: 'git.openDiff',
|
command: 'git.timeline.openDiff',
|
||||||
arguments: [uri, index ? '~' : 'HEAD', '']
|
arguments: [uri, this.id, item]
|
||||||
};
|
};
|
||||||
|
|
||||||
items.push(item);
|
items.push(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
return items;
|
return { items: items };
|
||||||
}
|
}
|
||||||
|
|
||||||
private onRepositoriesChanged(_repo: Repository) {
|
private onRepositoriesChanged(_repo: Repository) {
|
||||||
@@ -208,6 +241,6 @@ export class GitTimelineProvider implements TimelineProvider {
|
|||||||
|
|
||||||
@debounce(500)
|
@debounce(500)
|
||||||
private fireChanged() {
|
private fireChanged() {
|
||||||
this._onDidChange.fire();
|
this._onDidChange.fire({});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,11 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.11.7.tgz#57682a9771a3f7b09c2497f28129a0462966524a"
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.11.7.tgz#57682a9771a3f7b09c2497f28129a0462966524a"
|
||||||
integrity sha512-JNbGaHFCLwgHn/iCckiGSOZ1XYHsKFwREtzPwSGCVld1SGhOlmZw2D4ZI94HQCrBHbADzW9m4LER/8olJTRGHA==
|
integrity sha512-JNbGaHFCLwgHn/iCckiGSOZ1XYHsKFwREtzPwSGCVld1SGhOlmZw2D4ZI94HQCrBHbADzW9m4LER/8olJTRGHA==
|
||||||
|
|
||||||
|
"@types/vscode@^1.42":
|
||||||
|
version "1.42.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/vscode/-/vscode-1.42.0.tgz#0ad891a9487e91e34be7c56985058a179031eb76"
|
||||||
|
integrity sha512-ds6TceMsh77Fs0Mq0Vap6Y72JbGWB8Bay4DrnJlf5d9ui2RSe1wis13oQm+XhguOeH1HUfLGzaDAoupTUtgabw==
|
||||||
|
|
||||||
"@types/which@^1.0.28":
|
"@types/which@^1.0.28":
|
||||||
version "1.0.28"
|
version "1.0.28"
|
||||||
resolved "https://registry.yarnpkg.com/@types/which/-/which-1.0.28.tgz#016e387629b8817bed653fe32eab5d11279c8df6"
|
resolved "https://registry.yarnpkg.com/@types/which/-/which-1.0.28.tgz#016e387629b8817bed653fe32eab5d11279c8df6"
|
||||||
@@ -43,16 +48,6 @@ agent-base@4, agent-base@^4.3.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
es6-promisify "^5.0.0"
|
es6-promisify "^5.0.0"
|
||||||
|
|
||||||
ajv@^6.5.5:
|
|
||||||
version "6.11.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.11.0.tgz#c3607cbc8ae392d8a5a536f25b21f8e5f3f87fe9"
|
|
||||||
integrity sha512-nCprB/0syFYy9fVYU1ox1l2KN8S9I+tziH8D4zdZuLT3N6RMlGSGt5FSTpAiHB/Whv8Qs1cWHma1aMKZyaHRKA==
|
|
||||||
dependencies:
|
|
||||||
fast-deep-equal "^3.1.1"
|
|
||||||
fast-json-stable-stringify "^2.0.0"
|
|
||||||
json-schema-traverse "^0.4.1"
|
|
||||||
uri-js "^4.2.2"
|
|
||||||
|
|
||||||
ansi-regex@^3.0.0:
|
ansi-regex@^3.0.0:
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998"
|
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998"
|
||||||
@@ -67,45 +62,11 @@ applicationinsights@1.0.8:
|
|||||||
diagnostic-channel-publishers "0.2.1"
|
diagnostic-channel-publishers "0.2.1"
|
||||||
zone.js "0.7.6"
|
zone.js "0.7.6"
|
||||||
|
|
||||||
asn1@~0.2.3:
|
|
||||||
version "0.2.4"
|
|
||||||
resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136"
|
|
||||||
integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==
|
|
||||||
dependencies:
|
|
||||||
safer-buffer "~2.1.0"
|
|
||||||
|
|
||||||
assert-plus@1.0.0, assert-plus@^1.0.0:
|
|
||||||
version "1.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
|
|
||||||
integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=
|
|
||||||
|
|
||||||
asynckit@^0.4.0:
|
|
||||||
version "0.4.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
|
|
||||||
integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
|
|
||||||
|
|
||||||
aws-sign2@~0.7.0:
|
|
||||||
version "0.7.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
|
|
||||||
integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=
|
|
||||||
|
|
||||||
aws4@^1.8.0:
|
|
||||||
version "1.9.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.9.1.tgz#7e33d8f7d449b3f673cd72deb9abdc552dbe528e"
|
|
||||||
integrity sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==
|
|
||||||
|
|
||||||
balanced-match@^1.0.0:
|
balanced-match@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
|
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
|
||||||
integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
|
integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
|
||||||
|
|
||||||
bcrypt-pbkdf@^1.0.0:
|
|
||||||
version "1.0.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e"
|
|
||||||
integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=
|
|
||||||
dependencies:
|
|
||||||
tweetnacl "^0.14.3"
|
|
||||||
|
|
||||||
brace-expansion@^1.1.7:
|
brace-expansion@^1.1.7:
|
||||||
version "1.1.8"
|
version "1.1.8"
|
||||||
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292"
|
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292"
|
||||||
@@ -119,43 +80,16 @@ browser-stdout@1.3.0:
|
|||||||
resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f"
|
resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f"
|
||||||
integrity sha1-81HTKWnTL6XXpVZxVCY9korjvR8=
|
integrity sha1-81HTKWnTL6XXpVZxVCY9korjvR8=
|
||||||
|
|
||||||
browser-stdout@1.3.1:
|
|
||||||
version "1.3.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60"
|
|
||||||
integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==
|
|
||||||
|
|
||||||
buffer-from@^1.0.0:
|
|
||||||
version "1.1.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
|
|
||||||
integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==
|
|
||||||
|
|
||||||
byline@^5.0.0:
|
byline@^5.0.0:
|
||||||
version "5.0.0"
|
version "5.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/byline/-/byline-5.0.0.tgz#741c5216468eadc457b03410118ad77de8c1ddb1"
|
resolved "https://registry.yarnpkg.com/byline/-/byline-5.0.0.tgz#741c5216468eadc457b03410118ad77de8c1ddb1"
|
||||||
integrity sha1-dBxSFkaOrcRXsDQQEYrXfejB3bE=
|
integrity sha1-dBxSFkaOrcRXsDQQEYrXfejB3bE=
|
||||||
|
|
||||||
caseless@~0.12.0:
|
|
||||||
version "0.12.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
|
|
||||||
integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
|
|
||||||
|
|
||||||
charenc@~0.0.1:
|
charenc@~0.0.1:
|
||||||
version "0.0.2"
|
version "0.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667"
|
resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667"
|
||||||
integrity sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=
|
integrity sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=
|
||||||
|
|
||||||
combined-stream@^1.0.6, combined-stream@~1.0.6:
|
|
||||||
version "1.0.8"
|
|
||||||
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
|
|
||||||
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
|
|
||||||
dependencies:
|
|
||||||
delayed-stream "~1.0.0"
|
|
||||||
|
|
||||||
commander@2.15.1:
|
|
||||||
version "2.15.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f"
|
|
||||||
integrity sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==
|
|
||||||
|
|
||||||
commander@2.9.0:
|
commander@2.9.0:
|
||||||
version "2.9.0"
|
version "2.9.0"
|
||||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4"
|
resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4"
|
||||||
@@ -168,23 +102,11 @@ concat-map@0.0.1:
|
|||||||
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
||||||
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
|
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
|
||||||
|
|
||||||
core-util-is@1.0.2:
|
|
||||||
version "1.0.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
|
||||||
integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
|
|
||||||
|
|
||||||
crypt@~0.0.1:
|
crypt@~0.0.1:
|
||||||
version "0.0.2"
|
version "0.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b"
|
resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b"
|
||||||
integrity sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=
|
integrity sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=
|
||||||
|
|
||||||
dashdash@^1.12.0:
|
|
||||||
version "1.14.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
|
|
||||||
integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=
|
|
||||||
dependencies:
|
|
||||||
assert-plus "^1.0.0"
|
|
||||||
|
|
||||||
dayjs@1.8.19:
|
dayjs@1.8.19:
|
||||||
version "1.8.19"
|
version "1.8.19"
|
||||||
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.8.19.tgz#5117dc390d8f8e586d53891dbff3fa308f51abfe"
|
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.8.19.tgz#5117dc390d8f8e586d53891dbff3fa308f51abfe"
|
||||||
@@ -218,11 +140,6 @@ debug@^3.1.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
ms "^2.1.1"
|
ms "^2.1.1"
|
||||||
|
|
||||||
delayed-stream@~1.0.0:
|
|
||||||
version "1.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
|
|
||||||
integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk=
|
|
||||||
|
|
||||||
diagnostic-channel-publishers@0.2.1:
|
diagnostic-channel-publishers@0.2.1:
|
||||||
version "0.2.1"
|
version "0.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.2.1.tgz#8e2d607a8b6d79fe880b548bc58cc6beb288c4f3"
|
resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.2.1.tgz#8e2d607a8b6d79fe880b548bc58cc6beb288c4f3"
|
||||||
@@ -240,19 +157,6 @@ diff@3.2.0:
|
|||||||
resolved "https://registry.yarnpkg.com/diff/-/diff-3.2.0.tgz#c9ce393a4b7cbd0b058a725c93df299027868ff9"
|
resolved "https://registry.yarnpkg.com/diff/-/diff-3.2.0.tgz#c9ce393a4b7cbd0b058a725c93df299027868ff9"
|
||||||
integrity sha1-yc45Okt8vQsFinJck98pkCeGj/k=
|
integrity sha1-yc45Okt8vQsFinJck98pkCeGj/k=
|
||||||
|
|
||||||
diff@3.5.0:
|
|
||||||
version "3.5.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12"
|
|
||||||
integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==
|
|
||||||
|
|
||||||
ecc-jsbn@~0.1.1:
|
|
||||||
version "0.1.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9"
|
|
||||||
integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=
|
|
||||||
dependencies:
|
|
||||||
jsbn "~0.1.0"
|
|
||||||
safer-buffer "^2.1.0"
|
|
||||||
|
|
||||||
es6-promise@^4.0.3:
|
es6-promise@^4.0.3:
|
||||||
version "4.2.8"
|
version "4.2.8"
|
||||||
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a"
|
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a"
|
||||||
@@ -270,62 +174,16 @@ escape-string-regexp@1.0.5:
|
|||||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
|
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
|
||||||
integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
|
integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
|
||||||
|
|
||||||
extend@~3.0.2:
|
|
||||||
version "3.0.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
|
|
||||||
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
|
|
||||||
|
|
||||||
extsprintf@1.3.0:
|
|
||||||
version "1.3.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
|
|
||||||
integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=
|
|
||||||
|
|
||||||
extsprintf@^1.2.0:
|
|
||||||
version "1.4.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f"
|
|
||||||
integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8=
|
|
||||||
|
|
||||||
fast-deep-equal@^3.1.1:
|
|
||||||
version "3.1.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4"
|
|
||||||
integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==
|
|
||||||
|
|
||||||
fast-json-stable-stringify@^2.0.0:
|
|
||||||
version "2.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
|
|
||||||
integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
|
|
||||||
|
|
||||||
file-type@^7.2.0:
|
file-type@^7.2.0:
|
||||||
version "7.2.0"
|
version "7.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/file-type/-/file-type-7.2.0.tgz#113cfed52e1d6959ab80248906e2f25a8cdccb74"
|
resolved "https://registry.yarnpkg.com/file-type/-/file-type-7.2.0.tgz#113cfed52e1d6959ab80248906e2f25a8cdccb74"
|
||||||
integrity sha1-ETz+1S4daVmrgCSJBuLyWozcy3Q=
|
integrity sha1-ETz+1S4daVmrgCSJBuLyWozcy3Q=
|
||||||
|
|
||||||
forever-agent@~0.6.1:
|
|
||||||
version "0.6.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
|
|
||||||
integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=
|
|
||||||
|
|
||||||
form-data@~2.3.2:
|
|
||||||
version "2.3.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6"
|
|
||||||
integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==
|
|
||||||
dependencies:
|
|
||||||
asynckit "^0.4.0"
|
|
||||||
combined-stream "^1.0.6"
|
|
||||||
mime-types "^2.1.12"
|
|
||||||
|
|
||||||
fs.realpath@^1.0.0:
|
fs.realpath@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
|
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
|
||||||
integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
|
integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
|
||||||
|
|
||||||
getpass@^0.1.1:
|
|
||||||
version "0.1.7"
|
|
||||||
resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
|
|
||||||
integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=
|
|
||||||
dependencies:
|
|
||||||
assert-plus "^1.0.0"
|
|
||||||
|
|
||||||
glob@7.1.1:
|
glob@7.1.1:
|
||||||
version "7.1.1"
|
version "7.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8"
|
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8"
|
||||||
@@ -338,19 +196,7 @@ glob@7.1.1:
|
|||||||
once "^1.3.0"
|
once "^1.3.0"
|
||||||
path-is-absolute "^1.0.0"
|
path-is-absolute "^1.0.0"
|
||||||
|
|
||||||
glob@7.1.2:
|
glob@^7.1.3:
|
||||||
version "7.1.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
|
|
||||||
integrity sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==
|
|
||||||
dependencies:
|
|
||||||
fs.realpath "^1.0.0"
|
|
||||||
inflight "^1.0.4"
|
|
||||||
inherits "2"
|
|
||||||
minimatch "^3.0.4"
|
|
||||||
once "^1.3.0"
|
|
||||||
path-is-absolute "^1.0.0"
|
|
||||||
|
|
||||||
glob@^7.1.2:
|
|
||||||
version "7.1.6"
|
version "7.1.6"
|
||||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
|
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
|
||||||
integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==
|
integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==
|
||||||
@@ -367,39 +213,16 @@ glob@^7.1.2:
|
|||||||
resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725"
|
resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725"
|
||||||
integrity sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=
|
integrity sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=
|
||||||
|
|
||||||
growl@1.10.5:
|
|
||||||
version "1.10.5"
|
|
||||||
resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e"
|
|
||||||
integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==
|
|
||||||
|
|
||||||
growl@1.9.2:
|
growl@1.9.2:
|
||||||
version "1.9.2"
|
version "1.9.2"
|
||||||
resolved "https://registry.yarnpkg.com/growl/-/growl-1.9.2.tgz#0ea7743715db8d8de2c5ede1775e1b45ac85c02f"
|
resolved "https://registry.yarnpkg.com/growl/-/growl-1.9.2.tgz#0ea7743715db8d8de2c5ede1775e1b45ac85c02f"
|
||||||
integrity sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=
|
integrity sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=
|
||||||
|
|
||||||
har-schema@^2.0.0:
|
|
||||||
version "2.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
|
|
||||||
integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=
|
|
||||||
|
|
||||||
har-validator@~5.1.0:
|
|
||||||
version "5.1.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080"
|
|
||||||
integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==
|
|
||||||
dependencies:
|
|
||||||
ajv "^6.5.5"
|
|
||||||
har-schema "^2.0.0"
|
|
||||||
|
|
||||||
has-flag@^1.0.0:
|
has-flag@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa"
|
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa"
|
||||||
integrity sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=
|
integrity sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=
|
||||||
|
|
||||||
has-flag@^3.0.0:
|
|
||||||
version "3.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
|
|
||||||
integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0=
|
|
||||||
|
|
||||||
he@1.1.1:
|
he@1.1.1:
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd"
|
resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd"
|
||||||
@@ -413,16 +236,7 @@ http-proxy-agent@^2.1.0:
|
|||||||
agent-base "4"
|
agent-base "4"
|
||||||
debug "3.1.0"
|
debug "3.1.0"
|
||||||
|
|
||||||
http-signature@~1.2.0:
|
https-proxy-agent@^2.2.4:
|
||||||
version "1.2.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
|
|
||||||
integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=
|
|
||||||
dependencies:
|
|
||||||
assert-plus "^1.0.0"
|
|
||||||
jsprim "^1.2.2"
|
|
||||||
sshpk "^1.7.0"
|
|
||||||
|
|
||||||
https-proxy-agent@^2.2.1:
|
|
||||||
version "2.2.4"
|
version "2.2.4"
|
||||||
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz#4ee7a737abd92678a293d9b34a1af4d0d08c787b"
|
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz#4ee7a737abd92678a293d9b34a1af4d0d08c787b"
|
||||||
integrity sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==
|
integrity sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==
|
||||||
@@ -455,61 +269,21 @@ is-buffer@~1.1.1:
|
|||||||
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
|
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
|
||||||
integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
|
integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
|
||||||
|
|
||||||
is-typedarray@~1.0.0:
|
|
||||||
version "1.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
|
|
||||||
integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
|
|
||||||
|
|
||||||
isexe@^2.0.0:
|
isexe@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
|
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
|
||||||
integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=
|
integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=
|
||||||
|
|
||||||
isstream@~0.1.2:
|
|
||||||
version "0.1.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
|
|
||||||
integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
|
|
||||||
|
|
||||||
jsbn@~0.1.0:
|
|
||||||
version "0.1.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
|
|
||||||
integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM=
|
|
||||||
|
|
||||||
jschardet@2.1.1:
|
jschardet@2.1.1:
|
||||||
version "2.1.1"
|
version "2.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-2.1.1.tgz#af6f8fd0b3b0f5d46a8fd9614a4fce490575c184"
|
resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-2.1.1.tgz#af6f8fd0b3b0f5d46a8fd9614a4fce490575c184"
|
||||||
integrity sha512-pA5qG9Zwm8CBpGlK/lo2GE9jPxwqRgMV7Lzc/1iaPccw6v4Rhj8Zg2BTyrdmHmxlJojnbLupLeRnaPLsq03x6Q==
|
integrity sha512-pA5qG9Zwm8CBpGlK/lo2GE9jPxwqRgMV7Lzc/1iaPccw6v4Rhj8Zg2BTyrdmHmxlJojnbLupLeRnaPLsq03x6Q==
|
||||||
|
|
||||||
json-schema-traverse@^0.4.1:
|
|
||||||
version "0.4.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
|
|
||||||
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
|
|
||||||
|
|
||||||
json-schema@0.2.3:
|
|
||||||
version "0.2.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
|
|
||||||
integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
|
|
||||||
|
|
||||||
json-stringify-safe@~5.0.1:
|
|
||||||
version "5.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
|
|
||||||
integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
|
|
||||||
|
|
||||||
json3@3.3.2:
|
json3@3.3.2:
|
||||||
version "3.3.2"
|
version "3.3.2"
|
||||||
resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1"
|
resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1"
|
||||||
integrity sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=
|
integrity sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=
|
||||||
|
|
||||||
jsprim@^1.2.2:
|
|
||||||
version "1.4.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
|
|
||||||
integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=
|
|
||||||
dependencies:
|
|
||||||
assert-plus "1.0.0"
|
|
||||||
extsprintf "1.3.0"
|
|
||||||
json-schema "0.2.3"
|
|
||||||
verror "1.10.0"
|
|
||||||
|
|
||||||
lodash._baseassign@^3.0.0:
|
lodash._baseassign@^3.0.0:
|
||||||
version "3.2.0"
|
version "3.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz#8c38a099500f215ad09e59f1722fd0c52bfe0a4e"
|
resolved "https://registry.yarnpkg.com/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz#8c38a099500f215ad09e59f1722fd0c52bfe0a4e"
|
||||||
@@ -580,19 +354,7 @@ md5@^2.1.0:
|
|||||||
crypt "~0.0.1"
|
crypt "~0.0.1"
|
||||||
is-buffer "~1.1.1"
|
is-buffer "~1.1.1"
|
||||||
|
|
||||||
mime-db@1.43.0:
|
minimatch@^3.0.2, minimatch@^3.0.4:
|
||||||
version "1.43.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.43.0.tgz#0a12e0502650e473d735535050e7c8f4eb4fae58"
|
|
||||||
integrity sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==
|
|
||||||
|
|
||||||
mime-types@^2.1.12, mime-types@~2.1.19:
|
|
||||||
version "2.1.26"
|
|
||||||
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.26.tgz#9c921fc09b7e149a65dfdc0da4d20997200b0a06"
|
|
||||||
integrity sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==
|
|
||||||
dependencies:
|
|
||||||
mime-db "1.43.0"
|
|
||||||
|
|
||||||
minimatch@3.0.4, minimatch@^3.0.2, minimatch@^3.0.4:
|
|
||||||
version "3.0.4"
|
version "3.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
|
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
|
||||||
integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
|
integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
|
||||||
@@ -648,23 +410,6 @@ mocha@^3.2.0:
|
|||||||
mkdirp "0.5.1"
|
mkdirp "0.5.1"
|
||||||
supports-color "3.1.2"
|
supports-color "3.1.2"
|
||||||
|
|
||||||
mocha@^5.2.0:
|
|
||||||
version "5.2.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/mocha/-/mocha-5.2.0.tgz#6d8ae508f59167f940f2b5b3c4a612ae50c90ae6"
|
|
||||||
integrity sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==
|
|
||||||
dependencies:
|
|
||||||
browser-stdout "1.3.1"
|
|
||||||
commander "2.15.1"
|
|
||||||
debug "3.1.0"
|
|
||||||
diff "3.5.0"
|
|
||||||
escape-string-regexp "1.0.5"
|
|
||||||
glob "7.1.2"
|
|
||||||
growl "1.10.5"
|
|
||||||
he "1.1.1"
|
|
||||||
minimatch "3.0.4"
|
|
||||||
mkdirp "0.5.1"
|
|
||||||
supports-color "5.4.0"
|
|
||||||
|
|
||||||
ms@2.0.0:
|
ms@2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
|
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
|
||||||
@@ -675,11 +420,6 @@ ms@^2.1.1:
|
|||||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
|
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
|
||||||
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
|
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
|
||||||
|
|
||||||
oauth-sign@~0.9.0:
|
|
||||||
version "0.9.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
|
|
||||||
integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==
|
|
||||||
|
|
||||||
once@^1.3.0:
|
once@^1.3.0:
|
||||||
version "1.4.0"
|
version "1.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
|
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
|
||||||
@@ -692,73 +432,14 @@ path-is-absolute@^1.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
|
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
|
||||||
integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
|
integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
|
||||||
|
|
||||||
performance-now@^2.1.0:
|
rimraf@^2.6.3:
|
||||||
version "2.1.0"
|
version "2.7.1"
|
||||||
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
|
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec"
|
||||||
integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
|
integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==
|
||||||
|
|
||||||
psl@^1.1.24:
|
|
||||||
version "1.7.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/psl/-/psl-1.7.0.tgz#f1c4c47a8ef97167dea5d6bbf4816d736e884a3c"
|
|
||||||
integrity sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ==
|
|
||||||
|
|
||||||
punycode@^1.4.1:
|
|
||||||
version "1.4.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
|
|
||||||
integrity sha1-wNWmOycYgArY4esPpSachN1BhF4=
|
|
||||||
|
|
||||||
punycode@^2.1.0:
|
|
||||||
version "2.1.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
|
|
||||||
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
|
|
||||||
|
|
||||||
qs@~6.5.2:
|
|
||||||
version "6.5.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
|
|
||||||
integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==
|
|
||||||
|
|
||||||
querystringify@^2.1.1:
|
|
||||||
version "2.1.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.1.1.tgz#60e5a5fd64a7f8bfa4d2ab2ed6fdf4c85bad154e"
|
|
||||||
integrity sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==
|
|
||||||
|
|
||||||
request@^2.88.0:
|
|
||||||
version "2.88.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef"
|
|
||||||
integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==
|
|
||||||
dependencies:
|
dependencies:
|
||||||
aws-sign2 "~0.7.0"
|
glob "^7.1.3"
|
||||||
aws4 "^1.8.0"
|
|
||||||
caseless "~0.12.0"
|
|
||||||
combined-stream "~1.0.6"
|
|
||||||
extend "~3.0.2"
|
|
||||||
forever-agent "~0.6.1"
|
|
||||||
form-data "~2.3.2"
|
|
||||||
har-validator "~5.1.0"
|
|
||||||
http-signature "~1.2.0"
|
|
||||||
is-typedarray "~1.0.0"
|
|
||||||
isstream "~0.1.2"
|
|
||||||
json-stringify-safe "~5.0.1"
|
|
||||||
mime-types "~2.1.19"
|
|
||||||
oauth-sign "~0.9.0"
|
|
||||||
performance-now "^2.1.0"
|
|
||||||
qs "~6.5.2"
|
|
||||||
safe-buffer "^5.1.2"
|
|
||||||
tough-cookie "~2.4.3"
|
|
||||||
tunnel-agent "^0.6.0"
|
|
||||||
uuid "^3.3.2"
|
|
||||||
|
|
||||||
requires-port@^1.0.0:
|
"safer-buffer@>= 2.1.2 < 3":
|
||||||
version "1.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
|
|
||||||
integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=
|
|
||||||
|
|
||||||
safe-buffer@^5.0.1, safe-buffer@^5.1.2:
|
|
||||||
version "5.2.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519"
|
|
||||||
integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==
|
|
||||||
|
|
||||||
"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
|
|
||||||
version "2.1.2"
|
version "2.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
|
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
|
||||||
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
|
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
|
||||||
@@ -768,39 +449,6 @@ semver@^5.3.0:
|
|||||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab"
|
resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab"
|
||||||
integrity sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==
|
integrity sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==
|
||||||
|
|
||||||
semver@^5.4.1:
|
|
||||||
version "5.7.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
|
|
||||||
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
|
|
||||||
|
|
||||||
source-map-support@^0.5.0:
|
|
||||||
version "0.5.16"
|
|
||||||
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.16.tgz#0ae069e7fe3ba7538c64c98515e35339eac5a042"
|
|
||||||
integrity sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==
|
|
||||||
dependencies:
|
|
||||||
buffer-from "^1.0.0"
|
|
||||||
source-map "^0.6.0"
|
|
||||||
|
|
||||||
source-map@^0.6.0:
|
|
||||||
version "0.6.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
|
|
||||||
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
|
|
||||||
|
|
||||||
sshpk@^1.7.0:
|
|
||||||
version "1.16.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877"
|
|
||||||
integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==
|
|
||||||
dependencies:
|
|
||||||
asn1 "~0.2.3"
|
|
||||||
assert-plus "^1.0.0"
|
|
||||||
bcrypt-pbkdf "^1.0.0"
|
|
||||||
dashdash "^1.12.0"
|
|
||||||
ecc-jsbn "~0.1.1"
|
|
||||||
getpass "^0.1.1"
|
|
||||||
jsbn "~0.1.0"
|
|
||||||
safer-buffer "^2.0.2"
|
|
||||||
tweetnacl "~0.14.0"
|
|
||||||
|
|
||||||
strip-ansi@^4.0.0:
|
strip-ansi@^4.0.0:
|
||||||
version "4.0.0"
|
version "4.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f"
|
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f"
|
||||||
@@ -815,62 +463,6 @@ supports-color@3.1.2:
|
|||||||
dependencies:
|
dependencies:
|
||||||
has-flag "^1.0.0"
|
has-flag "^1.0.0"
|
||||||
|
|
||||||
supports-color@5.4.0:
|
|
||||||
version "5.4.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54"
|
|
||||||
integrity sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==
|
|
||||||
dependencies:
|
|
||||||
has-flag "^3.0.0"
|
|
||||||
|
|
||||||
tough-cookie@~2.4.3:
|
|
||||||
version "2.4.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781"
|
|
||||||
integrity sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==
|
|
||||||
dependencies:
|
|
||||||
psl "^1.1.24"
|
|
||||||
punycode "^1.4.1"
|
|
||||||
|
|
||||||
tunnel-agent@^0.6.0:
|
|
||||||
version "0.6.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
|
|
||||||
integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=
|
|
||||||
dependencies:
|
|
||||||
safe-buffer "^5.0.1"
|
|
||||||
|
|
||||||
tweetnacl@^0.14.3, tweetnacl@~0.14.0:
|
|
||||||
version "0.14.5"
|
|
||||||
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
|
|
||||||
integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=
|
|
||||||
|
|
||||||
uri-js@^4.2.2:
|
|
||||||
version "4.2.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0"
|
|
||||||
integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==
|
|
||||||
dependencies:
|
|
||||||
punycode "^2.1.0"
|
|
||||||
|
|
||||||
url-parse@^1.4.4:
|
|
||||||
version "1.4.7"
|
|
||||||
resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.4.7.tgz#a8a83535e8c00a316e403a5db4ac1b9b853ae278"
|
|
||||||
integrity sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==
|
|
||||||
dependencies:
|
|
||||||
querystringify "^2.1.1"
|
|
||||||
requires-port "^1.0.0"
|
|
||||||
|
|
||||||
uuid@^3.3.2:
|
|
||||||
version "3.4.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
|
|
||||||
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
|
|
||||||
|
|
||||||
verror@1.10.0:
|
|
||||||
version "1.10.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400"
|
|
||||||
integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=
|
|
||||||
dependencies:
|
|
||||||
assert-plus "^1.0.0"
|
|
||||||
core-util-is "1.0.2"
|
|
||||||
extsprintf "^1.2.0"
|
|
||||||
|
|
||||||
vscode-extension-telemetry@0.1.1:
|
vscode-extension-telemetry@0.1.1:
|
||||||
version "0.1.1"
|
version "0.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.1.tgz#91387e06b33400c57abd48979b0e790415ae110b"
|
resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.1.tgz#91387e06b33400c57abd48979b0e790415ae110b"
|
||||||
@@ -883,32 +475,20 @@ vscode-nls@^4.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-4.0.0.tgz#4001c8a6caba5cedb23a9c5ce1090395c0e44002"
|
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-4.0.0.tgz#4001c8a6caba5cedb23a9c5ce1090395c0e44002"
|
||||||
integrity sha512-qCfdzcH+0LgQnBpZA53bA32kzp9rpq/f66Som577ObeuDlFIrtbEJ+A/+CCxjIh4G8dpJYNCKIsxpRAHIfsbNw==
|
integrity sha512-qCfdzcH+0LgQnBpZA53bA32kzp9rpq/f66Som577ObeuDlFIrtbEJ+A/+CCxjIh4G8dpJYNCKIsxpRAHIfsbNw==
|
||||||
|
|
||||||
vscode-test@^0.4.1:
|
vscode-test@^1.3.0:
|
||||||
version "0.4.3"
|
version "1.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/vscode-test/-/vscode-test-0.4.3.tgz#461ebf25fc4bc93d77d982aed556658a2e2b90b8"
|
resolved "https://registry.yarnpkg.com/vscode-test/-/vscode-test-1.3.0.tgz#3310ab385d9b887b4c82e8f52be1030e7cf9493d"
|
||||||
integrity sha512-EkMGqBSefZH2MgW65nY05rdRSko15uvzq4VAPM5jVmwYuFQKE7eikKXNJDRxL+OITXHB6pI+a3XqqD32Y3KC5w==
|
integrity sha512-LddukcBiSU2FVTDr3c1D8lwkiOvwlJdDL2hqVbn6gIz+rpTqUCkMZSKYm94Y1v0WXlHSDQBsXyY+tchWQgGVsw==
|
||||||
dependencies:
|
dependencies:
|
||||||
http-proxy-agent "^2.1.0"
|
http-proxy-agent "^2.1.0"
|
||||||
https-proxy-agent "^2.2.1"
|
https-proxy-agent "^2.2.4"
|
||||||
|
rimraf "^2.6.3"
|
||||||
|
|
||||||
vscode-uri@^2.0.0:
|
vscode-uri@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-2.0.0.tgz#2df704222f72b8a71ff266ba0830ed6c51ac1542"
|
resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-2.0.0.tgz#2df704222f72b8a71ff266ba0830ed6c51ac1542"
|
||||||
integrity sha512-lWXWofDSYD8r/TIyu64MdwB4FaSirQ608PP/TzUyslyOeHGwQ0eTHUZeJrK1ILOmwUHaJtV693m2JoUYroUDpw==
|
integrity sha512-lWXWofDSYD8r/TIyu64MdwB4FaSirQ608PP/TzUyslyOeHGwQ0eTHUZeJrK1ILOmwUHaJtV693m2JoUYroUDpw==
|
||||||
|
|
||||||
vscode@^1.1.36:
|
|
||||||
version "1.1.36"
|
|
||||||
resolved "https://registry.yarnpkg.com/vscode/-/vscode-1.1.36.tgz#5e1a0d1bf4977d0c7bc5159a9a13d5b104d4b1b6"
|
|
||||||
integrity sha512-cGFh9jmGLcTapCpPCKvn8aG/j9zVQ+0x5hzYJq5h5YyUXVGa1iamOaB2M2PZXoumQPES4qeAP1FwkI0b6tL4bQ==
|
|
||||||
dependencies:
|
|
||||||
glob "^7.1.2"
|
|
||||||
mocha "^5.2.0"
|
|
||||||
request "^2.88.0"
|
|
||||||
semver "^5.4.1"
|
|
||||||
source-map-support "^0.5.0"
|
|
||||||
url-parse "^1.4.4"
|
|
||||||
vscode-test "^0.4.1"
|
|
||||||
|
|
||||||
which@^1.3.0:
|
which@^1.3.0:
|
||||||
version "1.3.0"
|
version "1.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a"
|
resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a"
|
||||||
|
|||||||
@@ -165,7 +165,7 @@
|
|||||||
"opn": "^6.0.0",
|
"opn": "^6.0.0",
|
||||||
"optimist": "0.3.5",
|
"optimist": "0.3.5",
|
||||||
"p-all": "^1.0.0",
|
"p-all": "^1.0.0",
|
||||||
"playwright": "^0.10.0",
|
"playwright": "0.11.0",
|
||||||
"pump": "^1.0.1",
|
"pump": "^1.0.1",
|
||||||
"queue": "3.0.6",
|
"queue": "3.0.6",
|
||||||
"rcedit": "^1.1.0",
|
"rcedit": "^1.1.0",
|
||||||
|
|||||||
@@ -140,6 +140,9 @@ function configureCommandlineSwitchesSync(cliArgs) {
|
|||||||
// provided by Electron
|
// provided by Electron
|
||||||
'disable-color-correct-rendering'
|
'disable-color-correct-rendering'
|
||||||
];
|
];
|
||||||
|
if (process.platform === 'linux') {
|
||||||
|
SUPPORTED_ELECTRON_SWITCHES.push('force-renderer-accessibility');
|
||||||
|
}
|
||||||
|
|
||||||
// Read argv config
|
// Read argv config
|
||||||
const argvConfig = readArgvConfigSync();
|
const argvConfig = readArgvConfigSync();
|
||||||
|
|||||||
@@ -5,6 +5,53 @@
|
|||||||
|
|
||||||
import { pad } from './strings';
|
import { pad } from './strings';
|
||||||
|
|
||||||
|
const minute = 60;
|
||||||
|
const hour = minute * 60;
|
||||||
|
const day = hour * 24;
|
||||||
|
const week = day * 7;
|
||||||
|
const month = day * 30;
|
||||||
|
const year = day * 365;
|
||||||
|
|
||||||
|
// TODO[ECA]: Localize strings
|
||||||
|
export function fromNow(date: number | Date) {
|
||||||
|
if (typeof date !== 'number') {
|
||||||
|
date = date.getTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
const seconds = Math.round((new Date().getTime() - date) / 1000);
|
||||||
|
if (seconds < 30) {
|
||||||
|
return 'now';
|
||||||
|
}
|
||||||
|
|
||||||
|
let value: number;
|
||||||
|
let unit: string;
|
||||||
|
if (seconds < minute) {
|
||||||
|
value = seconds;
|
||||||
|
unit = 'sec';
|
||||||
|
} else if (seconds < hour) {
|
||||||
|
value = Math.floor(seconds / minute);
|
||||||
|
unit = 'min';
|
||||||
|
} else if (seconds < day) {
|
||||||
|
value = Math.floor(seconds / hour);
|
||||||
|
unit = 'hr';
|
||||||
|
} else if (seconds < week) {
|
||||||
|
value = Math.floor(seconds / day);
|
||||||
|
unit = 'day';
|
||||||
|
} else if (seconds < month) {
|
||||||
|
value = Math.floor(seconds / week);
|
||||||
|
unit = 'wk';
|
||||||
|
} else if (seconds < year) {
|
||||||
|
value = Math.floor(seconds / month);
|
||||||
|
unit = 'mo';
|
||||||
|
} else {
|
||||||
|
value = Math.floor(seconds / year);
|
||||||
|
unit = 'yr';
|
||||||
|
}
|
||||||
|
|
||||||
|
return `${value} ${unit}${value === 1 ? '' : 's'}`;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
export function toLocalISOString(date: Date): string {
|
export function toLocalISOString(date: Date): string {
|
||||||
return date.getFullYear() +
|
return date.getFullYear() +
|
||||||
'-' + pad(date.getMonth() + 1, 2) +
|
'-' + pad(date.getMonth() + 1, 2) +
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
import { IWorkbenchConstructionOptions, create, URI, Event, Emitter, UriComponents, ICredentialsProvider, IURLCallbackProvider, IWorkspaceProvider, IWorkspace, IApplicationLinkProvider, IApplicationLink } from 'vs/workbench/workbench.web.api';
|
import { IWorkbenchConstructionOptions, create, URI, Event, Emitter, UriComponents, ICredentialsProvider, IURLCallbackProvider, IWorkspaceProvider, IWorkspace, IApplicationLink } from 'vs/workbench/workbench.web.api';
|
||||||
import { generateUuid } from 'vs/base/common/uuid';
|
import { generateUuid } from 'vs/base/common/uuid';
|
||||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||||
import { streamToBuffer } from 'vs/base/common/buffer';
|
import { streamToBuffer } from 'vs/base/common/buffer';
|
||||||
@@ -279,39 +279,6 @@ class WorkspaceProvider implements IWorkspaceProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ApplicationLinkProvider {
|
|
||||||
|
|
||||||
private links: IApplicationLink[] | undefined = undefined;
|
|
||||||
|
|
||||||
constructor(workspace: IWorkspace) {
|
|
||||||
this.computeLink(workspace);
|
|
||||||
}
|
|
||||||
|
|
||||||
private computeLink(workspace: IWorkspace): void {
|
|
||||||
if (!workspace) {
|
|
||||||
return; // not for empty workspaces
|
|
||||||
}
|
|
||||||
|
|
||||||
const workspaceUri = isWorkspaceToOpen(workspace) ? workspace.workspaceUri : isFolderToOpen(workspace) ? workspace.folderUri : undefined;
|
|
||||||
if (workspaceUri) {
|
|
||||||
this.links = [{
|
|
||||||
uri: URI.from({
|
|
||||||
scheme: product.quality === 'stable' ? 'vscode' : 'vscode-insiders',
|
|
||||||
authority: Schemas.vscodeRemote,
|
|
||||||
path: posix.join(posix.sep, workspaceUri.authority, workspaceUri.path),
|
|
||||||
query: workspaceUri.query,
|
|
||||||
fragment: workspaceUri.fragment,
|
|
||||||
}),
|
|
||||||
label: localize('openInDesktop', "Open in Desktop")
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
get provider(): IApplicationLinkProvider {
|
|
||||||
return () => this.links;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
(function () {
|
(function () {
|
||||||
|
|
||||||
// Find config by checking for DOM
|
// Find config by checking for DOM
|
||||||
@@ -375,12 +342,30 @@ class ApplicationLinkProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Application links ("Open in Desktop")
|
||||||
|
let applicationLinks: IApplicationLink[] | undefined = undefined;
|
||||||
|
if (workspace) {
|
||||||
|
const workspaceUri = isWorkspaceToOpen(workspace) ? workspace.workspaceUri : isFolderToOpen(workspace) ? workspace.folderUri : undefined;
|
||||||
|
if (workspaceUri) {
|
||||||
|
applicationLinks = [{
|
||||||
|
uri: URI.from({
|
||||||
|
scheme: product.quality === 'stable' ? 'vscode' : 'vscode-insiders',
|
||||||
|
authority: Schemas.vscodeRemote,
|
||||||
|
path: posix.join(posix.sep, workspaceUri.authority, workspaceUri.path),
|
||||||
|
query: workspaceUri.query,
|
||||||
|
fragment: workspaceUri.fragment,
|
||||||
|
}),
|
||||||
|
label: localize('openInDesktop', "Open in Desktop")
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Finally create workbench
|
// Finally create workbench
|
||||||
create(document.body, {
|
create(document.body, {
|
||||||
...config,
|
...config,
|
||||||
workspaceProvider: new WorkspaceProvider(workspace, payload),
|
workspaceProvider: new WorkspaceProvider(workspace, payload),
|
||||||
urlCallbackProvider: new PollingURLCallbackProvider(),
|
urlCallbackProvider: new PollingURLCallbackProvider(),
|
||||||
credentialsProvider: new LocalStorageCredentialsProvider(),
|
credentialsProvider: new LocalStorageCredentialsProvider(),
|
||||||
applicationLinkProvider: new ApplicationLinkProvider(workspace).provider
|
applicationLinks: applicationLinks
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -265,6 +265,34 @@ export interface HoverProvider {
|
|||||||
provideHover(model: model.ITextModel, position: Position, token: CancellationToken): ProviderResult<Hover>;
|
provideHover(model: model.ITextModel, position: Position, token: CancellationToken): ProviderResult<Hover>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An evaluatable expression represents additional information for an expression in a document. Evaluatable expression are
|
||||||
|
* evaluated by a debugger or runtime and their result is rendered in a tooltip-like widget.
|
||||||
|
*/
|
||||||
|
export interface EvaluatableExpression {
|
||||||
|
/**
|
||||||
|
* The range to which this expression applies.
|
||||||
|
*/
|
||||||
|
range: IRange;
|
||||||
|
/*
|
||||||
|
* This expression overrides the expression extracted from the range.
|
||||||
|
*/
|
||||||
|
expression?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The hover provider interface defines the contract between extensions and
|
||||||
|
* the [hover](https://code.visualstudio.com/docs/editor/intellisense)-feature.
|
||||||
|
*/
|
||||||
|
export interface EvaluatableExpressionProvider {
|
||||||
|
/**
|
||||||
|
* Provide a hover for the given position and document. Multiple hovers at the same
|
||||||
|
* position will be merged by the editor. A hover can have a range which defaults
|
||||||
|
* to the word range at the position when omitted.
|
||||||
|
*/
|
||||||
|
provideEvaluatableExpression(model: model.ITextModel, position: Position, token: CancellationToken): ProviderResult<EvaluatableExpression>;
|
||||||
|
}
|
||||||
|
|
||||||
export const enum CompletionItemKind {
|
export const enum CompletionItemKind {
|
||||||
Method,
|
Method,
|
||||||
Function,
|
Function,
|
||||||
@@ -1595,6 +1623,11 @@ export const SignatureHelpProviderRegistry = new LanguageFeatureRegistry<Signatu
|
|||||||
*/
|
*/
|
||||||
export const HoverProviderRegistry = new LanguageFeatureRegistry<HoverProvider>();
|
export const HoverProviderRegistry = new LanguageFeatureRegistry<HoverProvider>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
export const EvaluatableExpressionProviderRegistry = new LanguageFeatureRegistry<EvaluatableExpressionProvider>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
|
|||||||
25
src/vs/monaco.d.ts
vendored
25
src/vs/monaco.d.ts
vendored
@@ -5242,6 +5242,31 @@ declare namespace monaco.languages {
|
|||||||
provideHover(model: editor.ITextModel, position: Position, token: CancellationToken): ProviderResult<Hover>;
|
provideHover(model: editor.ITextModel, position: Position, token: CancellationToken): ProviderResult<Hover>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An evaluatable expression represents additional information for an expression in a document. Evaluatable expression are
|
||||||
|
* evaluated by a debugger or runtime and their result is rendered in a tooltip-like widget.
|
||||||
|
*/
|
||||||
|
export interface EvaluatableExpression {
|
||||||
|
/**
|
||||||
|
* The range to which this expression applies.
|
||||||
|
*/
|
||||||
|
range: IRange;
|
||||||
|
expression?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The hover provider interface defines the contract between extensions and
|
||||||
|
* the [hover](https://code.visualstudio.com/docs/editor/intellisense)-feature.
|
||||||
|
*/
|
||||||
|
export interface EvaluatableExpressionProvider {
|
||||||
|
/**
|
||||||
|
* Provide a hover for the given position and document. Multiple hovers at the same
|
||||||
|
* position will be merged by the editor. A hover can have a range which defaults
|
||||||
|
* to the word range at the position when omitted.
|
||||||
|
*/
|
||||||
|
provideEvaluatableExpression(model: editor.ITextModel, position: Position, token: CancellationToken): ProviderResult<EvaluatableExpression>;
|
||||||
|
}
|
||||||
|
|
||||||
export enum CompletionItemKind {
|
export enum CompletionItemKind {
|
||||||
Method = 0,
|
Method = 0,
|
||||||
Function = 1,
|
Function = 1,
|
||||||
|
|||||||
@@ -119,7 +119,9 @@ export class MenuId {
|
|||||||
static readonly DataExplorerContext = new MenuId('DataExplorerContext'); // {{SQL CARBON EDIT}}
|
static readonly DataExplorerContext = new MenuId('DataExplorerContext'); // {{SQL CARBON EDIT}}
|
||||||
static readonly DataExplorerAction = new MenuId('DataExplorerAction'); // {{SQL CARBON EDIT}}
|
static readonly DataExplorerAction = new MenuId('DataExplorerAction'); // {{SQL CARBON EDIT}}
|
||||||
static readonly ExplorerWidgetContext = new MenuId('ExplorerWidgetContext'); // {{SQL CARBON EDIT}}
|
static readonly ExplorerWidgetContext = new MenuId('ExplorerWidgetContext'); // {{SQL CARBON EDIT}}
|
||||||
|
static readonly TimelineItemContext = new MenuId('TimelineItemContext');
|
||||||
|
static readonly TimelineTitle = new MenuId('TimelineTitle');
|
||||||
|
static readonly TimelineTitleContext = new MenuId('TimelineTitleContext');
|
||||||
|
|
||||||
readonly id: number;
|
readonly id: number;
|
||||||
readonly _debugName: string;
|
readonly _debugName: string;
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ export interface IConstructorSignature0<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface IConstructorSignature1<A1, T> {
|
export interface IConstructorSignature1<A1, T> {
|
||||||
new(first: A1, ...services: BrandedService[]): T;
|
new <Services extends BrandedService[]>(first: A1, ...services: Services): T;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IConstructorSignature2<A1, A2, T> {
|
export interface IConstructorSignature2<A1, A2, T> {
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ export class UserDataAutoSyncService extends Disposable implements IUserDataAuto
|
|||||||
async triggerAutoSync(): Promise<void> {
|
async triggerAutoSync(): Promise<void> {
|
||||||
if (this.enabled) {
|
if (this.enabled) {
|
||||||
return this.syncDelayer.trigger(() => {
|
return this.syncDelayer.trigger(() => {
|
||||||
this.logService.info('Auto Sync: Triggerred.');
|
this.logService.info('Auto Sync: Triggered.');
|
||||||
return this.sync(false, true);
|
return this.sync(false, true);
|
||||||
}, this.successiveFailures
|
}, this.successiveFailures
|
||||||
? 1000 * 1 * Math.min(this.successiveFailures, 60) /* Delay by number of seconds as number of failures up to 1 minute */
|
? 1000 * 1 * Math.min(this.successiveFailures, 60) /* Delay by number of seconds as number of failures up to 1 minute */
|
||||||
|
|||||||
99
src/vs/vscode.proposed.d.ts
vendored
99
src/vs/vscode.proposed.d.ts
vendored
@@ -876,7 +876,65 @@ declare module 'vscode' {
|
|||||||
|
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
//#region Debug:
|
//#region locate evaluatable expressions for debug hover: https://github.com/microsoft/vscode/issues/89084
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An EvaluatableExpression represents an expression in a document that can be evaluated by an active debugger or runtime.
|
||||||
|
* The result of this evaluation is shown in a tooltip-like widget.
|
||||||
|
* If only a range is specified, the expression will be extracted from the underlying document.
|
||||||
|
* An optional expression can be used to override the extracted expression.
|
||||||
|
* In this case the range is still used to highlight the range in the document.
|
||||||
|
*/
|
||||||
|
export class EvaluatableExpression {
|
||||||
|
/*
|
||||||
|
* The range is used to extract the evaluatable expression from the underlying document and to highlight it.
|
||||||
|
*/
|
||||||
|
readonly range: Range;
|
||||||
|
/*
|
||||||
|
* If specified the expression overrides the extracted expression.
|
||||||
|
*/
|
||||||
|
readonly expression?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new evaluatable expression object.
|
||||||
|
*
|
||||||
|
* @param range The range in the underlying document from which the evaluatable expression is extracted.
|
||||||
|
* @param expression If specified overrides the extracted expression.
|
||||||
|
*/
|
||||||
|
constructor(range: Range, expression?: string);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The evaluatable expression provider interface defines the contract between extensions and
|
||||||
|
* the debug hover.
|
||||||
|
*/
|
||||||
|
export interface EvaluatableExpressionProvider {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provide an evaluatable expression for the given document and position.
|
||||||
|
* The expression can be implicitly specified by the range in the underlying document or by explicitly returning an expression.
|
||||||
|
*
|
||||||
|
* @param document The document in which the command was invoked.
|
||||||
|
* @param position The position where the command was invoked.
|
||||||
|
* @param token A cancellation token.
|
||||||
|
* @return An EvaluatableExpression or a thenable that resolves to such. The lack of a result can be
|
||||||
|
* signaled by returning `undefined` or `null`.
|
||||||
|
*/
|
||||||
|
provideEvaluatableExpression(document: TextDocument, position: Position, token: CancellationToken): ProviderResult<EvaluatableExpression>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace languages {
|
||||||
|
/**
|
||||||
|
* Register a provider that locates evaluatable expressions in text documents.
|
||||||
|
*
|
||||||
|
* If multiple providers are registered for a language an arbitrary provider will be used.
|
||||||
|
*
|
||||||
|
* @param selector A selector that defines the documents this provider is applicable to.
|
||||||
|
* @param provider An evaluatable expression provider.
|
||||||
|
* @return A [disposable](#Disposable) that unregisters this provider when being disposed.
|
||||||
|
*/
|
||||||
|
export function registerEvaluatableExpressionProvider(selector: DocumentSelector, provider: EvaluatableExpressionProvider): Disposable;
|
||||||
|
}
|
||||||
|
|
||||||
// deprecated
|
// deprecated
|
||||||
|
|
||||||
@@ -1553,6 +1611,40 @@ declare module 'vscode' {
|
|||||||
uri?: Uri;
|
uri?: Uri;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface TimelineCursor {
|
||||||
|
/**
|
||||||
|
* A provider-defined cursor specifing the range of timeline items to be returned. Must be serializable.
|
||||||
|
*/
|
||||||
|
cursor?: any;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A flag to specify whether the timeline items requested are before or after (default) the provided cursor.
|
||||||
|
*/
|
||||||
|
before?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The maximum number of timeline items that should be returned.
|
||||||
|
*/
|
||||||
|
limit?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Timeline {
|
||||||
|
/**
|
||||||
|
* A provider-defined cursor specifing the range of timeline items returned. Must be serializable.
|
||||||
|
*/
|
||||||
|
cursor?: any;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A flag which indicates whether there are any more items that weren't returned.
|
||||||
|
*/
|
||||||
|
more?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An array of [timeline items](#TimelineItem).
|
||||||
|
*/
|
||||||
|
items: TimelineItem[];
|
||||||
|
}
|
||||||
|
|
||||||
export interface TimelineProvider {
|
export interface TimelineProvider {
|
||||||
/**
|
/**
|
||||||
* An optional event to signal that the timeline for a source has changed.
|
* An optional event to signal that the timeline for a source has changed.
|
||||||
@@ -1575,10 +1667,11 @@ declare module 'vscode' {
|
|||||||
*
|
*
|
||||||
* @param uri The [uri](#Uri) of the file to provide the timeline for.
|
* @param uri The [uri](#Uri) of the file to provide the timeline for.
|
||||||
* @param token A cancellation token.
|
* @param token A cancellation token.
|
||||||
* @return An array of timeline items or a thenable that resolves to such. The lack of a result
|
* @param cursor TBD
|
||||||
|
* @return The [timeline result](#TimelineResult) or a thenable that resolves to such. The lack of a result
|
||||||
* can be signaled by returning `undefined`, `null`, or an empty array.
|
* can be signaled by returning `undefined`, `null`, or an empty array.
|
||||||
*/
|
*/
|
||||||
provideTimeline(uri: Uri, token: CancellationToken): ProviderResult<TimelineItem[]>;
|
provideTimeline(uri: Uri, cursor: TimelineCursor, token: CancellationToken): ProviderResult<Timeline>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export namespace workspace {
|
export namespace workspace {
|
||||||
|
|||||||
@@ -213,6 +213,16 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- debug hover
|
||||||
|
|
||||||
|
$registerEvaluatableExpressionProvider(handle: number, selector: IDocumentFilterDto[]): void {
|
||||||
|
this._registrations.set(handle, modes.EvaluatableExpressionProviderRegistry.register(selector, <modes.EvaluatableExpressionProvider>{
|
||||||
|
provideEvaluatableExpression: (model: ITextModel, position: EditorPosition, token: CancellationToken): Promise<modes.EvaluatableExpression | undefined> => {
|
||||||
|
return this._proxy.$provideEvaluatableExpression(handle, model.uri, position, token);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
// --- occurrences
|
// --- occurrences
|
||||||
|
|
||||||
$registerDocumentHighlightProvider(handle: number, selector: IDocumentFilterDto[]): void {
|
$registerDocumentHighlightProvider(handle: number, selector: IDocumentFilterDto[]): void {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import { URI } from 'vs/base/common/uri';
|
|||||||
import { ILogService } from 'vs/platform/log/common/log';
|
import { ILogService } from 'vs/platform/log/common/log';
|
||||||
import { MainContext, MainThreadTimelineShape, IExtHostContext, ExtHostTimelineShape, ExtHostContext } from 'vs/workbench/api/common/extHost.protocol';
|
import { MainContext, MainThreadTimelineShape, IExtHostContext, ExtHostTimelineShape, ExtHostContext } from 'vs/workbench/api/common/extHost.protocol';
|
||||||
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
|
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
|
||||||
import { ITimelineService, TimelineItem, TimelineProviderDescriptor, TimelineChangeEvent } from 'vs/workbench/contrib/timeline/common/timeline';
|
import { TimelineChangeEvent, TimelineCursor, TimelineProviderDescriptor, ITimelineService } from 'vs/workbench/contrib/timeline/common/timeline';
|
||||||
|
|
||||||
@extHostNamedCustomer(MainContext.MainThreadTimeline)
|
@extHostNamedCustomer(MainContext.MainThreadTimeline)
|
||||||
export class MainThreadTimeline implements MainThreadTimelineShape {
|
export class MainThreadTimeline implements MainThreadTimelineShape {
|
||||||
@@ -24,10 +24,6 @@ export class MainThreadTimeline implements MainThreadTimelineShape {
|
|||||||
this._proxy = context.getProxy(ExtHostContext.ExtHostTimeline);
|
this._proxy = context.getProxy(ExtHostContext.ExtHostTimeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
$getTimeline(uri: URI, token: CancellationToken): Promise<TimelineItem[]> {
|
|
||||||
return this._timelineService.getTimeline(uri, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
$registerTimelineProvider(provider: TimelineProviderDescriptor): void {
|
$registerTimelineProvider(provider: TimelineProviderDescriptor): void {
|
||||||
this.logService.trace(`MainThreadTimeline#registerTimelineProvider: id=${provider.id}`);
|
this.logService.trace(`MainThreadTimeline#registerTimelineProvider: id=${provider.id}`);
|
||||||
|
|
||||||
@@ -43,8 +39,8 @@ export class MainThreadTimeline implements MainThreadTimelineShape {
|
|||||||
this._timelineService.registerTimelineProvider({
|
this._timelineService.registerTimelineProvider({
|
||||||
...provider,
|
...provider,
|
||||||
onDidChange: onDidChange.event,
|
onDidChange: onDidChange.event,
|
||||||
provideTimeline(uri: URI, token: CancellationToken) {
|
provideTimeline(uri: URI, cursor: TimelineCursor, token: CancellationToken, options?: { cacheResults?: boolean }) {
|
||||||
return proxy.$getTimeline(provider.id, uri, token);
|
return proxy.$getTimeline(provider.id, uri, cursor, token, options);
|
||||||
},
|
},
|
||||||
dispose() {
|
dispose() {
|
||||||
emitters.delete(provider.id);
|
emitters.delete(provider.id);
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
|||||||
const extHostLabelService = rpcProtocol.set(ExtHostContext.ExtHostLabelService, new ExtHostLabelService(rpcProtocol));
|
const extHostLabelService = rpcProtocol.set(ExtHostContext.ExtHostLabelService, new ExtHostLabelService(rpcProtocol));
|
||||||
const extHostTheming = rpcProtocol.set(ExtHostContext.ExtHostTheming, new ExtHostTheming(rpcProtocol));
|
const extHostTheming = rpcProtocol.set(ExtHostContext.ExtHostTheming, new ExtHostTheming(rpcProtocol));
|
||||||
const extHostAuthentication = rpcProtocol.set(ExtHostContext.ExtHostAuthentication, new ExtHostAuthentication(rpcProtocol));
|
const extHostAuthentication = rpcProtocol.set(ExtHostContext.ExtHostAuthentication, new ExtHostAuthentication(rpcProtocol));
|
||||||
const extHostTimeline = rpcProtocol.set(ExtHostContext.ExtHostTimeline, new ExtHostTimeline(rpcProtocol));
|
const extHostTimeline = rpcProtocol.set(ExtHostContext.ExtHostTimeline, new ExtHostTimeline(rpcProtocol, extHostCommands));
|
||||||
|
|
||||||
// Check that no named customers are missing
|
// Check that no named customers are missing
|
||||||
// {{SQL CARBON EDIT}} filter out the services we don't expose
|
// {{SQL CARBON EDIT}} filter out the services we don't expose
|
||||||
@@ -348,6 +348,9 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
|||||||
registerHoverProvider(selector: vscode.DocumentSelector, provider: vscode.HoverProvider): vscode.Disposable {
|
registerHoverProvider(selector: vscode.DocumentSelector, provider: vscode.HoverProvider): vscode.Disposable {
|
||||||
return extHostLanguageFeatures.registerHoverProvider(extension, checkSelector(selector), provider, extension.identifier);
|
return extHostLanguageFeatures.registerHoverProvider(extension, checkSelector(selector), provider, extension.identifier);
|
||||||
},
|
},
|
||||||
|
registerEvaluatableExpressionProvider(selector: vscode.DocumentSelector, provider: vscode.EvaluatableExpressionProvider): vscode.Disposable {
|
||||||
|
return extHostLanguageFeatures.registerEvaluatableExpressionProvider(extension, checkSelector(selector), provider, extension.identifier);
|
||||||
|
},
|
||||||
registerDocumentHighlightProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentHighlightProvider): vscode.Disposable {
|
registerDocumentHighlightProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentHighlightProvider): vscode.Disposable {
|
||||||
return extHostLanguageFeatures.registerDocumentHighlightProvider(extension, checkSelector(selector), provider);
|
return extHostLanguageFeatures.registerDocumentHighlightProvider(extension, checkSelector(selector), provider);
|
||||||
},
|
},
|
||||||
@@ -928,6 +931,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
|||||||
DocumentLink: extHostTypes.DocumentLink,
|
DocumentLink: extHostTypes.DocumentLink,
|
||||||
DocumentSymbol: extHostTypes.DocumentSymbol,
|
DocumentSymbol: extHostTypes.DocumentSymbol,
|
||||||
EndOfLine: extHostTypes.EndOfLine,
|
EndOfLine: extHostTypes.EndOfLine,
|
||||||
|
EvaluatableExpression: extHostTypes.EvaluatableExpression,
|
||||||
EventEmitter: Emitter,
|
EventEmitter: Emitter,
|
||||||
ExtensionKind: extHostTypes.ExtensionKind,
|
ExtensionKind: extHostTypes.ExtensionKind,
|
||||||
CustomExecution: extHostTypes.CustomExecution,
|
CustomExecution: extHostTypes.CustomExecution,
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ import { SaveReason } from 'vs/workbench/common/editor';
|
|||||||
import { ExtensionActivationReason } from 'vs/workbench/api/common/extHostExtensionActivator';
|
import { ExtensionActivationReason } from 'vs/workbench/api/common/extHostExtensionActivator';
|
||||||
import { TunnelDto } from 'vs/workbench/api/common/extHostTunnelService';
|
import { TunnelDto } from 'vs/workbench/api/common/extHostTunnelService';
|
||||||
import { TunnelOptions } from 'vs/platform/remote/common/tunnel';
|
import { TunnelOptions } from 'vs/platform/remote/common/tunnel';
|
||||||
import { TimelineItem, TimelineProviderDescriptor, TimelineChangeEvent, TimelineItemWithSource } from 'vs/workbench/contrib/timeline/common/timeline';
|
import { Timeline, TimelineChangeEvent, TimelineCursor, TimelineProviderDescriptor } from 'vs/workbench/contrib/timeline/common/timeline';
|
||||||
|
|
||||||
// {{SQL CARBON EDIT}}
|
// {{SQL CARBON EDIT}}
|
||||||
import { ITreeItem as sqlITreeItem } from 'sql/workbench/common/views';
|
import { ITreeItem as sqlITreeItem } from 'sql/workbench/common/views';
|
||||||
@@ -357,6 +357,7 @@ export interface MainThreadLanguageFeaturesShape extends IDisposable {
|
|||||||
$registerImplementationSupport(handle: number, selector: IDocumentFilterDto[]): void;
|
$registerImplementationSupport(handle: number, selector: IDocumentFilterDto[]): void;
|
||||||
$registerTypeDefinitionSupport(handle: number, selector: IDocumentFilterDto[]): void;
|
$registerTypeDefinitionSupport(handle: number, selector: IDocumentFilterDto[]): void;
|
||||||
$registerHoverProvider(handle: number, selector: IDocumentFilterDto[]): void;
|
$registerHoverProvider(handle: number, selector: IDocumentFilterDto[]): void;
|
||||||
|
$registerEvaluatableExpressionProvider(handle: number, selector: IDocumentFilterDto[]): void;
|
||||||
$registerDocumentHighlightProvider(handle: number, selector: IDocumentFilterDto[]): void;
|
$registerDocumentHighlightProvider(handle: number, selector: IDocumentFilterDto[]): void;
|
||||||
$registerReferenceSupport(handle: number, selector: IDocumentFilterDto[]): void;
|
$registerReferenceSupport(handle: number, selector: IDocumentFilterDto[]): void;
|
||||||
$registerQuickFixSupport(handle: number, selector: IDocumentFilterDto[], metadata: ICodeActionProviderMetadataDto): void;
|
$registerQuickFixSupport(handle: number, selector: IDocumentFilterDto[], metadata: ICodeActionProviderMetadataDto): void;
|
||||||
@@ -806,8 +807,6 @@ export interface MainThreadTimelineShape extends IDisposable {
|
|||||||
$registerTimelineProvider(provider: TimelineProviderDescriptor): void;
|
$registerTimelineProvider(provider: TimelineProviderDescriptor): void;
|
||||||
$unregisterTimelineProvider(source: string): void;
|
$unregisterTimelineProvider(source: string): void;
|
||||||
$emitTimelineChangeEvent(e: TimelineChangeEvent): void;
|
$emitTimelineChangeEvent(e: TimelineChangeEvent): void;
|
||||||
|
|
||||||
$getTimeline(uri: UriComponents, token: CancellationToken): Promise<TimelineItem[]>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -- extension host
|
// -- extension host
|
||||||
@@ -1213,6 +1212,7 @@ export interface ExtHostLanguageFeaturesShape {
|
|||||||
$provideImplementation(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<IDefinitionLinkDto[]>;
|
$provideImplementation(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<IDefinitionLinkDto[]>;
|
||||||
$provideTypeDefinition(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<IDefinitionLinkDto[]>;
|
$provideTypeDefinition(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<IDefinitionLinkDto[]>;
|
||||||
$provideHover(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<modes.Hover | undefined>;
|
$provideHover(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<modes.Hover | undefined>;
|
||||||
|
$provideEvaluatableExpression(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<modes.EvaluatableExpression | undefined>;
|
||||||
$provideDocumentHighlights(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<modes.DocumentHighlight[] | undefined>;
|
$provideDocumentHighlights(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<modes.DocumentHighlight[] | undefined>;
|
||||||
$provideReferences(handle: number, resource: UriComponents, position: IPosition, context: modes.ReferenceContext, token: CancellationToken): Promise<ILocationDto[] | undefined>;
|
$provideReferences(handle: number, resource: UriComponents, position: IPosition, context: modes.ReferenceContext, token: CancellationToken): Promise<ILocationDto[] | undefined>;
|
||||||
$provideCodeActions(handle: number, resource: UriComponents, rangeOrSelection: IRange | ISelection, context: modes.CodeActionContext, token: CancellationToken): Promise<ICodeActionListDto | undefined>;
|
$provideCodeActions(handle: number, resource: UriComponents, rangeOrSelection: IRange | ISelection, context: modes.CodeActionContext, token: CancellationToken): Promise<ICodeActionListDto | undefined>;
|
||||||
@@ -1461,7 +1461,7 @@ export interface ExtHostTunnelServiceShape {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface ExtHostTimelineShape {
|
export interface ExtHostTimelineShape {
|
||||||
$getTimeline(source: string, uri: UriComponents, token: CancellationToken): Promise<TimelineItemWithSource[]>;
|
$getTimeline(source: string, uri: UriComponents, cursor: TimelineCursor, token: CancellationToken, options?: { cacheResults?: boolean }): Promise<Timeline | undefined>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- proxy identifiers
|
// --- proxy identifiers
|
||||||
|
|||||||
@@ -276,6 +276,27 @@ class HoverAdapter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class EvaluatableExpressionAdapter {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private readonly _documents: ExtHostDocuments,
|
||||||
|
private readonly _provider: vscode.EvaluatableExpressionProvider,
|
||||||
|
) { }
|
||||||
|
|
||||||
|
public provideEvaluatableExpression(resource: URI, position: IPosition, token: CancellationToken): Promise<modes.EvaluatableExpression | undefined> {
|
||||||
|
|
||||||
|
const doc = this._documents.getDocument(resource);
|
||||||
|
const pos = typeConvert.Position.to(position);
|
||||||
|
|
||||||
|
return asPromise(() => this._provider.provideEvaluatableExpression(doc, pos, token)).then(value => {
|
||||||
|
if (value) {
|
||||||
|
return typeConvert.EvaluatableExpression.from(value);
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class DocumentHighlightAdapter {
|
class DocumentHighlightAdapter {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@@ -1329,7 +1350,7 @@ type Adapter = DocumentSymbolAdapter | CodeLensAdapter | DefinitionAdapter | Hov
|
|||||||
| RangeFormattingAdapter | OnTypeFormattingAdapter | NavigateTypeAdapter | RenameAdapter
|
| RangeFormattingAdapter | OnTypeFormattingAdapter | NavigateTypeAdapter | RenameAdapter
|
||||||
| SuggestAdapter | SignatureHelpAdapter | LinkProviderAdapter | ImplementationAdapter
|
| SuggestAdapter | SignatureHelpAdapter | LinkProviderAdapter | ImplementationAdapter
|
||||||
| TypeDefinitionAdapter | ColorProviderAdapter | FoldingProviderAdapter | DeclarationAdapter
|
| TypeDefinitionAdapter | ColorProviderAdapter | FoldingProviderAdapter | DeclarationAdapter
|
||||||
| SelectionRangeAdapter | CallHierarchyAdapter | DocumentSemanticTokensAdapter | DocumentRangeSemanticTokensAdapter;
|
| SelectionRangeAdapter | CallHierarchyAdapter | DocumentSemanticTokensAdapter | DocumentRangeSemanticTokensAdapter | EvaluatableExpressionAdapter;
|
||||||
|
|
||||||
class AdapterData {
|
class AdapterData {
|
||||||
constructor(
|
constructor(
|
||||||
@@ -1549,6 +1570,18 @@ export class ExtHostLanguageFeatures implements extHostProtocol.ExtHostLanguageF
|
|||||||
return this._withAdapter(handle, HoverAdapter, adapter => adapter.provideHover(URI.revive(resource), position, token), undefined);
|
return this._withAdapter(handle, HoverAdapter, adapter => adapter.provideHover(URI.revive(resource), position, token), undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- debug hover
|
||||||
|
|
||||||
|
registerEvaluatableExpressionProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.EvaluatableExpressionProvider, extensionId?: ExtensionIdentifier): vscode.Disposable {
|
||||||
|
const handle = this._addNewAdapter(new EvaluatableExpressionAdapter(this._documents, provider), extension);
|
||||||
|
this._proxy.$registerEvaluatableExpressionProvider(handle, this._transformDocumentSelector(selector));
|
||||||
|
return this._createDisposable(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
$provideEvaluatableExpression(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<modes.EvaluatableExpression | undefined> {
|
||||||
|
return this._withAdapter(handle, EvaluatableExpressionAdapter, adapter => adapter.provideEvaluatableExpression(URI.revive(resource), position, token), undefined);
|
||||||
|
}
|
||||||
|
|
||||||
// --- occurrences
|
// --- occurrences
|
||||||
|
|
||||||
registerDocumentHighlightProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.DocumentHighlightProvider): vscode.Disposable {
|
registerDocumentHighlightProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.DocumentHighlightProvider): vscode.Disposable {
|
||||||
|
|||||||
@@ -7,61 +7,91 @@ import * as vscode from 'vscode';
|
|||||||
import { UriComponents, URI } from 'vs/base/common/uri';
|
import { UriComponents, URI } from 'vs/base/common/uri';
|
||||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||||
import { ExtHostTimelineShape, MainThreadTimelineShape, IMainContext, MainContext } from 'vs/workbench/api/common/extHost.protocol';
|
import { ExtHostTimelineShape, MainThreadTimelineShape, IMainContext, MainContext } from 'vs/workbench/api/common/extHost.protocol';
|
||||||
import { TimelineItemWithSource, TimelineProvider } from 'vs/workbench/contrib/timeline/common/timeline';
|
import { Timeline, TimelineCursor, TimelineItem, TimelineProvider } from 'vs/workbench/contrib/timeline/common/timeline';
|
||||||
import { IDisposable, toDisposable, DisposableStore } from 'vs/base/common/lifecycle';
|
import { IDisposable, toDisposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||||
import { CommandsConverter } from 'vs/workbench/api/common/extHostCommands';
|
import { CommandsConverter, ExtHostCommands } from 'vs/workbench/api/common/extHostCommands';
|
||||||
import { ThemeIcon } from 'vs/workbench/api/common/extHostTypes';
|
import { ThemeIcon } from 'vs/workbench/api/common/extHostTypes';
|
||||||
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||||
|
|
||||||
export interface IExtHostTimeline extends ExtHostTimelineShape {
|
export interface IExtHostTimeline extends ExtHostTimelineShape {
|
||||||
readonly _serviceBrand: undefined;
|
readonly _serviceBrand: undefined;
|
||||||
$getTimeline(id: string, uri: UriComponents, token: vscode.CancellationToken): Promise<TimelineItemWithSource[]>;
|
$getTimeline(id: string, uri: UriComponents, cursor: vscode.TimelineCursor, token: vscode.CancellationToken, options?: { cacheResults?: boolean }): Promise<Timeline | undefined>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const IExtHostTimeline = createDecorator<IExtHostTimeline>('IExtHostTimeline');
|
export const IExtHostTimeline = createDecorator<IExtHostTimeline>('IExtHostTimeline');
|
||||||
|
|
||||||
export class ExtHostTimeline implements IExtHostTimeline {
|
export class ExtHostTimeline implements IExtHostTimeline {
|
||||||
|
private static handlePool = 0;
|
||||||
|
|
||||||
_serviceBrand: undefined;
|
_serviceBrand: undefined;
|
||||||
|
|
||||||
private _proxy: MainThreadTimelineShape;
|
private _proxy: MainThreadTimelineShape;
|
||||||
|
|
||||||
private _providers = new Map<string, TimelineProvider>();
|
private _providers = new Map<string, TimelineProvider>();
|
||||||
|
|
||||||
|
private _itemsBySourceByUriMap = new Map<string | undefined, Map<string, Map<string, vscode.TimelineItem>>>();
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
mainContext: IMainContext,
|
mainContext: IMainContext,
|
||||||
|
commands: ExtHostCommands,
|
||||||
) {
|
) {
|
||||||
this._proxy = mainContext.getProxy(MainContext.MainThreadTimeline);
|
this._proxy = mainContext.getProxy(MainContext.MainThreadTimeline);
|
||||||
|
|
||||||
|
commands.registerArgumentProcessor({
|
||||||
|
processArgument: arg => {
|
||||||
|
if (arg && arg.$mid === 11) {
|
||||||
|
const uri = arg.uri === undefined ? undefined : URI.revive(arg.uri);
|
||||||
|
return this._itemsBySourceByUriMap.get(getUriKey(uri))?.get(arg.source)?.get(arg.handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
return arg;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async $getTimeline(id: string, uri: UriComponents, token: vscode.CancellationToken): Promise<TimelineItemWithSource[]> {
|
async $getTimeline(id: string, uri: UriComponents, cursor: vscode.TimelineCursor, token: vscode.CancellationToken, options?: { cacheResults?: boolean }): Promise<Timeline | undefined> {
|
||||||
const provider = this._providers.get(id);
|
const provider = this._providers.get(id);
|
||||||
return provider?.provideTimeline(URI.revive(uri), token) ?? [];
|
return provider?.provideTimeline(URI.revive(uri), cursor, token, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
registerTimelineProvider(scheme: string | string[], provider: vscode.TimelineProvider, extensionId: ExtensionIdentifier, commandConverter: CommandsConverter): IDisposable {
|
registerTimelineProvider(scheme: string | string[], provider: vscode.TimelineProvider, _extensionId: ExtensionIdentifier, commandConverter: CommandsConverter): IDisposable {
|
||||||
const timelineDisposables = new DisposableStore();
|
const timelineDisposables = new DisposableStore();
|
||||||
|
|
||||||
const convertTimelineItem = this.convertTimelineItem(provider.id, commandConverter, timelineDisposables);
|
const convertTimelineItem = this.convertTimelineItem(provider.id, commandConverter, timelineDisposables).bind(this);
|
||||||
|
|
||||||
let disposable: IDisposable | undefined;
|
let disposable: IDisposable | undefined;
|
||||||
if (provider.onDidChange) {
|
if (provider.onDidChange) {
|
||||||
disposable = provider.onDidChange(this.emitTimelineChangeEvent(provider.id), this);
|
disposable = provider.onDidChange(this.emitTimelineChangeEvent(provider.id), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const itemsBySourceByUriMap = this._itemsBySourceByUriMap;
|
||||||
return this.registerTimelineProviderCore({
|
return this.registerTimelineProviderCore({
|
||||||
...provider,
|
...provider,
|
||||||
scheme: scheme,
|
scheme: scheme,
|
||||||
onDidChange: undefined,
|
onDidChange: undefined,
|
||||||
async provideTimeline(uri: URI, token: CancellationToken) {
|
async provideTimeline(uri: URI, cursor: TimelineCursor, token: CancellationToken, options?: { cacheResults?: boolean }) {
|
||||||
timelineDisposables.clear();
|
timelineDisposables.clear();
|
||||||
|
|
||||||
const results = await provider.provideTimeline(uri, token);
|
// For now, only allow the caching of a single Uri
|
||||||
|
if (options?.cacheResults && !itemsBySourceByUriMap.has(getUriKey(uri))) {
|
||||||
|
itemsBySourceByUriMap.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await provider.provideTimeline(uri, cursor, token);
|
||||||
// Intentional == we don't know how a provider will respond
|
// Intentional == we don't know how a provider will respond
|
||||||
// eslint-disable-next-line eqeqeq
|
// eslint-disable-next-line eqeqeq
|
||||||
return results != null
|
if (result == null) {
|
||||||
? results.map(item => convertTimelineItem(item))
|
return undefined;
|
||||||
: [];
|
}
|
||||||
|
|
||||||
|
// TODO: Determine if we should cache dependent on who calls us (internal vs external)
|
||||||
|
const convertItem = convertTimelineItem(uri, options?.cacheResults ?? false);
|
||||||
|
return {
|
||||||
|
...result,
|
||||||
|
source: provider.id,
|
||||||
|
items: result.items.map(convertItem)
|
||||||
|
};
|
||||||
},
|
},
|
||||||
dispose() {
|
dispose() {
|
||||||
disposable?.dispose();
|
disposable?.dispose();
|
||||||
@@ -70,39 +100,72 @@ export class ExtHostTimeline implements IExtHostTimeline {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private convertTimelineItem(source: string, commandConverter: CommandsConverter, disposables: DisposableStore): (item: vscode.TimelineItem) => TimelineItemWithSource {
|
private convertTimelineItem(source: string, commandConverter: CommandsConverter, disposables: DisposableStore) {
|
||||||
return (item: vscode.TimelineItem) => {
|
return (uri: URI, cacheResults: boolean) => {
|
||||||
const { iconPath, ...props } = item;
|
let itemsMap: Map<string, vscode.TimelineItem> | undefined;
|
||||||
|
if (cacheResults) {
|
||||||
|
const uriKey = getUriKey(uri);
|
||||||
|
|
||||||
let icon;
|
let sourceMap = this._itemsBySourceByUriMap.get(uriKey);
|
||||||
let iconDark;
|
if (sourceMap === undefined) {
|
||||||
let themeIcon;
|
sourceMap = new Map();
|
||||||
if (item.iconPath) {
|
this._itemsBySourceByUriMap.set(uriKey, sourceMap);
|
||||||
if (iconPath instanceof ThemeIcon) {
|
|
||||||
themeIcon = { id: iconPath.id };
|
|
||||||
}
|
}
|
||||||
else if (URI.isUri(iconPath)) {
|
|
||||||
icon = iconPath;
|
itemsMap = sourceMap.get(source);
|
||||||
iconDark = iconPath;
|
if (itemsMap === undefined) {
|
||||||
}
|
itemsMap = new Map();
|
||||||
else {
|
sourceMap.set(source, itemsMap);
|
||||||
({ light: icon, dark: iconDark } = iconPath as { light: URI; dark: URI });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return (item: vscode.TimelineItem): TimelineItem => {
|
||||||
...props,
|
const { iconPath, ...props } = item;
|
||||||
source: source,
|
|
||||||
command: item.command ? commandConverter.toInternal(item.command, disposables) : undefined,
|
const handle = `${source}|${item.id ?? `${item.timestamp}-${ExtHostTimeline.handlePool++}`}`;
|
||||||
icon: icon,
|
itemsMap?.set(handle, item);
|
||||||
iconDark: iconDark,
|
|
||||||
themeIcon: themeIcon
|
let icon;
|
||||||
|
let iconDark;
|
||||||
|
let themeIcon;
|
||||||
|
if (item.iconPath) {
|
||||||
|
if (iconPath instanceof ThemeIcon) {
|
||||||
|
themeIcon = { id: iconPath.id };
|
||||||
|
}
|
||||||
|
else if (URI.isUri(iconPath)) {
|
||||||
|
icon = iconPath;
|
||||||
|
iconDark = iconPath;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
({ light: icon, dark: iconDark } = iconPath as { light: URI; dark: URI });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
...props,
|
||||||
|
handle: handle,
|
||||||
|
source: source,
|
||||||
|
command: item.command ? commandConverter.toInternal(item.command, disposables) : undefined,
|
||||||
|
icon: icon,
|
||||||
|
iconDark: iconDark,
|
||||||
|
themeIcon: themeIcon
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private emitTimelineChangeEvent(id: string) {
|
private emitTimelineChangeEvent(id: string) {
|
||||||
return (e: vscode.TimelineChangeEvent) => {
|
return (e: vscode.TimelineChangeEvent) => {
|
||||||
|
// Clear caches
|
||||||
|
if (e?.uri === undefined) {
|
||||||
|
for (const sourceMap of this._itemsBySourceByUriMap.values()) {
|
||||||
|
sourceMap.get(id)?.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this._itemsBySourceByUriMap.get(getUriKey(e.uri))?.clear();
|
||||||
|
}
|
||||||
|
|
||||||
this._proxy.$emitTimelineChangeEvent({ ...e, id: id });
|
this._proxy.$emitTimelineChangeEvent({ ...e, id: id });
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -123,9 +186,18 @@ export class ExtHostTimeline implements IExtHostTimeline {
|
|||||||
this._providers.set(provider.id, provider);
|
this._providers.set(provider.id, provider);
|
||||||
|
|
||||||
return toDisposable(() => {
|
return toDisposable(() => {
|
||||||
|
for (const sourceMap of this._itemsBySourceByUriMap.values()) {
|
||||||
|
sourceMap.get(provider.id)?.clear();
|
||||||
|
}
|
||||||
|
|
||||||
this._providers.delete(provider.id);
|
this._providers.delete(provider.id);
|
||||||
this._proxy.$unregisterTimelineProvider(provider.id);
|
this._proxy.$unregisterTimelineProvider(provider.id);
|
||||||
provider.dispose();
|
provider.dispose();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getUriKey(uri: URI | undefined): string | undefined {
|
||||||
|
return uri?.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -257,7 +257,7 @@ export namespace MarkdownString {
|
|||||||
} else if (htmlContent.isMarkdownString(markup)) {
|
} else if (htmlContent.isMarkdownString(markup)) {
|
||||||
res = markup;
|
res = markup;
|
||||||
} else if (typeof markup === 'string') {
|
} else if (typeof markup === 'string') {
|
||||||
res = { value: <string>markup };
|
res = { value: markup };
|
||||||
} else {
|
} else {
|
||||||
res = { value: '' };
|
res = { value: '' };
|
||||||
}
|
}
|
||||||
@@ -737,6 +737,20 @@ export namespace Hover {
|
|||||||
return new types.Hover(info.contents.map(MarkdownString.to), Range.to(info.range));
|
return new types.Hover(info.contents.map(MarkdownString.to), Range.to(info.range));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export namespace EvaluatableExpression {
|
||||||
|
export function from(expression: vscode.EvaluatableExpression): modes.EvaluatableExpression {
|
||||||
|
return <modes.EvaluatableExpression>{
|
||||||
|
range: Range.from(expression.range),
|
||||||
|
expression: expression.expression
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function to(info: modes.EvaluatableExpression): types.EvaluatableExpression {
|
||||||
|
return new types.EvaluatableExpression(Range.to(info.range), info.expression);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export namespace DocumentHighlight {
|
export namespace DocumentHighlight {
|
||||||
export function from(documentHighlight: vscode.DocumentHighlight): modes.DocumentHighlight {
|
export function from(documentHighlight: vscode.DocumentHighlight): modes.DocumentHighlight {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -2283,6 +2283,17 @@ export class DebugAdapterInlineImplementation implements vscode.DebugAdapterInli
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@es5ClassCompat
|
||||||
|
export class EvaluatableExpression implements vscode.EvaluatableExpression {
|
||||||
|
readonly range: vscode.Range;
|
||||||
|
readonly expression?: string;
|
||||||
|
|
||||||
|
constructor(range: vscode.Range, expression?: string) {
|
||||||
|
this.range = range;
|
||||||
|
this.expression = expression;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export enum LogLevel {
|
export enum LogLevel {
|
||||||
Trace = 1,
|
Trace = 1,
|
||||||
Debug = 2,
|
Debug = 2,
|
||||||
|
|||||||
@@ -57,6 +57,8 @@ namespace schema {
|
|||||||
case 'comments/comment/title': return MenuId.CommentTitle;
|
case 'comments/comment/title': return MenuId.CommentTitle;
|
||||||
case 'comments/comment/context': return MenuId.CommentActions;
|
case 'comments/comment/context': return MenuId.CommentActions;
|
||||||
case 'extension/context': return MenuId.ExtensionContext;
|
case 'extension/context': return MenuId.ExtensionContext;
|
||||||
|
case 'timeline/title': return MenuId.TimelineTitle;
|
||||||
|
case 'timeline/item/context': return MenuId.TimelineItemContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
return undefined;
|
return undefined;
|
||||||
@@ -220,6 +222,16 @@ namespace schema {
|
|||||||
type: 'array',
|
type: 'array',
|
||||||
items: menuItem
|
items: menuItem
|
||||||
},
|
},
|
||||||
|
'timeline/title': {
|
||||||
|
description: localize('view.timelineTitle', "The Timeline view title menu"),
|
||||||
|
type: 'array',
|
||||||
|
items: menuItem
|
||||||
|
},
|
||||||
|
'timeline/item/context': {
|
||||||
|
description: localize('view.timelineContext', "The Timeline view item context menu"),
|
||||||
|
type: 'array',
|
||||||
|
items: menuItem
|
||||||
|
},
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
|||||||
|
|
||||||
//#region IView
|
//#region IView
|
||||||
|
|
||||||
readonly minimumWidth: number = 420;
|
readonly minimumWidth: number = 300;
|
||||||
readonly maximumWidth: number = Number.POSITIVE_INFINITY;
|
readonly maximumWidth: number = Number.POSITIVE_INFINITY;
|
||||||
readonly minimumHeight: number = 77;
|
readonly minimumHeight: number = 77;
|
||||||
readonly maximumHeight: number = Number.POSITIVE_INFINITY;
|
readonly maximumHeight: number = Number.POSITIVE_INFINITY;
|
||||||
|
|||||||
@@ -57,12 +57,12 @@ export interface IViewContainerDescriptor {
|
|||||||
|
|
||||||
export interface IViewContainersRegistry {
|
export interface IViewContainersRegistry {
|
||||||
/**
|
/**
|
||||||
* An event that is triggerred when a view container is registered.
|
* An event that is triggered when a view container is registered.
|
||||||
*/
|
*/
|
||||||
readonly onDidRegister: Event<{ viewContainer: ViewContainer, viewContainerLocation: ViewContainerLocation }>;
|
readonly onDidRegister: Event<{ viewContainer: ViewContainer, viewContainerLocation: ViewContainerLocation }>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An event that is triggerred when a view container is deregistered.
|
* An event that is triggered when a view container is deregistered.
|
||||||
*/
|
*/
|
||||||
readonly onDidDeregister: Event<{ viewContainer: ViewContainer, viewContainerLocation: ViewContainerLocation }>;
|
readonly onDidDeregister: Event<{ viewContainer: ViewContainer, viewContainerLocation: ViewContainerLocation }>;
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
import 'vs/css!./bulkEdit';
|
import 'vs/css!./bulkEdit';
|
||||||
import { WorkbenchAsyncDataTree, TreeResourceNavigator, IOpenEvent } from 'vs/platform/list/browser/listService';
|
import { WorkbenchAsyncDataTree, TreeResourceNavigator, IOpenEvent } from 'vs/platform/list/browser/listService';
|
||||||
import { WorkspaceEdit } from 'vs/editor/common/modes';
|
import { WorkspaceEdit } from 'vs/editor/common/modes';
|
||||||
import { BulkEditElement, BulkEditDelegate, TextEditElementRenderer, FileElementRenderer, BulkEditDataSource, BulkEditIdentityProvider, FileElement, TextEditElement, BulkEditAccessibilityProvider, BulkEditAriaProvider, CategoryElementRenderer, BulkEditNaviLabelProvider, CategoryElement } from 'vs/workbench/contrib/bulkEdit/browser/bulkEditTree';
|
import { BulkEditElement, BulkEditDelegate, TextEditElementRenderer, FileElementRenderer, BulkEditDataSource, BulkEditIdentityProvider, FileElement, TextEditElement, BulkEditAccessibilityProvider, BulkEditAriaProvider, CategoryElementRenderer, BulkEditNaviLabelProvider, CategoryElement, BulkEditSorter } from 'vs/workbench/contrib/bulkEdit/browser/bulkEditTree';
|
||||||
import { FuzzyScore } from 'vs/base/common/filters';
|
import { FuzzyScore } from 'vs/base/common/filters';
|
||||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
import { registerThemingParticipant, ITheme, ICssStyleCollector, IThemeService } from 'vs/platform/theme/common/themeService';
|
import { registerThemingParticipant, ITheme, ICssStyleCollector, IThemeService } from 'vs/platform/theme/common/themeService';
|
||||||
@@ -135,6 +135,7 @@ export class BulkEditPane extends ViewPane {
|
|||||||
expandOnlyOnTwistieClick: true,
|
expandOnlyOnTwistieClick: true,
|
||||||
multipleSelectionSupport: false,
|
multipleSelectionSupport: false,
|
||||||
keyboardNavigationLabelProvider: new BulkEditNaviLabelProvider(),
|
keyboardNavigationLabelProvider: new BulkEditNaviLabelProvider(),
|
||||||
|
sorter: new BulkEditSorter()
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -99,6 +99,15 @@ export class BulkFileOperation {
|
|||||||
this.newUri = edit.newUri;
|
this.newUri = edit.newUri;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
needsConfirmation(): boolean {
|
||||||
|
for (let [, edit] of this.originalEdits) {
|
||||||
|
if (!this.parent.checked.isChecked(edit)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class BulkCategory {
|
export class BulkCategory {
|
||||||
@@ -230,7 +239,7 @@ export class BulkFileOperations {
|
|||||||
}
|
}
|
||||||
|
|
||||||
operationByResource.forEach(value => this.fileOperations.push(value));
|
operationByResource.forEach(value => this.fileOperations.push(value));
|
||||||
operationByCategory.forEach(value => value.metadata.needsConfirmation ? this.categories.unshift(value) : this.categories.push(value));
|
operationByCategory.forEach(value => this.categories.push(value));
|
||||||
|
|
||||||
// "correct" invalid parent-check child states that is
|
// "correct" invalid parent-check child states that is
|
||||||
// unchecked file edits (rename, create, delete) uncheck
|
// unchecked file edits (rename, create, delete) uncheck
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
import { IAsyncDataSource, ITreeRenderer, ITreeNode } from 'vs/base/browser/ui/tree/tree';
|
import { IAsyncDataSource, ITreeRenderer, ITreeNode, ITreeSorter } from 'vs/base/browser/ui/tree/tree';
|
||||||
import { ITextModelService } from 'vs/editor/common/services/resolverService';
|
import { ITextModelService } from 'vs/editor/common/services/resolverService';
|
||||||
import { FuzzyScore, createMatches } from 'vs/base/common/filters';
|
import { FuzzyScore, createMatches } from 'vs/base/common/filters';
|
||||||
import { IResourceLabel, ResourceLabels } from 'vs/workbench/browser/labels';
|
import { IResourceLabel, ResourceLabels } from 'vs/workbench/browser/labels';
|
||||||
@@ -24,6 +24,7 @@ import { IconLabel } from 'vs/base/browser/ui/iconLabel/iconLabel';
|
|||||||
import { basename } from 'vs/base/common/resources';
|
import { basename } from 'vs/base/common/resources';
|
||||||
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
|
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
|
||||||
import { WorkspaceFileEdit } from 'vs/editor/common/modes';
|
import { WorkspaceFileEdit } from 'vs/editor/common/modes';
|
||||||
|
import { compare } from 'vs/base/common/strings';
|
||||||
|
|
||||||
// --- VIEW MODEL
|
// --- VIEW MODEL
|
||||||
|
|
||||||
@@ -248,6 +249,39 @@ export class BulkEditDataSource implements IAsyncDataSource<BulkFileOperations,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export class BulkEditSorter implements ITreeSorter<BulkEditElement> {
|
||||||
|
|
||||||
|
compare(a: BulkEditElement, b: BulkEditElement): number {
|
||||||
|
if (a instanceof CategoryElement && b instanceof CategoryElement) {
|
||||||
|
//
|
||||||
|
const aConfirm = BulkEditSorter._needsConfirmation(a.category);
|
||||||
|
const bConfirm = BulkEditSorter._needsConfirmation(b.category);
|
||||||
|
if (aConfirm === bConfirm) {
|
||||||
|
return a.category.metadata.label.localeCompare(b.category.metadata.label);
|
||||||
|
} else if (aConfirm) {
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a instanceof FileElement && b instanceof FileElement) {
|
||||||
|
return compare(a.edit.uri.toString(), b.edit.uri.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a instanceof TextEditElement && b instanceof TextEditElement) {
|
||||||
|
return Range.compareRangesUsingStarts(a.edit.textEdit.edit.range, b.edit.textEdit.edit.range);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static _needsConfirmation(a: BulkCategory): boolean {
|
||||||
|
return a.fileOperations.some(ops => ops.needsConfirmation());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// --- ACCESSI
|
// --- ACCESSI
|
||||||
|
|
||||||
export class BulkEditAccessibilityProvider implements IAccessibilityProvider<BulkEditElement> {
|
export class BulkEditAccessibilityProvider implements IAccessibilityProvider<BulkEditElement> {
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ CommandsRegistry.registerCommand('_workbench.openWith', (accessor: ServicesAcces
|
|||||||
// #region Reopen With
|
// #region Reopen With
|
||||||
|
|
||||||
const REOPEN_WITH_COMMAND_ID = 'reOpenWith';
|
const REOPEN_WITH_COMMAND_ID = 'reOpenWith';
|
||||||
const REOPEN_WITH_TITLE = { value: nls.localize('reopenWith.title', 'Reopen With'), original: 'Reopen With' };
|
const REOPEN_WITH_TITLE = { value: nls.localize('reopenWith.title', 'Reopen With...'), original: 'Reopen With' };
|
||||||
|
|
||||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||||
id: REOPEN_WITH_COMMAND_ID,
|
id: REOPEN_WITH_COMMAND_ID,
|
||||||
@@ -83,6 +83,17 @@ MenuRegistry.appendMenuItem(MenuId.CommandPalette, {
|
|||||||
when: CONTEXT_HAS_CUSTOM_EDITORS,
|
when: CONTEXT_HAS_CUSTOM_EDITORS,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
MenuRegistry.appendMenuItem(MenuId.EditorTitle, {
|
||||||
|
command: {
|
||||||
|
id: REOPEN_WITH_COMMAND_ID,
|
||||||
|
title: REOPEN_WITH_TITLE,
|
||||||
|
category: viewCategory,
|
||||||
|
},
|
||||||
|
group: '3_open',
|
||||||
|
order: 20,
|
||||||
|
when: CONTEXT_HAS_CUSTOM_EDITORS,
|
||||||
|
});
|
||||||
|
|
||||||
// #endregion
|
// #endregion
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ import { FuzzyScore, createMatches } from 'vs/base/common/filters';
|
|||||||
import { LinkDetector } from 'vs/workbench/contrib/debug/browser/linkDetector';
|
import { LinkDetector } from 'vs/workbench/contrib/debug/browser/linkDetector';
|
||||||
import { ReplEvaluationResult } from 'vs/workbench/contrib/debug/common/replModel';
|
import { ReplEvaluationResult } from 'vs/workbench/contrib/debug/common/replModel';
|
||||||
import { once } from 'vs/base/common/functional';
|
import { once } from 'vs/base/common/functional';
|
||||||
import { ViewPane } from 'vs/workbench/browser/parts/views/viewPaneContainer';
|
|
||||||
|
|
||||||
export const MAX_VALUE_RENDER_LENGTH_IN_VIEWLET = 1024;
|
export const MAX_VALUE_RENDER_LENGTH_IN_VIEWLET = 1024;
|
||||||
export const twistiePixels = 20;
|
export const twistiePixels = 20;
|
||||||
@@ -233,11 +232,3 @@ export abstract class AbstractExpressionsRenderer implements ITreeRenderer<IExpr
|
|||||||
templateData.toDispose.dispose();
|
templateData.toDispose.dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export abstract class BaseDebugViewPane extends ViewPane {
|
|
||||||
|
|
||||||
render(): void {
|
|
||||||
super.render();
|
|
||||||
dom.addClass(this.element, 'debug-pane');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -28,14 +28,13 @@ import { attachInputBoxStyler } from 'vs/platform/theme/common/styler';
|
|||||||
import { isCodeEditor } from 'vs/editor/browser/editorBrowser';
|
import { isCodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||||
import { IEditorService, SIDE_GROUP, ACTIVE_GROUP } from 'vs/workbench/services/editor/common/editorService';
|
import { IEditorService, SIDE_GROUP, ACTIVE_GROUP } from 'vs/workbench/services/editor/common/editorService';
|
||||||
import { IViewPaneOptions } from 'vs/workbench/browser/parts/views/viewPaneContainer';
|
import { IViewPaneOptions, ViewPane } from 'vs/workbench/browser/parts/views/viewPaneContainer';
|
||||||
import { ILabelService } from 'vs/platform/label/common/label';
|
import { ILabelService } from 'vs/platform/label/common/label';
|
||||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||||
import { Gesture } from 'vs/base/browser/touch';
|
import { Gesture } from 'vs/base/browser/touch';
|
||||||
import { IViewDescriptorService } from 'vs/workbench/common/views';
|
import { IViewDescriptorService } from 'vs/workbench/common/views';
|
||||||
import { TextEditorSelectionRevealType } from 'vs/platform/editor/common/editor';
|
import { TextEditorSelectionRevealType } from 'vs/platform/editor/common/editor';
|
||||||
import { IOpenerService } from 'vs/platform/opener/common/opener';
|
import { IOpenerService } from 'vs/platform/opener/common/opener';
|
||||||
import { BaseDebugViewPane } from 'vs/workbench/contrib/debug/browser/baseDebugView';
|
|
||||||
|
|
||||||
const $ = dom.$;
|
const $ = dom.$;
|
||||||
|
|
||||||
@@ -54,7 +53,7 @@ export function getExpandedBodySize(model: IDebugModel): number {
|
|||||||
return Math.min(MAX_VISIBLE_BREAKPOINTS, length) * 22;
|
return Math.min(MAX_VISIBLE_BREAKPOINTS, length) * 22;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class BreakpointsView extends BaseDebugViewPane {
|
export class BreakpointsView extends ViewPane {
|
||||||
|
|
||||||
private list!: WorkbenchList<IEnablement>;
|
private list!: WorkbenchList<IEnablement>;
|
||||||
private needsRefresh = false;
|
private needsRefresh = false;
|
||||||
@@ -82,6 +81,7 @@ export class BreakpointsView extends BaseDebugViewPane {
|
|||||||
public renderBody(container: HTMLElement): void {
|
public renderBody(container: HTMLElement): void {
|
||||||
super.renderBody(container);
|
super.renderBody(container);
|
||||||
|
|
||||||
|
dom.addClass(this.element, 'debug-pane');
|
||||||
dom.addClass(container, 'debug-breakpoints');
|
dom.addClass(container, 'debug-breakpoints');
|
||||||
const delegate = new BreakpointsDelegate(this.debugService);
|
const delegate = new BreakpointsDelegate(this.debugService);
|
||||||
|
|
||||||
|
|||||||
@@ -13,12 +13,12 @@ import { IContextMenuService } from 'vs/platform/contextview/browser/contextView
|
|||||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
import { MenuId, IMenu, IMenuService } from 'vs/platform/actions/common/actions';
|
import { MenuId, IMenu, IMenuService } from 'vs/platform/actions/common/actions';
|
||||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||||
import { renderViewTree, BaseDebugViewPane } from 'vs/workbench/contrib/debug/browser/baseDebugView';
|
import { renderViewTree } from 'vs/workbench/contrib/debug/browser/baseDebugView';
|
||||||
import { IAction, Action } from 'vs/base/common/actions';
|
import { IAction, Action } from 'vs/base/common/actions';
|
||||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||||
import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||||
import { IViewPaneOptions } from 'vs/workbench/browser/parts/views/viewPaneContainer';
|
import { IViewPaneOptions, ViewPane } from 'vs/workbench/browser/parts/views/viewPaneContainer';
|
||||||
import { ILabelService } from 'vs/platform/label/common/label';
|
import { ILabelService } from 'vs/platform/label/common/label';
|
||||||
import { IAccessibilityProvider } from 'vs/base/browser/ui/list/listWidget';
|
import { IAccessibilityProvider } from 'vs/base/browser/ui/list/listWidget';
|
||||||
import { createAndFillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
|
import { createAndFillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
|
||||||
@@ -74,7 +74,7 @@ export function getContextForContributedActions(element: CallStackItem | null):
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
export class CallStackView extends BaseDebugViewPane {
|
export class CallStackView extends ViewPane {
|
||||||
private pauseMessage!: HTMLSpanElement;
|
private pauseMessage!: HTMLSpanElement;
|
||||||
private pauseMessageLabel!: HTMLSpanElement;
|
private pauseMessageLabel!: HTMLSpanElement;
|
||||||
private onCallStackChangeScheduler: RunOnceScheduler;
|
private onCallStackChangeScheduler: RunOnceScheduler;
|
||||||
@@ -158,7 +158,7 @@ export class CallStackView extends BaseDebugViewPane {
|
|||||||
|
|
||||||
renderBody(container: HTMLElement): void {
|
renderBody(container: HTMLElement): void {
|
||||||
super.renderBody(container);
|
super.renderBody(container);
|
||||||
|
dom.addClass(this.element, 'debug-pane');
|
||||||
dom.addClass(container, 'debug-call-stack');
|
dom.addClass(container, 'debug-call-stack');
|
||||||
const treeContainer = renderViewTree(container);
|
const treeContainer = renderViewTree(container);
|
||||||
|
|
||||||
|
|||||||
@@ -136,17 +136,19 @@ function getWordToLineNumbersMap(model: ITextModel | null): Map<string, number[]
|
|||||||
model.forceTokenization(lineNumber);
|
model.forceTokenization(lineNumber);
|
||||||
const lineTokens = model.getLineTokens(lineNumber);
|
const lineTokens = model.getLineTokens(lineNumber);
|
||||||
for (let tokenIndex = 0, tokenCount = lineTokens.getCount(); tokenIndex < tokenCount; tokenIndex++) {
|
for (let tokenIndex = 0, tokenCount = lineTokens.getCount(); tokenIndex < tokenCount; tokenIndex++) {
|
||||||
const tokenStartOffset = lineTokens.getStartOffset(tokenIndex);
|
|
||||||
const tokenEndOffset = lineTokens.getEndOffset(tokenIndex);
|
|
||||||
const tokenType = lineTokens.getStandardTokenType(tokenIndex);
|
const tokenType = lineTokens.getStandardTokenType(tokenIndex);
|
||||||
const tokenStr = lineContent.substring(tokenStartOffset, tokenEndOffset);
|
|
||||||
|
|
||||||
// Token is a word and not a comment
|
// Token is a word and not a comment
|
||||||
if (tokenType === StandardTokenType.Other) {
|
if (tokenType === StandardTokenType.Other) {
|
||||||
DEFAULT_WORD_REGEXP.lastIndex = 0; // We assume tokens will usually map 1:1 to words if they match
|
DEFAULT_WORD_REGEXP.lastIndex = 0; // We assume tokens will usually map 1:1 to words if they match
|
||||||
|
|
||||||
|
const tokenStartOffset = lineTokens.getStartOffset(tokenIndex);
|
||||||
|
const tokenEndOffset = lineTokens.getEndOffset(tokenIndex);
|
||||||
|
const tokenStr = lineContent.substring(tokenStartOffset, tokenEndOffset);
|
||||||
const wordMatch = DEFAULT_WORD_REGEXP.exec(tokenStr);
|
const wordMatch = DEFAULT_WORD_REGEXP.exec(tokenStr);
|
||||||
|
|
||||||
if (wordMatch) {
|
if (wordMatch) {
|
||||||
|
|
||||||
const word = wordMatch[0];
|
const word = wordMatch[0];
|
||||||
if (!result.has(word)) {
|
if (!result.has(word)) {
|
||||||
result.set(word, []);
|
result.set(word, []);
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import * as dom from 'vs/base/browser/dom';
|
|||||||
import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||||
import { ConfigurationChangedEvent, EditorOption } from 'vs/editor/common/config/editorOptions';
|
import { ConfigurationChangedEvent, EditorOption } from 'vs/editor/common/config/editorOptions';
|
||||||
import { Position } from 'vs/editor/common/core/position';
|
import { Position } from 'vs/editor/common/core/position';
|
||||||
import { Range } from 'vs/editor/common/core/range';
|
import { Range, IRange } from 'vs/editor/common/core/range';
|
||||||
import { IContentWidget, ICodeEditor, IContentWidgetPosition, ContentWidgetPositionPreference } from 'vs/editor/browser/editorBrowser';
|
import { IContentWidget, ICodeEditor, IContentWidgetPosition, ContentWidgetPositionPreference } from 'vs/editor/browser/editorBrowser';
|
||||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
import { IDebugService, IExpression, IExpressionContainer, IStackFrame } from 'vs/workbench/contrib/debug/common/debug';
|
import { IDebugService, IExpression, IExpressionContainer, IStackFrame } from 'vs/workbench/contrib/debug/common/debug';
|
||||||
@@ -30,6 +30,8 @@ import { WorkbenchAsyncDataTree } from 'vs/platform/list/browser/listService';
|
|||||||
import { coalesce } from 'vs/base/common/arrays';
|
import { coalesce } from 'vs/base/common/arrays';
|
||||||
import { IAsyncDataSource } from 'vs/base/browser/ui/tree/tree';
|
import { IAsyncDataSource } from 'vs/base/browser/ui/tree/tree';
|
||||||
import { VariablesRenderer } from 'vs/workbench/contrib/debug/browser/variablesView';
|
import { VariablesRenderer } from 'vs/workbench/contrib/debug/browser/variablesView';
|
||||||
|
import { EvaluatableExpressionProviderRegistry } from 'vs/editor/common/modes';
|
||||||
|
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||||
|
|
||||||
const $ = dom.$;
|
const $ = dom.$;
|
||||||
const MAX_TREE_HEIGHT = 324;
|
const MAX_TREE_HEIGHT = 324;
|
||||||
@@ -107,6 +109,7 @@ export class DebugHoverWidget implements IContentWidget {
|
|||||||
accessibilityProvider: new DebugHoverAccessibilityProvider(),
|
accessibilityProvider: new DebugHoverAccessibilityProvider(),
|
||||||
mouseSupport: false,
|
mouseSupport: false,
|
||||||
horizontalScrolling: true,
|
horizontalScrolling: true,
|
||||||
|
useShadows: false,
|
||||||
overrideStyles: {
|
overrideStyles: {
|
||||||
listBackground: editorHoverBackground
|
listBackground: editorHoverBackground
|
||||||
}
|
}
|
||||||
@@ -174,18 +177,52 @@ export class DebugHoverWidget implements IContentWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async showAt(range: Range, focus: boolean): Promise<void> {
|
async showAt(range: Range, focus: boolean): Promise<void> {
|
||||||
const pos = range.getStartPosition();
|
|
||||||
|
|
||||||
const session = this.debugService.getViewModel().focusedSession;
|
const session = this.debugService.getViewModel().focusedSession;
|
||||||
if (!this.editor.hasModel()) {
|
|
||||||
|
if (!session || !this.editor.hasModel()) {
|
||||||
return Promise.resolve(this.hide());
|
return Promise.resolve(this.hide());
|
||||||
}
|
}
|
||||||
|
|
||||||
const lineContent = this.editor.getModel().getLineContent(pos.lineNumber);
|
const model = this.editor.getModel();
|
||||||
const { start, end } = getExactExpressionStartAndEnd(lineContent, range.startColumn, range.endColumn);
|
const pos = range.getStartPosition();
|
||||||
// use regex to extract the sub-expression #9821
|
|
||||||
const matchingExpression = lineContent.substring(start - 1, end);
|
let rng: IRange | undefined = undefined;
|
||||||
if (!matchingExpression || !session) {
|
let matchingExpression: string | undefined;
|
||||||
|
|
||||||
|
if (EvaluatableExpressionProviderRegistry.has(model)) {
|
||||||
|
const supports = EvaluatableExpressionProviderRegistry.ordered(model);
|
||||||
|
|
||||||
|
const promises = supports.map(support => {
|
||||||
|
return Promise.resolve(support.provideEvaluatableExpression(model, pos, CancellationToken.None)).then(expression => {
|
||||||
|
return expression;
|
||||||
|
}, err => {
|
||||||
|
//onUnexpectedExternalError(err);
|
||||||
|
return undefined;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const results = await Promise.all(promises).then(coalesce);
|
||||||
|
if (results.length > 0) {
|
||||||
|
matchingExpression = results[0].expression;
|
||||||
|
rng = results[0].range;
|
||||||
|
|
||||||
|
if (!matchingExpression) {
|
||||||
|
const lineContent = model.getLineContent(pos.lineNumber);
|
||||||
|
matchingExpression = lineContent.substring(rng.startColumn - 1, rng.endColumn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else { // old one-size-fits-all strategy
|
||||||
|
const lineContent = model.getLineContent(pos.lineNumber);
|
||||||
|
const { start, end } = getExactExpressionStartAndEnd(lineContent, range.startColumn, range.endColumn);
|
||||||
|
|
||||||
|
// use regex to extract the sub-expression #9821
|
||||||
|
matchingExpression = lineContent.substring(start - 1, end);
|
||||||
|
rng = new Range(pos.lineNumber, start, pos.lineNumber, start + matchingExpression.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!matchingExpression) {
|
||||||
return Promise.resolve(this.hide());
|
return Promise.resolve(this.hide());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,13 +239,15 @@ export class DebugHoverWidget implements IContentWidget {
|
|||||||
|
|
||||||
if (!expression || (expression instanceof Expression && !expression.available)) {
|
if (!expression || (expression instanceof Expression && !expression.available)) {
|
||||||
this.hide();
|
this.hide();
|
||||||
return undefined;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.highlightDecorations = this.editor.deltaDecorations(this.highlightDecorations, [{
|
if (rng) {
|
||||||
range: new Range(pos.lineNumber, start, pos.lineNumber, start + matchingExpression.length),
|
this.highlightDecorations = this.editor.deltaDecorations(this.highlightDecorations, [{
|
||||||
options: DebugHoverWidget._HOVER_HIGHLIGHT_DECORATION_OPTIONS
|
range: rng,
|
||||||
}]);
|
options: DebugHoverWidget._HOVER_HIGHLIGHT_DECORATION_OPTIONS
|
||||||
|
}]);
|
||||||
|
}
|
||||||
|
|
||||||
return this.doShow(pos, expression, focus);
|
return this.doShow(pos, expression, focus);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,12 +7,12 @@ import * as nls from 'vs/nls';
|
|||||||
import * as dom from 'vs/base/browser/dom';
|
import * as dom from 'vs/base/browser/dom';
|
||||||
import { IViewletViewOptions } from 'vs/workbench/browser/parts/views/viewsViewlet';
|
import { IViewletViewOptions } from 'vs/workbench/browser/parts/views/viewsViewlet';
|
||||||
import { normalize, isAbsolute, posix } from 'vs/base/common/path';
|
import { normalize, isAbsolute, posix } from 'vs/base/common/path';
|
||||||
import { IViewPaneOptions } from 'vs/workbench/browser/parts/views/viewPaneContainer';
|
import { IViewPaneOptions, ViewPane } from 'vs/workbench/browser/parts/views/viewPaneContainer';
|
||||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||||
import { renderViewTree, BaseDebugViewPane } from 'vs/workbench/contrib/debug/browser/baseDebugView';
|
import { renderViewTree } from 'vs/workbench/contrib/debug/browser/baseDebugView';
|
||||||
import { IDebugSession, IDebugService, CONTEXT_LOADED_SCRIPTS_ITEM_TYPE } from 'vs/workbench/contrib/debug/common/debug';
|
import { IDebugSession, IDebugService, CONTEXT_LOADED_SCRIPTS_ITEM_TYPE } from 'vs/workbench/contrib/debug/common/debug';
|
||||||
import { Source } from 'vs/workbench/contrib/debug/common/debugSource';
|
import { Source } from 'vs/workbench/contrib/debug/common/debugSource';
|
||||||
import { IWorkspaceContextService, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
|
import { IWorkspaceContextService, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
|
||||||
@@ -402,7 +402,7 @@ function asTreeElement(item: BaseTreeItem, viewState?: IViewState): ITreeElement
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export class LoadedScriptsView extends BaseDebugViewPane {
|
export class LoadedScriptsView extends ViewPane {
|
||||||
|
|
||||||
private treeContainer!: HTMLElement;
|
private treeContainer!: HTMLElement;
|
||||||
private loadedScriptsItemType: IContextKey<string>;
|
private loadedScriptsItemType: IContextKey<string>;
|
||||||
@@ -435,6 +435,7 @@ export class LoadedScriptsView extends BaseDebugViewPane {
|
|||||||
renderBody(container: HTMLElement): void {
|
renderBody(container: HTMLElement): void {
|
||||||
super.renderBody(container);
|
super.renderBody(container);
|
||||||
|
|
||||||
|
dom.addClass(this.element, 'debug-pane');
|
||||||
dom.addClass(container, 'debug-loaded-scripts');
|
dom.addClass(container, 'debug-loaded-scripts');
|
||||||
dom.addClass(container, 'show-file-icons');
|
dom.addClass(container, 'show-file-icons');
|
||||||
|
|
||||||
|
|||||||
@@ -75,7 +75,7 @@
|
|||||||
|
|
||||||
/* Expressions */
|
/* Expressions */
|
||||||
|
|
||||||
.monaco-workbench .debug-viewlet .monaco-list-row .expression,
|
.monaco-workbench .debug-pane .monaco-list-row .expression,
|
||||||
.monaco-workbench .debug-hover-widget .monaco-list-row .expression {
|
.monaco-workbench .debug-hover-widget .monaco-list-row .expression {
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@@ -84,7 +84,7 @@
|
|||||||
white-space: pre;
|
white-space: pre;
|
||||||
}
|
}
|
||||||
|
|
||||||
.monaco-workbench.mac .debug-viewlet .monaco-list-row .expression,
|
.monaco-workbench.mac .debug-pane .monaco-list-row .expression,
|
||||||
.monaco-workbench.mac .debug-hover-widget .monaco-list-row .expression {
|
.monaco-workbench.mac .debug-hover-widget .monaco-list-row .expression {
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
user-select: text;
|
user-select: text;
|
||||||
-webkit-user-select: text;
|
-webkit-user-select: text;
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
padding: 4px 5px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.monaco-editor .debug-hover-widget .complex-value {
|
.monaco-editor .debug-hover-widget .complex-value {
|
||||||
@@ -62,6 +61,7 @@
|
|||||||
overflow: auto;
|
overflow: auto;
|
||||||
font-family: var(--monaco-monospace-font);
|
font-family: var(--monaco-monospace-font);
|
||||||
max-height: 500px;
|
max-height: 500px;
|
||||||
|
padding: 4px 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.monaco-editor .debug-hover-widget .error {
|
.monaco-editor .debug-hover-widget .error {
|
||||||
|
|||||||
@@ -601,7 +601,7 @@ export class RawDebugSession implements IDisposable {
|
|||||||
private send<R extends DebugProtocol.Response>(command: string, args: any, token?: CancellationToken, timeout?: number): Promise<R> {
|
private send<R extends DebugProtocol.Response>(command: string, args: any, token?: CancellationToken, timeout?: number): Promise<R> {
|
||||||
return new Promise<DebugProtocol.Response>((completeDispatch, errorDispatch) => {
|
return new Promise<DebugProtocol.Response>((completeDispatch, errorDispatch) => {
|
||||||
if (!this.debugAdapter) {
|
if (!this.debugAdapter) {
|
||||||
errorDispatch(new Error('no debug adapter found'));
|
errorDispatch(new Error(nls.localize('noDebugAdapter', "No debug adapter found. Can not send '{0}'.", command)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let cancelationListener: IDisposable;
|
let cancelationListener: IDisposable;
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic
|
|||||||
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
|
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
|
||||||
import { IFileDialogService } from 'vs/platform/dialogs/common/dialogs';
|
import { IFileDialogService } from 'vs/platform/dialogs/common/dialogs';
|
||||||
import { equals } from 'vs/base/common/arrays';
|
import { equals } from 'vs/base/common/arrays';
|
||||||
import { ViewPane, IViewPaneOptions } from 'vs/workbench/browser/parts/views/viewPaneContainer';
|
import { IViewPaneOptions, ViewPane } from 'vs/workbench/browser/parts/views/viewPaneContainer';
|
||||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
@@ -170,6 +170,7 @@ export class StartView extends ViewPane {
|
|||||||
}));
|
}));
|
||||||
attachButtonStyler(this.debugButton, this.themeService);
|
attachButtonStyler(this.debugButton, this.themeService);
|
||||||
|
|
||||||
|
dom.addClass(this.element, 'debug-pane');
|
||||||
dom.addClass(container, 'debug-start-view');
|
dom.addClass(container, 'debug-start-view');
|
||||||
|
|
||||||
this.secondMessageContainer = $('.section');
|
this.secondMessageContainer = $('.section');
|
||||||
|
|||||||
@@ -12,12 +12,12 @@ import { IDebugService, IExpression, IScope, CONTEXT_VARIABLES_FOCUSED, IViewMod
|
|||||||
import { Variable, Scope } from 'vs/workbench/contrib/debug/common/debugModel';
|
import { Variable, Scope } from 'vs/workbench/contrib/debug/common/debugModel';
|
||||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||||
import { renderViewTree, renderVariable, IInputBoxOptions, AbstractExpressionsRenderer, IExpressionTemplateData, BaseDebugViewPane } from 'vs/workbench/contrib/debug/browser/baseDebugView';
|
import { renderViewTree, renderVariable, IInputBoxOptions, AbstractExpressionsRenderer, IExpressionTemplateData } from 'vs/workbench/contrib/debug/browser/baseDebugView';
|
||||||
import { IAction, Action } from 'vs/base/common/actions';
|
import { IAction, Action } from 'vs/base/common/actions';
|
||||||
import { CopyValueAction } from 'vs/workbench/contrib/debug/browser/debugActions';
|
import { CopyValueAction } from 'vs/workbench/contrib/debug/browser/debugActions';
|
||||||
import { Separator } from 'vs/base/browser/ui/actionbar/actionbar';
|
import { Separator } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||||
import { IViewPaneOptions } from 'vs/workbench/browser/parts/views/viewPaneContainer';
|
import { IViewPaneOptions, ViewPane } from 'vs/workbench/browser/parts/views/viewPaneContainer';
|
||||||
import { IAccessibilityProvider } from 'vs/base/browser/ui/list/listWidget';
|
import { IAccessibilityProvider } from 'vs/base/browser/ui/list/listWidget';
|
||||||
import { IListVirtualDelegate } from 'vs/base/browser/ui/list/list';
|
import { IListVirtualDelegate } from 'vs/base/browser/ui/list/list';
|
||||||
import { ITreeRenderer, ITreeNode, ITreeMouseEvent, ITreeContextMenuEvent, IAsyncDataSource } from 'vs/base/browser/ui/tree/tree';
|
import { ITreeRenderer, ITreeNode, ITreeMouseEvent, ITreeContextMenuEvent, IAsyncDataSource } from 'vs/base/browser/ui/tree/tree';
|
||||||
@@ -39,7 +39,7 @@ let forgetScopes = true;
|
|||||||
|
|
||||||
export const variableSetEmitter = new Emitter<void>();
|
export const variableSetEmitter = new Emitter<void>();
|
||||||
|
|
||||||
export class VariablesView extends BaseDebugViewPane {
|
export class VariablesView extends ViewPane {
|
||||||
|
|
||||||
private onFocusStackFrameScheduler: RunOnceScheduler;
|
private onFocusStackFrameScheduler: RunOnceScheduler;
|
||||||
private needsRefresh = false;
|
private needsRefresh = false;
|
||||||
@@ -90,6 +90,7 @@ export class VariablesView extends BaseDebugViewPane {
|
|||||||
renderBody(container: HTMLElement): void {
|
renderBody(container: HTMLElement): void {
|
||||||
super.renderBody(container);
|
super.renderBody(container);
|
||||||
|
|
||||||
|
dom.addClass(this.element, 'debug-pane');
|
||||||
dom.addClass(container, 'debug-variables');
|
dom.addClass(container, 'debug-variables');
|
||||||
const treeContainer = renderViewTree(container);
|
const treeContainer = renderViewTree(container);
|
||||||
|
|
||||||
|
|||||||
@@ -16,9 +16,9 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
|
|||||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||||
import { IAction, Action } from 'vs/base/common/actions';
|
import { IAction, Action } from 'vs/base/common/actions';
|
||||||
import { Separator } from 'vs/base/browser/ui/actionbar/actionbar';
|
import { Separator } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||||
import { renderExpressionValue, renderViewTree, IInputBoxOptions, AbstractExpressionsRenderer, IExpressionTemplateData, BaseDebugViewPane } from 'vs/workbench/contrib/debug/browser/baseDebugView';
|
import { renderExpressionValue, renderViewTree, IInputBoxOptions, AbstractExpressionsRenderer, IExpressionTemplateData } from 'vs/workbench/contrib/debug/browser/baseDebugView';
|
||||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||||
import { IViewPaneOptions } from 'vs/workbench/browser/parts/views/viewPaneContainer';
|
import { IViewPaneOptions, ViewPane } from 'vs/workbench/browser/parts/views/viewPaneContainer';
|
||||||
import { IListVirtualDelegate } from 'vs/base/browser/ui/list/list';
|
import { IListVirtualDelegate } from 'vs/base/browser/ui/list/list';
|
||||||
import { IAccessibilityProvider } from 'vs/base/browser/ui/list/listWidget';
|
import { IAccessibilityProvider } from 'vs/base/browser/ui/list/listWidget';
|
||||||
import { WorkbenchAsyncDataTree } from 'vs/platform/list/browser/listService';
|
import { WorkbenchAsyncDataTree } from 'vs/platform/list/browser/listService';
|
||||||
@@ -38,7 +38,7 @@ const MAX_VALUE_RENDER_LENGTH_IN_VIEWLET = 1024;
|
|||||||
let ignoreVariableSetEmitter = false;
|
let ignoreVariableSetEmitter = false;
|
||||||
let useCachedEvaluation = false;
|
let useCachedEvaluation = false;
|
||||||
|
|
||||||
export class WatchExpressionsView extends BaseDebugViewPane {
|
export class WatchExpressionsView extends ViewPane {
|
||||||
|
|
||||||
private onWatchExpressionsUpdatedScheduler: RunOnceScheduler;
|
private onWatchExpressionsUpdatedScheduler: RunOnceScheduler;
|
||||||
private needsRefresh = false;
|
private needsRefresh = false;
|
||||||
@@ -67,6 +67,7 @@ export class WatchExpressionsView extends BaseDebugViewPane {
|
|||||||
renderBody(container: HTMLElement): void {
|
renderBody(container: HTMLElement): void {
|
||||||
super.renderBody(container);
|
super.renderBody(container);
|
||||||
|
|
||||||
|
dom.addClass(this.element, 'debug-pane');
|
||||||
dom.addClass(container, 'debug-watch');
|
dom.addClass(container, 'debug-watch');
|
||||||
const treeContainer = renderViewTree(container);
|
const treeContainer = renderViewTree(container);
|
||||||
|
|
||||||
|
|||||||
@@ -676,7 +676,11 @@ export class ExplorerView extends ViewPane {
|
|||||||
if (item.isDisposed) {
|
if (item.isDisposed) {
|
||||||
return this.onSelectResource(resource, reveal, retry + 1);
|
return this.onSelectResource(resource, reveal, retry + 1);
|
||||||
}
|
}
|
||||||
this.tree.reveal(item, 0.5);
|
|
||||||
|
// Don't scroll to the item if it's already visible
|
||||||
|
if (this.tree.getRelativeTop(item) === null) {
|
||||||
|
this.tree.reveal(item, 0.5);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.tree.setFocus([item]);
|
this.tree.setFocus([item]);
|
||||||
|
|||||||
@@ -29,13 +29,13 @@ export class OpenInDesktopIndicator extends Disposable implements IWorkbenchCont
|
|||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
const links = environmentService.options?.applicationLinkProvider?.();
|
const links = environmentService.options?.applicationLinks;
|
||||||
if (Array.isArray(links) && links?.length > 0) {
|
if (Array.isArray(links) && links?.length > 0) {
|
||||||
this.installOpenInDesktopIndicator(links);
|
this.installOpenInDesktopIndicator(links);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private installOpenInDesktopIndicator(links: IApplicationLink[]): void {
|
private installOpenInDesktopIndicator(links: readonly IApplicationLink[]): void {
|
||||||
|
|
||||||
// Register action to trigger "Open In Desktop"
|
// Register action to trigger "Open In Desktop"
|
||||||
const registry = Registry.as<IWorkbenchActionRegistry>(ActionExtensions.WorkbenchActions);
|
const registry = Registry.as<IWorkbenchActionRegistry>(ActionExtensions.WorkbenchActions);
|
||||||
@@ -71,7 +71,7 @@ export class OpenInDesktopAction extends Action {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async run(): Promise<boolean> {
|
async run(): Promise<boolean> {
|
||||||
const links = this.environmentService.options?.applicationLinkProvider?.();
|
const links = this.environmentService.options?.applicationLinks;
|
||||||
if (Array.isArray(links)) {
|
if (Array.isArray(links)) {
|
||||||
if (links.length === 1) {
|
if (links.length === 1) {
|
||||||
return this.openApplicationLink(links[0]);
|
return this.openApplicationLink(links[0]);
|
||||||
@@ -83,7 +83,7 @@ export class OpenInDesktopAction extends Action {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async runWithPicker(links: IApplicationLink[]): Promise<boolean> {
|
private async runWithPicker(links: readonly IApplicationLink[]): Promise<boolean> {
|
||||||
|
|
||||||
// Show a picker with choices
|
// Show a picker with choices
|
||||||
const quickPick = this.quickInputService.createQuickPick<IApplicationLink>();
|
const quickPick = this.quickInputService.createQuickPick<IApplicationLink>();
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ import { localize } from 'vs/nls';
|
|||||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||||
import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||||
import { IResourceInput, TextEditorSelectionRevealType } from 'vs/platform/editor/common/editor';
|
import { TextEditorSelectionRevealType } from 'vs/platform/editor/common/editor';
|
||||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||||
import { WorkbenchDataTree } from 'vs/platform/list/browser/listService';
|
import { WorkbenchDataTree } from 'vs/platform/list/browser/listService';
|
||||||
@@ -37,7 +37,7 @@ import { IThemeService } from 'vs/platform/theme/common/themeService';
|
|||||||
import { ViewPane } from 'vs/workbench/browser/parts/views/viewPaneContainer';
|
import { ViewPane } from 'vs/workbench/browser/parts/views/viewPaneContainer';
|
||||||
import { IViewletViewOptions } from 'vs/workbench/browser/parts/views/viewsViewlet';
|
import { IViewletViewOptions } from 'vs/workbench/browser/parts/views/viewsViewlet';
|
||||||
import { CollapseAction } from 'vs/workbench/browser/viewlet';
|
import { CollapseAction } from 'vs/workbench/browser/viewlet';
|
||||||
import { ACTIVE_GROUP, IEditorService, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService';
|
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||||
import { OutlineConfigKeys, OutlineViewFocused, OutlineViewFiltered } from 'vs/editor/contrib/documentSymbols/outline';
|
import { OutlineConfigKeys, OutlineViewFocused, OutlineViewFiltered } from 'vs/editor/contrib/documentSymbols/outline';
|
||||||
import { FuzzyScore } from 'vs/base/common/filters';
|
import { FuzzyScore } from 'vs/base/common/filters';
|
||||||
import { OutlineDataSource, OutlineItemComparator, OutlineSortOrder, OutlineVirtualDelegate, OutlineGroupRenderer, OutlineElementRenderer, OutlineItem, OutlineIdentityProvider, OutlineNavigationLabelProvider, OutlineFilter } from 'vs/editor/contrib/documentSymbols/outlineTree';
|
import { OutlineDataSource, OutlineItemComparator, OutlineSortOrder, OutlineVirtualDelegate, OutlineGroupRenderer, OutlineElementRenderer, OutlineItem, OutlineIdentityProvider, OutlineNavigationLabelProvider, OutlineFilter } from 'vs/editor/contrib/documentSymbols/outlineTree';
|
||||||
@@ -49,6 +49,7 @@ import { IMarkerDecorationsService } from 'vs/editor/common/services/markersDeco
|
|||||||
import { MarkerSeverity } from 'vs/platform/markers/common/markers';
|
import { MarkerSeverity } from 'vs/platform/markers/common/markers';
|
||||||
import { IViewDescriptorService } from 'vs/workbench/common/views';
|
import { IViewDescriptorService } from 'vs/workbench/common/views';
|
||||||
import { IOpenerService } from 'vs/platform/opener/common/opener';
|
import { IOpenerService } from 'vs/platform/opener/common/opener';
|
||||||
|
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
|
||||||
|
|
||||||
class RequestState {
|
class RequestState {
|
||||||
|
|
||||||
@@ -261,7 +262,7 @@ export class OutlinePane extends ViewPane {
|
|||||||
@IViewDescriptorService viewDescriptorService: IViewDescriptorService,
|
@IViewDescriptorService viewDescriptorService: IViewDescriptorService,
|
||||||
@IThemeService private readonly _themeService: IThemeService,
|
@IThemeService private readonly _themeService: IThemeService,
|
||||||
@IStorageService private readonly _storageService: IStorageService,
|
@IStorageService private readonly _storageService: IStorageService,
|
||||||
@IEditorService private readonly _editorService: IEditorService,
|
@ICodeEditorService private readonly _editorService: ICodeEditorService,
|
||||||
@IMarkerDecorationsService private readonly _markerDecorationService: IMarkerDecorationsService,
|
@IMarkerDecorationsService private readonly _markerDecorationService: IMarkerDecorationsService,
|
||||||
@IConfigurationService private readonly _configurationService: IConfigurationService,
|
@IConfigurationService private readonly _configurationService: IConfigurationService,
|
||||||
@IKeybindingService keybindingService: IKeybindingService,
|
@IKeybindingService keybindingService: IKeybindingService,
|
||||||
@@ -347,7 +348,7 @@ export class OutlinePane extends ViewPane {
|
|||||||
|
|
||||||
this._disposables.push(this._tree);
|
this._disposables.push(this._tree);
|
||||||
this._disposables.push(this._outlineViewState.onDidChange(this._onDidChangeUserState, this));
|
this._disposables.push(this._outlineViewState.onDidChange(this._onDidChangeUserState, this));
|
||||||
this._disposables.push(this.viewDescriptorService.onDidChangeLocation(({ views, from, to }) => {
|
this._disposables.push(this.viewDescriptorService.onDidChangeLocation(({ views }) => {
|
||||||
if (views.some(v => v.id === this.id)) {
|
if (views.some(v => v.id === this.id)) {
|
||||||
this._tree.updateOptions({ overrideStyles: { listBackground: this.getBackgroundColor() } });
|
this._tree.updateOptions({ overrideStyles: { listBackground: this.getBackgroundColor() } });
|
||||||
}
|
}
|
||||||
@@ -629,15 +630,18 @@ export class OutlinePane extends ViewPane {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async _revealTreeSelection(model: OutlineModel, element: OutlineElement, focus: boolean, aside: boolean): Promise<void> {
|
private async _revealTreeSelection(model: OutlineModel, element: OutlineElement, focus: boolean, aside: boolean): Promise<void> {
|
||||||
|
await this._editorService.openCodeEditor(
|
||||||
await this._editorService.openEditor({
|
{
|
||||||
resource: model.textModel.uri,
|
resource: model.textModel.uri,
|
||||||
options: {
|
options: {
|
||||||
preserveFocus: !focus,
|
preserveFocus: !focus,
|
||||||
selection: Range.collapseToStart(element.symbol.selectionRange),
|
selection: Range.collapseToStart(element.symbol.selectionRange),
|
||||||
selectionRevealType: TextEditorSelectionRevealType.NearTop,
|
selectionRevealType: TextEditorSelectionRevealType.NearTop,
|
||||||
}
|
}
|
||||||
} as IResourceInput, aside ? SIDE_GROUP : ACTIVE_GROUP);
|
},
|
||||||
|
this._editorService.getActiveCodeEditor(),
|
||||||
|
aside
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _revealEditorSelection(model: OutlineModel, selection: Selection): void {
|
private _revealEditorSelection(model: OutlineModel, selection: Selection): void {
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ import { SelectionHighlighter } from 'vs/editor/contrib/multicursor/multicursor'
|
|||||||
import * as nls from 'vs/nls';
|
import * as nls from 'vs/nls';
|
||||||
import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration';
|
import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration';
|
||||||
import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
import { IInstantiationService, IConstructorSignature1 } from 'vs/platform/instantiation/common/instantiation';
|
||||||
import { ILogService } from 'vs/platform/log/common/log';
|
import { ILogService } from 'vs/platform/log/common/log';
|
||||||
import { IEditorProgressService } from 'vs/platform/progress/common/progress';
|
import { IEditorProgressService } from 'vs/platform/progress/common/progress';
|
||||||
import { Registry } from 'vs/platform/registry/common/platform';
|
import { Registry } from 'vs/platform/registry/common/platform';
|
||||||
@@ -984,7 +984,7 @@ export class DefaultPreferencesEditor extends BaseTextEditor {
|
|||||||
private static _getContributions(): IEditorContributionDescription[] {
|
private static _getContributions(): IEditorContributionDescription[] {
|
||||||
const skipContributions = [FoldingController.ID, SelectionHighlighter.ID, FindController.ID];
|
const skipContributions = [FoldingController.ID, SelectionHighlighter.ID, FindController.ID];
|
||||||
const contributions = EditorExtensionsRegistry.getEditorContributions().filter(c => skipContributions.indexOf(c.id) === -1);
|
const contributions = EditorExtensionsRegistry.getEditorContributions().filter(c => skipContributions.indexOf(c.id) === -1);
|
||||||
contributions.push({ id: DefaultSettingsEditorContribution.ID, ctor: DefaultSettingsEditorContribution });
|
contributions.push({ id: DefaultSettingsEditorContribution.ID, ctor: DefaultSettingsEditorContribution as IConstructorSignature1<ICodeEditor, editorCommon.IEditorContribution> });
|
||||||
return contributions;
|
return contributions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import { IExtensionService } from 'vs/workbench/services/extensions/common/exten
|
|||||||
import { RunOnceScheduler } from 'vs/base/common/async';
|
import { RunOnceScheduler } from 'vs/base/common/async';
|
||||||
import { URI } from 'vs/base/common/uri';
|
import { URI } from 'vs/base/common/uri';
|
||||||
import { isEqual } from 'vs/base/common/resources';
|
import { isEqual } from 'vs/base/common/resources';
|
||||||
import { isMacintosh, isNative } from 'vs/base/common/platform';
|
import { isMacintosh, isNative, isLinux } from 'vs/base/common/platform';
|
||||||
import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
|
import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
|
||||||
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
|
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
|
||||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||||
@@ -26,6 +26,7 @@ interface IConfiguration extends IWindowsConfiguration {
|
|||||||
telemetry: { enableCrashReporter: boolean };
|
telemetry: { enableCrashReporter: boolean };
|
||||||
workbench: { list: { horizontalScrolling: boolean } };
|
workbench: { list: { horizontalScrolling: boolean } };
|
||||||
debug: { console: { wordWrap: boolean } };
|
debug: { console: { wordWrap: boolean } };
|
||||||
|
editor: { accessibilitySupport: 'on' | 'off' | 'auto' };
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SettingsChangeRelauncher extends Disposable implements IWorkbenchContribution {
|
export class SettingsChangeRelauncher extends Disposable implements IWorkbenchContribution {
|
||||||
@@ -38,6 +39,7 @@ export class SettingsChangeRelauncher extends Disposable implements IWorkbenchCo
|
|||||||
private enableCrashReporter: boolean | undefined;
|
private enableCrashReporter: boolean | undefined;
|
||||||
private treeHorizontalScrolling: boolean | undefined;
|
private treeHorizontalScrolling: boolean | undefined;
|
||||||
private debugConsoleWordWrap: boolean | undefined;
|
private debugConsoleWordWrap: boolean | undefined;
|
||||||
|
private accessibilitySupport: 'on' | 'off' | 'auto' | undefined;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@IHostService private readonly hostService: IHostService,
|
@IHostService private readonly hostService: IHostService,
|
||||||
@@ -103,6 +105,14 @@ export class SettingsChangeRelauncher extends Disposable implements IWorkbenchCo
|
|||||||
this.enableCrashReporter = config.telemetry.enableCrashReporter;
|
this.enableCrashReporter = config.telemetry.enableCrashReporter;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// On linux turning on accessibility support will also pass this flag to the chrome renderer, thus a restart is required
|
||||||
|
if (isLinux && typeof config.editor?.accessibilitySupport === 'string' && config.editor.accessibilitySupport !== this.accessibilitySupport) {
|
||||||
|
this.accessibilitySupport = config.editor.accessibilitySupport;
|
||||||
|
if (this.accessibilitySupport === 'on') {
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notify only when changed and we are the focused window (avoids notification spam across windows)
|
// Notify only when changed and we are the focused window (avoids notification spam across windows)
|
||||||
|
|||||||
@@ -13,3 +13,20 @@
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.timeline-tree-view .monaco-list .monaco-list-row .custom-view-tree-node-item .monaco-icon-label {
|
||||||
|
flex: 1;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-tree-view .monaco-list .monaco-list-row .custom-view-tree-node-item .timeline-timestamp-container {
|
||||||
|
margin-left: 2px;
|
||||||
|
margin-right: 4px;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-tree-view .monaco-list .monaco-list-row .custom-view-tree-node-item .timeline-timestamp-container .timeline-timestamp {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,11 +8,11 @@ import { localize } from 'vs/nls';
|
|||||||
import * as DOM from 'vs/base/browser/dom';
|
import * as DOM from 'vs/base/browser/dom';
|
||||||
import { CancellationTokenSource } from 'vs/base/common/cancellation';
|
import { CancellationTokenSource } from 'vs/base/common/cancellation';
|
||||||
import { FuzzyScore, createMatches } from 'vs/base/common/filters';
|
import { FuzzyScore, createMatches } from 'vs/base/common/filters';
|
||||||
import { DisposableStore } from 'vs/base/common/lifecycle';
|
import { DisposableStore, IDisposable, Disposable } from 'vs/base/common/lifecycle';
|
||||||
import { URI } from 'vs/base/common/uri';
|
import { URI } from 'vs/base/common/uri';
|
||||||
import { IconLabel } from 'vs/base/browser/ui/iconLabel/iconLabel';
|
import { IconLabel } from 'vs/base/browser/ui/iconLabel/iconLabel';
|
||||||
import { IListVirtualDelegate, IIdentityProvider, IKeyboardNavigationLabelProvider } from 'vs/base/browser/ui/list/list';
|
import { IListVirtualDelegate, IIdentityProvider, IKeyboardNavigationLabelProvider } from 'vs/base/browser/ui/list/list';
|
||||||
import { ITreeNode, ITreeRenderer } from 'vs/base/browser/ui/tree/tree';
|
import { ITreeNode, ITreeRenderer, ITreeContextMenuEvent } from 'vs/base/browser/ui/tree/tree';
|
||||||
import { ViewPane, IViewPaneOptions } from 'vs/workbench/browser/parts/views/viewPaneContainer';
|
import { ViewPane, IViewPaneOptions } from 'vs/workbench/browser/parts/views/viewPaneContainer';
|
||||||
import { TreeResourceNavigator, WorkbenchObjectTree } from 'vs/platform/list/browser/listService';
|
import { TreeResourceNavigator, WorkbenchObjectTree } from 'vs/platform/list/browser/listService';
|
||||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||||
@@ -20,7 +20,7 @@ import { IContextMenuService } from 'vs/platform/contextview/browser/contextView
|
|||||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
import { TimelineItem, ITimelineService, TimelineChangeEvent, TimelineProvidersChangeEvent, TimelineRequest, TimelineItemWithSource } from 'vs/workbench/contrib/timeline/common/timeline';
|
import { ITimelineService, TimelineChangeEvent, TimelineProvidersChangeEvent, TimelineRequest, TimelineItem } from 'vs/workbench/contrib/timeline/common/timeline';
|
||||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||||
import { SideBySideEditor, toResource } from 'vs/workbench/common/editor';
|
import { SideBySideEditor, toResource } from 'vs/workbench/common/editor';
|
||||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||||
@@ -31,10 +31,20 @@ import { IProgressService } from 'vs/platform/progress/common/progress';
|
|||||||
import { VIEWLET_ID } from 'vs/workbench/contrib/files/common/files';
|
import { VIEWLET_ID } from 'vs/workbench/contrib/files/common/files';
|
||||||
import { debounce } from 'vs/base/common/decorators';
|
import { debounce } from 'vs/base/common/decorators';
|
||||||
import { IOpenerService } from 'vs/platform/opener/common/opener';
|
import { IOpenerService } from 'vs/platform/opener/common/opener';
|
||||||
|
import { IActionViewItemProvider, ActionBar, ActionViewItem } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||||
|
import { IAction, ActionRunner } from 'vs/base/common/actions';
|
||||||
|
import { ContextAwareMenuEntryActionViewItem, createAndFillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
|
||||||
|
import { MenuItemAction, IMenuService, MenuId } from 'vs/platform/actions/common/actions';
|
||||||
|
import { fromNow } from 'vs/base/common/date';
|
||||||
|
|
||||||
|
// TODO[ECA]: Localize all the strings
|
||||||
|
|
||||||
type TreeElement = TimelineItem;
|
type TreeElement = TimelineItem;
|
||||||
|
|
||||||
// TODO[ECA]: Localize all the strings
|
interface TimelineActionContext {
|
||||||
|
uri: URI | undefined;
|
||||||
|
item: TreeElement;
|
||||||
|
}
|
||||||
|
|
||||||
export class TimelinePane extends ViewPane {
|
export class TimelinePane extends ViewPane {
|
||||||
static readonly ID = 'timeline';
|
static readonly ID = 'timeline';
|
||||||
@@ -44,10 +54,12 @@ export class TimelinePane extends ViewPane {
|
|||||||
private _messageElement!: HTMLDivElement;
|
private _messageElement!: HTMLDivElement;
|
||||||
private _treeElement!: HTMLDivElement;
|
private _treeElement!: HTMLDivElement;
|
||||||
private _tree!: WorkbenchObjectTree<TreeElement, FuzzyScore>;
|
private _tree!: WorkbenchObjectTree<TreeElement, FuzzyScore>;
|
||||||
|
private _treeRenderer: TimelineTreeRenderer | undefined;
|
||||||
|
private _menus: TimelineMenus;
|
||||||
private _visibilityDisposables: DisposableStore | undefined;
|
private _visibilityDisposables: DisposableStore | undefined;
|
||||||
|
|
||||||
// private _excludedSources: Set<string> | undefined;
|
// private _excludedSources: Set<string> | undefined;
|
||||||
private _items: TimelineItemWithSource[] = [];
|
private _items: TimelineItem[] = [];
|
||||||
private _loadingMessageTimer: any | undefined;
|
private _loadingMessageTimer: any | undefined;
|
||||||
private _pendingRequests = new Map<string, TimelineRequest>();
|
private _pendingRequests = new Map<string, TimelineRequest>();
|
||||||
private _uri: URI | undefined;
|
private _uri: URI | undefined;
|
||||||
@@ -67,7 +79,9 @@ export class TimelinePane extends ViewPane {
|
|||||||
@IOpenerService openerService: IOpenerService,
|
@IOpenerService openerService: IOpenerService,
|
||||||
@IThemeService themeService: IThemeService,
|
@IThemeService themeService: IThemeService,
|
||||||
) {
|
) {
|
||||||
super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService);
|
super({ ...options, titleMenuId: MenuId.TimelineTitle }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService);
|
||||||
|
|
||||||
|
this._menus = this._register(this.instantiationService.createInstance(TimelineMenus, this.id));
|
||||||
|
|
||||||
const scopedContextKeyService = this._register(this.contextKeyService.createScoped());
|
const scopedContextKeyService = this._register(this.contextKeyService.createScoped());
|
||||||
scopedContextKeyService.createKey('view', TimelinePane.ID);
|
scopedContextKeyService.createKey('view', TimelinePane.ID);
|
||||||
@@ -88,6 +102,7 @@ export class TimelinePane extends ViewPane {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this._uri = uri;
|
this._uri = uri;
|
||||||
|
this._treeRenderer?.setUri(uri);
|
||||||
this.loadTimeline();
|
this.loadTimeline();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,7 +202,7 @@ export class TimelinePane extends ViewPane {
|
|||||||
let request = this._pendingRequests.get(source);
|
let request = this._pendingRequests.get(source);
|
||||||
request?.tokenSource.dispose(true);
|
request?.tokenSource.dispose(true);
|
||||||
|
|
||||||
request = this.timelineService.getTimelineRequest(source, this._uri, new CancellationTokenSource())!;
|
request = this.timelineService.getTimeline(source, this._uri, {}, new CancellationTokenSource(), { cacheResults: true })!;
|
||||||
|
|
||||||
this._pendingRequests.set(source, request);
|
this._pendingRequests.set(source, request);
|
||||||
request.tokenSource.token.onCancellationRequested(() => this._pendingRequests.delete(source));
|
request.tokenSource.token.onCancellationRequested(() => this._pendingRequests.delete(source));
|
||||||
@@ -199,7 +214,7 @@ export class TimelinePane extends ViewPane {
|
|||||||
private async handleRequest(request: TimelineRequest) {
|
private async handleRequest(request: TimelineRequest) {
|
||||||
let items;
|
let items;
|
||||||
try {
|
try {
|
||||||
items = await this.progressService.withProgress({ location: VIEWLET_ID }, () => request.items);
|
items = await this.progressService.withProgress({ location: VIEWLET_ID }, () => request.result.then(r => r?.items ?? []));
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
|
|
||||||
@@ -211,7 +226,7 @@ export class TimelinePane extends ViewPane {
|
|||||||
this.replaceItems(request.source, items);
|
this.replaceItems(request.source, items);
|
||||||
}
|
}
|
||||||
|
|
||||||
private replaceItems(source: string, items?: TimelineItemWithSource[]) {
|
private replaceItems(source: string, items?: TimelineItem[]) {
|
||||||
const hasItems = this._items.length !== 0;
|
const hasItems = this._items.length !== 0;
|
||||||
|
|
||||||
if (items?.length) {
|
if (items?.length) {
|
||||||
@@ -291,17 +306,20 @@ export class TimelinePane extends ViewPane {
|
|||||||
// DOM.addClass(this._treeElement, 'show-file-icons');
|
// DOM.addClass(this._treeElement, 'show-file-icons');
|
||||||
container.appendChild(this._treeElement);
|
container.appendChild(this._treeElement);
|
||||||
|
|
||||||
const renderer = this.instantiationService.createInstance(TimelineTreeRenderer);
|
this._treeRenderer = this.instantiationService.createInstance(TimelineTreeRenderer, this._menus);
|
||||||
this._tree = <WorkbenchObjectTree<TreeElement, FuzzyScore>>this.instantiationService.createInstance(WorkbenchObjectTree, 'TimelinePane', this._treeElement, new TimelineListVirtualDelegate(), [renderer], {
|
this._tree = <WorkbenchObjectTree<TreeElement, FuzzyScore>>this.instantiationService.createInstance(WorkbenchObjectTree, 'TimelinePane',
|
||||||
|
this._treeElement, new TimelineListVirtualDelegate(), [this._treeRenderer], {
|
||||||
identityProvider: new TimelineIdentityProvider(),
|
identityProvider: new TimelineIdentityProvider(),
|
||||||
keyboardNavigationLabelProvider: new TimelineKeyboardNavigationLabelProvider(),
|
keyboardNavigationLabelProvider: new TimelineKeyboardNavigationLabelProvider(),
|
||||||
overrideStyles: {
|
overrideStyles: {
|
||||||
listBackground: this.getBackgroundColor()
|
listBackground: this.getBackgroundColor(),
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const customTreeNavigator = new TreeResourceNavigator(this._tree, { openOnFocus: false, openOnSelection: false });
|
const customTreeNavigator = new TreeResourceNavigator(this._tree, { openOnFocus: false, openOnSelection: false });
|
||||||
this._register(customTreeNavigator);
|
this._register(customTreeNavigator);
|
||||||
|
this._register(this._tree.onContextMenu(e => this.onContextMenu(this._menus, e)));
|
||||||
this._register(
|
this._register(
|
||||||
customTreeNavigator.onDidOpenResource(e => {
|
customTreeNavigator.onDidOpenResource(e => {
|
||||||
if (!e.browserEvent) {
|
if (!e.browserEvent) {
|
||||||
@@ -316,36 +334,112 @@ export class TimelinePane extends ViewPane {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
export class TimelineElementTemplate {
|
private onContextMenu(menus: TimelineMenus, treeEvent: ITreeContextMenuEvent<TreeElement | null>): void {
|
||||||
static readonly id = 'TimelineElementTemplate';
|
const item = treeEvent.element;
|
||||||
|
if (item === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const event: UIEvent = treeEvent.browserEvent;
|
||||||
|
|
||||||
constructor(
|
event.preventDefault();
|
||||||
readonly container: HTMLElement,
|
event.stopPropagation();
|
||||||
readonly iconLabel: IconLabel,
|
|
||||||
readonly icon: HTMLElement
|
|
||||||
) { }
|
|
||||||
}
|
|
||||||
|
|
||||||
export class TimelineIdentityProvider implements IIdentityProvider<TimelineItem> {
|
this._tree.setFocus([item]);
|
||||||
getId(item: TimelineItem): { toString(): string } {
|
const actions = menus.getResourceContextActions(item);
|
||||||
return `${item.id}|${item.timestamp}`;
|
if (!actions.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.contextMenuService.showContextMenu({
|
||||||
|
getAnchor: () => treeEvent.anchor,
|
||||||
|
getActions: () => actions,
|
||||||
|
getActionViewItem: (action) => {
|
||||||
|
const keybinding = this.keybindingService.lookupKeybinding(action.id);
|
||||||
|
if (keybinding) {
|
||||||
|
return new ActionViewItem(action, action, { label: true, keybinding: keybinding.getLabel() });
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
},
|
||||||
|
onHide: (wasCancelled?: boolean) => {
|
||||||
|
if (wasCancelled) {
|
||||||
|
this._tree.domFocus();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getActionsContext: (): TimelineActionContext => ({ uri: this._uri, item: item }),
|
||||||
|
actionRunner: new TimelineActionRunner()
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TimelineKeyboardNavigationLabelProvider implements IKeyboardNavigationLabelProvider<TimelineItem> {
|
export class TimelineElementTemplate implements IDisposable {
|
||||||
getKeyboardNavigationLabel(element: TimelineItem): { toString(): string } {
|
static readonly id = 'TimelineElementTemplate';
|
||||||
|
|
||||||
|
readonly actionBar: ActionBar;
|
||||||
|
readonly icon: HTMLElement;
|
||||||
|
readonly iconLabel: IconLabel;
|
||||||
|
readonly timestamp: HTMLSpanElement;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
readonly container: HTMLElement,
|
||||||
|
actionViewItemProvider: IActionViewItemProvider
|
||||||
|
) {
|
||||||
|
DOM.addClass(container, 'custom-view-tree-node-item');
|
||||||
|
this.icon = DOM.append(container, DOM.$('.custom-view-tree-node-item-icon'));
|
||||||
|
|
||||||
|
this.iconLabel = new IconLabel(container, { supportHighlights: true, supportCodicons: true });
|
||||||
|
|
||||||
|
const timestampContainer = DOM.append(this.iconLabel.element, DOM.$('.timeline-timestamp-container'));
|
||||||
|
this.timestamp = DOM.append(timestampContainer, DOM.$('span.timeline-timestamp'));
|
||||||
|
|
||||||
|
const actionsContainer = DOM.append(this.iconLabel.element, DOM.$('.actions'));
|
||||||
|
this.actionBar = new ActionBar(actionsContainer, { actionViewItemProvider: actionViewItemProvider });
|
||||||
|
}
|
||||||
|
|
||||||
|
dispose() {
|
||||||
|
this.iconLabel.dispose();
|
||||||
|
this.actionBar.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
reset() {
|
||||||
|
this.actionBar.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class TimelineIdentityProvider implements IIdentityProvider<TreeElement> {
|
||||||
|
getId(item: TreeElement): { toString(): string } {
|
||||||
|
return item.handle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TimelineActionRunner extends ActionRunner {
|
||||||
|
|
||||||
|
runAction(action: IAction, { uri, item }: TimelineActionContext): Promise<any> {
|
||||||
|
return action.run(...[
|
||||||
|
{
|
||||||
|
$mid: 11,
|
||||||
|
handle: item.handle,
|
||||||
|
source: item.source,
|
||||||
|
uri: uri
|
||||||
|
},
|
||||||
|
uri,
|
||||||
|
item.source,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class TimelineKeyboardNavigationLabelProvider implements IKeyboardNavigationLabelProvider<TreeElement> {
|
||||||
|
getKeyboardNavigationLabel(element: TreeElement): { toString(): string } {
|
||||||
return element.label;
|
return element.label;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TimelineListVirtualDelegate implements IListVirtualDelegate<TimelineItem> {
|
export class TimelineListVirtualDelegate implements IListVirtualDelegate<TreeElement> {
|
||||||
getHeight(_element: TimelineItem): number {
|
getHeight(_element: TreeElement): number {
|
||||||
return 22;
|
return 22;
|
||||||
}
|
}
|
||||||
|
|
||||||
getTemplateId(element: TimelineItem): string {
|
getTemplateId(element: TreeElement): string {
|
||||||
return TimelineElementTemplate.id;
|
return TimelineElementTemplate.id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -353,14 +447,25 @@ export class TimelineListVirtualDelegate implements IListVirtualDelegate<Timelin
|
|||||||
class TimelineTreeRenderer implements ITreeRenderer<TreeElement, FuzzyScore, TimelineElementTemplate> {
|
class TimelineTreeRenderer implements ITreeRenderer<TreeElement, FuzzyScore, TimelineElementTemplate> {
|
||||||
readonly templateId: string = TimelineElementTemplate.id;
|
readonly templateId: string = TimelineElementTemplate.id;
|
||||||
|
|
||||||
constructor(@IThemeService private _themeService: IThemeService) { }
|
private _actionViewItemProvider: IActionViewItemProvider;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private readonly _menus: TimelineMenus,
|
||||||
|
@IInstantiationService protected readonly instantiationService: IInstantiationService,
|
||||||
|
@IThemeService private _themeService: IThemeService
|
||||||
|
) {
|
||||||
|
this._actionViewItemProvider = (action: IAction) => action instanceof MenuItemAction
|
||||||
|
? this.instantiationService.createInstance(ContextAwareMenuEntryActionViewItem, action)
|
||||||
|
: undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _uri: URI | undefined;
|
||||||
|
setUri(uri: URI | undefined) {
|
||||||
|
this._uri = uri;
|
||||||
|
}
|
||||||
|
|
||||||
renderTemplate(container: HTMLElement): TimelineElementTemplate {
|
renderTemplate(container: HTMLElement): TimelineElementTemplate {
|
||||||
DOM.addClass(container, 'custom-view-tree-node-item');
|
return new TimelineElementTemplate(container, this._actionViewItemProvider);
|
||||||
const icon = DOM.append(container, DOM.$('.custom-view-tree-node-item-icon'));
|
|
||||||
|
|
||||||
const iconLabel = new IconLabel(container, { supportHighlights: true, supportCodicons: true });
|
|
||||||
return new TimelineElementTemplate(container, iconLabel, icon);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
renderElement(
|
renderElement(
|
||||||
@@ -369,30 +474,74 @@ class TimelineTreeRenderer implements ITreeRenderer<TreeElement, FuzzyScore, Tim
|
|||||||
template: TimelineElementTemplate,
|
template: TimelineElementTemplate,
|
||||||
height: number | undefined
|
height: number | undefined
|
||||||
): void {
|
): void {
|
||||||
const { element } = node;
|
template.reset();
|
||||||
|
|
||||||
const icon = this._themeService.getTheme().type === LIGHT ? element.icon : element.iconDark;
|
const { element: item } = node;
|
||||||
|
|
||||||
|
const icon = this._themeService.getTheme().type === LIGHT ? item.icon : item.iconDark;
|
||||||
const iconUrl = icon ? URI.revive(icon) : null;
|
const iconUrl = icon ? URI.revive(icon) : null;
|
||||||
|
|
||||||
if (iconUrl) {
|
if (iconUrl) {
|
||||||
template.icon.className = 'custom-view-tree-node-item-icon';
|
template.icon.className = 'custom-view-tree-node-item-icon';
|
||||||
template.icon.style.backgroundImage = DOM.asCSSUrl(iconUrl);
|
template.icon.style.backgroundImage = DOM.asCSSUrl(iconUrl);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
let iconClass: string | undefined;
|
let iconClass: string | undefined;
|
||||||
if (element.themeIcon /*&& !this.isFileKindThemeIcon(element.themeIcon)*/) {
|
if (item.themeIcon /*&& !this.isFileKindThemeIcon(element.themeIcon)*/) {
|
||||||
iconClass = ThemeIcon.asClassName(element.themeIcon);
|
iconClass = ThemeIcon.asClassName(item.themeIcon);
|
||||||
}
|
}
|
||||||
template.icon.className = iconClass ? `custom-view-tree-node-item-icon ${iconClass}` : '';
|
template.icon.className = iconClass ? `custom-view-tree-node-item-icon ${iconClass}` : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
template.iconLabel.setLabel(element.label, element.description, {
|
template.iconLabel.setLabel(item.label, item.description, {
|
||||||
title: element.detail,
|
title: item.detail,
|
||||||
matches: createMatches(node.filterData)
|
matches: createMatches(node.filterData)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
template.timestamp.textContent = fromNow(item.timestamp);
|
||||||
|
|
||||||
|
template.actionBar.context = { uri: this._uri, item: item } as TimelineActionContext;
|
||||||
|
template.actionBar.actionRunner = new TimelineActionRunner();
|
||||||
|
template.actionBar.push(this._menus.getResourceActions(item), { icon: true, label: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
disposeTemplate(template: TimelineElementTemplate): void {
|
disposeTemplate(template: TimelineElementTemplate): void {
|
||||||
template.iconLabel.dispose();
|
template.iconLabel.dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class TimelineMenus extends Disposable {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private id: string,
|
||||||
|
@IContextKeyService private readonly contextKeyService: IContextKeyService,
|
||||||
|
@IMenuService private readonly menuService: IMenuService,
|
||||||
|
@IContextMenuService private readonly contextMenuService: IContextMenuService
|
||||||
|
) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
getResourceActions(element: TreeElement): IAction[] {
|
||||||
|
return this.getActions(MenuId.TimelineItemContext, { key: 'timelineItem', value: element.contextValue }).primary;
|
||||||
|
}
|
||||||
|
|
||||||
|
getResourceContextActions(element: TreeElement): IAction[] {
|
||||||
|
return this.getActions(MenuId.TimelineItemContext, { key: 'timelineItem', value: element.contextValue }).secondary;
|
||||||
|
}
|
||||||
|
|
||||||
|
private getActions(menuId: MenuId, context: { key: string, value?: string }): { primary: IAction[]; secondary: IAction[]; } {
|
||||||
|
const contextKeyService = this.contextKeyService.createScoped();
|
||||||
|
contextKeyService.createKey('view', this.id);
|
||||||
|
contextKeyService.createKey(context.key, context.value);
|
||||||
|
|
||||||
|
const menu = this.menuService.createMenu(menuId, contextKeyService);
|
||||||
|
const primary: IAction[] = [];
|
||||||
|
const secondary: IAction[] = [];
|
||||||
|
const result = { primary, secondary };
|
||||||
|
createAndFillInContextMenuActions(menu, { shouldForwardArgs: true }, result, this.contextMenuService, g => /^inline/.test(g));
|
||||||
|
|
||||||
|
menu.dispose();
|
||||||
|
contextKeyService.dispose();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -16,9 +16,11 @@ export function toKey(extension: ExtensionIdentifier | string, source: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface TimelineItem {
|
export interface TimelineItem {
|
||||||
|
handle: string;
|
||||||
|
source: string;
|
||||||
|
|
||||||
timestamp: number;
|
timestamp: number;
|
||||||
label: string;
|
label: string;
|
||||||
id?: string;
|
|
||||||
icon?: URI,
|
icon?: URI,
|
||||||
iconDark?: URI,
|
iconDark?: URI,
|
||||||
themeIcon?: { id: string },
|
themeIcon?: { id: string },
|
||||||
@@ -28,19 +30,29 @@ export interface TimelineItem {
|
|||||||
contextValue?: string;
|
contextValue?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TimelineItemWithSource extends TimelineItem {
|
|
||||||
source: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TimelineChangeEvent {
|
export interface TimelineChangeEvent {
|
||||||
id: string;
|
id: string;
|
||||||
uri?: URI;
|
uri?: URI;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface TimelineCursor {
|
||||||
|
cursor?: any;
|
||||||
|
before?: boolean;
|
||||||
|
limit?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Timeline {
|
||||||
|
source: string;
|
||||||
|
items: TimelineItem[];
|
||||||
|
|
||||||
|
cursor?: any;
|
||||||
|
more?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
export interface TimelineProvider extends TimelineProviderDescriptor, IDisposable {
|
export interface TimelineProvider extends TimelineProviderDescriptor, IDisposable {
|
||||||
onDidChange?: Event<TimelineChangeEvent>;
|
onDidChange?: Event<TimelineChangeEvent>;
|
||||||
|
|
||||||
provideTimeline(uri: URI, token: CancellationToken): Promise<TimelineItemWithSource[]>;
|
provideTimeline(uri: URI, cursor: TimelineCursor, token: CancellationToken, options?: { cacheResults?: boolean }): Promise<Timeline | undefined>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TimelineProviderDescriptor {
|
export interface TimelineProviderDescriptor {
|
||||||
@@ -55,7 +67,7 @@ export interface TimelineProvidersChangeEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface TimelineRequest {
|
export interface TimelineRequest {
|
||||||
readonly items: Promise<TimelineItemWithSource[]>;
|
readonly result: Promise<Timeline | undefined>;
|
||||||
readonly source: string;
|
readonly source: string;
|
||||||
readonly tokenSource: CancellationTokenSource;
|
readonly tokenSource: CancellationTokenSource;
|
||||||
readonly uri: URI;
|
readonly uri: URI;
|
||||||
@@ -72,9 +84,7 @@ export interface ITimelineService {
|
|||||||
|
|
||||||
getSources(): string[];
|
getSources(): string[];
|
||||||
|
|
||||||
getTimeline(uri: URI, token: CancellationToken): Promise<TimelineItem[]>;
|
getTimeline(id: string, uri: URI, cursor: TimelineCursor, tokenSource: CancellationTokenSource, options?: { cacheResults?: boolean }): TimelineRequest | undefined;
|
||||||
|
|
||||||
getTimelineRequest(id: string, uri: URI, tokenSource: CancellationTokenSource): TimelineRequest | undefined;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const TIMELINE_SERVICE_ID = 'timeline';
|
const TIMELINE_SERVICE_ID = 'timeline';
|
||||||
|
|||||||
@@ -3,13 +3,13 @@
|
|||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation';
|
import { CancellationTokenSource } from 'vs/base/common/cancellation';
|
||||||
import { Event, Emitter } from 'vs/base/common/event';
|
import { Event, Emitter } from 'vs/base/common/event';
|
||||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||||
// import { basename } from 'vs/base/common/path';
|
// import { basename } from 'vs/base/common/path';
|
||||||
import { URI } from 'vs/base/common/uri';
|
import { URI } from 'vs/base/common/uri';
|
||||||
import { ILogService } from 'vs/platform/log/common/log';
|
import { ILogService } from 'vs/platform/log/common/log';
|
||||||
import { ITimelineService, TimelineProvider, TimelineItem, TimelineChangeEvent, TimelineProvidersChangeEvent } from './timeline';
|
import { ITimelineService, TimelineChangeEvent, TimelineCursor, TimelineProvidersChangeEvent, TimelineProvider } from './timeline';
|
||||||
|
|
||||||
export class TimelineService implements ITimelineService {
|
export class TimelineService implements ITimelineService {
|
||||||
_serviceBrand: undefined;
|
_serviceBrand: undefined;
|
||||||
@@ -81,42 +81,7 @@ export class TimelineService implements ITimelineService {
|
|||||||
return [...this._providers.keys()];
|
return [...this._providers.keys()];
|
||||||
}
|
}
|
||||||
|
|
||||||
async getTimeline(uri: URI, token: CancellationToken, predicate?: (provider: TimelineProvider) => boolean) {
|
getTimeline(id: string, uri: URI, cursor: TimelineCursor, tokenSource: CancellationTokenSource, options?: { cacheResults?: boolean }) {
|
||||||
this.logService.trace(`TimelineService#getTimeline(${uri.toString(true)})`);
|
|
||||||
|
|
||||||
const requests: Promise<[string, TimelineItem[]]>[] = [];
|
|
||||||
|
|
||||||
for (const provider of this._providers.values()) {
|
|
||||||
if (typeof provider.scheme === 'string') {
|
|
||||||
if (provider.scheme !== '*' && provider.scheme !== uri.scheme) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
} else if (!provider.scheme.includes(uri.scheme)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!(predicate?.(provider) ?? true)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
requests.push(provider.provideTimeline(uri, token).then(p => [provider.id, p]));
|
|
||||||
}
|
|
||||||
|
|
||||||
const timelines = await Promise.all(requests);
|
|
||||||
|
|
||||||
const timeline = [];
|
|
||||||
for (const [source, items] of timelines) {
|
|
||||||
if (items.length === 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
timeline.push(...items.map(item => ({ ...item, source: source })));
|
|
||||||
}
|
|
||||||
|
|
||||||
timeline.sort((a, b) => b.timestamp - a.timestamp);
|
|
||||||
return timeline;
|
|
||||||
}
|
|
||||||
|
|
||||||
getTimelineRequest(id: string, uri: URI, tokenSource: CancellationTokenSource) {
|
|
||||||
this.logService.trace(`TimelineService#getTimeline(${id}): uri=${uri.toString(true)}`);
|
this.logService.trace(`TimelineService#getTimeline(${id}): uri=${uri.toString(true)}`);
|
||||||
|
|
||||||
const provider = this._providers.get(id);
|
const provider = this._providers.get(id);
|
||||||
@@ -133,12 +98,16 @@ export class TimelineService implements ITimelineService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
items: provider.provideTimeline(uri, tokenSource.token)
|
result: provider.provideTimeline(uri, cursor, tokenSource.token, options)
|
||||||
.then(items => {
|
.then(result => {
|
||||||
items = items.map(item => ({ ...item, source: provider.id }));
|
if (result === undefined) {
|
||||||
items.sort((a, b) => (b.timestamp - a.timestamp) || b.source.localeCompare(a.source, undefined, { numeric: true, sensitivity: 'base' }));
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
return items;
|
result.items = result.items.map(item => ({ ...item, source: provider.id }));
|
||||||
|
result.items.sort((a, b) => (b.timestamp - a.timestamp) || b.source.localeCompare(a.source, undefined, { numeric: true, sensitivity: 'base' }));
|
||||||
|
|
||||||
|
return result;
|
||||||
}),
|
}),
|
||||||
source: provider.id,
|
source: provider.id,
|
||||||
tokenSource: tokenSource,
|
tokenSource: tokenSource,
|
||||||
|
|||||||
@@ -127,41 +127,41 @@ export class ProductContribution implements IWorkbenchContribution {
|
|||||||
@IHostService hostService: IHostService,
|
@IHostService hostService: IHostService,
|
||||||
@IProductService productService: IProductService
|
@IProductService productService: IProductService
|
||||||
) {
|
) {
|
||||||
if (!hostService.hasFocus) {
|
hostService.hadLastFocus().then(hadLastFocus => {
|
||||||
return;
|
if (!hadLastFocus) {
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const lastVersion = storageService.get(ProductContribution.KEY, StorageScope.GLOBAL, '');
|
const lastVersion = storageService.get(ProductContribution.KEY, StorageScope.GLOBAL, '');
|
||||||
const shouldShowReleaseNotes = configurationService.getValue<boolean>('update.showReleaseNotes');
|
const shouldShowReleaseNotes = configurationService.getValue<boolean>('update.showReleaseNotes');
|
||||||
|
|
||||||
// was there an update? if so, open release notes
|
// was there an update? if so, open release notes
|
||||||
const releaseNotesUrl = productService.releaseNotesUrl;
|
const releaseNotesUrl = productService.releaseNotesUrl;
|
||||||
if (shouldShowReleaseNotes && !environmentService.args['skip-release-notes'] && releaseNotesUrl && lastVersion && productService.version !== lastVersion && productService.quality === 'stable') { // {{SQL CARBON EDIT}} Only show release notes for stable build
|
if (shouldShowReleaseNotes && !environmentService.args['skip-release-notes'] && releaseNotesUrl && lastVersion && productService.version !== lastVersion && productService.quality === 'stable') { // {{SQL CARBON EDIT}} Only show release notes for stable build) {
|
||||||
/* // {{SQL CARBON EDIT}} Prompt user to open release notes in browser until we can get ADS release notes from the web
|
/*showReleaseNotes(instantiationService, productService.version) {{SQL CARBON EDIT}} Prompt user to open release notes in browser until we can get ADS release notes from the web
|
||||||
showReleaseNotes(instantiationService, productService.version)
|
.then(undefined, () => {*/
|
||||||
.then(undefined, () => {
|
notificationService.prompt(
|
||||||
*/
|
severity.Info,
|
||||||
notificationService.prompt(
|
nls.localize('read the release notes', "Welcome to {0} v{1}! Would you like to read the Release Notes?", productService.nameLong, productService.version),
|
||||||
severity.Info,
|
[{
|
||||||
nls.localize('read the release notes', "Welcome to {0} v{1}! Would you like to read the Release Notes?", productService.nameLong, productService.version),
|
label: nls.localize('releaseNotes', "Release Notes"),
|
||||||
[{
|
run: () => {
|
||||||
label: nls.localize('releaseNotes', "Release Notes"),
|
const uri = URI.parse(releaseNotesUrl);
|
||||||
run: () => {
|
openerService.open(uri);
|
||||||
const uri = URI.parse(releaseNotesUrl);
|
}
|
||||||
openerService.open(uri);
|
}],
|
||||||
}
|
{ sticky: true }
|
||||||
}],
|
);
|
||||||
{ sticky: true }
|
}/*);
|
||||||
);
|
}*/
|
||||||
// }); // {{SQL CARBON EDIT}}
|
|
||||||
}
|
|
||||||
|
|
||||||
// should we show the new license?
|
// should we show the new license?
|
||||||
if (productService.licenseUrl && lastVersion && semver.satisfies(lastVersion, '<1.0.0') && semver.satisfies(productService.version, '>=1.0.0')) {
|
if (productService.licenseUrl && lastVersion && semver.satisfies(lastVersion, '<1.0.0') && semver.satisfies(productService.version, '>=1.0.0')) {
|
||||||
notificationService.info(nls.localize('licenseChanged', "Our license terms have changed, please click [here]({0}) to go through them.", productService.licenseUrl));
|
notificationService.info(nls.localize('licenseChanged', "Our license terms have changed, please click [here]({0}) to go through them.", productService.licenseUrl));
|
||||||
}
|
}
|
||||||
|
|
||||||
storageService.store(ProductContribution.KEY, productService.version, StorageScope.GLOBAL);
|
storageService.store(ProductContribution.KEY, productService.version, StorageScope.GLOBAL);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -286,4 +286,10 @@ export abstract class BaseWebview<T extends HTMLElement> extends Disposable {
|
|||||||
this.element.style.pointerEvents = '';
|
this.element.style.pointerEvents = '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public selectAll() {
|
||||||
|
if (this.element) {
|
||||||
|
this._send('execCommand', 'selectAll');
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -187,6 +187,7 @@ export class DynamicWebviewEditorOverlay extends Disposable implements WebviewEd
|
|||||||
showFind(): void { this.withWebview(webview => webview.showFind()); }
|
showFind(): void { this.withWebview(webview => webview.showFind()); }
|
||||||
hideFind(): void { this.withWebview(webview => webview.hideFind()); }
|
hideFind(): void { this.withWebview(webview => webview.hideFind()); }
|
||||||
runFindAction(previous: boolean): void { this.withWebview(webview => webview.runFindAction(previous)); }
|
runFindAction(previous: boolean): void { this.withWebview(webview => webview.runFindAction(previous)); }
|
||||||
|
selectAll(): void { this.withWebview(webview => webview.selectAll()); }
|
||||||
|
|
||||||
public getInnerWebview() {
|
public getInnerWebview() {
|
||||||
return this._webview.value;
|
return this._webview.value;
|
||||||
|
|||||||
@@ -232,23 +232,23 @@
|
|||||||
* @param {MouseEvent} event
|
* @param {MouseEvent} event
|
||||||
*/
|
*/
|
||||||
const handleAuxClick =
|
const handleAuxClick =
|
||||||
(event) => {
|
(event) => {
|
||||||
// Prevent middle clicks opening a broken link in the browser
|
// Prevent middle clicks opening a broken link in the browser
|
||||||
if (!event.view || !event.view.document) {
|
if (!event.view || !event.view.document) {
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if (event.button === 1) {
|
|
||||||
let node = /** @type {any} */ (event.target);
|
|
||||||
while (node) {
|
|
||||||
if (node.tagName && node.tagName.toLowerCase() === 'a' && node.href) {
|
|
||||||
event.preventDefault();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
node = node.parentNode;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
};
|
if (event.button === 1) {
|
||||||
|
let node = /** @type {any} */ (event.target);
|
||||||
|
while (node) {
|
||||||
|
if (node.tagName && node.tagName.toLowerCase() === 'a' && node.href) {
|
||||||
|
event.preventDefault();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
node = node.parentNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {KeyboardEvent} e
|
* @param {KeyboardEvent} e
|
||||||
@@ -449,6 +449,10 @@
|
|||||||
}, 0);
|
}, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Document} contentDocument
|
||||||
|
* @param {Window} contentWindow
|
||||||
|
*/
|
||||||
const onLoad = (contentDocument, contentWindow) => {
|
const onLoad = (contentDocument, contentWindow) => {
|
||||||
if (contentDocument && contentDocument.body) {
|
if (contentDocument && contentDocument.body) {
|
||||||
// Workaround for https://github.com/Microsoft/vscode/issues/12865
|
// Workaround for https://github.com/Microsoft/vscode/issues/12865
|
||||||
@@ -492,10 +496,12 @@
|
|||||||
}, 200);
|
}, 200);
|
||||||
|
|
||||||
newFrame.contentWindow.addEventListener('load', function (e) {
|
newFrame.contentWindow.addEventListener('load', function (e) {
|
||||||
|
const contentDocument = /** @type {Document} */ (e.target);
|
||||||
|
|
||||||
if (loadTimeout) {
|
if (loadTimeout) {
|
||||||
clearTimeout(loadTimeout);
|
clearTimeout(loadTimeout);
|
||||||
loadTimeout = undefined;
|
loadTimeout = undefined;
|
||||||
onLoad(e.target, this);
|
onLoad(contentDocument, this);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -539,6 +545,13 @@
|
|||||||
initData.initialScrollProgress = progress;
|
initData.initialScrollProgress = progress;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
host.onMessage('execCommand', (_event, data) => {
|
||||||
|
const target = getActiveFrame();
|
||||||
|
if (!target) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
target.contentDocument.execCommand(data);
|
||||||
|
});
|
||||||
|
|
||||||
trackFocus({
|
trackFocus({
|
||||||
onFocus: () => host.postMessage('did-focus'),
|
onFocus: () => host.postMessage('did-focus'),
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import { Extensions as ActionExtensions, IWorkbenchActionRegistry } from 'vs/wor
|
|||||||
import { Extensions as EditorInputExtensions, IEditorInputFactoryRegistry } from 'vs/workbench/common/editor';
|
import { Extensions as EditorInputExtensions, IEditorInputFactoryRegistry } from 'vs/workbench/common/editor';
|
||||||
import { webviewDeveloperCategory } from 'vs/workbench/contrib/webview/browser/webview';
|
import { webviewDeveloperCategory } from 'vs/workbench/contrib/webview/browser/webview';
|
||||||
import { WebviewEditorInputFactory } from 'vs/workbench/contrib/webview/browser/webviewEditorInputFactory';
|
import { WebviewEditorInputFactory } from 'vs/workbench/contrib/webview/browser/webviewEditorInputFactory';
|
||||||
import { HideWebViewEditorFindCommand, ReloadWebviewAction, ShowWebViewEditorFindWidgetAction, WebViewEditorFindNextCommand, WebViewEditorFindPreviousCommand } from '../browser/webviewCommands';
|
import { HideWebViewEditorFindCommand, ReloadWebviewAction, ShowWebViewEditorFindWidgetAction, WebViewEditorFindNextCommand, WebViewEditorFindPreviousCommand, SelectAllWebviewEditorCommand } from '../browser/webviewCommands';
|
||||||
import { WebviewEditor } from './webviewEditor';
|
import { WebviewEditor } from './webviewEditor';
|
||||||
import { WebviewInput } from './webviewEditorInput';
|
import { WebviewInput } from './webviewEditorInput';
|
||||||
import { IWebviewWorkbenchService, WebviewEditorService } from './webviewWorkbenchService';
|
import { IWebviewWorkbenchService, WebviewEditorService } from './webviewWorkbenchService';
|
||||||
@@ -50,6 +50,11 @@ registerAction2(class extends WebViewEditorFindPreviousCommand {
|
|||||||
constructor() { super(webviewActiveContextKeyExpr); }
|
constructor() { super(webviewActiveContextKeyExpr); }
|
||||||
});
|
});
|
||||||
|
|
||||||
|
registerAction2(class extends SelectAllWebviewEditorCommand {
|
||||||
|
constructor() { super(webviewActiveContextKeyExpr); }
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
const actionRegistry = Registry.as<IWorkbenchActionRegistry>(ActionExtensions.WorkbenchActions);
|
const actionRegistry = Registry.as<IWorkbenchActionRegistry>(ActionExtensions.WorkbenchActions);
|
||||||
actionRegistry.registerWorkbenchAction(
|
actionRegistry.registerWorkbenchAction(
|
||||||
SyncActionDescriptor.create(ReloadWebviewAction, ReloadWebviewAction.ID, ReloadWebviewAction.LABEL),
|
SyncActionDescriptor.create(ReloadWebviewAction, ReloadWebviewAction.ID, ReloadWebviewAction.LABEL),
|
||||||
|
|||||||
@@ -93,6 +93,8 @@ export interface Webview extends IDisposable {
|
|||||||
hideFind(): void;
|
hideFind(): void;
|
||||||
runFindAction(previous: boolean): void;
|
runFindAction(previous: boolean): void;
|
||||||
|
|
||||||
|
selectAll(): void;
|
||||||
|
|
||||||
windowDidDragStart(): void;
|
windowDidDragStart(): void;
|
||||||
windowDidDragEnd(): void;
|
windowDidDragEnd(): void;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegis
|
|||||||
import { KEYBINDING_CONTEXT_WEBVIEW_FIND_WIDGET_FOCUSED, KEYBINDING_CONTEXT_WEBVIEW_FIND_WIDGET_VISIBLE } from 'vs/workbench/contrib/webview/browser/webview';
|
import { KEYBINDING_CONTEXT_WEBVIEW_FIND_WIDGET_FOCUSED, KEYBINDING_CONTEXT_WEBVIEW_FIND_WIDGET_VISIBLE } from 'vs/workbench/contrib/webview/browser/webview';
|
||||||
import { WebviewEditor } from 'vs/workbench/contrib/webview/browser/webviewEditor';
|
import { WebviewEditor } from 'vs/workbench/contrib/webview/browser/webviewEditor';
|
||||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||||
|
import { InputFocusedContextKey } from 'vs/platform/contextkey/common/contextkeys';
|
||||||
|
|
||||||
export class ShowWebViewEditorFindWidgetAction extends Action2 {
|
export class ShowWebViewEditorFindWidgetAction extends Action2 {
|
||||||
public static readonly ID = 'editor.action.webvieweditor.showFind';
|
public static readonly ID = 'editor.action.webvieweditor.showFind';
|
||||||
@@ -97,6 +98,29 @@ export class WebViewEditorFindPreviousCommand extends Action2 {
|
|||||||
getActiveWebviewEditor(accessor)?.find(true);
|
getActiveWebviewEditor(accessor)?.find(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class SelectAllWebviewEditorCommand extends Action2 {
|
||||||
|
public static readonly ID = 'editor.action.webvieweditor.selectAll';
|
||||||
|
public static readonly LABEL = nls.localize('editor.action.webvieweditor.selectAll', 'Select all');
|
||||||
|
|
||||||
|
constructor(contextKeyExpr: ContextKeyExpr) {
|
||||||
|
const precondition = ContextKeyExpr.and(contextKeyExpr, ContextKeyExpr.not(InputFocusedContextKey));
|
||||||
|
super({
|
||||||
|
id: SelectAllWebviewEditorCommand.ID,
|
||||||
|
title: SelectAllWebviewEditorCommand.LABEL,
|
||||||
|
keybinding: {
|
||||||
|
when: precondition,
|
||||||
|
primary: KeyMod.CtrlCmd | KeyCode.KEY_A,
|
||||||
|
weight: KeybindingWeight.EditorContrib
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public run(accessor: ServicesAccessor, args: any): void {
|
||||||
|
getActiveWebviewEditor(accessor)?.selectAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class ReloadWebviewAction extends Action {
|
export class ReloadWebviewAction extends Action {
|
||||||
static readonly ID = 'workbench.action.webview.reloadWebviewAction';
|
static readonly ID = 'workbench.action.webview.reloadWebviewAction';
|
||||||
static readonly LABEL = nls.localize('refreshWebviewLabel', "Reload Webviews");
|
static readonly LABEL = nls.localize('refreshWebviewLabel', "Reload Webviews");
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import { IThemeService } from 'vs/platform/theme/common/themeService';
|
|||||||
import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor';
|
import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor';
|
||||||
import { EditorPart } from 'vs/workbench/browser/parts/editor/editorPart';
|
import { EditorPart } from 'vs/workbench/browser/parts/editor/editorPart';
|
||||||
import { EditorInput, EditorOptions } from 'vs/workbench/common/editor';
|
import { EditorInput, EditorOptions } from 'vs/workbench/common/editor';
|
||||||
import { KEYBINDING_CONTEXT_WEBVIEW_FIND_WIDGET_VISIBLE, Webview, WebviewEditorOverlay } from 'vs/workbench/contrib/webview/browser/webview';
|
import { KEYBINDING_CONTEXT_WEBVIEW_FIND_WIDGET_VISIBLE, WebviewEditorOverlay } from 'vs/workbench/contrib/webview/browser/webview';
|
||||||
import { WebviewInput } from 'vs/workbench/contrib/webview/browser/webviewEditorInput';
|
import { WebviewInput } from 'vs/workbench/contrib/webview/browser/webviewEditorInput';
|
||||||
import { IEditorGroup, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
|
import { IEditorGroup, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||||
@@ -71,31 +71,33 @@ export class WebviewEditor extends BaseEditor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public showFind() {
|
public showFind() {
|
||||||
this.withWebview(webview => {
|
if (this.webview) {
|
||||||
webview.showFind();
|
this.webview.showFind();
|
||||||
this._findWidgetVisible.set(true);
|
this._findWidgetVisible.set(true);
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public hideFind() {
|
public hideFind() {
|
||||||
this._findWidgetVisible.reset();
|
this._findWidgetVisible.reset();
|
||||||
this.withWebview(webview => webview.hideFind());
|
this.webview?.hideFind();
|
||||||
}
|
}
|
||||||
|
|
||||||
public find(previous: boolean) {
|
public find(previous: boolean) {
|
||||||
this.withWebview(webview => {
|
this.webview?.runFindAction(previous);
|
||||||
webview.runFindAction(previous);
|
}
|
||||||
});
|
|
||||||
|
public selectAll() {
|
||||||
|
this.webview?.selectAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
public reload() {
|
public reload() {
|
||||||
this.withWebview(webview => webview.reload());
|
this.webview?.reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
public layout(dimension: DOM.Dimension): void {
|
public layout(dimension: DOM.Dimension): void {
|
||||||
this._dimension = dimension;
|
this._dimension = dimension;
|
||||||
if (this.input && this.input instanceof WebviewInput) {
|
if (this.webview) {
|
||||||
this.synchronizeWebviewContainerDimensions(this.input.webview, dimension);
|
this.synchronizeWebviewContainerDimensions(this.webview, dimension);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,22 +111,19 @@ export class WebviewEditor extends BaseEditor {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
this.withWebview(webview => webview.focus());
|
this.webview?.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
public withWebview(f: (element: Webview) => void): void {
|
public get webview(): WebviewEditorOverlay | undefined {
|
||||||
if (this.input && this.input instanceof WebviewInput) {
|
return this.input instanceof WebviewInput ? this.input.webview : undefined;
|
||||||
f(this.input.webview);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected setEditorVisible(visible: boolean, group: IEditorGroup | undefined): void {
|
protected setEditorVisible(visible: boolean, group: IEditorGroup | undefined): void {
|
||||||
if (this.input instanceof WebviewInput) {
|
if (this.input instanceof WebviewInput && this.webview) {
|
||||||
const webview = this.input.webview;
|
|
||||||
if (visible) {
|
if (visible) {
|
||||||
webview.claim(this);
|
this.webview.claim(this);
|
||||||
} else {
|
} else {
|
||||||
webview.release(this);
|
this.webview.release(this);
|
||||||
}
|
}
|
||||||
this.claimWebview(this.input);
|
this.claimWebview(this.input);
|
||||||
}
|
}
|
||||||
@@ -132,8 +131,8 @@ export class WebviewEditor extends BaseEditor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public clearInput() {
|
public clearInput() {
|
||||||
if (this.input && this.input instanceof WebviewInput) {
|
if (this.webview) {
|
||||||
this.input.webview.release(this);
|
this.webview.release(this);
|
||||||
this._webviewVisibleDisposables.clear();
|
this._webviewVisibleDisposables.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,8 +144,8 @@ export class WebviewEditor extends BaseEditor {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.input && this.input instanceof WebviewInput) {
|
if (this.webview) {
|
||||||
this.input.webview.release(this);
|
this.webview.release(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
await super.setInput(input, options, token);
|
await super.setInput(input, options, token);
|
||||||
@@ -189,15 +188,11 @@ export class WebviewEditor extends BaseEditor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this._webviewVisibleDisposables.add(DOM.addDisposableListener(window, DOM.EventType.DRAG_START, () => {
|
this._webviewVisibleDisposables.add(DOM.addDisposableListener(window, DOM.EventType.DRAG_START, () => {
|
||||||
if (this.input instanceof WebviewInput) {
|
this.webview?.windowDidDragStart();
|
||||||
this.input.webview.windowDidDragStart();
|
|
||||||
}
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const onDragEnd = () => {
|
const onDragEnd = () => {
|
||||||
if (this.input instanceof WebviewInput) {
|
this.webview?.windowDidDragEnd();
|
||||||
this.input.webview.windowDidDragEnd();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
this._webviewVisibleDisposables.add(DOM.addDisposableListener(window, DOM.EventType.DRAG_END, onDragEnd));
|
this._webviewVisibleDisposables.add(DOM.addDisposableListener(window, DOM.EventType.DRAG_END, onDragEnd));
|
||||||
this._webviewVisibleDisposables.add(DOM.addDisposableListener(window, DOM.EventType.MOUSE_MOVE, currentEvent => {
|
this._webviewVisibleDisposables.add(DOM.addDisposableListener(window, DOM.EventType.MOUSE_MOVE, currentEvent => {
|
||||||
|
|||||||
@@ -26,8 +26,6 @@ actionRegistry.registerWorkbenchAction(
|
|||||||
function registerWebViewCommands(editorId: string): void {
|
function registerWebViewCommands(editorId: string): void {
|
||||||
const contextKeyExpr = ContextKeyExpr.and(ContextKeyExpr.equals('activeEditor', editorId), ContextKeyExpr.not('editorFocus') /* https://github.com/Microsoft/vscode/issues/58668 */)!;
|
const contextKeyExpr = ContextKeyExpr.and(ContextKeyExpr.equals('activeEditor', editorId), ContextKeyExpr.not('editorFocus') /* https://github.com/Microsoft/vscode/issues/58668 */)!;
|
||||||
|
|
||||||
registerAction2(class extends webviewCommands.SelectAllWebviewEditorCommand { constructor() { super(contextKeyExpr); } });
|
|
||||||
|
|
||||||
// These commands are only needed on MacOS where we have to disable the menu bar commands
|
// These commands are only needed on MacOS where we have to disable the menu bar commands
|
||||||
if (isMacintosh) {
|
if (isMacintosh) {
|
||||||
registerAction2(class extends webviewCommands.CopyWebviewEditorCommand { constructor() { super(contextKeyExpr); } });
|
registerAction2(class extends webviewCommands.CopyWebviewEditorCommand { constructor() { super(contextKeyExpr); } });
|
||||||
|
|||||||
@@ -38,28 +38,6 @@ export class OpenWebviewDeveloperToolsAction extends Action {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SelectAllWebviewEditorCommand extends Action2 {
|
|
||||||
public static readonly ID = 'editor.action.webvieweditor.selectAll';
|
|
||||||
public static readonly LABEL = nls.localize('editor.action.webvieweditor.selectAll', 'Select all');
|
|
||||||
|
|
||||||
constructor(contextKeyExpr: ContextKeyExpr) {
|
|
||||||
const precondition = ContextKeyExpr.and(contextKeyExpr, ContextKeyExpr.not(InputFocusedContextKey));
|
|
||||||
super({
|
|
||||||
id: SelectAllWebviewEditorCommand.ID,
|
|
||||||
title: SelectAllWebviewEditorCommand.LABEL,
|
|
||||||
keybinding: {
|
|
||||||
when: precondition,
|
|
||||||
primary: KeyMod.CtrlCmd | KeyCode.KEY_A,
|
|
||||||
weight: KeybindingWeight.EditorContrib
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public run(accessor: ServicesAccessor, args: any): void {
|
|
||||||
withActiveWebviewBasedWebview(accessor, webview => webview.selectAll());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class CopyWebviewEditorCommand extends Action2 {
|
export class CopyWebviewEditorCommand extends Action2 {
|
||||||
public static readonly ID = 'editor.action.webvieweditor.copy';
|
public static readonly ID = 'editor.action.webvieweditor.copy';
|
||||||
public static readonly LABEL = nls.localize('editor.action.webvieweditor.copy', "Copy2");
|
public static readonly LABEL = nls.localize('editor.action.webvieweditor.copy', "Copy2");
|
||||||
@@ -77,7 +55,7 @@ export class CopyWebviewEditorCommand extends Action2 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public run(accessor: ServicesAccessor): void {
|
public run(accessor: ServicesAccessor): void {
|
||||||
withActiveWebviewBasedWebview(accessor, webview => webview.copy());
|
getActiveWebviewBasedWebview(accessor)?.copy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,7 +76,7 @@ export class PasteWebviewEditorCommand extends Action2 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public run(accessor: ServicesAccessor): void {
|
public run(accessor: ServicesAccessor): void {
|
||||||
withActiveWebviewBasedWebview(accessor, webview => webview.paste());
|
getActiveWebviewBasedWebview(accessor)?.paste();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,7 +97,7 @@ export class CutWebviewEditorCommand extends Action2 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public run(accessor: ServicesAccessor): void {
|
public run(accessor: ServicesAccessor): void {
|
||||||
withActiveWebviewBasedWebview(accessor, webview => webview.cut());
|
getActiveWebviewBasedWebview(accessor)?.cut();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,7 +118,7 @@ export class UndoWebviewEditorCommand extends Action2 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public run(accessor: ServicesAccessor, args: any): void {
|
public run(accessor: ServicesAccessor, args: any): void {
|
||||||
withActiveWebviewBasedWebview(accessor, webview => webview.undo());
|
getActiveWebviewBasedWebview(accessor)?.undo();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,22 +141,24 @@ export class RedoWebviewEditorCommand extends Action2 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public run(accessor: ServicesAccessor, args: any): void {
|
public run(accessor: ServicesAccessor, args: any): void {
|
||||||
withActiveWebviewBasedWebview(accessor, webview => webview.redo());
|
getActiveWebviewBasedWebview(accessor)?.redo();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function withActiveWebviewBasedWebview(accessor: ServicesAccessor, f: (webview: ElectronWebviewBasedWebview) => void): void {
|
function getActiveWebviewBasedWebview(accessor: ServicesAccessor): ElectronWebviewBasedWebview | undefined {
|
||||||
const webViewEditor = getActiveWebviewEditor(accessor);
|
const webview = getActiveWebviewEditor(accessor)?.webview;
|
||||||
if (webViewEditor) {
|
if (!webview) {
|
||||||
webViewEditor.withWebview(webview => {
|
return undefined;
|
||||||
if (webview instanceof ElectronWebviewBasedWebview) {
|
|
||||||
f(webview);
|
|
||||||
} else if ((webview as WebviewEditorOverlay).getInnerWebview) {
|
|
||||||
const innerWebview = (webview as WebviewEditorOverlay).getInnerWebview();
|
|
||||||
if (innerWebview instanceof ElectronWebviewBasedWebview) {
|
|
||||||
f(innerWebview);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (webview instanceof ElectronWebviewBasedWebview) {
|
||||||
|
return webview;
|
||||||
|
} else if ((webview as WebviewEditorOverlay).getInnerWebview) {
|
||||||
|
const innerWebview = (webview as WebviewEditorOverlay).getInnerWebview();
|
||||||
|
if (innerWebview instanceof ElectronWebviewBasedWebview) {
|
||||||
|
return innerWebview;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import { NoEditorsVisibleContext, SingleEditorGroupsContext } from 'vs/workbench
|
|||||||
import { IElectronService } from 'vs/platform/electron/node/electron';
|
import { IElectronService } from 'vs/platform/electron/node/electron';
|
||||||
import { IJSONContributionRegistry, Extensions as JSONExtensions } from 'vs/platform/jsonschemas/common/jsonContributionRegistry';
|
import { IJSONContributionRegistry, Extensions as JSONExtensions } from 'vs/platform/jsonschemas/common/jsonContributionRegistry';
|
||||||
import product from 'vs/platform/product/common/product';
|
import product from 'vs/platform/product/common/product';
|
||||||
|
import { IJSONSchema } from 'vs/base/common/jsonSchema';
|
||||||
|
|
||||||
import { InstallVSIXAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions'; // {{SQL CARBON EDIT}} add import
|
import { InstallVSIXAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions'; // {{SQL CARBON EDIT}} add import
|
||||||
|
|
||||||
@@ -333,8 +334,7 @@ import { InstallVSIXAction } from 'vs/workbench/contrib/extensions/browser/exten
|
|||||||
(function registerJSONSchemas(): void {
|
(function registerJSONSchemas(): void {
|
||||||
const argvDefinitionFileSchemaId = 'vscode://schemas/argv';
|
const argvDefinitionFileSchemaId = 'vscode://schemas/argv';
|
||||||
const jsonRegistry = Registry.as<IJSONContributionRegistry>(JSONExtensions.JSONContribution);
|
const jsonRegistry = Registry.as<IJSONContributionRegistry>(JSONExtensions.JSONContribution);
|
||||||
|
const schema: IJSONSchema = {
|
||||||
jsonRegistry.registerSchema(argvDefinitionFileSchemaId, {
|
|
||||||
id: argvDefinitionFileSchemaId,
|
id: argvDefinitionFileSchemaId,
|
||||||
allowComments: true,
|
allowComments: true,
|
||||||
allowTrailingCommas: true,
|
allowTrailingCommas: true,
|
||||||
@@ -355,5 +355,13 @@ import { InstallVSIXAction } from 'vs/workbench/contrib/extensions/browser/exten
|
|||||||
description: nls.localize('argv.disableColorCorrectRendering', 'Resolves issues around color profile selection. ONLY change this option if you encounter graphic issues.')
|
description: nls.localize('argv.disableColorCorrectRendering', 'Resolves issues around color profile selection. ONLY change this option if you encounter graphic issues.')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
if (isLinux) {
|
||||||
|
schema.properties!['force-renderer-accessibility'] = {
|
||||||
|
type: 'boolean',
|
||||||
|
description: nls.localize('argv.force-renderer-accessibility', 'Forces the renderer to be accessible. ONLY change this if you are using a screen reader on Linux. On other platforms the renderer will automatically be accessible. This flag is automatically set if you have editor.accessibilitySupport: on.'),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonRegistry.registerSchema(argvDefinitionFileSchemaId, schema);
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -4,13 +4,18 @@
|
|||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
import { IAccessibilityService, AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility';
|
import { IAccessibilityService, AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility';
|
||||||
import { isWindows } from 'vs/base/common/platform';
|
import { isWindows, isLinux } from 'vs/base/common/platform';
|
||||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||||
|
import { Registry } from 'vs/platform/registry/common/platform';
|
||||||
import { AccessibilityService } from 'vs/platform/accessibility/common/accessibilityService';
|
import { AccessibilityService } from 'vs/platform/accessibility/common/accessibilityService';
|
||||||
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
||||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||||
|
import { IJSONEditingService } from 'vs/workbench/services/configuration/common/jsonEditing';
|
||||||
|
import { IWorkbenchContribution, IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions';
|
||||||
|
import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
|
||||||
|
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||||
|
|
||||||
interface AccessibilityMetrics {
|
interface AccessibilityMetrics {
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
@@ -65,3 +70,22 @@ export class NodeAccessibilityService extends AccessibilityService implements IA
|
|||||||
}
|
}
|
||||||
|
|
||||||
registerSingleton(IAccessibilityService, NodeAccessibilityService, true);
|
registerSingleton(IAccessibilityService, NodeAccessibilityService, true);
|
||||||
|
|
||||||
|
// On linux we do not automatically detect that a screen reader is detected, thus we have to implicitly notify the renderer to enable accessibility when user configures it in settings
|
||||||
|
class LinuxAccessibilityContribution implements IWorkbenchContribution {
|
||||||
|
constructor(
|
||||||
|
@IJSONEditingService jsonEditingService: IJSONEditingService,
|
||||||
|
@IAccessibilityService accessibilityService: AccessibilityService,
|
||||||
|
@IEnvironmentService environmentService: IEnvironmentService
|
||||||
|
) {
|
||||||
|
accessibilityService.onDidChangeScreenReaderOptimized(async () => {
|
||||||
|
if (accessibilityService.isScreenReaderOptimized()) {
|
||||||
|
await jsonEditingService.write(environmentService.argvResource, [{ key: 'force-renderer-accessibility', value: true }], true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isLinux) {
|
||||||
|
Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench).registerWorkbenchContribution(LinuxAccessibilityContribution, LifecyclePhase.Ready);
|
||||||
|
}
|
||||||
|
|||||||
@@ -95,6 +95,10 @@ export class BrowserHostService extends Disposable implements IHostService {
|
|||||||
return document.hasFocus();
|
return document.hasFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async hadLastFocus(): Promise<boolean> {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
async focus(): Promise<void> {
|
async focus(): Promise<void> {
|
||||||
window.focus();
|
window.focus();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,11 @@ export interface IHostService {
|
|||||||
*/
|
*/
|
||||||
readonly hasFocus: boolean;
|
readonly hasFocus: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find out if the window had the last focus.
|
||||||
|
*/
|
||||||
|
hadLastFocus(): Promise<boolean>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempt to bring the window to the foreground and focus it.
|
* Attempt to bring the window to the foreground and focus it.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -36,6 +36,16 @@ export class DesktopHostService extends Disposable implements IHostService {
|
|||||||
return document.hasFocus();
|
return document.hasFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async hadLastFocus(): Promise<boolean> {
|
||||||
|
const activeWindowId = await this.electronService.getActiveWindowId();
|
||||||
|
|
||||||
|
if (typeof activeWindowId === 'undefined') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return activeWindowId === this.electronEnvironmentService.windowId;
|
||||||
|
}
|
||||||
|
|
||||||
openWindow(options?: IOpenEmptyWindowOptions): Promise<void>;
|
openWindow(options?: IOpenEmptyWindowOptions): Promise<void>;
|
||||||
openWindow(toOpen: IWindowOpenable[], options?: IOpenWindowOptions): Promise<void>;
|
openWindow(toOpen: IWindowOpenable[], options?: IOpenWindowOptions): Promise<void>;
|
||||||
openWindow(arg1?: IOpenEmptyWindowOptions | IWindowOpenable[], arg2?: IOpenWindowOptions): Promise<void> {
|
openWindow(arg1?: IOpenEmptyWindowOptions | IWindowOpenable[], arg2?: IOpenWindowOptions): Promise<void> {
|
||||||
|
|||||||
@@ -79,7 +79,6 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
|
|||||||
private lastResolvedFileStat: IFileStatWithMetadata | undefined;
|
private lastResolvedFileStat: IFileStatWithMetadata | undefined;
|
||||||
|
|
||||||
private readonly saveSequentializer = new TaskSequentializer();
|
private readonly saveSequentializer = new TaskSequentializer();
|
||||||
private lastSaveAttemptTime = 0;
|
|
||||||
|
|
||||||
private dirty = false;
|
private dirty = false;
|
||||||
private inConflictMode = false;
|
private inConflictMode = false;
|
||||||
@@ -553,16 +552,15 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
|
|||||||
return false; // if model is in save conflict or error, do not save unless save reason is explicit
|
return false; // if model is in save conflict or error, do not save unless save reason is explicit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Actually do save and log
|
||||||
this.logService.trace('[text file model] save() - enter', this.resource.toString());
|
this.logService.trace('[text file model] save() - enter', this.resource.toString());
|
||||||
|
|
||||||
await this.doSave(options);
|
await this.doSave(options);
|
||||||
|
|
||||||
this.logService.trace('[text file model] save() - exit', this.resource.toString());
|
this.logService.trace('[text file model] save() - exit', this.resource.toString());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private doSave(options: ITextFileSaveOptions): Promise<void> {
|
private async doSave(options: ITextFileSaveOptions): Promise<void> {
|
||||||
if (typeof options.reason !== 'number') {
|
if (typeof options.reason !== 'number') {
|
||||||
options.reason = SaveReason.EXPLICIT;
|
options.reason = SaveReason.EXPLICIT;
|
||||||
}
|
}
|
||||||
@@ -587,7 +585,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
|
|||||||
if (!options.force && !this.dirty) {
|
if (!options.force && !this.dirty) {
|
||||||
this.logService.trace(`[text file model] doSave(${versionId}) - exit - because not dirty and/or versionId is different (this.isDirty: ${this.dirty}, this.versionId: ${this.versionId})`, this.resource.toString());
|
this.logService.trace(`[text file model] doSave(${versionId}) - exit - because not dirty and/or versionId is different (this.isDirty: ${this.dirty}, this.versionId: ${this.versionId})`, this.resource.toString());
|
||||||
|
|
||||||
return Promise.resolve();
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return if currently saving by storing this save request as the next save that should happen.
|
// Return if currently saving by storing this save request as the next save that should happen.
|
||||||
@@ -618,26 +616,22 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
|
|||||||
this.textEditorModel.pushStackElement();
|
this.textEditorModel.pushStackElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
// A save participant can still change the model now and since we are so close to saving
|
|
||||||
// we do not want to trigger another auto save or similar, so we block this
|
|
||||||
// In addition we update our version right after in case it changed because of a model change
|
|
||||||
//
|
|
||||||
// Save participants can also be skipped through API.
|
|
||||||
const saveParticipantCancellation = new CancellationTokenSource();
|
const saveParticipantCancellation = new CancellationTokenSource();
|
||||||
let saveParticipantPromise: Promise<number> = Promise.resolve(versionId);
|
|
||||||
if (this.isResolved() && this.textFileService.saveParticipant && !options.skipSaveParticipants) {
|
|
||||||
const onCompleteOrError = () => {
|
|
||||||
this.ignoreDirtyOnModelContentChange = false;
|
|
||||||
|
|
||||||
return this.versionId;
|
return (this.saveSequentializer as TaskSequentializer).setPending(versionId, (async () => { // {{SQL CARBON EDIT}} strict-null-checks
|
||||||
};
|
|
||||||
|
|
||||||
this.ignoreDirtyOnModelContentChange = true;
|
// A save participant can still change the model now and since we are so close to saving
|
||||||
saveParticipantPromise = this.textFileService.saveParticipant.participate(this, { reason: options.reason }, saveParticipantCancellation.token).then(onCompleteOrError, onCompleteOrError);
|
// we do not want to trigger another auto save or similar, so we block this
|
||||||
}
|
// In addition we update our version right after in case it changed because of a model change
|
||||||
|
//
|
||||||
// mark the save participant as current pending save operation
|
// Save participants can also be skipped through API.
|
||||||
return (this.saveSequentializer as TaskSequentializer).setPending(versionId, saveParticipantPromise.then(newVersionId => { // {{SQL CARBON EDIT}} strict-null-check
|
if (this.isResolved() && this.textFileService.saveParticipant && !options.skipSaveParticipants) {
|
||||||
|
try {
|
||||||
|
await this.textFileService.saveParticipant.participate(this, { reason: options.reason ?? SaveReason.EXPLICIT }, saveParticipantCancellation.token);
|
||||||
|
} catch (error) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// We have to protect against being disposed at this point. It could be that the save() operation
|
// We have to protect against being disposed at this point. It could be that the save() operation
|
||||||
// was triggerd followed by a dispose() operation right after without waiting. Typically we cannot
|
// was triggerd followed by a dispose() operation right after without waiting. Typically we cannot
|
||||||
@@ -661,32 +655,39 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
|
|||||||
// - the model is not dirty (otherwise we know there are changed which needs to go to the file)
|
// - the model is not dirty (otherwise we know there are changed which needs to go to the file)
|
||||||
// - the model is not in orphan mode (because in that case we know the file does not exist on disk)
|
// - the model is not in orphan mode (because in that case we know the file does not exist on disk)
|
||||||
// - the model version did not change due to save participants running
|
// - the model version did not change due to save participants running
|
||||||
if (options.force && !this.dirty && !this.inOrphanMode && options.reason === SaveReason.EXPLICIT && versionId === newVersionId) {
|
if (options.force && !this.dirty && !this.inOrphanMode && options.reason === SaveReason.EXPLICIT && versionId === this.versionId) {
|
||||||
return this.doTouch(newVersionId, options.reason);
|
return this.doTouch(this.versionId, options.reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
// update versionId with its new value (if pre-save changes happened)
|
// update versionId with its new value (if pre-save changes happened)
|
||||||
versionId = newVersionId;
|
versionId = this.versionId;
|
||||||
|
|
||||||
// Clear error flag since we are trying to save again
|
// Clear error flag since we are trying to save again
|
||||||
this.inErrorMode = false;
|
this.inErrorMode = false;
|
||||||
|
|
||||||
// Remember when this model was saved last
|
// Save to Disk. We mark the save operation as currently pending with
|
||||||
this.lastSaveAttemptTime = Date.now();
|
// the latest versionId because it might have changed from a save
|
||||||
|
// participant triggering
|
||||||
// Save to Disk
|
|
||||||
// mark the save operation as currently pending with the versionId (it might have changed from a save participant triggering)
|
|
||||||
this.logService.trace(`[text file model] doSave(${versionId}) - before write()`, this.resource.toString());
|
this.logService.trace(`[text file model] doSave(${versionId}) - before write()`, this.resource.toString());
|
||||||
const lastResolvedFileStat = assertIsDefined(this.lastResolvedFileStat);
|
const lastResolvedFileStat = assertIsDefined(this.lastResolvedFileStat);
|
||||||
return this.saveSequentializer.setPending(newVersionId, this.textFileService.write(lastResolvedFileStat.resource, this.createSnapshot(), {
|
const textFileEdiorModel = this;
|
||||||
overwriteReadonly: options.overwriteReadonly,
|
return this.saveSequentializer.setPending(versionId, (async () => {
|
||||||
overwriteEncoding: options.overwriteEncoding,
|
try {
|
||||||
mtime: lastResolvedFileStat.mtime,
|
const stat = await this.textFileService.write(lastResolvedFileStat.resource, textFileEdiorModel.createSnapshot(), {
|
||||||
encoding: this.getEncoding(),
|
overwriteReadonly: options.overwriteReadonly,
|
||||||
etag: (options.ignoreModifiedSince || !this.filesConfigurationService.preventSaveConflicts(lastResolvedFileStat.resource, this.getMode())) ? ETAG_DISABLED : lastResolvedFileStat.etag,
|
overwriteEncoding: options.overwriteEncoding,
|
||||||
writeElevated: options.writeElevated
|
mtime: lastResolvedFileStat.mtime,
|
||||||
}).then(stat => this.handleSaveSuccess(stat, versionId, options), error => this.handleSaveError(error, versionId, options)));
|
encoding: this.getEncoding(),
|
||||||
}), () => saveParticipantCancellation.cancel());
|
etag: (options.ignoreModifiedSince || !this.filesConfigurationService.preventSaveConflicts(lastResolvedFileStat.resource, textFileEdiorModel.getMode())) ? ETAG_DISABLED : lastResolvedFileStat.etag,
|
||||||
|
writeElevated: options.writeElevated
|
||||||
|
});
|
||||||
|
|
||||||
|
this.handleSaveSuccess(stat, versionId, options);
|
||||||
|
} catch (error) {
|
||||||
|
this.handleSaveError(error, versionId, options);
|
||||||
|
}
|
||||||
|
})());
|
||||||
|
})(), () => saveParticipantCancellation.cancel());
|
||||||
}
|
}
|
||||||
|
|
||||||
private handleSaveSuccess(stat: IFileStatWithMetadata, versionId: number, options: ITextFileSaveOptions): void {
|
private handleSaveSuccess(stat: IFileStatWithMetadata, versionId: number, options: ITextFileSaveOptions): void {
|
||||||
@@ -733,19 +734,24 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
|
|||||||
|
|
||||||
private doTouch(this: TextFileEditorModel & IResolvedTextFileEditorModel, versionId: number, reason: SaveReason): Promise<void> {
|
private doTouch(this: TextFileEditorModel & IResolvedTextFileEditorModel, versionId: number, reason: SaveReason): Promise<void> {
|
||||||
const lastResolvedFileStat = assertIsDefined(this.lastResolvedFileStat);
|
const lastResolvedFileStat = assertIsDefined(this.lastResolvedFileStat);
|
||||||
return this.saveSequentializer.setPending(versionId, this.textFileService.write(lastResolvedFileStat.resource, this.createSnapshot(), {
|
|
||||||
mtime: lastResolvedFileStat.mtime,
|
|
||||||
encoding: this.getEncoding(),
|
|
||||||
etag: lastResolvedFileStat.etag
|
|
||||||
}).then(stat => {
|
|
||||||
|
|
||||||
// Updated resolved stat with updated stat since touching it might have changed mtime
|
return this.saveSequentializer.setPending(versionId, (async () => {
|
||||||
this.updateLastResolvedFileStat(stat);
|
try {
|
||||||
|
const stat = await this.textFileService.write(lastResolvedFileStat.resource, this.createSnapshot(), {
|
||||||
|
mtime: lastResolvedFileStat.mtime,
|
||||||
|
encoding: this.getEncoding(),
|
||||||
|
etag: lastResolvedFileStat.etag
|
||||||
|
});
|
||||||
|
|
||||||
// Emit File Saved Event
|
// Updated resolved stat with updated stat since touching it might have changed mtime
|
||||||
this._onDidSave.fire(reason);
|
this.updateLastResolvedFileStat(stat);
|
||||||
|
|
||||||
}, error => onUnexpectedError(error) /* just log any error but do not notify the user since the file was not dirty */));
|
// Emit File Saved Event
|
||||||
|
this._onDidSave.fire(reason);
|
||||||
|
} catch (error) {
|
||||||
|
onUnexpectedError(error); // just log any error but do not notify the user since the file was not dirty
|
||||||
|
}
|
||||||
|
})());
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateSavedVersionId(): void {
|
private updateSavedVersionId(): void {
|
||||||
@@ -776,10 +782,6 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
|
|||||||
|
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
getLastSaveAttemptTime(): number {
|
|
||||||
return this.lastSaveAttemptTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
hasState(state: ModelState): boolean {
|
hasState(state: ModelState): boolean {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case ModelState.CONFLICT:
|
case ModelState.CONFLICT:
|
||||||
|
|||||||
@@ -84,7 +84,13 @@ export class TextFileEditorModelManager extends Disposable implements ITextFileE
|
|||||||
// to have a size of 2 (1 running load and 1 queued load).
|
// to have a size of 2 (1 running load and 1 queued load).
|
||||||
const queue = this.modelLoadQueue.queueFor(model.resource);
|
const queue = this.modelLoadQueue.queueFor(model.resource);
|
||||||
if (queue.size <= 1) {
|
if (queue.size <= 1) {
|
||||||
queue.queue(() => model.load().then(undefined, onUnexpectedError));
|
queue.queue(async () => {
|
||||||
|
try {
|
||||||
|
await model.load();
|
||||||
|
} catch (error) {
|
||||||
|
onUnexpectedError(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -120,7 +120,6 @@ suite('Files - TextFileEditorModel', () => {
|
|||||||
|
|
||||||
await pendingSave;
|
await pendingSave;
|
||||||
|
|
||||||
assert.ok(model.getLastSaveAttemptTime() <= Date.now());
|
|
||||||
assert.ok(model.hasState(ModelState.SAVED));
|
assert.ok(model.hasState(ModelState.SAVED));
|
||||||
assert.ok(!model.isDirty());
|
assert.ok(!model.isDirty());
|
||||||
assert.ok(savedEvent);
|
assert.ok(savedEvent);
|
||||||
@@ -488,8 +487,6 @@ suite('Files - TextFileEditorModel', () => {
|
|||||||
assert.ok(!accessor.textFileService.isDirty(toResource.call(this, '/path/index_async2.txt')));
|
assert.ok(!accessor.textFileService.isDirty(toResource.call(this, '/path/index_async2.txt')));
|
||||||
assert.ok(assertIsDefined(model1.getStat()).mtime > m1Mtime);
|
assert.ok(assertIsDefined(model1.getStat()).mtime > m1Mtime);
|
||||||
assert.ok(assertIsDefined(model2.getStat()).mtime > m2Mtime);
|
assert.ok(assertIsDefined(model2.getStat()).mtime > m2Mtime);
|
||||||
assert.ok(model1.getLastSaveAttemptTime() > m1Mtime);
|
|
||||||
assert.ok(model2.getLastSaveAttemptTime() > m2Mtime);
|
|
||||||
|
|
||||||
model1.dispose();
|
model1.dispose();
|
||||||
model2.dispose();
|
model2.dispose();
|
||||||
@@ -506,12 +503,11 @@ suite('Files - TextFileEditorModel', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
accessor.textFileService.saveParticipant = {
|
accessor.textFileService.saveParticipant = {
|
||||||
participate: model => {
|
participate: async model => {
|
||||||
assert.ok(model.isDirty());
|
assert.ok(model.isDirty());
|
||||||
model.textEditorModel!.setValue('bar');
|
model.textEditorModel!.setValue('bar');
|
||||||
assert.ok(model.isDirty());
|
assert.ok(model.isDirty());
|
||||||
eventCounter++;
|
eventCounter++;
|
||||||
return Promise.resolve();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -545,8 +541,8 @@ suite('Files - TextFileEditorModel', () => {
|
|||||||
const model: TextFileEditorModel = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/index_async.txt'), 'utf8', undefined);
|
const model: TextFileEditorModel = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/index_async.txt'), 'utf8', undefined);
|
||||||
|
|
||||||
accessor.textFileService.saveParticipant = {
|
accessor.textFileService.saveParticipant = {
|
||||||
participate: (model) => {
|
participate: async model => {
|
||||||
return Promise.reject(new Error('boom'));
|
new Error('boom');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -563,10 +559,9 @@ suite('Files - TextFileEditorModel', () => {
|
|||||||
let participations: boolean[] = [];
|
let participations: boolean[] = [];
|
||||||
|
|
||||||
accessor.textFileService.saveParticipant = {
|
accessor.textFileService.saveParticipant = {
|
||||||
participate: (model) => {
|
participate: async model => {
|
||||||
return timeout(10).then(() => {
|
await timeout(10);
|
||||||
participations.push(true);
|
participations.push(true);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -586,4 +581,49 @@ suite('Files - TextFileEditorModel', () => {
|
|||||||
assert.equal(participations.length, 1);
|
assert.equal(participations.length, 1);
|
||||||
model.dispose();
|
model.dispose();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('Save Participant, calling save from within is unsupported but does not explode (sync save)', async function () {
|
||||||
|
const model: TextFileEditorModel = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/index_async.txt'), 'utf8', undefined);
|
||||||
|
|
||||||
|
await testSaveFromSaveParticipant(model, false);
|
||||||
|
|
||||||
|
model.dispose();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Save Participant, calling save from within is unsupported but does not explode (async save)', async function () {
|
||||||
|
const model: TextFileEditorModel = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/index_async.txt'), 'utf8', undefined);
|
||||||
|
|
||||||
|
await testSaveFromSaveParticipant(model, true);
|
||||||
|
|
||||||
|
model.dispose();
|
||||||
|
});
|
||||||
|
|
||||||
|
async function testSaveFromSaveParticipant(model: TextFileEditorModel, async: boolean): Promise<void> {
|
||||||
|
let savePromise: Promise<boolean>;
|
||||||
|
let breakLoop = false;
|
||||||
|
|
||||||
|
accessor.textFileService.saveParticipant = {
|
||||||
|
participate: async model => {
|
||||||
|
if (breakLoop) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
breakLoop = true;
|
||||||
|
|
||||||
|
if (async) {
|
||||||
|
await timeout(10);
|
||||||
|
}
|
||||||
|
const newSavePromise = model.save();
|
||||||
|
|
||||||
|
// assert that this is the same promise as the outer one
|
||||||
|
assert.equal(savePromise, newSavePromise);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
await model.load();
|
||||||
|
model.textEditorModel!.setValue('foo');
|
||||||
|
|
||||||
|
savePromise = model.save();
|
||||||
|
await savePromise;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -537,6 +537,22 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If a value is not present in the cache, it must be reset to default
|
||||||
|
this.viewContainersRegistry.all.forEach(viewContainer => {
|
||||||
|
const viewDescriptorCollection = this.getViewDescriptors(viewContainer);
|
||||||
|
viewDescriptorCollection.allViewDescriptors.forEach(viewDescriptor => {
|
||||||
|
if (!newCachedPositions.has(viewDescriptor.id)) {
|
||||||
|
const currentContainer = this.getViewContainer(viewDescriptor.id);
|
||||||
|
const defaultContainer = this.getDefaultContainer(viewDescriptor.id);
|
||||||
|
if (currentContainer && defaultContainer && currentContainer !== defaultContainer) {
|
||||||
|
this.moveViews([viewDescriptor], currentContainer, defaultContainer);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.cachedViewInfo.delete(viewDescriptor.id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
this.cachedViewInfo = this.getCachedViewPositions();
|
this.cachedViewInfo = this.getCachedViewPositions();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -571,6 +587,16 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Do no save default positions to the cache
|
||||||
|
// so that default changes can be recognized
|
||||||
|
// https://github.com/microsoft/vscode/issues/90414
|
||||||
|
for (const [viewId, containerInfo] of this.cachedViewInfo) {
|
||||||
|
const defaultContainer = this.getDefaultContainer(viewId);
|
||||||
|
if (defaultContainer?.id === containerInfo.containerId) {
|
||||||
|
this.cachedViewInfo.delete(viewId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.cachedViewPositionsValue = JSON.stringify([...this.cachedViewInfo]);
|
this.cachedViewPositionsValue = JSON.stringify([...this.cachedViewInfo]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -865,6 +865,7 @@ export class TestHostService implements IHostService {
|
|||||||
_serviceBrand: undefined;
|
_serviceBrand: undefined;
|
||||||
|
|
||||||
readonly hasFocus: boolean = true;
|
readonly hasFocus: boolean = true;
|
||||||
|
async hadLastFocus(): Promise<boolean> { return true; }
|
||||||
readonly onDidChangeFocus: Event<boolean> = Event.None;
|
readonly onDidChangeFocus: Event<boolean> = Event.None;
|
||||||
|
|
||||||
async restart(): Promise<void> { }
|
async restart(): Promise<void> { }
|
||||||
|
|||||||
@@ -80,17 +80,29 @@ interface IApplicationLink {
|
|||||||
uri: URI;
|
uri: URI;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A label for the link to display.
|
* A label for the application link to display.
|
||||||
*/
|
*/
|
||||||
label: string;
|
label: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IApplicationLinkProvider {
|
interface ICommand {
|
||||||
(): IApplicationLink[] | undefined
|
|
||||||
|
/**
|
||||||
|
* An identifier for the command. Commands can be executed from extensions
|
||||||
|
* using the `vscode.commands.executeCommand` API using that command ID.
|
||||||
|
*/
|
||||||
|
id: string,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A function that is being executed with any arguments passed over.
|
||||||
|
*/
|
||||||
|
handler: (...args: any[]) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IWorkbenchConstructionOptions {
|
interface IWorkbenchConstructionOptions {
|
||||||
|
|
||||||
|
//#region Connection related configuration
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The remote authority is the IP:PORT from where the workbench is served
|
* The remote authority is the IP:PORT from where the workbench is served
|
||||||
* from. It is for example being used for the websocket connections as address.
|
* from. It is for example being used for the websocket connections as address.
|
||||||
@@ -108,6 +120,36 @@ interface IWorkbenchConstructionOptions {
|
|||||||
*/
|
*/
|
||||||
readonly webviewEndpoint?: string;
|
readonly webviewEndpoint?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A factory for web sockets.
|
||||||
|
*/
|
||||||
|
readonly webSocketFactory?: IWebSocketFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A provider for resource URIs.
|
||||||
|
*/
|
||||||
|
readonly resourceUriProvider?: IResourceUriProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolves an external uri before it is opened.
|
||||||
|
*/
|
||||||
|
readonly resolveExternalUri?: IExternalUriResolver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Support for creating tunnels.
|
||||||
|
*/
|
||||||
|
readonly tunnelFactory?: ITunnelFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Support for filtering candidate ports
|
||||||
|
*/
|
||||||
|
readonly showCandidate?: IShowCandidate;
|
||||||
|
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
|
||||||
|
//#region Workbench configuration
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A handler for opening workspaces and providing the initial workspace.
|
* A handler for opening workspaces and providing the initial workspace.
|
||||||
*/
|
*/
|
||||||
@@ -119,16 +161,6 @@ interface IWorkbenchConstructionOptions {
|
|||||||
*/
|
*/
|
||||||
userDataProvider?: IFileSystemProvider;
|
userDataProvider?: IFileSystemProvider;
|
||||||
|
|
||||||
/**
|
|
||||||
* A factory for web sockets.
|
|
||||||
*/
|
|
||||||
readonly webSocketFactory?: IWebSocketFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A provider for resource URIs.
|
|
||||||
*/
|
|
||||||
readonly resourceUriProvider?: IResourceUriProvider;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The credentials provider to store and retrieve secrets.
|
* The credentials provider to store and retrieve secrets.
|
||||||
*/
|
*/
|
||||||
@@ -154,21 +186,6 @@ interface IWorkbenchConstructionOptions {
|
|||||||
*/
|
*/
|
||||||
readonly resolveCommonTelemetryProperties?: ICommontTelemetryPropertiesResolver;
|
readonly resolveCommonTelemetryProperties?: ICommontTelemetryPropertiesResolver;
|
||||||
|
|
||||||
/**
|
|
||||||
* Resolves an external uri before it is opened.
|
|
||||||
*/
|
|
||||||
readonly resolveExternalUri?: IExternalUriResolver;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Support for creating tunnels.
|
|
||||||
*/
|
|
||||||
readonly tunnelFactory?: ITunnelFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Support for filtering candidate ports
|
|
||||||
*/
|
|
||||||
readonly showCandidate?: IShowCandidate;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provide entries for the "Open in Desktop" feature.
|
* Provide entries for the "Open in Desktop" feature.
|
||||||
*
|
*
|
||||||
@@ -179,7 +196,20 @@ interface IWorkbenchConstructionOptions {
|
|||||||
* - N elements: there will be a "Open in Desktop" affordance that opens
|
* - N elements: there will be a "Open in Desktop" affordance that opens
|
||||||
* a picker on click to select which application to open.
|
* a picker on click to select which application to open.
|
||||||
*/
|
*/
|
||||||
readonly applicationLinkProvider?: IApplicationLinkProvider;
|
readonly applicationLinks?: readonly IApplicationLink[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A set of optional commands that should be registered with the commands
|
||||||
|
* registry.
|
||||||
|
*
|
||||||
|
* Note: commands can be called from extensions if the identifier is known!
|
||||||
|
*/
|
||||||
|
readonly commands?: readonly ICommand[];
|
||||||
|
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
|
||||||
|
//#region Diagnostics
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Current logging level. Default is `LogLevel.Info`.
|
* Current logging level. Default is `LogLevel.Info`.
|
||||||
@@ -190,20 +220,8 @@ interface IWorkbenchConstructionOptions {
|
|||||||
* Whether to enable the smoke test driver.
|
* Whether to enable the smoke test driver.
|
||||||
*/
|
*/
|
||||||
readonly driver?: boolean;
|
readonly driver?: boolean;
|
||||||
}
|
|
||||||
|
|
||||||
interface ICommandHandler {
|
//#endregion
|
||||||
(...args: any[]): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IWorkbench {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Register a command with the provided identifier and handler with
|
|
||||||
* the workbench. The command can be called from extensions using the
|
|
||||||
* `vscode.commands.executeCommand` API.
|
|
||||||
*/
|
|
||||||
registerCommand(id: string, command: ICommandHandler): IDisposable;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -211,24 +229,22 @@ interface IWorkbench {
|
|||||||
*
|
*
|
||||||
* @param domElement the container to create the workbench in
|
* @param domElement the container to create the workbench in
|
||||||
* @param options for setting up the workbench
|
* @param options for setting up the workbench
|
||||||
*
|
|
||||||
* @returns the workbench facade with additional methods to call on.
|
|
||||||
*/
|
*/
|
||||||
async function create(domElement: HTMLElement, options: IWorkbenchConstructionOptions): Promise<IWorkbench> {
|
async function create(domElement: HTMLElement, options: IWorkbenchConstructionOptions): Promise<void> {
|
||||||
|
|
||||||
// Startup workbench
|
// Startup workbench
|
||||||
await main(domElement, options);
|
await main(domElement, options);
|
||||||
|
|
||||||
// Return facade
|
// Register commands if any
|
||||||
return {
|
if (Array.isArray(options.commands)) {
|
||||||
registerCommand: (id: string, command: ICommandHandler): IDisposable => {
|
for (const command of options.commands) {
|
||||||
return CommandsRegistry.registerCommand(id, (accessor, ...args: any[]) => {
|
CommandsRegistry.registerCommand(command.id, (accessor, ...args: any[]) => {
|
||||||
// we currently only pass on the arguments but not the accessor
|
// we currently only pass on the arguments but not the accessor
|
||||||
// to the command to reduce our exposure of internal API.
|
// to the command to reduce our exposure of internal API.
|
||||||
command(...args);
|
command.handler(...args);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
@@ -237,9 +253,6 @@ export {
|
|||||||
create,
|
create,
|
||||||
IWorkbenchConstructionOptions,
|
IWorkbenchConstructionOptions,
|
||||||
|
|
||||||
// Workbench Facade
|
|
||||||
IWorkbench,
|
|
||||||
ICommandHandler,
|
|
||||||
|
|
||||||
// Basic Types
|
// Basic Types
|
||||||
URI,
|
URI,
|
||||||
@@ -291,5 +304,7 @@ export {
|
|||||||
|
|
||||||
// Protocol Links
|
// Protocol Links
|
||||||
IApplicationLink,
|
IApplicationLink,
|
||||||
IApplicationLinkProvider
|
|
||||||
|
// Commands
|
||||||
|
ICommand
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -141,10 +141,12 @@ export function connect(engine: 'chromium' | 'webkit' | 'firefox' = 'chromium'):
|
|||||||
return new Promise(async (c) => {
|
return new Promise(async (c) => {
|
||||||
const browser = await playwright[engine].launch({
|
const browser = await playwright[engine].launch({
|
||||||
// Run in Edge dev on macOS
|
// Run in Edge dev on macOS
|
||||||
// executablePath: '/Applications/Microsoft\ Edge\ Dev.app/Contents/MacOS/Microsoft\ Edge\ Dev'
|
// executablePath: '/Applications/Microsoft\ Edge\ Dev.app/Contents/MacOS/Microsoft\ Edge\ Dev',
|
||||||
|
headless: false
|
||||||
});
|
});
|
||||||
const page = (await browser.defaultContext().pages())[0];
|
const context = await browser.newContext();
|
||||||
await page.setViewport({ width, height });
|
const page = await context.newPage();
|
||||||
|
await page.setViewportSize({ width, height });
|
||||||
await page.goto(`${endpoint}&folder=vscode-remote://localhost:9888${URI.file(workspacePath!).path}`);
|
await page.goto(`${endpoint}&folder=vscode-remote://localhost:9888${URI.file(workspacePath!).path}`);
|
||||||
const result = {
|
const result = {
|
||||||
client: { dispose: () => browser.close() && teardown() },
|
client: { dispose: () => browser.close() && teardown() },
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/mkdirp": "0.5.1",
|
"@types/mkdirp": "0.5.1",
|
||||||
"@types/node": "^12.11.7",
|
"@types/node": "^12.11.7",
|
||||||
|
"@types/optimist": "0.0.29",
|
||||||
"@types/rimraf": "2.0.2",
|
"@types/rimraf": "2.0.2",
|
||||||
"@types/tmp": "^0.1.0",
|
"@types/tmp": "^0.1.0",
|
||||||
"rimraf": "^2.6.1",
|
"rimraf": "^2.6.1",
|
||||||
|
|||||||
@@ -11,8 +11,9 @@ import * as tmp from 'tmp';
|
|||||||
import * as rimraf from 'rimraf';
|
import * as rimraf from 'rimraf';
|
||||||
import { URI } from 'vscode-uri';
|
import { URI } from 'vscode-uri';
|
||||||
import * as kill from 'tree-kill';
|
import * as kill from 'tree-kill';
|
||||||
|
import * as optimistLib from 'optimist';
|
||||||
|
|
||||||
const optimist = require('optimist')
|
const optimist = optimistLib
|
||||||
.describe('workspacePath', 'path to the workspace to open in the test').string('workspacePath')
|
.describe('workspacePath', 'path to the workspace to open in the test').string('workspacePath')
|
||||||
.describe('extensionDevelopmentPath', 'path to the extension to test').string('extensionDevelopmentPath')
|
.describe('extensionDevelopmentPath', 'path to the extension to test').string('extensionDevelopmentPath')
|
||||||
.describe('extensionTestsPath', 'path to the extension tests').string('extensionTestsPath')
|
.describe('extensionTestsPath', 'path to the extension tests').string('extensionTestsPath')
|
||||||
@@ -28,11 +29,12 @@ if (optimist.argv.help) {
|
|||||||
const width = 1200;
|
const width = 1200;
|
||||||
const height = 800;
|
const height = 800;
|
||||||
|
|
||||||
async function runTestsInBrowser(browserType: string, endpoint: url.UrlWithStringQuery, server: cp.ChildProcess): Promise<void> {
|
async function runTestsInBrowser(browserType: 'chromium' | 'firefox' | 'webkit', endpoint: url.UrlWithStringQuery, server: cp.ChildProcess): Promise<void> {
|
||||||
const args = process.platform === 'linux' && browserType === 'chromium' ? ['--no-sandbox'] : undefined; // disable sandbox to run chrome on certain Linux distros
|
const args = process.platform === 'linux' && browserType === 'chromium' ? ['--no-sandbox'] : undefined; // disable sandbox to run chrome on certain Linux distros
|
||||||
const browser = await playwright[browserType].launch({ headless: !Boolean(optimist.argv.debug), dumpio: true, args });
|
const browser = await playwright[browserType].launch({ headless: !Boolean(optimist.argv.debug), dumpio: true, args });
|
||||||
const page = (await browser.defaultContext().pages())[0];
|
const context = await browser.newContext();
|
||||||
await page.setViewport({ width, height });
|
const page = await context.newPage();
|
||||||
|
await page.setViewportSize({ width, height });
|
||||||
|
|
||||||
const host = endpoint.host;
|
const host = endpoint.host;
|
||||||
const protocol = 'vscode-remote';
|
const protocol = 'vscode-remote';
|
||||||
|
|||||||
@@ -38,6 +38,11 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.26.tgz#213e153babac0ed169d44a6d919501e68f59dea9"
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.26.tgz#213e153babac0ed169d44a6d919501e68f59dea9"
|
||||||
integrity sha512-UmUm94/QZvU5xLcUlNR8hA7Ac+fGpO1EG/a8bcWVz0P0LqtxFmun9Y2bbtuckwGboWJIT70DoWq1r3hb56n3DA==
|
integrity sha512-UmUm94/QZvU5xLcUlNR8hA7Ac+fGpO1EG/a8bcWVz0P0LqtxFmun9Y2bbtuckwGboWJIT70DoWq1r3hb56n3DA==
|
||||||
|
|
||||||
|
"@types/optimist@0.0.29":
|
||||||
|
version "0.0.29"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/optimist/-/optimist-0.0.29.tgz#a8873580b3a84b69ac1e687323b15fbbeb90479a"
|
||||||
|
integrity sha1-qIc1gLOoS2msHmhzI7Ffu+uQR5o=
|
||||||
|
|
||||||
"@types/rimraf@2.0.2":
|
"@types/rimraf@2.0.2":
|
||||||
version "2.0.2"
|
version "2.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/@types/rimraf/-/rimraf-2.0.2.tgz#7f0fc3cf0ff0ad2a99bb723ae1764f30acaf8b6e"
|
resolved "https://registry.yarnpkg.com/@types/rimraf/-/rimraf-2.0.2.tgz#7f0fc3cf0ff0ad2a99bb723ae1764f30acaf8b6e"
|
||||||
|
|||||||
@@ -120,7 +120,8 @@ const testModules = (async function () {
|
|||||||
async function runTestsInBrowser(testModules, browserType) {
|
async function runTestsInBrowser(testModules, browserType) {
|
||||||
const args = process.platform === 'linux' && browserType === 'chromium' ? ['--no-sandbox'] : undefined; // disable sandbox to run chrome on certain Linux distros
|
const args = process.platform === 'linux' && browserType === 'chromium' ? ['--no-sandbox'] : undefined; // disable sandbox to run chrome on certain Linux distros
|
||||||
const browser = await playwright[browserType].launch({ headless: !Boolean(argv.debug), dumpio: true, args });
|
const browser = await playwright[browserType].launch({ headless: !Boolean(argv.debug), dumpio: true, args });
|
||||||
const page = (await browser.defaultContext().pages())[0]
|
const context = await browser.newContext();
|
||||||
|
const page = await context.newPage();
|
||||||
const target = url.pathToFileURL(path.join(__dirname, 'renderer.html'));
|
const target = url.pathToFileURL(path.join(__dirname, 'renderer.html'));
|
||||||
if (argv.build) {
|
if (argv.build) {
|
||||||
target.search = `?build=true`;
|
target.search = `?build=true`;
|
||||||
|
|||||||
33
yarn.lock
33
yarn.lock
@@ -6046,11 +6046,6 @@ mime@^1.4.1:
|
|||||||
resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
|
resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
|
||||||
integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
|
integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
|
||||||
|
|
||||||
mime@^2.0.3:
|
|
||||||
version "2.4.4"
|
|
||||||
resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.4.tgz#bd7b91135fc6b01cde3e9bae33d659b63d8857e5"
|
|
||||||
integrity sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==
|
|
||||||
|
|
||||||
mimic-fn@^1.0.0:
|
mimic-fn@^1.0.0:
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18"
|
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18"
|
||||||
@@ -7107,29 +7102,28 @@ pkg-dir@^3.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
find-up "^3.0.0"
|
find-up "^3.0.0"
|
||||||
|
|
||||||
playwright-core@=0.10.0:
|
playwright-core@=0.11.0:
|
||||||
version "0.10.0"
|
version "0.11.0"
|
||||||
resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-0.10.0.tgz#86699c9cc3e613d733e6635a54aceea1993013d5"
|
resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-0.11.0.tgz#a2372833f6ec4e7886c4409e3da93df997aee61b"
|
||||||
integrity sha512-yernA6yrrBhmb8M5eO6GZsJOrBKWOZszlu65Luz8LP7ryaDExN1sE9XjQBNbiwJ5Gfs8cehtAO7GfTDJt+Z2cQ==
|
integrity sha512-9UPP/Max65PMiZJz9DNWB3ZRWtTlYlceLFnm6JO8aU7m6Vw3gwCvuSGoC5W69H67q98jH0VPSPp546+EnkiR2g==
|
||||||
dependencies:
|
dependencies:
|
||||||
debug "^4.1.0"
|
debug "^4.1.0"
|
||||||
extract-zip "^1.6.6"
|
extract-zip "^1.6.6"
|
||||||
https-proxy-agent "^3.0.0"
|
https-proxy-agent "^3.0.0"
|
||||||
jpeg-js "^0.3.6"
|
jpeg-js "^0.3.6"
|
||||||
mime "^2.0.3"
|
|
||||||
pngjs "^3.4.0"
|
pngjs "^3.4.0"
|
||||||
progress "^2.0.3"
|
progress "^2.0.3"
|
||||||
proxy-from-env "^1.0.0"
|
proxy-from-env "^1.0.0"
|
||||||
rimraf "^2.6.1"
|
rimraf "^3.0.2"
|
||||||
uuid "^3.4.0"
|
uuid "^3.4.0"
|
||||||
ws "^6.1.0"
|
ws "^6.1.0"
|
||||||
|
|
||||||
playwright@^0.10.0:
|
playwright@0.11.0:
|
||||||
version "0.10.0"
|
version "0.11.0"
|
||||||
resolved "https://registry.yarnpkg.com/playwright/-/playwright-0.10.0.tgz#d37f7e42e0e868dcc4ec35cb0a8dbc6248457642"
|
resolved "https://registry.yarnpkg.com/playwright/-/playwright-0.11.0.tgz#2abec99ea278b220bcd3902d7520ec22abc2d97e"
|
||||||
integrity sha512-f3VRME/PIO5NbcWnlCDfXwPC0DAZJ7ETkcAdE+sensLCOkfDtLh97E71ZuxNCaPYsUA6FIPi5syD8pHJW/4hQQ==
|
integrity sha512-cTJZ06OhwseMC9+D6KX1NmZXyEoaJl0o6GLkDhwmou3IFTrUFVOw7KYMBpcbJz0Rhb/de5ZPFlDTffLfEy/9lg==
|
||||||
dependencies:
|
dependencies:
|
||||||
playwright-core "=0.10.0"
|
playwright-core "=0.11.0"
|
||||||
|
|
||||||
plist@^3.0.1:
|
plist@^3.0.1:
|
||||||
version "3.0.1"
|
version "3.0.1"
|
||||||
@@ -8160,6 +8154,13 @@ rimraf@^2.4.2, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2:
|
|||||||
dependencies:
|
dependencies:
|
||||||
glob "^7.0.5"
|
glob "^7.0.5"
|
||||||
|
|
||||||
|
rimraf@^3.0.2:
|
||||||
|
version "3.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a"
|
||||||
|
integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==
|
||||||
|
dependencies:
|
||||||
|
glob "^7.1.3"
|
||||||
|
|
||||||
rimraf@~2.2.6:
|
rimraf@~2.2.6:
|
||||||
version "2.2.8"
|
version "2.2.8"
|
||||||
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.2.8.tgz#e439be2aaee327321952730f99a8929e4fc50582"
|
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.2.8.tgz#e439be2aaee327321952730f99a8929e4fc50582"
|
||||||
|
|||||||
Reference in New Issue
Block a user