@jupyterlab/lsp
Version:
545 lines (544 loc) • 18.7 kB
TypeScript
import { IDisposable } from '@lumino/disposable';
import { IDocumentInfo } from '../ws-connection/types';
import { IPosition } from '../positioning';
import { CodeEditor } from '@jupyterlab/codeeditor';
import { ISignal } from '@lumino/signaling';
import { Document, ILSPCodeExtractorsManager } from '../tokens';
import { LanguageIdentifier } from '../lsp';
import { IEditorPosition, IRootPosition, ISourcePosition, IVirtualPosition } from '../positioning';
import { DefaultMap } from '../utils';
type IRange = CodeEditor.IRange;
type language = string;
interface IVirtualLine {
/**
* Inspections for which document should be skipped for this virtual line?
*/
skipInspect: Array<VirtualDocument.idPath>;
/**
* Where does the virtual line belongs to in the source document?
*/
sourceLine: number | null;
/**
* The editor holding this virtual line
*/
editor: Document.IEditor;
}
export type ForeignDocumentsMap = Map<IRange, Document.IVirtualDocumentBlock>;
interface ISourceLine {
/**
* Line corresponding to the block in the entire foreign document
*/
virtualLine: number;
/**
* The CM editor associated with this virtual line.
*/
editor: Document.IEditor;
/**
* Line in the CM editor corresponding to the virtual line.
*/
editorLine: number;
/**
* Shift of the virtual line
*/
editorShift: CodeEditor.IPosition;
/**
* Everything which is not in the range of foreign documents belongs to the host.
*/
foreignDocumentsMap: ForeignDocumentsMap;
}
/**
* Check if given position is within range.
* Both start and end are inclusive.
* @param position
* @param range
*/
export declare function isWithinRange(position: CodeEditor.IPosition, range: CodeEditor.IRange): boolean;
/**
* A virtual implementation of IDocumentInfo
*/
export declare class VirtualDocumentInfo implements IDocumentInfo {
/**
* Creates an instance of VirtualDocumentInfo.
* @param document - the virtual document need to
* be wrapped.
*/
constructor(document: VirtualDocument);
/**
* Current version of the virtual document.
*/
version: number;
/**
* Get the text content of the virtual document.
*/
get text(): string;
/**
* Get the uri of the virtual document, if the document is not available,
* it returns an empty string, users need to check for the length of returned
* value before using it.
*/
get uri(): string;
/**
* Get the language identifier of the document.
*/
get languageId(): string;
/**
* The wrapped virtual document.
*/
private _document;
}
export declare namespace VirtualDocument {
interface IOptions {
/**
* The language identifier of the document.
*/
language: LanguageIdentifier;
/**
* The foreign code extractor manager token.
*/
foreignCodeExtractors: ILSPCodeExtractorsManager;
/**
* Path to the document.
*/
path: string;
/**
* File extension of the document.
*/
fileExtension: string | undefined;
/**
* 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.
*/
hasLspSupportedFile: 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 of the current virtual document.
*/
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 implements IDisposable {
constructor(options: VirtualDocument.IOptions);
/**
* Convert from code editor position into code mirror position.
*/
static ceToCm(position: CodeEditor.IPosition): IPosition;
/**
* Number of blank lines appended to the virtual document between
* each cell.
*/
blankLinesBetweenCells: number;
/**
* Line number of the last line in the real document.
*/
lastSourceLine: number;
/**
* Line number of the last line in the virtual document.
*/
lastVirtualLine: number;
/**
* the remote document uri, version and other server-related info
*/
documentInfo: IDocumentInfo;
/**
* Parent of the current virtual document.
*/
parent?: VirtualDocument | null;
/**
* The language identifier of the document.
*/
readonly language: string;
/**
* 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)
*/
readonly standalone: boolean;
/**
* Path to the document.
*/
readonly path: string;
/**
* File extension of the document.
*/
readonly fileExtension: string | undefined;
/**
* 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.
*/
readonly hasLspSupportedFile: boolean;
/**
* Map holding the children `VirtualDocument` .
*/
readonly foreignDocuments: Map<VirtualDocument.virtualId, VirtualDocument>;
/**
* The update manager object.
*/
readonly updateManager: UpdateManager;
/**
* Unique id of the virtual document.
*/
readonly instanceId: number;
/**
* Test whether the document is disposed.
*/
get isDisposed(): boolean;
/**
* Signal emitted when the foreign document is closed
*/
get foreignDocumentClosed(): ISignal<VirtualDocument, Document.IForeignContext>;
/**
* Signal emitted when the foreign document is opened
*/
get foreignDocumentOpened(): ISignal<VirtualDocument, Document.IForeignContext>;
/**
* Signal emitted when the foreign document is changed
*/
get changed(): ISignal<VirtualDocument, VirtualDocument>;
/**
* Id of the virtual document.
*/
get virtualId(): VirtualDocument.virtualId;
/**
* Return the ancestry to this document.
*/
get ancestry(): Array<VirtualDocument>;
/**
* Return the id path to the virtual document.
*/
get idPath(): VirtualDocument.idPath;
/**
* Get the uri of the virtual document.
*/
get uri(): VirtualDocument.uri;
/**
* Get the text value of the document
*/
get value(): string;
/**
* Get the last line in the virtual document
*/
get lastLine(): string;
/**
* Get the root document of current virtual document.
*/
get root(): VirtualDocument;
/**
* Dispose the virtual document.
*/
dispose(): void;
/**
* Clear the virtual document and all related stuffs
*/
clear(): void;
/**
* Get the virtual document from the cursor position of the source
* document
* @param position - position in source document
*/
documentAtSourcePosition(position: ISourcePosition): VirtualDocument;
/**
* Detect if the input source position is belong to the current
* virtual document.
*
* @param sourcePosition - position in the source document
*/
isWithinForeign(sourcePosition: ISourcePosition): boolean;
/**
* Compute the position in root document from the position of
* a child editor.
*
* @param editor - the active editor.
* @param position - position in the active editor.
*/
transformFromEditorToRoot(editor: Document.IEditor, position: IEditorPosition): IRootPosition | null;
/**
* Compute the position in the virtual document from the position
* if the source document.
*
* @param sourcePosition - position in source document
*/
virtualPositionAtDocument(sourcePosition: ISourcePosition): IVirtualPosition;
/**
* Append a code block to the end of the virtual document.
*
* @param block - block to be appended
* @param editorShift - position shift in source
* document
* @param [virtualShift] - position shift in
* virtual document.
*/
appendCodeBlock(block: Document.ICodeBlockOptions, editorShift?: CodeEditor.IPosition, virtualShift?: CodeEditor.IPosition): void;
/**
* Extract a code block into list of string in supported language and
* a map of foreign document if any.
* @param block - block to be appended
* @param editorShift - position shift in source document
*/
prepareCodeBlock(block: Document.ICodeBlockOptions, editorShift?: CodeEditor.IPosition): {
lines: string[];
foreignDocumentsMap: Map<CodeEditor.IRange, Document.IVirtualDocumentBlock>;
};
/**
* Extract the foreign code from input block by using the registered
* extractors.
* @param block - block to be appended
* @param editorShift - position shift in source document
*/
extractForeignCode(block: Document.ICodeBlockOptions, editorShift: CodeEditor.IPosition): {
cellCodeKept: string;
foreignDocumentsMap: Map<CodeEditor.IRange, Document.IVirtualDocumentBlock>;
};
/**
* Close a foreign document and disconnect all associated signals
*/
closeForeign(document: VirtualDocument): void;
/**
* Close all foreign documents.
*/
closeAllForeignDocuments(): void;
/**
* Close all expired documents.
*/
closeExpiredDocuments(): void;
/**
* Transform the position of the source to the editor
* position.
*
* @param pos - position in the source document
* @return position in the editor.
*/
transformSourceToEditor(pos: ISourcePosition): IEditorPosition;
/**
* Transform the position in the virtual document to the
* editor position.
* 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.
*/
transformVirtualToEditor(virtualPosition: IVirtualPosition): IEditorPosition | null;
/**
* Transform the position in the virtual document to the source.
* Can be null because some lines are added as padding/anchors
* to the virtual document and those do not exist in the source document.
*/
transformVirtualToSource(position: IVirtualPosition): ISourcePosition | null;
/**
* Compute the position in root document from the position of
* a virtual document.
*/
transformVirtualToRoot(position: IVirtualPosition): IRootPosition | null;
/**
* Get the corresponding editor of the virtual line.
*/
getEditorAtVirtualLine(pos: IVirtualPosition): Document.IEditor;
/**
* Get the corresponding editor of the source line
*/
getEditorAtSourceLine(pos: ISourcePosition): Document.IEditor;
/**
* Recursively emits changed signal from the document or any descendant foreign document.
*/
maybeEmitChanged(): 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 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 remainingLifetime(): number;
protected set remainingLifetime(value: number);
/**
* Virtual lines keep all the lines present in the document AND extracted to the foreign document.
*/
protected virtualLines: Map<number, IVirtualLine>;
protected sourceLines: Map<number, ISourceLine>;
protected lineBlocks: Array<string>;
protected unusedStandaloneDocuments: DefaultMap<language, Array<VirtualDocument>>;
private _isDisposed;
private _remainingLifetime;
private _editorToSourceLine;
private _editorToSourceLineNew;
private _foreignCodeExtractors;
private previousValue;
private static instancesCount;
private readonly options;
/**
* Get the foreign document that can be opened with the input extractor.
*/
private _chooseForeignDocument;
/**
* Create a foreign document from input language and file extension.
*
* @param language - the required language
* @param standalone - the document type is supported natively by LSP?
* @param fileExtension - File extension.
*/
private openForeign;
/**
* Forward the closed signal from the foreign document to the host document's
* signal
*/
private forwardClosedSignal;
/**
* Forward the opened signal from the foreign document to the host document's
* signal
*/
private forwardOpenedSignal;
/**
* Slot of the `updateBegan` signal.
*/
private _updateBeganSlot;
/**
* Slot of the `blockAdded` signal.
*/
private _blockAddedSlot;
/**
* Slot of the `updateFinished` signal.
*/
private _updateFinishedSlot;
private _foreignDocumentClosed;
private _foreignDocumentOpened;
private _changed;
}
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 idPath = string;
/**
* Instance identifier for standalone documents (snippets), or language identifier
* for documents which should be interpreted as one when stretched across cells.
*/
type virtualId = string;
/**
* Identifier composed of the file path and id_path.
*/
type uri = string;
}
/**
* Create foreign documents if available from input virtual documents.
* @param virtualDocument - the virtual document to be collected
* @return - Set of generated foreign documents
*/
export declare function collectDocuments(virtualDocument: VirtualDocument): Set<VirtualDocument>;
export interface IBlockAddedInfo {
/**
* The virtual document.
*/
virtualDocument: VirtualDocument;
/**
* Option of the code block.
*/
block: Document.ICodeBlockOptions;
}
export declare class UpdateManager implements IDisposable {
private virtualDocument;
constructor(virtualDocument: VirtualDocument);
/**
* Promise resolved when the updating process finishes.
*/
get updateDone(): Promise<void>;
/**
* Test whether the document is disposed.
*/
get isDisposed(): boolean;
/**
* Signal emitted when a code block is added to the document.
*/
get blockAdded(): ISignal<UpdateManager, IBlockAddedInfo>;
/**
* Signal emitted by the editor that triggered the update,
* providing the root document of the updated documents.
*/
get documentUpdated(): ISignal<UpdateManager, VirtualDocument>;
/**
* Signal emitted when the update is started
*/
get updateBegan(): ISignal<UpdateManager, Document.ICodeBlockOptions[]>;
/**
* Signal emitted when the update is finished
*/
get updateFinished(): ISignal<UpdateManager, Document.ICodeBlockOptions[]>;
/**
* Dispose the class
*/
dispose(): void;
/**
* 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
*/
withUpdateLock(fn: () => void): Promise<void>;
/**
* 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.
*/
updateDocuments(blocks: Document.ICodeBlockOptions[]): Promise<void>;
private _isDisposed;
/**
* Promise resolved when the updating process finishes.
*/
private _updateDone;
/**
* Virtual documents update guard.
*/
private _isUpdateInProgress;
/**
* Update lock to prevent multiple updates are applied at the same time.
*/
private _updateLock;
private _blockAdded;
private _documentUpdated;
private _updateBegan;
private _updateFinished;
/**
* Once all the foreign documents were refreshed, the unused documents (and their connections)
* should be terminated if their lifetime has expired.
*/
private _onUpdated;
/**
* Check if the document can be updated.
*/
private _canUpdate;
}
export {};