import { CodeEditor } from '@jupyterlab/codeeditor'; import { Signal } from '@lumino/signaling'; import { IDocumentInfo } from 'lsp-ws-connection'; import { IForeignCodeExtractor, IForeignCodeExtractorsRegistry } from '../extractors/types'; import { LanguageIdentifier } from '../lsp'; import { ICodeOverridesRegistry } from '../overrides/tokens'; import { IEditorPosition, ISourcePosition, IVirtualPosition } from '../positioning'; import { ILSPLogConsole } from '../tokens'; import { DefaultMap } from '../utils'; import IRange = CodeEditor.IRange; declare type language = string; interface IVirtualLine { /** * Inspections for which document should be skipped for this virtual line? */ skip_inspect: Array; /** * Where does the virtual line belongs to in the source document? */ source_line: number | null; editor: CodeEditor.IEditor; } export interface ICodeBlockOptions { ce_editor: CodeEditor.IEditor; value: string; } export interface IVirtualDocumentBlock { /** * Line corresponding to the block in the entire foreign document */ virtual_line: number; virtual_document: VirtualDocument; editor: CodeEditor.IEditor; } export declare type ForeignDocumentsMap = Map; interface ISourceLine { virtual_line: number; editor: CodeEditor.IEditor; editor_line: number; editor_shift: CodeEditor.IPosition; /** * Everything which is not in the range of foreign documents belongs to the host. */ foreign_documents_map: ForeignDocumentsMap; } export interface IForeignContext { foreign_document: VirtualDocument; parent_host: VirtualDocument; } /** * Check if given position is within range. * Both start and end are inclusive. * @param position * @param range */ export declare function is_within_range(position: CodeEditor.IPosition, range: CodeEditor.IRange): boolean; /** * a virtual implementation of IDocumentInfo */ export declare class VirtualDocumentInfo implements IDocumentInfo { private _document; version: number; constructor(document: VirtualDocument); get text(): string; get uri(): string; get languageId(): string; } export declare namespace VirtualDocument { interface IOptions { language: LanguageIdentifier; foreign_code_extractors: IForeignCodeExtractorsRegistry; overrides_registry: ICodeOverridesRegistry; path: string; file_extension: string | undefined; console: ILSPLogConsole; /** * Notebooks or any other aggregates of documents are not supported * by the LSP specification, and we need to make appropriate * adjustments for them, pretending they are simple files * so that the LSP servers do not refuse to cooperate. */ has_lsp_supported_file: boolean; /** * Being standalone is relevant to foreign documents * and defines whether following chunks of code in the same * language should be appended to this document (false, not standalone) * or should be considered separate documents (true, standalone) * */ standalone?: boolean; parent?: VirtualDocument; } } /** * A notebook can hold one or more virtual documents; there is always one, * "root" document, corresponding to the language of the kernel. All other * virtual documents are extracted out of the notebook, based on magics, * or other syntax constructs, depending on the kernel language. * * Virtual documents represent the underlying code in a single language, * which has been parsed excluding interactive kernel commands (magics) * which could be misunderstood by the specific LSP server. * * VirtualDocument has no awareness of the notebook or editor it lives in, * however it is able to transform its content back to the notebook space, * as it keeps editor coordinates for each virtual line. * * The notebook/editor aware transformations are preferred to be placed in * VirtualEditor descendants rather than here. * * No dependency on editor implementation (such as CodeMirrorEditor) * is allowed for VirtualEditor. */ export declare class VirtualDocument { language: string; last_virtual_line: number; foreign_document_closed: Signal; foreign_document_opened: Signal; readonly instance_id: number; protected console: ILSPLogConsole; standalone: boolean; isDisposed: boolean; /** * the remote document uri, version and other server-related info */ document_info: IDocumentInfo; /** * Virtual lines keep all the lines present in the document AND extracted to the foreign document. */ virtual_lines: Map; protected source_lines: Map; foreign_extractors: IForeignCodeExtractor[]; overrides_registry: ICodeOverridesRegistry; protected foreign_extractors_registry: IForeignCodeExtractorsRegistry; protected line_blocks: Array; protected unused_documents: Set; protected unused_standalone_documents: DefaultMap>; private _remaining_lifetime; private cell_magics_overrides; private line_magics_overrides; private static instances_count; foreign_documents: Map; blank_lines_between_cells: number; last_source_line: number; private previous_value; changed: Signal; path: string; file_extension: string | undefined; has_lsp_supported_file: boolean; parent?: VirtualDocument | null; private readonly options; update_manager: UpdateManager; constructor(options: VirtualDocument.IOptions); dispose(): void; /** * When this counter goes down to 0, the document will be destroyed and the associated connection will be closed; * This is meant to reduce the number of open connections when a a foreign code snippet was removed from the document. * * Note: top level virtual documents are currently immortal (unless killed by other means); it might be worth * implementing culling of unused documents, but if and only if JupyterLab will also implement culling of * idle kernels - otherwise the user experience could be a bit inconsistent, and we would need to invent our own rules. */ protected get remaining_lifetime(): number; protected set remaining_lifetime(value: number); clear(): void; private forward_closed_signal; private forward_opened_signal; private open_foreign; document_at_source_position(position: ISourcePosition): VirtualDocument; is_within_foreign(source_position: ISourcePosition): boolean; virtual_position_at_document(source_position: ISourcePosition): IVirtualPosition; private choose_foreign_document; extract_foreign_code(block: ICodeBlockOptions, editor_shift: CodeEditor.IPosition): { cell_code_kept: string; foreign_document_map: Map; }; decode_code_block(raw_code: string): string; prepare_code_block(block: ICodeBlockOptions, editor_shift?: CodeEditor.IPosition): { lines: string[]; foreign_document_map: Map; skip_inspect: string[][]; }; get foreign_document_maps(): ForeignDocumentsMap[]; append_code_block(block: ICodeBlockOptions, editor_shift?: CodeEditor.IPosition, virtual_shift?: CodeEditor.IPosition): void; get value(): string; get last_line(): string; close_expired_documents(): void; close_foreign(document: VirtualDocument): void; close_all_foreign_documents(): void; get virtual_id(): VirtualDocument.virtual_id; get ancestry(): Array; get id_path(): VirtualDocument.id_path; get uri(): VirtualDocument.uri; transform_source_to_editor(pos: ISourcePosition): IEditorPosition; /** Can be null because some lines are added as padding/anchors to the virtual document and those do not exist in the source document and thus they are absent in the editor. */ transform_virtual_to_editor(virtual_position: IVirtualPosition): IEditorPosition | null; /** Can be null because some lines are added as padding/anchors to the virtual document and those do not exist in the source document. */ transform_virtual_to_source(position: IVirtualPosition): ISourcePosition | null; get root(): VirtualDocument; get_editor_at_virtual_line(pos: IVirtualPosition): CodeEditor.IEditor; get_editor_at_source_line(pos: ISourcePosition): CodeEditor.IEditor; /** * Recursively emits changed signal from the document or any descendant foreign document. */ maybe_emit_changed(): void; } export declare namespace VirtualDocument { /** * Identifier composed of `virtual_id`s of a nested structure of documents, * used to aide assignment of the connection to the virtual document * handling specific, nested language usage; it will be appended to the file name * when creating a connection. */ type id_path = string; /** * Instance identifier for standalone documents (snippets), or language identifier * for documents which should be interpreted as one when stretched across cells. */ type virtual_id = string; /** * Identifier composed of the file path and id_path. */ type uri = string; } export declare function collect_documents(virtual_document: VirtualDocument): Set; export interface IBlockAddedInfo { virtual_document: VirtualDocument; block: ICodeBlockOptions; } export declare class UpdateManager { private virtual_document; console: ILSPLogConsole; /** * Virtual documents update guard. */ private is_update_in_progress; private update_lock; protected isDisposed: boolean; /** * Signal emitted by the editor that triggered the update, providing the root document of the updated documents. */ private document_updated; block_added: Signal; update_done: Promise; update_began: Signal; update_finished: Signal; constructor(virtual_document: VirtualDocument, console: ILSPLogConsole); dispose(): void; /** * Once all the foreign documents were refreshed, the unused documents (and their connections) * should be terminated if their lifetime has expired. */ private on_updated; private can_update; /** * Execute provided callback within an update-locked context, which guarantees that: * - the previous updates must have finished before the callback call, and * - no update will happen when executing the callback * @param fn - the callback to execute in update lock */ with_update_lock(fn: () => void): Promise; /** * Update all the virtual documents, emit documents updated with root document if succeeded, * and resolve a void promise. The promise does not contain the text value of the root document, * as to avoid an easy trap of ignoring the changes in the virtual documents. */ update_documents(blocks: ICodeBlockOptions[]): Promise; } export {};