import { BasicEvent, Event, IExtensionInfo, URI } from '@opensumi/ide-core-common';
import { Uri, UriComponents } from './ext-types';
import type { IWebviewPanelOptions, WebviewPanel } from './webview';
import type { CancellationToken } from '@opensumi/ide-core-common';
import type { TextDocument } from 'vscode';
/**
 * Provider for text based custom editors.
 *
 * Text based custom editors use a [`TextDocument`](#TextDocument) as their data model. This considerably simplifies
 * implementing a custom editor as it allows VS Code to handle many common operations such as
 * undo and backup. The provider is responsible for synchronizing text changes between the webview and the `TextDocument`.
 */
export interface CustomTextEditorProvider {
    /**
     * Resolve a custom editor for a given text resource.
     *
     * This is called when a user first opens a resource for a `CustomTextEditorProvider`, or if they reopen an
     * existing editor using this `CustomTextEditorProvider`.
     *
     *
     * @param document Document for the resource to resolve.
     *
     * @param webviewPanel The webview panel used to display the editor UI for this resource.
     *
     * During resolve, the provider must fill in the initial html for the content webview panel and hook up all
     * the event listeners on it that it is interested in. The provider can also hold onto the `WebviewPanel` to
     * use later for example in a command. See [`WebviewPanel`](#WebviewPanel) for additional details.
     *
     * @param token A cancellation token that indicates the result is no longer needed.
     *
     * @return Thenable indicating that the custom editor has been resolved.
     */
    resolveCustomTextEditor(document: TextDocument, webviewPanel: WebviewPanel, token: CancellationToken): Thenable<void> | void;
}
/**
 * Represents a custom document used by a [`CustomEditorProvider`](#CustomEditorProvider).
 *
 * Custom documents are only used within a given `CustomEditorProvider`. The lifecycle of a `CustomDocument` is
 * managed by VS Code. When no more references remain to a `CustomDocument`, it is disposed of.
 */
export interface CustomDocument {
    /**
     * The associated uri for this document.
     */
    readonly uri: Uri;
    /**
     * Dispose of the custom document.
     *
     * This is invoked by VS Code when there are no more references to a given `CustomDocument` (for example when
     * all editors associated with the document have been closed.)
     */
    dispose(): void;
}
/**
 * Event triggered by extensions to signal to VS Code that an edit has occurred on an [`CustomDocument`](#CustomDocument).
 *
 * @see [`CustomDocumentProvider.onDidChangeCustomDocument`](#CustomDocumentProvider.onDidChangeCustomDocument).
 */
export interface CustomDocumentEditEvent<T extends CustomDocument = CustomDocument> {
    /**
     * The document that the edit is for.
     */
    readonly document: T;
    /**
     * Undo the edit operation.
     *
     * This is invoked by VS Code when the user undoes this edit. To implement `undo`, your
     * extension should restore the document and editor to the state they were in just before this
     * edit was added to VS Code's internal edit stack by `onDidChangeCustomDocument`.
     */
    undo(): Thenable<void> | void;
    /**
     * Redo the edit operation.
     *
     * This is invoked by VS Code when the user redoes this edit. To implement `redo`, your
     * extension should restore the document and editor to the state they were in just after this
     * edit was added to VS Code's internal edit stack by `onDidChangeCustomDocument`.
     */
    redo(): Thenable<void> | void;
    /**
     * Display name describing the edit.
     *
     * This will be shown to users in the UI for undo/redo operations.
     */
    readonly label?: string;
}
/**
 * Event triggered by extensions to signal to VS Code that the content of a [`CustomDocument`](#CustomDocument)
 * has changed.
 *
 * @see [`CustomDocumentProvider.onDidChangeCustomDocument`](#CustomDocumentProvider.onDidChangeCustomDocument).
 */
export interface CustomDocumentContentChangeEvent<T extends CustomDocument = CustomDocument> {
    /**
     * The document that the change is for.
     */
    readonly document: T;
}
/**
 * A backup for an [`CustomDocument`](#CustomDocument).
 */
export interface CustomDocumentBackup {
    /**
     * Unique identifier for the backup.
     *
     * This id is passed back to your extension in `openCustomDocument` when opening a custom editor from a backup.
     */
    readonly id: string;
    /**
     * Delete the current backup.
     *
     * This is called by VS Code when it is clear the current backup is no longer needed, such as when a new backup
     * is made or when the file is saved.
     */
    delete(): void;
}
/**
 * Additional information used to implement [`CustomEditableDocument.backup`](#CustomEditableDocument.backup).
 */
