Merge from vscode a416c77e56ef0314ae00633faa04878151610de8 (#8600)

* Merge from vscode a416c77e56ef0314ae00633faa04878151610de8

* distro

* fix tests

* fix tests
This commit is contained in:
Anthony Dresser
2019-12-07 17:19:16 -08:00
committed by GitHub
parent a7ff238653
commit d614116b63
155 changed files with 1982 additions and 1599 deletions

View File

@@ -68,7 +68,7 @@ declare module 'vscode' {
//#endregion
//#region Alex - semantic tokens
//#region Semantic tokens: https://github.com/microsoft/vscode/issues/86415
export class SemanticTokensLegend {
public readonly tokenTypes: string[];
@@ -83,15 +83,13 @@ declare module 'vscode' {
build(): Uint32Array;
}
/**
* A certain token (at index `i` is encoded using 5 uint32 integers):
* - at index `5*i` - `deltaLine`: token line number, relative to `SemanticColoringArea.line`
* - at index `5*i+1` - `deltaStart`: token start character offset inside the line (relative to 0 or the previous token if they are on the same line)
* - at index `5*i+2` - `length`: the length of the token
* - at index `5*i+3` - `tokenType`: will be looked up in `SemanticColoringLegend.tokenTypes`
* - at index `5*i+4` - `tokenModifiers`: each set bit will be looked up in `SemanticColoringLegend.tokenModifiers`
*/
export class SemanticTokens {
/**
* The result id of the tokens.
*
* On a next call to `provideSemanticTokens`, if VS Code still holds in memory this result,
* the result id will be passed in as `SemanticTokensRequestOptions.previousResultId`.
*/
readonly resultId?: string;
readonly data: Uint32Array;
@@ -99,6 +97,12 @@ declare module 'vscode' {
}
export class SemanticTokensEdits {
/**
* The result id of the tokens.
*
* On a next call to `provideSemanticTokens`, if VS Code still holds in memory this result,
* the result id will be passed in as `SemanticTokensRequestOptions.previousResultId`.
*/
readonly resultId?: string;
readonly edits: SemanticTokensEdit[];
@@ -115,6 +119,11 @@ declare module 'vscode' {
export interface SemanticTokensRequestOptions {
readonly ranges?: readonly Range[];
/**
* The previous result id that the editor still holds in memory.
*
* Only when this is set it is safe for a `SemanticTokensProvider` to return `SemanticTokensEdits`.
*/
readonly previousResultId?: string;
}
@@ -123,6 +132,102 @@ declare module 'vscode' {
* semantic tokens.
*/
export interface SemanticTokensProvider {
/**
* A file can contain many tokens, perhaps even hundreds of thousands tokens. Therefore, to improve
* the memory consumption around describing semantic tokens, we have decided to avoid allocating objects
* and we have decided to represent tokens from a file as an array of integers.
*
*
* In short, each token takes 5 integers to represent, so a specific token i in the file consists of the following fields:
* - at index `5*i` - `deltaLine`: token line number, relative to the previous token
* - at index `5*i+1` - `deltaStart`: token start character, relative to the previous token (relative to 0 or the previous token's start if they are on the same line)
* - at index `5*i+2` - `length`: the length of the token. A token cannot be multiline.
* - at index `5*i+3` - `tokenType`: will be looked up in `SemanticTokensLegend.tokenTypes`
* - at index `5*i+4` - `tokenModifiers`: each set bit will be looked up in `SemanticTokensLegend.tokenModifiers`
*
*
* Here is an example for encoding a file with 3 tokens:
* ```
* [ { line: 2, startChar: 5, length: 3, tokenType: "properties", tokenModifiers: ["private", "static"] },
* { line: 2, startChar: 10, length: 4, tokenType: "types", tokenModifiers: [] },
* { line: 5, startChar: 2, length: 7, tokenType: "classes", tokenModifiers: [] } ]
* ```
*
* 1. First of all, a legend must be devised. This legend must be provided up-front and capture all possible token types.
* For this example, we will choose the following legend which is passed in when registering the provider:
* ```
* { tokenTypes: ['', 'properties', 'types', 'classes'],
* tokenModifiers: ['', 'private', 'static'] }
* ```
*
* 2. The first transformation is to encode `tokenType` and `tokenModifiers` as integers using the legend. Token types are looked
* up by index, so a `tokenType` value of `1` means `tokenTypes[1]`. Multiple token modifiers can be set by using bit flags,
* so a `tokenModifier` value of `6` is first viewed as binary `0b110`, which means `[tokenModifiers[1], tokenModifiers[2]]` because
* bits 1 and 2 are set. Using this legend, the tokens now are:
* ```
* [ { line: 2, startChar: 5, length: 3, tokenType: 1, tokenModifiers: 6 }, // 6 is 0b110
* { line: 2, startChar: 10, length: 4, tokenType: 2, tokenModifiers: 0 },
* { line: 5, startChar: 2, length: 7, tokenType: 3, tokenModifiers: 0 } ]
* ```
*
* 3. Then, we will encode each token relative to the previous token in the file:
* ```
* [ { deltaLine: 2, deltaStartChar: 5, length: 3, tokenType: 1, tokenModifiers: 6 },
* // this token is on the same line as the first one, so the startChar is made relative
* { deltaLine: 0, deltaStartChar: 5, length: 4, tokenType: 2, tokenModifiers: 0 },
* // this token is on a different line than the second one, so the startChar remains unchanged
* { deltaLine: 3, deltaStartChar: 2, length: 7, tokenType: 3, tokenModifiers: 0 } ]
* ```
*
* 4. Finally, the integers are organized in a single array, which is a memory friendly representation:
* ```
* // 1st token, 2nd token, 3rd token
* [ 2,5,3,1,6, 0,5,4,2,0, 3,2,7,3,0 ]
* ```
*
* In principle, each call to `provideSemanticTokens` expects a complete representations of the semantic tokens.
* It is possible to simply return all the tokens at each call.
*
* But oftentimes, a small edit in the file will result in a small change to the above delta-based represented tokens.
* (In fact, that is why the above tokens are delta-encoded relative to their corresponding previous tokens).
* In such a case, if VS Code passes in the previous result id, it is possible for an advanced tokenization provider
* to return a delta to the integers array.
*
* To continue with the previous example, suppose a new line has been pressed at the beginning of the file, such that
* all the tokens are now one line lower, and that a new token has appeared since the last result on line 4.
* For example, the tokens might look like:
* ```
* [ { line: 3, startChar: 5, length: 3, tokenType: "properties", tokenModifiers: ["private", "static"] },
* { line: 3, startChar: 10, length: 4, tokenType: "types", tokenModifiers: [] },
* { line: 4, startChar: 3, length: 5, tokenType: "properties", tokenModifiers: ["static"] },
* { line: 6, startChar: 2, length: 7, tokenType: "classes", tokenModifiers: [] } ]
* ```
*
* The integer encoding of all new tokens would be:
* ```
* [ 3,5,3,1,6, 0,5,4,2,0, 1,3,5,1,2, 2,2,7,3,0 ]
* ```
*
* A smart tokens provider can return a `resultId` to `SemanticTokens`. Then, if the editor still has in memory the previous
* result, the editor will pass in options the previous result id at `SemanticTokensRequestOptions.previousResultId`. Only when
* the editor passes in the previous result id, it is safe and smart for a smart tokens provider can compute a diff from the
* previous result to the new result.
*
* *NOTE*: It is illegal to return `SemanticTokensEdits` if `options.previousResultId` is not set!
*
* ```
* [ 2,5,3,1,6, 0,5,4,2,0, 3,2,7,3,0 ]
* [ 3,5,3,1,6, 0,5,4,2,0, 1,3,5,1,2, 2,2,7,3,0 ]
* ```
* and return as simple integer edits the diff:
* ```
* { edits: [
* { start: 0, deleteCount: 1, data: [3] } // replace integer at offset 0 with 3
* { start: 10, deleteCount: 1, data: [1,3,5,1,2,2] } // replace integer at offset 10 with [1,3,5,1,2,2]
* ]}
* ```
* All indices expressed in the returned diff represent indices in the old result array, so they all refer to the previous result state.
*/
provideSemanticTokens(document: TextDocument, options: SemanticTokensRequestOptions, token: CancellationToken): ProviderResult<SemanticTokens | SemanticTokensEdits>;
}
@@ -171,7 +276,7 @@ declare module 'vscode' {
//#endregion
//#region Rob: search provider
//#region TextSearchProvider: https://github.com/microsoft/vscode/issues/59921
/**
* The parameters of a query for text search.
@@ -315,32 +420,6 @@ declare module 'vscode' {
limitHit?: boolean;
}
/**
* The parameters of a query for file search.
*/
export interface FileSearchQuery {
/**
* The search pattern to match against file paths.
*/
pattern: string;
}
/**
* Options that apply to file search.
*/
export interface FileSearchOptions extends SearchOptions {
/**
* The maximum number of results to be returned.
*/
maxResults?: number;
/**
* A CancellationToken that represents the session for this search query. If the provider chooses to, this object can be used as the key for a cache,
* and searches with the same session object can search the same cache. When the token is cancelled, the session is complete and the cache can be cleared.
*/
session?: CancellationToken;
}
/**
* A preview of the text result.
*/
@@ -400,6 +479,50 @@ declare module 'vscode' {
export type TextSearchResult = TextSearchMatch | TextSearchContext;
/**
* A TextSearchProvider provides search results for text results inside files in the workspace.
*/
export interface TextSearchProvider {
/**
* Provide results that match the given text pattern.
* @param query The parameters for this query.
* @param options A set of options to consider while searching.
* @param progress A progress callback that must be invoked for all results.
* @param token A cancellation token.
*/
provideTextSearchResults(query: TextSearchQuery, options: TextSearchOptions, progress: Progress<TextSearchResult>, token: CancellationToken): ProviderResult<TextSearchComplete>;
}
//#endregion
//#region FileSearchProvider: https://github.com/microsoft/vscode/issues/73524
/**
* The parameters of a query for file search.
*/
export interface FileSearchQuery {
/**
* The search pattern to match against file paths.
*/
pattern: string;
}
/**
* Options that apply to file search.
*/
export interface FileSearchOptions extends SearchOptions {
/**
* The maximum number of results to be returned.
*/
maxResults?: number;
/**
* A CancellationToken that represents the session for this search query. If the provider chooses to, this object can be used as the key for a cache,
* and searches with the same session object can search the same cache. When the token is cancelled, the session is complete and the cache can be cleared.
*/
session?: CancellationToken;
}
/**
* A FileSearchProvider provides search results for files in the given folder that match a query string. It can be invoked by quickopen or other extensions.
*
@@ -419,20 +542,34 @@ declare module 'vscode' {
provideFileSearchResults(query: FileSearchQuery, options: FileSearchOptions, token: CancellationToken): ProviderResult<Uri[]>;
}
/**
* A TextSearchProvider provides search results for text results inside files in the workspace.
*/
export interface TextSearchProvider {
export namespace workspace {
/**
* Provide results that match the given text pattern.
* @param query The parameters for this query.
* @param options A set of options to consider while searching.
* @param progress A progress callback that must be invoked for all results.
* @param token A cancellation token.
* Register a search provider.
*
* Only one provider can be registered per scheme.
*
* @param scheme The provider will be invoked for workspace folders that have this file scheme.
* @param provider The provider.
* @return A [disposable](#Disposable) that unregisters this provider when being disposed.
*/
provideTextSearchResults(query: TextSearchQuery, options: TextSearchOptions, progress: Progress<TextSearchResult>, token: CancellationToken): ProviderResult<TextSearchComplete>;
export function registerFileSearchProvider(scheme: string, provider: FileSearchProvider): Disposable;
/**
* Register a text search provider.
*
* Only one provider can be registered per scheme.
*
* @param scheme The provider will be invoked for workspace folders that have this file scheme.
* @param provider The provider.
* @return A [disposable](#Disposable) that unregisters this provider when being disposed.
*/
export function registerTextSearchProvider(scheme: string, provider: TextSearchProvider): Disposable;
}
//#endregion
//#region findTextInFiles: https://github.com/microsoft/vscode/issues/59924
/**
* Options that can be set on a findTextInFiles search.
*/
@@ -497,28 +634,6 @@ declare module 'vscode' {
}
export namespace workspace {
/**
* Register a search provider.
*
* Only one provider can be registered per scheme.
*
* @param scheme The provider will be invoked for workspace folders that have this file scheme.
* @param provider The provider.
* @return A [disposable](#Disposable) that unregisters this provider when being disposed.
*/
export function registerFileSearchProvider(scheme: string, provider: FileSearchProvider): Disposable;
/**
* Register a text search provider.
*
* Only one provider can be registered per scheme.
*
* @param scheme The provider will be invoked for workspace folders that have this file scheme.
* @param provider The provider.
* @return A [disposable](#Disposable) that unregisters this provider when being disposed.
*/
export function registerTextSearchProvider(scheme: string, provider: TextSearchProvider): Disposable;
/**
* Search text in files across all [workspace folders](#workspace.workspaceFolders) in the workspace.
* @param query The query parameters for the search - the search string, whether it's case-sensitive, or a regex, or matches whole words.
@@ -647,7 +762,7 @@ declare module 'vscode' {
//#endregion
//#region Rob, Matt: logging
//#region LogLevel: https://github.com/microsoft/vscode/issues/85992
/**
* The severity level of a log message
@@ -869,247 +984,6 @@ declare module 'vscode' {
//#endregion
//#region mjbvz,joh: https://github.com/Microsoft/vscode/issues/43768
/**
* An event that is fired when files are going to be created.
*
* To make modifications to the workspace before the files are created,
* call the [`waitUntil](#FileWillCreateEvent.waitUntil)-function with a
* thenable that resolves to a [workspace edit](#WorkspaceEdit).
*/
export interface FileWillCreateEvent {
/**
* The files that are going to be created.
*/
readonly files: ReadonlyArray<Uri>;
/**
* Allows to pause the event and to apply a [workspace edit](#WorkspaceEdit).
*
* *Note:* This function can only be called during event dispatch and not
* in an asynchronous manner:
*
* ```ts
* workspace.onWillCreateFiles(event => {
* // async, will *throw* an error
* setTimeout(() => event.waitUntil(promise));
*
* // sync, OK
* event.waitUntil(promise);
* })
* ```
*
* @param thenable A thenable that delays saving.
*/
waitUntil(thenable: Thenable<WorkspaceEdit>): void;
/**
* Allows to pause the event until the provided thenable resolves.
*
* *Note:* This function can only be called during event dispatch.
*
* @param thenable A thenable that delays saving.
*/
waitUntil(thenable: Thenable<any>): void;
}
/**
* An event that is fired after files are created.
*/
export interface FileCreateEvent {
/**
* The files that got created.
*/
readonly files: ReadonlyArray<Uri>;
}
/**
* An event that is fired when files are going to be deleted.
*
* To make modifications to the workspace before the files are deleted,
* call the [`waitUntil](#FileWillCreateEvent.waitUntil)-function with a
* thenable that resolves to a [workspace edit](#WorkspaceEdit).
*/
export interface FileWillDeleteEvent {
/**
* The files that are going to be deleted.
*/
readonly files: ReadonlyArray<Uri>;
/**
* Allows to pause the event and to apply a [workspace edit](#WorkspaceEdit).
*
* *Note:* This function can only be called during event dispatch and not
* in an asynchronous manner:
*
* ```ts
* workspace.onWillCreateFiles(event => {
* // async, will *throw* an error
* setTimeout(() => event.waitUntil(promise));
*
* // sync, OK
* event.waitUntil(promise);
* })
* ```
*
* @param thenable A thenable that delays saving.
*/
waitUntil(thenable: Thenable<WorkspaceEdit>): void;
/**
* Allows to pause the event until the provided thenable resolves.
*
* *Note:* This function can only be called during event dispatch.
*
* @param thenable A thenable that delays saving.
*/
waitUntil(thenable: Thenable<any>): void;
}
/**
* An event that is fired after files are deleted.
*/
export interface FileDeleteEvent {
/**
* The files that got deleted.
*/
readonly files: ReadonlyArray<Uri>;
}
/**
* An event that is fired when files are going to be renamed.
*
* To make modifications to the workspace before the files are renamed,
* call the [`waitUntil](#FileWillCreateEvent.waitUntil)-function with a
* thenable that resolves to a [workspace edit](#WorkspaceEdit).
*/
export interface FileWillRenameEvent {
/**
* The files that are going to be renamed.
*/
readonly files: ReadonlyArray<{ oldUri: Uri, newUri: Uri }>;
/**
* Allows to pause the event and to apply a [workspace edit](#WorkspaceEdit).
*
* *Note:* This function can only be called during event dispatch and not
* in an asynchronous manner:
*
* ```ts
* workspace.onWillCreateFiles(event => {
* // async, will *throw* an error
* setTimeout(() => event.waitUntil(promise));
*
* // sync, OK
* event.waitUntil(promise);
* })
* ```
*
* @param thenable A thenable that delays saving.
*/
waitUntil(thenable: Thenable<WorkspaceEdit>): void;
/**
* Allows to pause the event until the provided thenable resolves.
*
* *Note:* This function can only be called during event dispatch.
*
* @param thenable A thenable that delays saving.
*/
waitUntil(thenable: Thenable<any>): void;
}
/**
* An event that is fired after files are renamed.
*/
export interface FileRenameEvent {
/**
* The files that got renamed.
*/
readonly files: ReadonlyArray<{ oldUri: Uri, newUri: Uri }>;
}
export namespace workspace {
/**
* An event that is emitted when files are being created.
*
* *Note 1:* This event is triggered by user gestures, like creating a file from the
* explorer, or from the [`workspace.applyEdit`](#workspace.applyEdit)-api. This event is *not* fired when
* files change on disk, e.g triggered by another application, or when using the
* [`workspace.fs`](#FileSystem)-api.
*
* *Note 2:* When this event is fired, edits to files thare are being created cannot be applied.
*/
export const onWillCreateFiles: Event<FileWillCreateEvent>;
/**
* An event that is emitted when files have been created.
*
* *Note:* This event is triggered by user gestures, like creating a file from the
* explorer, or from the [`workspace.applyEdit`](#workspace.applyEdit)-api, but this event is *not* fired when
* files change on disk, e.g triggered by another application, or when using the
* [`workspace.fs`](#FileSystem)-api.
*/
export const onDidCreateFiles: Event<FileCreateEvent>;
/**
* An event that is emitted when files are being deleted.
*
* *Note 1:* This event is triggered by user gestures, like deleting a file from the
* explorer, or from the [`workspace.applyEdit`](#workspace.applyEdit)-api, but this event is *not* fired when
* files change on disk, e.g triggered by another application, or when using the
* [`workspace.fs`](#FileSystem)-api.
*
* *Note 2:* When deleting a folder with children only one event is fired.
*/
export const onWillDeleteFiles: Event<FileWillDeleteEvent>;
/**
* An event that is emitted when files have been deleted.
*
* *Note 1:* This event is triggered by user gestures, like deleting a file from the
* explorer, or from the [`workspace.applyEdit`](#workspace.applyEdit)-api, but this event is *not* fired when
* files change on disk, e.g triggered by another application, or when using the
* [`workspace.fs`](#FileSystem)-api.
*
* *Note 2:* When deleting a folder with children only one event is fired.
*/
export const onDidDeleteFiles: Event<FileDeleteEvent>;
/**
* An event that is emitted when files are being renamed.
*
* *Note 1:* This event is triggered by user gestures, like renaming a file from the
* explorer, and from the [`workspace.applyEdit`](#workspace.applyEdit)-api, but this event is *not* fired when
* files change on disk, e.g triggered by another application, or when using the
* [`workspace.fs`](#FileSystem)-api.
*
* *Note 2:* When renaming a folder with children only one event is fired.
*/
export const onWillRenameFiles: Event<FileWillRenameEvent>;
/**
* An event that is emitted when files have been renamed.
*
* *Note 1:* This event is triggered by user gestures, like renaming a file from the
* explorer, and from the [`workspace.applyEdit`](#workspace.applyEdit)-api, but this event is *not* fired when
* files change on disk, e.g triggered by another application, or when using the
* [`workspace.fs`](#FileSystem)-api.
*
* *Note 2:* When renaming a folder with children only one event is fired.
*/
export const onDidRenameFiles: Event<FileRenameEvent>;
}
//#endregion
//#region Alex - OnEnter enhancement
export interface OnEnterRule {
/**