Skip to content

Commit

Permalink
Add support for Delta documents
Browse files Browse the repository at this point in the history
  • Loading branch information
ddaspit committed Dec 6, 2024
1 parent 920740b commit 90c7bfe
Show file tree
Hide file tree
Showing 31 changed files with 516 additions and 132 deletions.
57 changes: 55 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion packages/core/src/common/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
export type { Position } from './position';
export type { Range } from './range';
export type { TextEdit } from './text-edit';
6 changes: 0 additions & 6 deletions packages/core/src/common/text-edit.ts

This file was deleted.

3 changes: 1 addition & 2 deletions packages/core/src/diagnostic/diagnostic-fix.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { TextEdit } from '../common/text-edit';
import { Diagnostic } from './diagnostic';

export interface DiagnosticFix {
title: string;
diagnostic: Diagnostic;
isPreferred?: boolean;
edits: TextEdit[];
edits: unknown[];
}
12 changes: 3 additions & 9 deletions packages/core/src/document/document-factory.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
import { Range } from '../common/range';
import { Document } from './document';

export interface DocumentChange {
range?: Range;
text: string;
}

export interface DocumentFactory<T extends Document> {
create(uri: string, format: string, version: number, content: string): T;
update(document: T, changes: readonly DocumentChange[], version: number): T;
export interface DocumentFactory<T extends Document = Document> {
create(uri: string, format: string, version: number, content: unknown): T;
update(document: T, changes: readonly unknown[], version: number): T;
}
6 changes: 3 additions & 3 deletions packages/core/src/document/document-manager.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Observable, Subject } from 'rxjs';

import { Document } from './document';
import { DocumentChange, DocumentFactory } from './document-factory';
import { DocumentFactory } from './document-factory';
import { DocumentReader } from './document-reader';

