Merge branch 'master' into rebornix/separate-textmodel-selection

This commit is contained in:
Peng Lyu
2020-06-25 14:48:26 -07:00
committed by GitHub
274 changed files with 7970 additions and 4665 deletions

View File

@@ -18,7 +18,7 @@ import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
import { fromNow } from 'vs/base/common/date';
const VSO_ALLOWED_EXTENSIONS = ['github.vscode-pull-request-github', 'github.vscode-pull-request-github-insiders', 'vscode.git', 'ms-vsonline.vsonline'];
const VSO_ALLOWED_EXTENSIONS = ['github.vscode-pull-request-github', 'github.vscode-pull-request-github-insiders', 'vscode.git', 'ms-vsonline.vsonline', 'vscode.github-browser'];
interface IAccountUsage {
extensionId: string;

View File

@@ -6,7 +6,6 @@
import { CancellationToken } from 'vs/base/common/cancellation';
import { Emitter, Event } from 'vs/base/common/event';
import { Disposable, DisposableStore, dispose, IDisposable } from 'vs/base/common/lifecycle';
import { keys } from 'vs/base/common/map';
import { URI, UriComponents } from 'vs/base/common/uri';
import { generateUuid } from 'vs/base/common/uuid';
import { IRange } from 'vs/editor/common/core/range';
@@ -284,7 +283,7 @@ export class MainThreadCommentController {
async getDocumentComments(resource: URI, token: CancellationToken) {
let ret: modes.CommentThread[] = [];
for (let thread of keys(this._threads)) {
for (let thread of [...this._threads.keys()]) {
const commentThread = this._threads.get(thread)!;
if (commentThread.resource === resource.toString()) {
ret.push(commentThread);
@@ -315,7 +314,7 @@ export class MainThreadCommentController {
getAllComments(): MainThreadCommentThread[] {
let ret: MainThreadCommentThread[] = [];
for (let thread of keys(this._threads)) {
for (let thread of [...this._threads.keys()]) {
ret.push(this._threads.get(thread)!);
}
@@ -486,7 +485,7 @@ export class MainThreadComments extends Disposable implements MainThreadComments
if (!commentsPanelAlreadyConstructed && !this._openViewListener) {
this._openViewListener = this._viewsService.onDidChangeViewVisibility(e => {
if (e.id === COMMENTS_VIEW_ID && e.visible) {
keys(this._commentControllers).forEach(handle => {
[...this._commentControllers.keys()].forEach(handle => {
let threads = this._commentControllers.get(handle)!.getAllComments();
if (threads.length) {

View File

@@ -231,7 +231,8 @@ export class MainThreadDebugService implements MainThreadDebugServiceShape, IDeb
const debugOptions: IDebugSessionOptions = {
noDebug: options.noDebug,
parentSession: this.getSession(options.parentSessionID),
repl: options.repl
repl: options.repl,
noCompact: options.noCompact
};
return this.debugService.startDebugging(launch, nameOrConfig, debugOptions).then(success => {
return success;

View File

@@ -50,8 +50,8 @@ class DecorationRequestsQueue {
const requests = this._requests;
const resolver = this._resolver;
this._proxy.$provideDecorations(this._handle, [...requests.values()], CancellationToken.None).then(data => {
for (const id in resolver) {
resolver.get(Number(id))!(data[Number(id)]);
for (let [id, resolve] of resolver) {
resolve(data[id]);
}
});

View File

@@ -126,8 +126,12 @@ export class MainThreadDocuments implements MainThreadDocumentsShape {
}));
this._toDispose.add(workingCopyFileService.onDidRunWorkingCopyFileOperation(e => {
if (e.source && (e.operation === FileOperation.MOVE || e.operation === FileOperation.DELETE)) {
this._modelReferenceCollection.remove(e.source);
if (e.operation === FileOperation.MOVE || e.operation === FileOperation.DELETE) {
for (const { source } of e.files) {
if (source) {
this._modelReferenceCollection.remove(source);
}
}
}
}));

View File

@@ -57,14 +57,14 @@ export class MainThreadFileSystemEventService {
// BEFORE file operation
workingCopyFileService.addFileOperationParticipant({
participate: (target, source, operation, progress, timeout, token) => {
return proxy.$onWillRunFileOperation(operation, target, source, timeout, token);
participate: (files, operation, progress, timeout, token) => {
return proxy.$onWillRunFileOperation(operation, files, timeout, token);
}
});
// AFTER file operation
this._listener.add(textFileService.onDidCreateTextFile(e => proxy.$onDidRunFileOperation(FileOperation.CREATE, e.resource, undefined)));
this._listener.add(workingCopyFileService.onDidRunWorkingCopyFileOperation(e => proxy.$onDidRunFileOperation(e.operation, e.target, e.source)));
this._listener.add(textFileService.onDidCreateTextFile(e => proxy.$onDidRunFileOperation(FileOperation.CREATE, [{ target: e.resource }])));
this._listener.add(workingCopyFileService.onDidRunWorkingCopyFileOperation(e => proxy.$onDidRunFileOperation(e.operation, e.files)));
}
dispose(): void {

View File

@@ -15,6 +15,7 @@ import { IAccessibilityInformation } from 'vs/platform/accessibility/common/acce
export class MainThreadStatusBar implements MainThreadStatusBarShape {
private readonly entries: Map<number, { accessor: IStatusbarEntryAccessor, alignment: MainThreadStatusBarAlignment, priority: number }> = new Map();
static readonly CODICON_REGEXP = /\$\((.*?)\)/g;
constructor(
_extHostContext: IExtHostContext,
@@ -32,7 +33,7 @@ export class MainThreadStatusBar implements MainThreadStatusBarShape {
if (accessibilityInformation) {
ariaLabel = accessibilityInformation.label;
} else {
ariaLabel = text && text.indexOf('$(') === -1 ? text : tooltip || text;
ariaLabel = text ? text.replace(MainThreadStatusBar.CODICON_REGEXP, (_match, codiconName) => codiconName) : '';
}
const entry: IStatusbarEntry = { text, tooltip, command, color, ariaLabel };

View File

@@ -5,7 +5,7 @@
import { Disposable } from 'vs/base/common/lifecycle';
import { ExtHostContext, MainThreadTreeViewsShape, ExtHostTreeViewsShape, MainContext, IExtHostContext } from 'vs/workbench/api/common/extHost.protocol';
import { ITreeViewDataProvider, ITreeItem, IViewsService, ITreeView, IViewsRegistry, ITreeViewDescriptor, IRevealOptions, Extensions } from 'vs/workbench/common/views';
import { ITreeViewDataProvider, ITreeItem, IViewsService, ITreeView, IViewsRegistry, ITreeViewDescriptor, IRevealOptions, Extensions, ResolvableTreeItem } from 'vs/workbench/common/views';
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
import { distinct } from 'vs/base/common/arrays';
import { INotificationService } from 'vs/platform/notification/common/notification';
@@ -163,11 +163,13 @@ type TreeItemHandle = string;
class TreeViewDataProvider implements ITreeViewDataProvider {
private readonly itemsMap: Map<TreeItemHandle, ITreeItem> = new Map<TreeItemHandle, ITreeItem>();
private hasResolve: Promise<boolean>;
constructor(private readonly treeViewId: string,
private readonly _proxy: ExtHostTreeViewsShape,
private readonly notificationService: INotificationService
) {
this.hasResolve = this._proxy.$hasResolve(this.treeViewId);
}
getChildren(treeItem?: ITreeItem): Promise<ITreeItem[]> {
@@ -214,12 +216,16 @@ class TreeViewDataProvider implements ITreeViewDataProvider {
return this.itemsMap.size === 0;
}
private postGetChildren(elements: ITreeItem[]): ITreeItem[] {
const result: ITreeItem[] = [];
private async postGetChildren(elements: ITreeItem[]): Promise<ResolvableTreeItem[]> {
const result: ResolvableTreeItem[] = [];
const hasResolve = await this.hasResolve;
if (elements) {
for (const element of elements) {
const resolvable = new ResolvableTreeItem(element, hasResolve ? () => {
return this._proxy.$resolve(this.treeViewId, element.handle);
} : undefined);
this.itemsMap.set(element.handle, element);
result.push(element);
result.push(resolvable);
}
}
return result;

View File

@@ -206,12 +206,6 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
getSession(providerId: string, scopes: string[], options: vscode.AuthenticationGetSessionOptions) {
return extHostAuthentication.getSession(extension, providerId, scopes, options as any);
},
getSessions(providerId: string, scopes: string[]): Thenable<readonly vscode.AuthenticationSession[]> {
return extHostAuthentication.getSessions(extension, providerId, scopes);
},
login(providerId: string, scopes: string[]): Thenable<vscode.AuthenticationSession> {
return extHostAuthentication.login(extension, providerId, scopes);
},
logout(providerId: string, sessionId: string): Thenable<void> {
return extHostAuthentication.logout(providerId, sessionId);
},
@@ -1102,7 +1096,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
CellKind: extHostTypes.CellKind,
CellOutputKind: extHostTypes.CellOutputKind,
NotebookCellRunState: extHostTypes.NotebookCellRunState,
AuthenticationSession2: extHostTypes.AuthenticationSession
AuthenticationSession: extHostTypes.AuthenticationSession
};
};
}

View File

@@ -858,6 +858,7 @@ export interface IStartDebuggingOptions {
parentSessionID?: DebugSessionUUID;
repl?: IDebugSessionReplMode;
noDebug?: boolean;
noCompact?: boolean;
}
export interface MainThreadDebugServiceShape extends IDisposable {
@@ -987,6 +988,8 @@ export interface ExtHostTreeViewsShape {
$setExpanded(treeViewId: string, treeItemHandle: string, expanded: boolean): void;
$setSelection(treeViewId: string, treeItemHandles: string[]): void;
$setVisible(treeViewId: string, visible: boolean): void;
$hasResolve(treeViewId: string): Promise<boolean>;
$resolve(treeViewId: string, treeItemHandle: string): Promise<ITreeItem | undefined>;
}
export interface ExtHostWorkspaceShape {
@@ -1068,10 +1071,15 @@ export interface FileSystemEvents {
deleted: UriComponents[];
}
export interface SourceTargetPair {
source?: UriComponents;
target: UriComponents;
}
export interface ExtHostFileSystemEventServiceShape {
$onFileEvent(events: FileSystemEvents): void;
$onWillRunFileOperation(operation: files.FileOperation, target: UriComponents, source: UriComponents | undefined, timeout: number, token: CancellationToken): Promise<any>;
$onDidRunFileOperation(operation: files.FileOperation, target: UriComponents, source: UriComponents | undefined): void;
$onWillRunFileOperation(operation: files.FileOperation, files: SourceTargetPair[], timeout: number, token: CancellationToken): Promise<any>;
$onDidRunFileOperation(operation: files.FileOperation, files: SourceTargetPair[]): void;
}
export interface ObjectIdentifier {

View File

@@ -56,8 +56,8 @@ export class ExtHostAuthentication implements ExtHostAuthenticationShape {
return !!(sessions.filter(session => session.scopes.sort().join(' ') === orderedScopes).length);
}
async getSession(requestingExtension: IExtensionDescription, providerId: string, scopes: string[], options: vscode.AuthenticationGetSessionOptions & { createIfNone: true }): Promise<vscode.AuthenticationSession2>;
async getSession(requestingExtension: IExtensionDescription, providerId: string, scopes: string[], options: vscode.AuthenticationGetSessionOptions): Promise<vscode.AuthenticationSession2 | undefined> {
async getSession(requestingExtension: IExtensionDescription, providerId: string, scopes: string[], options: vscode.AuthenticationGetSessionOptions & { createIfNone: true }): Promise<vscode.AuthenticationSession>;
async getSession(requestingExtension: IExtensionDescription, providerId: string, scopes: string[], options: vscode.AuthenticationGetSessionOptions): Promise<vscode.AuthenticationSession | undefined> {
const provider = this._authenticationProviders.get(providerId);
const extensionName = requestingExtension.displayName || requestingExtension.name;
const extensionId = ExtensionIdentifier.toKey(requestingExtension.identifier);
@@ -100,71 +100,6 @@ export class ExtHostAuthentication implements ExtHostAuthenticationShape {
}
}
async getSessions(requestingExtension: IExtensionDescription, providerId: string, scopes: string[]): Promise<readonly vscode.AuthenticationSession[]> {
const extensionId = ExtensionIdentifier.toKey(requestingExtension.identifier);
const orderedScopes = scopes.sort().join(' ');
const sessions = await this.resolveSessions(providerId);
return sessions
.filter(session => session.scopes.sort().join(' ') === orderedScopes)
.map(session => {
return {
id: session.id,
account: session.account,
scopes: session.scopes,
getAccessToken: async () => {
const isAllowed = await this._proxy.$getSessionsPrompt(
providerId,
session.account.displayName,
'', // TODO
// provider.displayName,
extensionId,
requestingExtension.displayName || requestingExtension.name);
if (!isAllowed) {
throw new Error('User did not consent to token access.');
}
return session.accessToken;
}
};
});
}
async login(requestingExtension: IExtensionDescription, providerId: string, scopes: string[]): Promise<vscode.AuthenticationSession> {
const provider = this._authenticationProviders.get(providerId);
if (!provider) {
throw new Error(`No authentication provider with id '${providerId}' is currently registered.`);
}
const extensionName = requestingExtension.displayName || requestingExtension.name;
const isAllowed = await this._proxy.$loginPrompt(provider.displayName, extensionName);
if (!isAllowed) {
throw new Error('User did not consent to login.');
}
const session = await provider.login(scopes);
await this._proxy.$setTrustedExtension(provider.id, session.account.displayName, ExtensionIdentifier.toKey(requestingExtension.identifier), extensionName);
return {
id: session.id,
account: session.account,
scopes: session.scopes,
getAccessToken: async () => {
const isAllowed = await this._proxy.$getSessionsPrompt(
provider.id,
session.account.displayName,
provider.displayName,
ExtensionIdentifier.toKey(requestingExtension.identifier),
requestingExtension.displayName || requestingExtension.name);
if (!isAllowed) {
throw new Error('User did not consent to token access.');
}
return session.accessToken;
}
};
}
async logout(providerId: string, sessionId: string): Promise<void> {
const provider = this._authenticationProviders.get(providerId);
if (!provider) {

View File

@@ -296,7 +296,8 @@ export abstract class ExtHostDebugServiceBase implements IExtHostDebugService, E
return this._debugServiceProxy.$startDebugging(folder ? folder.uri : undefined, nameOrConfig, {
parentSessionID: options.parentSession ? options.parentSession.id : undefined,
repl: options.consoleMode === DebugConsoleMode.MergeWithParent ? 'mergeWithParent' : 'separate',
noDebug: options.noDebug
noDebug: options.noDebug,
noCompact: options.noCompact
});
}

View File

@@ -5,10 +5,10 @@
import { AsyncEmitter, Emitter, Event, IWaitUntil } from 'vs/base/common/event';
import { IRelativePattern, parse } from 'vs/base/common/glob';
import { URI, UriComponents } from 'vs/base/common/uri';
import { URI } from 'vs/base/common/uri';
import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors';
import type * as vscode from 'vscode';
import { ExtHostFileSystemEventServiceShape, FileSystemEvents, IMainContext, MainContext, MainThreadTextEditorsShape, IWorkspaceFileEditDto, IWorkspaceTextEditDto } from './extHost.protocol';
import { ExtHostFileSystemEventServiceShape, FileSystemEvents, IMainContext, MainContext, MainThreadTextEditorsShape, IWorkspaceFileEditDto, IWorkspaceTextEditDto, SourceTargetPair } from './extHost.protocol';
import * as typeConverter from './extHostTypeConverters';
import { Disposable, WorkspaceEdit } from './extHostTypes';
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
@@ -142,16 +142,16 @@ export class ExtHostFileSystemEventService implements ExtHostFileSystemEventServ
//--- file operations
$onDidRunFileOperation(operation: FileOperation, target: UriComponents, source: UriComponents | undefined): void {
$onDidRunFileOperation(operation: FileOperation, files: SourceTargetPair[]): void {
switch (operation) {
case FileOperation.MOVE:
this._onDidRenameFile.fire(Object.freeze({ files: [{ oldUri: URI.revive(source!), newUri: URI.revive(target) }] }));
this._onDidRenameFile.fire(Object.freeze({ files: files.map(f => ({ oldUri: URI.revive(f.source!), newUri: URI.revive(f.target) })) }));
break;
case FileOperation.DELETE:
this._onDidDeleteFile.fire(Object.freeze({ files: [URI.revive(target)] }));
this._onDidDeleteFile.fire(Object.freeze({ files: files.map(f => URI.revive(f.target)) }));
break;
case FileOperation.CREATE:
this._onDidCreateFile.fire(Object.freeze({ files: [URI.revive(target)] }));
this._onDidCreateFile.fire(Object.freeze({ files: files.map(f => URI.revive(f.target)) }));
break;
default:
//ignore, dont send
@@ -179,16 +179,16 @@ export class ExtHostFileSystemEventService implements ExtHostFileSystemEventServ
};
}
async $onWillRunFileOperation(operation: FileOperation, target: UriComponents, source: UriComponents | undefined, timeout: number, token: CancellationToken): Promise<any> {
async $onWillRunFileOperation(operation: FileOperation, files: SourceTargetPair[], timeout: number, token: CancellationToken): Promise<any> {
switch (operation) {
case FileOperation.MOVE:
await this._fireWillEvent(this._onWillRenameFile, { files: [{ oldUri: URI.revive(source!), newUri: URI.revive(target) }] }, timeout, token);
await this._fireWillEvent(this._onWillRenameFile, { files: files.map(f => ({ oldUri: URI.revive(f.source!), newUri: URI.revive(f.target) })) }, timeout, token);
break;
case FileOperation.DELETE:
await this._fireWillEvent(this._onWillDeleteFile, { files: [URI.revive(target)] }, timeout, token);
await this._fireWillEvent(this._onWillDeleteFile, { files: files.map(f => URI.revive(f.target)) }, timeout, token);
break;
case FileOperation.CREATE:
await this._fireWillEvent(this._onWillCreateFile, { files: [URI.revive(target)] }, timeout, token);
await this._fireWillEvent(this._onWillCreateFile, { files: files.map(f => URI.revive(f.target)) }, timeout, token);
break;
default:
//ignore, dont send

View File

@@ -12,17 +12,15 @@ import { PrefixSumComputer } from 'vs/editor/common/viewModel/prefixSumComputer'
import { DisposableStore } from 'vs/base/common/lifecycle';
import { score } from 'vs/editor/common/modes/languageSelector';
import { CellKind } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { basename } from 'vs/base/common/resources';
import { ResourceMap } from 'vs/base/common/map';
import { ExtHostDocumentLine } from 'vs/workbench/api/common/extHostDocumentData';
export class ExtHostNotebookConcatDocument implements vscode.NotebookConcatTextDocument, vscode.TextDocument {
export class ExtHostNotebookConcatDocument implements vscode.NotebookConcatTextDocument {
private _disposables = new DisposableStore();
private _isClosed = false;
private _cells!: ExtHostCell[];
private _cellByUri!: ResourceMap<number>;
private _cellUris!: ResourceMap<number>;
private _cellLengths!: PrefixSumComputer;
private _cellLines!: PrefixSumComputer;
private _versionId = 0;
@@ -30,27 +28,17 @@ export class ExtHostNotebookConcatDocument implements vscode.NotebookConcatTextD
private readonly _onDidChange = new Emitter<void>();
readonly onDidChange: Event<void> = this._onDidChange.event;
readonly uri: vscode.Uri;
readonly fileName: string;
readonly languageId: string;
readonly isUntitled: boolean = false;
readonly isDirty: boolean = false;
constructor(
extHostNotebooks: ExtHostNotebookController,
extHostDocuments: ExtHostDocuments,
private readonly _notebook: vscode.NotebookDocument,
private readonly _selector: vscode.DocumentSelector | undefined,
) {
this.uri = _notebook.uri.with({ scheme: 'vscode-notebook-concat-doc' });
this.fileName = basename(this.uri);
this.languageId = this._createLanguageId();
this._init();
this._disposables.add(extHostDocuments.onDidChangeDocument(e => {
const cellIdx = this._cellByUri.get(e.document.uri);
if (typeof cellIdx === 'number') {
let cellIdx = this._cellUris.get(e.document.uri);
if (cellIdx !== undefined) {
this._cellLengths.changeValue(cellIdx, this._cells[cellIdx].document.getText().length + 1);
this._cellLines.changeValue(cellIdx, this._cells[cellIdx].document.lineCount);
this._versionId += 1;
@@ -66,7 +54,6 @@ export class ExtHostNotebookConcatDocument implements vscode.NotebookConcatTextD
};
this._disposables.add(extHostNotebooks.onDidChangeCellLanguage(e => documentChange(e.document)));
this._disposables.add(extHostNotebooks.onDidChangeCellOutputs(e => documentChange(e.document)));
this._disposables.add(extHostNotebooks.onDidChangeNotebookCells(e => documentChange(e.document)));
}
@@ -81,12 +68,12 @@ export class ExtHostNotebookConcatDocument implements vscode.NotebookConcatTextD
private _init() {
this._cells = [];
this._cellByUri = new ResourceMap();
this._cellUris = new ResourceMap();
const cellLengths: number[] = [];
const cellLineCounts: number[] = [];
for (let cell of this._notebook.cells) {
if (cell.cellKind === CellKind.Code && (!this._selector || score(this._selector, cell.uri, cell.language, true))) {
this._cellByUri.set(cell.uri, this._cells.length);
this._cellUris.set(cell.uri, this._cells.length);
this._cells.push(<ExtHostCell>cell);
cellLengths.push(cell.document.getText().length + 1);
cellLineCounts.push(cell.document.lineCount);
@@ -96,67 +83,6 @@ export class ExtHostNotebookConcatDocument implements vscode.NotebookConcatTextD
this._cellLines = new PrefixSumComputer(new Uint32Array(cellLineCounts));
}
private _createLanguageId(): string {
const languageIds = new Set<string>();
(function fillInLanguageIds(selector: vscode.DocumentSelector | undefined) {
if (Array.isArray(selector)) {
selector.forEach(fillInLanguageIds);
} else if (typeof selector === 'string') {
languageIds.add(selector);
} else if (selector?.language) {
languageIds.add(selector.language);
}
})(this._selector);
if (languageIds.size === 0) {
return 'unknown';
}
return [...languageIds.values()].sort().join(';');
}
save(): Thenable<boolean> {
// todo@jrieken throw error instead?
return Promise.resolve(false);
}
get eol(): vscode.EndOfLine {
return types.EndOfLine.LF;
}
get lineCount(): number {
let total = 0;
for (let cell of this._cells) {
total += cell.document.lineCount;
}
return total;
}
lineAt(lineOrPosition: number | vscode.Position): vscode.TextLine {
const line = typeof lineOrPosition === 'number' ? lineOrPosition : lineOrPosition.line;
const cellIdx = this._cellLines.getIndexOf(line);
return new ExtHostDocumentLine(
line,
this._cells[cellIdx.index].document.lineAt(cellIdx.remainder).text,
line >= this.lineCount
);
}
getWordRangeAtPosition(position: vscode.Position, regex?: RegExp | undefined): vscode.Range | undefined {
const cellIdx = this._cellLines.getIndexOf(position.line);
return this._cells[cellIdx.index].document.getWordRangeAtPosition(position.with({ line: cellIdx.remainder }), regex);
}
validateRange(range: vscode.Range): vscode.Range {
const start = this.validatePosition(range.start);
const end = this.validatePosition(range.end);
return range.with({ start, end });
}
validatePosition(position: vscode.Position): vscode.Position {
const cellIdx = this._cellLines.getIndexOf(position.line);
return this._cells[cellIdx.index].document.validatePosition(position.with({ line: cellIdx.remainder }));
}
get version(): number {
return this._versionId;
}
@@ -179,8 +105,8 @@ export class ExtHostNotebookConcatDocument implements vscode.NotebookConcatTextD
// get start and end locations and create substrings
const start = this.locationAt(range.start);
const end = this.locationAt(range.end);
const startCell = this._cells[this._cellByUri.get(start.uri) ?? -1];
const endCell = this._cells[this._cellByUri.get(end.uri) ?? -1];
const startCell = this._cells[this._cellUris.get(start.uri) ?? -1];
const endCell = this._cells[this._cellUris.get(end.uri) ?? -1];
if (!startCell || !endCell) {
return '';
@@ -207,8 +133,8 @@ export class ExtHostNotebookConcatDocument implements vscode.NotebookConcatTextD
return this._cells[idx.index].document.positionAt(idx.remainder).translate(lineCount);
}
const idx = this._cellByUri.get(locationOrOffset.uri);
if (typeof idx === 'number') {
const idx = this._cellUris.get(locationOrOffset.uri);
if (idx !== undefined) {
let line = this._cellLines.getAccumulatedValue(idx - 1);
return new types.Position(line + locationOrOffset.range.start.line, locationOrOffset.range.start.character);
}
@@ -235,4 +161,24 @@ export class ExtHostNotebookConcatDocument implements vscode.NotebookConcatTextD
const startCell = this._cells[startIdx.index];
return new types.Location(startCell.uri, <types.Range>startCell.document.validateRange(range));
}
contains(uri: vscode.Uri): boolean {
return this._cellUris.has(uri);
}
validateRange(range: vscode.Range): vscode.Range {
const start = this.validatePosition(range.start);
const end = this.validatePosition(range.end);
return range.with(start, end);
}
validatePosition(position: vscode.Position): vscode.Position {
const startIdx = this._cellLines.getIndexOf(position.line);
const cellPosition = new types.Position(startIdx.remainder, position.character);
const validCellPosition = this._cells[startIdx.index].document.validatePosition(cellPosition);
const line = this._cellLines.getAccumulatedValue(startIdx.index - 1);
return new types.Position(line + validCellPosition.line, validCellPosition.character);
}
}

View File

@@ -625,10 +625,11 @@ export abstract class BaseExtHostTerminalService implements IExtHostTerminalServ
for (const provideResult of provideResults) {
if (provideResult && provideResult.links.length > 0) {
result.push(...provideResult.links.map(providerLink => {
const endIndex = Math.max(providerLink.endIndex, providerLink.startIndex + 1);
const link = {
id: nextLinkId++,
startIndex: providerLink.startIndex,
length: providerLink.length,
length: endIndex - providerLink.startIndex,
label: providerLink.tooltip
};
cacheLinkMap.set(link.id, {
@@ -651,9 +652,6 @@ export abstract class BaseExtHostTerminalService implements IExtHostTerminalServ
return;
}
cachedLink.provider.handleTerminalLink(cachedLink.link);
// TODO: Handle when result is false? Should this be return void instead and remove
// TerminalLink.target? It's a simple call to window.openUri for the extension otherwise
// and would simplify the API.
}
private _onProcessExit(id: number, exitCode: number | undefined): void {

View File

@@ -119,6 +119,22 @@ export class ExtHostTreeViews implements ExtHostTreeViewsShape {
return treeView.getChildren(treeItemHandle);
}
async $hasResolve(treeViewId: string): Promise<boolean> {
const treeView = this.treeViews.get(treeViewId);
if (!treeView) {
throw new Error(localize('treeView.notRegistered', 'No tree view with id \'{0}\' registered.', treeViewId));
}
return treeView.hasResolve;
}
$resolve(treeViewId: string, treeItemHandle: string): Promise<ITreeItem | undefined> {
const treeView = this.treeViews.get(treeViewId);
if (!treeView) {
throw new Error(localize('treeView.notRegistered', 'No tree view with id \'{0}\' registered.', treeViewId));
}
return treeView.resolveTreeItem(treeItemHandle);
}
$setExpanded(treeViewId: string, treeItemHandle: string, expanded: boolean): void {
const treeView = this.treeViews.get(treeViewId);
if (!treeView) {
@@ -160,6 +176,7 @@ type TreeData<T> = { message: boolean, element: T | Root | false };
interface TreeNode extends IDisposable {
item: ITreeItem;
extensionItem: vscode.TreeItem2;
parent: TreeNode | Root;
children?: TreeNode[];
}
@@ -329,6 +346,27 @@ class ExtHostTreeView<T> extends Disposable {
}
}
get hasResolve(): boolean {
return !!this.dataProvider.resolveTreeItem;
}
async resolveTreeItem(treeItemHandle: string): Promise<ITreeItem | undefined> {
if (!this.dataProvider.resolveTreeItem) {
return;
}
const element = this.elements.get(treeItemHandle);
if (element) {
const node = this.nodes.get(element);
if (node) {
const resolve = await this.dataProvider.resolveTreeItem(element, node.extensionItem);
// Resolvable elements. Currently only tooltip.
node.item.tooltip = resolve.tooltip;
return node.item;
}
}
return;
}
private resolveUnknownParentChain(element: T): Promise<TreeNode[]> {
return this.resolveParent(element)
.then((parent) => {
@@ -521,6 +559,7 @@ class ExtHostTreeView<T> extends Disposable {
return {
item,
extensionItem: extensionTreeItem,
parent,
children: undefined,
dispose(): void { disposable.dispose(); }

View File

@@ -2769,7 +2769,7 @@ export enum ExtensionMode {
//#region Authentication
export class AuthenticationSession implements vscode.AuthenticationSession2 {
export class AuthenticationSession implements vscode.AuthenticationSession {
constructor(public id: string, public accessToken: string, public account: { displayName: string, id: string }, public scopes: string[]) { }
}