export interface CustomDocumentBackupContext {
    /**
     * Suggested file location to write the new backup.
     *
     * Note that your extension is free to ignore this and use its own strategy for backup.
     *
     * If the editor is for a resource from the current workspace, `destination` will point to a file inside
     * `ExtensionContext.storagePath`. The parent folder of `destination` may not exist, so make sure to created it
     * before writing the backup to this location.
     */
    readonly destination: Uri;
}
/**
 * Additional information about the opening custom document.
 */
export interface CustomDocumentOpenContext {
    /**
     * The id of the backup to restore the document from or `undefined` if there is no backup.
     *
     * If this is provided, your extension should restore the editor from the backup instead of reading the file
     * from the user's workspace.
     */
    readonly backupId?: string;
}
/**
 * Provider for readonly custom editors that use a custom document model.
 *
 * Custom editors use [`CustomDocument`](#CustomDocument) as their document model instead of a [`TextDocument`](#TextDocument).
 *
 * You should use this type of custom editor when dealing with binary files or more complex scenarios. For simple
 * text based documents, use [`CustomTextEditorProvider`](#CustomTextEditorProvider) instead.
 *
 * @param T Type of the custom document returned by this provider.
 */
export interface CustomReadonlyEditorProvider<T extends CustomDocument = CustomDocument> {
    /**
     * Create a new document for a given resource.
     *
     * `openCustomDocument` is called when the first time an editor for a given resource is opened. The opened
     * document is then passed to `resolveCustomEditor` so that the editor can be shown to the user.
     *
     * Already opened `CustomDocument` are re-used if the user opened additional editors. When all editors for a
     * given resource are closed, the `CustomDocument` is disposed of. Opening an editor at this point will
     * trigger another call to `openCustomDocument`.
     *
     * @param uri Uri of the document to open.
     * @param openContext Additional information about the opening custom document.
     * @param token A cancellation token that indicates the result is no longer needed.
     *
     * @return The custom document.
     */
    openCustomDocument(uri: Uri, openContext: CustomDocumentOpenContext, token: CancellationToken): Thenable<T> | T;
    /**
     * Resolve a custom editor for a given resource.
     *
     * This is called whenever the user opens a new editor for this `CustomEditorProvider`.
     *
     * @param document Document for the resource being resolved.
     *
     * @param webviewPanel The webview panel used to display the editor UI for this resource.
     *
     * During resolve, the provider must fill in the initial html for the content webview panel and hook up all
     * the event listeners on it that it is interested in. The provider can also hold onto the `WebviewPanel` to
     * use later for example in a command. See [`WebviewPanel`](#WebviewPanel) for additional details.
     *
     * @param token A cancellation token that indicates the result is no longer needed.
     *
     * @return Optional thenable indicating that the custom editor has been resolved.
     */
    resolveCustomEditor(document: T, webviewPanel: WebviewPanel, token: CancellationToken): Thenable<void> | void;
}
/**
 * Provider for editable custom editors that use a custom document model.
 *
 * Custom editors use [`CustomDocument`](#CustomDocument) as their document model instead of a [`TextDocument`](#TextDocument).
 * This gives extensions full control over actions such as edit, save, and backup.
 *
 * You should use this type of custom editor when dealing with binary files or more complex scenarios. For simple
 * text based documents, use [`CustomTextEditorProvider`](#CustomTextEditorProvider) instead.
 *
 * @param T Type of the custom document returned by this provider.
 */