export interface DocumentCreated<T extends Document> {
Expand All @@ -24,7 +24,7 @@ export interface DocumentChanged<T extends Document> {
document: T;
}

export class DocumentManager<T extends Document> {
export class DocumentManager<T extends Document = Document> {
private readonly documents = new Map<string, T>();
private readonly activeDocuments = new Set<string>();
private readonly createdSubject = new Subject<DocumentCreated<T>>();
Expand Down Expand Up @@ -124,7 +124,7 @@ export class DocumentManager<T extends Document> {
return Promise.resolve();
}

async fireChanged(uri: string, changes?: readonly DocumentChange[], version?: number): Promise<void> {
async fireChanged(uri: string, changes?: readonly unknown[], version?: number): Promise<void> {
let doc: T | undefined = undefined;
if (changes == null) {
doc = await this.reload(uri);
Expand Down
4 changes: 4 additions & 0 deletions packages/core/src/document/document.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
export interface Document {
readonly uri: string;
readonly version: number;

getText(): string;
createTextEdit(startOffset: number, endOffset: number, newText: string): unknown[];
}
5 changes: 4 additions & 1 deletion packages/core/src/document/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export type { Document } from './document';
export type { DocumentChange, DocumentFactory } from './document-factory';
export type { DocumentFactory } from './document-factory';
export { DocumentManager } from './document-manager';
export type { DocumentReader } from './document-reader';
export { ScriptureBook } from './scripture-book';
Expand All @@ -22,4 +22,7 @@ export { ScriptureTable } from './scripture-table';
export { ScriptureText } from './scripture-text';
export { ScriptureVerse } from './scripture-verse';
export { TextDocument } from './text-document';
export type { TextDocumentChange } from './text-document-change';
export type { TextDocumentEdit } from './text-document-edit';
export { TextDocumentFactory } from './text-document-factory';
export { TextScriptureDocument } from './text-scripture-document';
17 changes: 12 additions & 5 deletions packages/core/src/document/scripture-document.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,20 @@
import { Position } from '../common/position';
import { Range } from '../common/range';
import { Document } from './document';
import { TextDocument } from './text-document';

export class ScriptureDocument extends TextDocument implements Document, ScriptureNode {
export abstract class ScriptureDocument implements Document, ScriptureNode {
private readonly _children: ScriptureNode[] = [];
readonly parent: undefined = undefined;
readonly isLeaf = false;
readonly type = ScriptureNodeType.Document;
readonly document = this;
abstract readonly version: number;
range: Range = { start: { line: 0, character: 0 }, end: { line: 0, character: 0 } };

constructor(
public readonly uri: string,
version: number,
content: string,
children?: ScriptureNode[],
) {
super(uri, version, content);
if (children != null) {
for (const child of children) {
this.appendChild(child);
Expand Down Expand Up @@ -78,6 +75,16 @@ export class ScriptureDocument extends TextDocument implements Document, Scriptu
clearChildren(): void {
this._children.length = 0;
}

abstract getText(range?: Range): string;
abstract offsetAt(position: Position): number;
abstract positionAt(offset: number, range?: Range): Position;
abstract createTextEdit(startOffset: number, endOffset: number, newText: string): unknown[];
abstract createScriptureEdit(
startOffset: number,
endOffset: number,
nodes: ScriptureNode[] | ScriptureNode,
): unknown[];
}

export enum ScriptureNodeType {
Expand Down
6 changes: 6 additions & 0 deletions packages/core/src/document/text-document-change.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { Range } from '../common/range';

export interface TextDocumentChange {
range?: Range;
text: string;
}
6 changes: 6 additions & 0 deletions packages/core/src/document/text-document-edit.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { Range } from '../common/range';

export interface TextDocumentEdit {
range: Range;
newText: string;
}
9 changes: 5 additions & 4 deletions packages/core/src/document/text-document-factory.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { DocumentChange, DocumentFactory } from './document-factory';
import { DocumentFactory } from './document-factory';
import { TextDocument } from './text-document';
import { TextDocumentChange } from './text-document-change';

export class TextDocumentFactory implements DocumentFactory<TextDocument> {
create(uri: string, _format: string, version: number, content: string): TextDocument {
return new TextDocument(uri, version, content);
create(uri: string, format: string, version: number, content: string): TextDocument {
return new TextDocument(uri, format, version, content);
}

update(document: TextDocument, changes: readonly DocumentChange[], version: number): TextDocument {
update(document: TextDocument, changes: readonly TextDocumentChange[], version: number): TextDocument {
document.update(changes, version);
return document;
}
Expand Down
28 changes: 12 additions & 16 deletions packages/core/src/document/text-document.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,26 @@
import { Position } from '../common/position';
import { Range } from '../common/range';
import { Document } from './document';
import { DocumentChange } from './document-factory';
import { TextDocumentChange } from './text-document-change';
import { TextDocumentEdit } from './text-document-edit';

export class TextDocument implements Document {
private _lineOffsets: number[] | undefined = undefined;
private _content: string;
private _version: number;

constructor(
public readonly uri: string,
version: number,
public readonly format: string,
public version: number,
content: string,
) {
this._version = version;
this._content = content;
}

get content(): string {
return this._content;
}

get version(): number {
return this._version;
}

protected set version(value: number) {
this._version = value;
}

getText(range?: Range): string {
if (range != null) {
const start = this.offsetAt(range.start);
Expand Down Expand Up @@ -95,14 +87,14 @@ export class TextDocument implements Document {
return { line, character: contentOffset - lineOffsets[line] };
}

update(changes: readonly DocumentChange[], version: number): void {
update(changes: readonly TextDocumentChange[], version: number): void {
for (const change of changes) {
this.updateContent(change);
}
this.version = version;
}

protected updateContent(change: DocumentChange): void {
updateContent(change: TextDocumentChange): void {
if (change.range == null) {
this._content = change.text;
this._lineOffsets = undefined;
Expand Down Expand Up @@ -143,14 +135,18 @@ export class TextDocument implements Document {
}
}

public getLineOffsets(): number[] {
createTextEdit(startOffset: number, endOffset: number, newText: string): TextDocumentEdit[] {
return [{ range: { start: this.positionAt(startOffset), end: this.positionAt(endOffset) }, newText }];
}

private getLineOffsets(): number[] {
if (this._lineOffsets === undefined) {
this._lineOffsets = computeLineOffsets(this._content, true);
}
return this._lineOffsets;
}

public ensureBeforeEndOfLine(offset: number, lineOffset: number): number {
private ensureBeforeEndOfLine(offset: number, lineOffset: number): number {
while (offset > lineOffset && (this._content[offset - 1] === '\r' || this._content[offset - 1] === '\n')) {
offset--;
}
Expand Down
Loading

0 comments on commit 90c7bfe

Please sign in to comment.