Skip to content

Commit

Permalink
improve caret movement during ctrl delete or backspace
Browse files Browse the repository at this point in the history
  • Loading branch information
sora committed Jun 29, 2022
1 parent 02d60e5 commit 0f89c29
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 2 deletions.
55 changes: 55 additions & 0 deletions packages/server/public/src/components/text-editor/caret.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,10 @@ export class CaretService {
this.extendFocus({ seeker: this.getWordEndPositionFromCaret, root });
}

selectWordEndLazy(root: HTMLElement) {
this.extendFocus({ seeker: this.getWordEndLazyPositionFromCaret, root });
}

moveLeft(root: HTMLElement) {
this.moveCaretCollapsedByOffset(-1, root);
}
Expand All @@ -135,6 +139,10 @@ export class CaretService {
this.extendFocus({ seeker: this.getWordStartPositionFromCaret, root });
}

selectWordStartLazy(root: HTMLElement) {
this.extendFocus({ seeker: this.getWordStartLazyPositionFromCaret, root });
}

moveHome(root: HTMLElement) {
this.moveCaretCollapsed({
seeker: this.getVisualHomePositionFromCaret,
Expand Down Expand Up @@ -609,6 +617,29 @@ export class CaretService {
return null;
}

// similar to getWordEndPosition but treats line ending as a word
private getWordEndLazyPositionFromCaret(caret: Caret): SeekOutput | null {
const currentLine = this.lineQueryService.getLine(caret.focus.node)!;
const currentLineMetrics = this.lineQueryService.getLineMetrics(currentLine);
const { offset: caretOffset } = this.getCaretLinePosition(caret.focus);

if (caretOffset === currentLineMetrics.selectableLength) {
// if at line end, search next line
const nextLine = this.lineQueryService.getNextLine(currentLine);
if (nextLine) {
return this.lineQueryService.seekToLineStart(nextLine);
}
} else {
// search current line (a result is guaranteed)
const textAfterCaret = this.lineQueryService.sliceLine(currentLine, caretOffset);
const wordEndOffset = getWordEndOffset(textAfterCaret);
const foundPosition = seek({ source: currentLine, offset: caretOffset + wordEndOffset })!;
return foundPosition;
}

return null;
}

private getWordStartPositionFromCaret(caret: Caret): SeekOutput | null {
const currentLine = this.lineQueryService.getLine(caret.focus.node)!;
const { offset: caretOffset } = this.getCaretLinePosition(caret.focus);
Expand Down Expand Up @@ -637,6 +668,30 @@ export class CaretService {
return null;
}

// similar to getWordStartPosition but treats line ending as a word
private getWordStartLazyPositionFromCaret(caret: Caret): SeekOutput | null {
const currentLine = this.lineQueryService.getLine(caret.focus.node)!;
const { offset: caretOffset } = this.getCaretLinePosition(caret.focus);

if (caretOffset === 0) {
// if at line start, search previous line
const previousLine = this.lineQueryService.getPreviousLine(currentLine);
if (previousLine) {
return this.lineQueryService.seekToLineEnd(previousLine);
}
} else {
// search current line (a result is guaranteed)
const textBeforeCaretBackward = ensureLineEnding(
reverse(this.lineQueryService.sliceLine(currentLine, 0, caretOffset))
);
const wordEndOffsetBackward = getWordEndOffset(textBeforeCaretBackward);
const foundPosition = seek({ source: currentLine, offset: caretOffset - wordEndOffsetBackward })!;
return foundPosition;
}

return null;
}

/**
* If after indent, get indent end position
* If within indent, get line start
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,9 @@ export class EditService {
return;
}

this.caretService.selectWordStart(root);
// Note that most editors seek word boundary more conservatively when deleting compared to just moving
// Using the lazy mode to ensure line ending is treated as a word
this.caretService.selectWordStartLazy(root);
this.deleteSelectionExplicit(root);
}

Expand All @@ -225,7 +227,7 @@ export class EditService {
return;
}

this.caretService.selectWordEnd(root);
this.caretService.selectWordEndLazy(root);
this.deleteSelectionExplicit(root);
}

Expand Down

0 comments on commit 0f89c29

Please sign in to comment.