export interface CustomEditorProvider<T extends CustomDocument = CustomDocument> extends CustomReadonlyEditorProvider<T> {
    /**
     * Signal that an edit has occurred inside a custom editor.
     *
     * This event must be fired by your extension whenever an edit happens in a custom editor. An edit can be
     * anything from changing some text, to cropping an image, to reordering a list. Your extension is free to
     * define what an edit is and what data is stored on each edit.
     *
     * Firing `onDidChange` causes VS Code to mark the editors as being dirty. This is cleared when the user either
     * saves or reverts the file.
     *
     * Editors that support undo/redo must fire a `CustomDocumentEditEvent` whenever an edit happens. This allows
     * users to undo and redo the edit using VS Code's standard VS Code keyboard shortcuts. VS Code will also mark
     * the editor as no longer being dirty if the user undoes all edits to the last saved state.
     *
     * Editors that support editing but cannot use VS Code's standard undo/redo mechanism must fire a `CustomDocumentContentChangeEvent`.
     * The only way for a user to clear the dirty state of an editor that does not support undo/redo is to either
     * `save` or `revert` the file.
     *
     * An editor should only ever fire `CustomDocumentEditEvent` events, or only ever fire `CustomDocumentContentChangeEvent` events.
     */
    readonly onDidChangeCustomDocument: Event<CustomDocumentEditEvent<T> | CustomDocumentContentChangeEvent<T>>;
    /**
     * Save a custom document.
     *
     * This method is invoked by VS Code when the user saves a custom editor. This can happen when the user
     * triggers save while the custom editor is active, by commands such as `save all`, or by auto save if enabled.
     *
     * To implement `save`, the implementer must persist the custom editor. This usually means writing the
     * file data for the custom document to disk. After `save` completes, any associated editor instances will
     * no longer be marked as dirty.
     *
     * @param document Document to save.
     * @param cancellation Token that signals the save is no longer required (for example, if another save was triggered).
     *
     * @return Thenable signaling that saving has completed.
     */
    saveCustomDocument(document: T, cancellation: CancellationToken): Thenable<void>;
    /**
     * Revert a custom document to its last saved state.
     *
     * This method is invoked by VS Code when the user triggers `File: Revert File` in a custom editor. (Note that
     * this is only used using VS Code's `File: Revert File` command and not on a `git revert` of the file).
     *
     * To implement `revert`, the implementer must make sure all editor instances (webviews) for `document`
     * are displaying the document in the same state is saved in. This usually means reloading the file from the
     * workspace.
     *
     * @param document Document to revert.
     * @param cancellation Token that signals the revert is no longer required.
     *
     * @return Thenable signaling that the change has completed.
     */
    revertCustomDocument(document: T, cancellation: CancellationToken): Thenable<void>;
}
export interface ICustomEditorSelector {
    filenamePattern: string;
}
export interface CustomEditorScheme {
    viewType: string;
    displayName: string;
    selector: ICustomEditorSelector[];
    priority?: 'default' | 'option';
}
export declare class CustomEditorShouldDisplayEvent extends BasicEvent<{
    uri: URI;
    viewType: string;
    openTypeId: string;
    webviewPanelId: string;
    cancellationToken: CancellationToken;
}> {
}
export declare class CustomEditorShouldHideEvent extends BasicEvent<{
    uri: URI;
    viewType: string;
}> {
}
export declare class CustomEditorShouldSaveEvent extends BasicEvent<{
    uri: URI;
    viewType: string;
    cancellationToken: CancellationToken;
}> {
}
export declare class CustomEditorShouldRevertEvent extends BasicEvent<{
    uri: URI;
    viewType: string;
    cancellationToken: CancellationToken;
}> {
}
export declare class CustomEditorShouldEditEvent extends BasicEvent<{
    type: 'redo' | 'undo';
    uri: URI;
    viewType: string;
}> {
}
export declare class CustomEditorOptionChangeEvent extends BasicEvent<{
    viewType: string;
    options: ICustomEditorOptions;
}> {
}
export interface IExtHostCustomEditor {
    $resolveCustomTextEditor(viewType: string, uri: UriComponents, webviewPanelId: string, token: CancellationToken): any;
    $saveCustomDocument(viewType: string, uri: UriComponents, token: CancellationToken): any;
    $revertCustomDocument(viewType: string, uri: UriComponents, token: CancellationToken): any;
    $undo(viewType: string, uri: UriComponents): any;
    $redo(viewType: string, uri: UriComponents): any;
}
export declare enum CustomEditorType {
    TextEditor = 1,
    ReadonlyEditor = 2,
    FullEditor = 3
}
export interface ICustomEditorOptions {
    supportsMultipleEditorsPerDocument?: boolean;
    webviewOptions?: IWebviewPanelOptions;
}
export interface IMainThreadCustomEditor {
    $registerCustomEditor(viewType: string, editorType: CustomEditorType, options: ICustomEditorOptions, extensionInfo: IExtensionInfo): any;
    $acceptCustomDocumentDirty(uri: UriComponents, dirty: boolean): any;
    $unregisterCustomEditor(viewType: string): any;
}
export type TCustomEditorProvider = {
    type: CustomEditorType.FullEditor;
    provider: CustomEditorProvider;
} | {
    type: CustomEditorType.ReadonlyEditor;
    provider: CustomReadonlyEditorProvider;
} | {
    type: CustomEditorType.TextEditor;
    provider: CustomTextEditorProvider;
};
//# sourceMappingURL=custom-editor.d.ts.map