Skip to content

Commit

Permalink
feat(json-crdt-peritext-ui): 🎸 add ability to delete at arbitrary pos…
Browse files Browse the repository at this point in the history
…ition
  • Loading branch information
streamich committed Nov 3, 2024
1 parent 3a28733 commit 98fff74
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 3 deletions.
4 changes: 2 additions & 2 deletions src/json-crdt-peritext-ui/events/PeritextEventTarget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ export class PeritextEventTarget extends TypedEventTarget<PeritextEventMap> {
this.dispatch('insert', {text});
}

public delete(len: DeleteDetail['len'], unit?: DeleteDetail['unit']): void {
this.dispatch('delete', {len, unit});
public delete(len: DeleteDetail['len'], unit?: DeleteDetail['unit'], at?: DeleteDetail['at']): void {
this.dispatch('delete', {len, unit, at});
}

public cursor(detail: CursorDetail): void {
Expand Down
22 changes: 22 additions & 0 deletions src/json-crdt-peritext-ui/events/__tests__/delete.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,28 @@ const testSuite = (getKit: () => Kit) => {
kit.et.delete(DIRECTION, 'word');
expect(kit.editor.text()).toBe('abcde klmnopqrstuvwxyz');
});

test('can delete a word at specific position', async () => {
const kit = setup();
kit.editor.cursor.setAt(10);
kit.et.insert(' ');
kit.editor.cursor.setAt(5);
kit.et.insert(' ');
kit.editor.delCursors();
expect(kit.editor.text()).toBe('abcde fghij klmnopqrstuvwxyz');
kit.et.delete(0, 'word', 8);
expect(kit.editor.text()).toBe('abcde klmnopqrstuvwxyz');
expect(kit.editor.cursor.start.viewPos()).toBe(6);
expect(kit.editor.cursor.isCollapsed()).toBe(true);
kit.et.delete(0, 'word', 3);
expect(kit.editor.text()).toBe(' klmnopqrstuvwxyz');
expect(kit.editor.cursor.start.viewPos()).toBe(0);
expect(kit.editor.cursor.isCollapsed()).toBe(true);
kit.et.delete(0, 'word', 10);
expect(kit.editor.text()).toBe(' ');
expect(kit.editor.cursor.start.viewPos()).toBe(2);
expect(kit.editor.cursor.isCollapsed()).toBe(true);
});
});

describe('lines', () => {
Expand Down
29 changes: 28 additions & 1 deletion src/json-crdt-peritext-ui/events/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type {Point} from '../../json-crdt-extensions/peritext/rga/Point';
import type {Position as EditorPosition} from '../../json-crdt-extensions/peritext/editor/types';
import type {SliceType} from '../../json-crdt-extensions/peritext/slice/types';

/**
Expand Down Expand Up @@ -57,6 +58,17 @@ export interface DeleteDetail {
* @default 'char'
*/
unit?: 'char' | 'word' | 'line';

/**
* Position in the document to start the deletion from. If not specified, the
* deletion is executed for all cursors in the document at their current
* positions. If specified, only one cursor will be placed at the specified
* position and the deletion will be executed from that position (while all
* other cursors will be removed).
*
* @default undefined
*/
at?: Position;
}

/**
Expand Down Expand Up @@ -117,7 +129,7 @@ export interface CursorDetail {
* second `0 | 1` member specifies the anchor point of the character: `0`
* for the beginning of the character and `1` for the end of the character.
*/
at?: number | [at: number, anchor: 0 | 1] | Point;
at?: Position;

/**
* Specify the length of the movement or selection in units specified by the
Expand Down Expand Up @@ -164,6 +176,21 @@ export interface InlineDetail {
// biome-ignore lint: empty interface is expected
export type MarkerDetail = {};

/**
* Position represents a caret position in the document. The position can either
* be an instance of {@link Point} or a numeric position in the document, which
* will be immediately converted to a {@link Point} instance.
*
* If a number is provided, the number represents the character index in the
* document, where `0` is the beginning of the document and `1` is the position
* right after the first character, etc.
*
* If 2-tuple is provided, the first element is the character index and the
* second `0 | 1` member specifies the anchor point of the character: `0`
* for the beginning of the character and `1` for the end of the character.
*/
export type Position = EditorPosition<string>;

export type PeritextEventMap = {
change: ChangeDetail;
insert: InsertDetail;
Expand Down

0 comments on commit 98fff74

Please sign in to comment.