adopt to stable'ish API

This commit is contained in:
Johannes Rieken
2018-04-23 15:49:57 +02:00
parent 546b6bfe71
commit 83b6a15e27
3 changed files with 159 additions and 105 deletions

View File

@ -6,7 +6,7 @@ import { MemFS } from './fileSystemProvider';
export function activate(context: vscode.ExtensionContext) {
const memFs = new MemFS();
const registration = vscode.workspace.registerFileSystemProvider2('memfs', memFs, { isCaseSensitive: true });
const registration = vscode.workspace.registerFileSystemProvider('memfs', memFs, { isCaseSensitive: true });
let initialized = false;
vscode.commands.registerCommand('memfs.reset', _ => {

View File

@ -48,28 +48,28 @@ class Directory {
type Entry = File | Directory;
export class MemFS implements vscode.FileSystemProvider2 {
export class MemFS implements vscode.FileSystemProvider {
_version: 9 = 9;
private _root = new Directory('');
private _data = new WeakMap<Entry, Uint8Array>();
private _emitter = new vscode.EventEmitter<vscode.FileChange2[]>();
private _emitter = new vscode.EventEmitter<vscode.FileChangeEvent[]>();
readonly onDidChangeFile: vscode.Event<vscode.FileChange2[]> = this._emitter.event;
readonly onDidChangeFile: vscode.Event<vscode.FileChangeEvent[]> = this._emitter.event;
watch(resource: vscode.Uri, opts): vscode.Disposable {
// ignore, fires for all changes...
return new vscode.Disposable(() => { });
}
stat(uri: vscode.Uri): vscode.FileStat2 {
stat(uri: vscode.Uri): vscode.FileStat {
return this._lookup(uri);
}
readDirectory(uri: vscode.Uri): [string, vscode.FileStat2][] {
readDirectory(uri: vscode.Uri): [string, vscode.FileStat][] {
const entry = this._lookupDir(uri);
let result: [string, vscode.FileStat2][] = [];
let result: [string, vscode.FileStat][] = [];
for (const [name, child] of entry.entries) {
result.push([name, child]);
}
@ -94,15 +94,15 @@ export class MemFS implements vscode.FileSystemProvider2 {
if (!entry) {
entry = new File(basename);
parent.entries.set(basename, entry);
this._fireSoon({ type: vscode.FileChangeType2.Created, uri });
this._fireSoon({ type: vscode.FileChangeType.Created, uri });
}
entry.mtime = Date.now();
entry.size = content.byteLength;
this._data.set(entry, content);
this._fireSoon({ type: vscode.FileChangeType2.Changed, uri });
this._fireSoon({ type: vscode.FileChangeType.Changed, uri });
}
rename(oldUri: vscode.Uri, newUri: vscode.Uri): vscode.FileStat2 {
rename(oldUri: vscode.Uri, newUri: vscode.Uri): vscode.FileStat {
let entry = this._lookup(oldUri);
let oldParent = this._lookupContainer(oldUri);
@ -114,8 +114,8 @@ export class MemFS implements vscode.FileSystemProvider2 {
newParent.entries.set(newName, entry);
this._fireSoon(
{ type: vscode.FileChangeType2.Deleted, uri: oldUri },
{ type: vscode.FileChangeType2.Created, uri: newUri }
{ type: vscode.FileChangeType.Deleted, uri: oldUri },
{ type: vscode.FileChangeType.Created, uri: newUri }
);
return entry;
}
@ -130,10 +130,10 @@ export class MemFS implements vscode.FileSystemProvider2 {
parent.entries.delete(basename);
parent.mtime = Date.now();
parent.size -= 1;
this._fireSoon({ type: vscode.FileChangeType2.Changed, uri: dirname }, { uri, type: vscode.FileChangeType2.Deleted });
this._fireSoon({ type: vscode.FileChangeType.Changed, uri: dirname }, { uri, type: vscode.FileChangeType.Deleted });
}
createDirectory(uri: vscode.Uri): vscode.FileStat2 {
createDirectory(uri: vscode.Uri): vscode.FileStat {
let basename = path.posix.basename(uri.path);
let dirname = uri.with({ path: path.posix.dirname(uri.path) });
let parent = this._lookupDir(dirname);
@ -142,7 +142,7 @@ export class MemFS implements vscode.FileSystemProvider2 {
parent.entries.set(entry.name, entry);
parent.mtime = Date.now();
parent.size += 1;
this._fireSoon({ type: vscode.FileChangeType2.Changed, uri: dirname }, { type: vscode.FileChangeType2.Created, uri });
this._fireSoon({ type: vscode.FileChangeType.Changed, uri: dirname }, { type: vscode.FileChangeType.Created, uri });
return entry;
}
@ -182,15 +182,15 @@ export class MemFS implements vscode.FileSystemProvider2 {
// --- events
private _bufferedEvents: vscode.FileChange2[] = [];
private _bufferedEvents: vscode.FileChangeEvent[] = [];
private _fireSoonHandle: NodeJS.Timer;
private _fireSoon(...events: vscode.FileChange2[]): void {
private _fireSoon(...events: vscode.FileChangeEvent[]): void {
this._bufferedEvents.push(...events);
clearTimeout(this._fireSoonHandle);
this._fireSoonHandle = setTimeout(() => {
this._emitter.fire(this._bufferedEvents);
this._bufferedEvents.length = 0;
}, 25);
}, 5);
}
}

View File

@ -13,86 +13,40 @@ declare module 'vscode' {
//#region Joh: file system provider (OLD)
export enum FileChangeType {
export enum DeprecatedFileChangeType {
Updated = 0,
Added = 1,
Deleted = 2
}
export interface FileChange {
type: FileChangeType;
export interface DeprecatedFileChange {
type: DeprecatedFileChangeType;
resource: Uri;
}
export enum FileType {
export enum DeprecatedFileType {
File = 0,
Dir = 1,
Symlink = 2
}
export interface FileStat {
export interface DeprecatedFileStat {
id: number | string;
mtime: number;
// atime: number;
size: number;
type: FileType;
type: DeprecatedFileType;
}
// todo@joh discover files etc
// todo@joh CancellationToken everywhere
// todo@joh add open/close calls?
export interface FileSystemProvider {
readonly onDidChange?: Event<FileChange[]>;
// more...
// @deprecated - will go away
utimes(resource: Uri, mtime: number, atime: number): Thenable<FileStat>;
stat(resource: Uri): Thenable<FileStat>;
export interface DeprecatedFileSystemProvider {
readonly onDidChange?: Event<DeprecatedFileChange[]>;
utimes(resource: Uri, mtime: number, atime: number): Thenable<DeprecatedFileStat>;
stat(resource: Uri): Thenable<DeprecatedFileStat>;
read(resource: Uri, offset: number, length: number, progress: Progress<Uint8Array>): Thenable<number>;
// todo@joh - have an option to create iff not exist
// todo@remote
// offset - byte offset to start
// count - number of bytes to write
// Thenable<number> - number of bytes actually written
write(resource: Uri, content: Uint8Array): Thenable<void>;
// todo@remote
// Thenable<FileStat>
move(resource: Uri, target: Uri): Thenable<FileStat>;
// todo@remote
// helps with performance bigly
// copy?(from: Uri, to: Uri): Thenable<void>;
// todo@remote
// Thenable<FileStat>
mkdir(resource: Uri): Thenable<FileStat>;
readdir(resource: Uri): Thenable<[Uri, FileStat][]>;
// todo@remote
// ? merge both
// ? recursive del
move(resource: Uri, target: Uri): Thenable<DeprecatedFileStat>;
mkdir(resource: Uri): Thenable<DeprecatedFileStat>;
readdir(resource: Uri): Thenable<[Uri, DeprecatedFileStat][]>;
rmdir(resource: Uri): Thenable<void>;
unlink(resource: Uri): Thenable<void>;
// todo@remote
// create(resource: Uri): Thenable<FileStat>;
}
export type DeprecatedFileChangeType = FileChangeType;
export type DeprecatedFileType = FileType;
export type DeprecatedFileChange = FileChange;
export type DeprecatedFileStat = FileStat;
export type DeprecatedFileSystemProvider = FileSystemProvider;
export namespace workspace {
export function registerDeprecatedFileSystemProvider(scheme: string, provider: DeprecatedFileSystemProvider): Disposable;
export function registerFileSystemProvider(scheme: string, provider: FileSystemProvider, newProvider?: FileSystemProvider2): Disposable;
}
//#endregion
@ -100,39 +54,115 @@ declare module 'vscode' {
//#region Joh: file system provider (new)
/**
* A type that filesystem providers should use to signal errors.
*
* This class has factory methods for common error-cases, like `EntryNotFound` when
* a file or folder doesn't exist, use them like so: `throw vscode.FileSystemError.EntryNotFound(someUri);`
*/
export class FileSystemError extends Error {
static EntryExists(message?: string): FileSystemError;
static EntryNotFound(message?: string): FileSystemError;
static EntryNotADirectory(message?: string): FileSystemError;
static EntryIsADirectory(message?: string): FileSystemError;
/**
* Create an error to signal that a file or folder wasn't found.
* @param messageOrUri Message or uri.
*/
static EntryNotFound(messageOrUri?: string | Uri): FileSystemError;
constructor(message?: string);
/**
* Create an error to signal that a file or folder already exists, e.g. when
* creating but not overwriting a file.
* @param messageOrUri Message or uri.
*/
static EntryExists(messageOrUri?: string | Uri): FileSystemError;
/**
* Create an error to signal that a file is not a folder.
* @param messageOrUri Message or uri.
*/
static EntryNotADirectory(messageOrUri?: string | Uri): FileSystemError;
/**
* Create an error to signal that a file is a folder.
* @param messageOrUri Message or uri.
*/
static EntryIsADirectory(messageOrUri?: string | Uri): FileSystemError;
/**
* Creates a new filesystem error.
*
* @param messageOrUri Message or uri.
*/
constructor(messageOrUri?: string | Uri);
}
export enum FileChangeType2 {
/**
* Enumeration of file change types.
*/
export enum FileChangeType {
/**
* The contents or metadata of a file have changed.
*/
Changed = 1,
/**
* A file has been created.
*/
Created = 2,
/**
* A file has been deleted.
*/
Deleted = 3,
}
export interface FileChange2 {
type: FileChangeType2;
/**
* The event filesystem providers must use to signal a file change.
*/
export interface FileChangeEvent {
/**
* The type of change.
*/
type: FileChangeType;
/**
* The uri of the file that has changed.
*/
uri: Uri;
}
export interface FileStat2 {
isFile: boolean;
isDirectory: boolean;
isSymbolicLink: boolean;
/**
* The `FileStat`-type represents metadata about a file.
*/
export interface FileStat {
/**
* The file is a regular file.
*/
isFile?: boolean;
/**
* The file is a directory.
*/
isDirectory?: boolean;
/**
* The file is symbolic link to another file.
*/
isSymbolicLink?: boolean;
/**
* The modification timestamp in milliseconds.
*/
mtime: number;
/**
* The size in bytes.
*/
size: number;
}
/**
*
* Commonly used options when reading, writing, or stat'ing files or folders.
*/
export interface FileOptions {
@ -159,18 +189,20 @@ declare module 'vscode' {
}
/**
*
* loose notes:
* -activation event `onFileSystem:foo`,
* -paths are hierarchical and the identifier of a file
* -use posix-path-math
* -etc...
*/
export interface FileSystemProvider2 {
_version: 9;
export interface FileSystemProvider {
/**
* An event to signal that a resource has been created, changed, or deleted. This
* event should fire for resources that are being [watched](#FileSystemProvider2.watch)
* by clients of this provider.
*/
readonly onDidChangeFile: Event<FileChange2[]>;
readonly onDidChangeFile: Event<FileChangeEvent[]>;
/**
* Subscribe to events in the file or folder denoted by `uri`.
@ -187,7 +219,7 @@ declare module 'vscode' {
* @param token A cancellation token.
* @return The file metadata about the file.
*/
stat(uri: Uri, options: { /*future: followSymlinks*/ }, token: CancellationToken): FileStat2 | Thenable<FileStat2>;
stat(uri: Uri, options: { /*future: followSymlinks*/ }, token: CancellationToken): FileStat | Thenable<FileStat>;
/**
* Retrieve the meta data of all entries of a [directory](#FileType2.Directory)
@ -196,7 +228,7 @@ declare module 'vscode' {
* @param token A cancellation token.
* @return A thenable that resolves to an array of tuples of file names and files stats.
*/
readDirectory(uri: Uri, options: { /*future: onlyType?*/ }, token: CancellationToken): [string, FileStat2][] | Thenable<[string, FileStat2][]>;
readDirectory(uri: Uri, options: { /*future: onlyType?*/ }, token: CancellationToken): [string, FileStat][] | Thenable<[string, FileStat][]>;
/**
* Create a new directory. *Note* that new files are created via `write`-calls.
@ -204,7 +236,7 @@ declare module 'vscode' {
* @param uri The uri of the *new* folder.
* @param token A cancellation token.
*/
createDirectory(uri: Uri, options: { /*future: permissions?*/ }, token: CancellationToken): FileStat2 | Thenable<FileStat2>;
createDirectory(uri: Uri, options: { /*future: permissions?*/ }, token: CancellationToken): FileStat | Thenable<FileStat>;
/**
* Read the entire contents of a file.
@ -240,7 +272,7 @@ declare module 'vscode' {
* @param newUri The target location.
* @param token A cancellation token.
*/
rename(oldUri: Uri, newUri: Uri, options: FileOptions, token: CancellationToken): FileStat2 | Thenable<FileStat2>;
rename(oldUri: Uri, newUri: Uri, options: FileOptions, token: CancellationToken): FileStat | Thenable<FileStat>;
/**
* Copy files or folders. Implementing this function is optional but it will speedup
@ -250,11 +282,11 @@ declare module 'vscode' {
* @param target The target location.
* @param token A cancellation token.
*/
copy?(uri: Uri, target: Uri, options: FileOptions, token: CancellationToken): FileStat2 | Thenable<FileStat2>;
copy?(uri: Uri, target: Uri, options: FileOptions, token: CancellationToken): FileStat | Thenable<FileStat>;
}
export namespace workspace {
export function registerFileSystemProvider2(scheme: string, provider: FileSystemProvider2, options: { isCaseSensitive?: boolean }): Disposable;
export function registerFileSystemProvider(scheme: string, provider: FileSystemProvider, options: { isCaseSensitive?: boolean }): Disposable;
}
//#endregion
@ -637,6 +669,10 @@ declare module 'vscode' {
//#region Terminal
export interface Terminal {
onData: Event<string>;
}
export namespace window {
/**
* The currently active terminals or an empty array.
@ -656,16 +692,34 @@ declare module 'vscode' {
//#region URLs
export interface UrlHandler {
handleUrl(uri: Uri): void;
export interface ProtocolHandler {
handleUri(uri: Uri): void;
}
export namespace window {
/**
* Registers a URL handler.
* Registers a protocol handler capable of handling system-wide URIs.
*/
export function registerUrlHandler(handler: UrlHandler): Disposable;
export function registerProtocolHandler(handler: ProtocolHandler): Disposable;
}
//#endregion
//#region Joh: hierarchical document symbols, https://github.com/Microsoft/vscode/issues/34968
export class HierarchicalSymbolInformation {
name: string;
kind: SymbolKind;
location: Location;
range: Range;
children: HierarchicalSymbolInformation[];
constructor(name: string, kind: SymbolKind, location: Location, range: Range);
}
export interface DocumentSymbolProvider {
provideDocumentSymbols(document: TextDocument, token: CancellationToken): ProviderResult<HierarchicalSymbolInformation | SymbolInformation[]>;
}
//#endregion