Standardise types for ranges (#16927)

GitOrigin-RevId: 28dd0eb67e1684e6bd0e452d15315ce1f9e3481a
This commit is contained in:
Alf Eaton
2024-02-09 09:06:51 +00:00
committed by Copybot
parent c997d1dc2b
commit 7b3ffb9fae
13 changed files with 171 additions and 185 deletions
@@ -8,9 +8,12 @@ import {
} from '../vertical-overflow'
import { EditorSelection, EditorState } from '@codemirror/state'
import { EditorView, ViewUpdate } from '@codemirror/view'
import { CurrentDoc } from '../../../../../../types/current-doc'
import { fullHeightCoordsAtPos } from '../../utils/layer'
import { debounce } from 'lodash'
import { Change, EditOperation } from '../../../../../../types/change'
import { ThreadId } from '../../../../../../types/review-panel/review-panel'
import { isDeleteOperation, isInsertOperation } from '@/utils/operations'
import { DocumentContainer } from '@/features/ide-react/editor/document-container'
// With less than this number of entries, don't bother culling to avoid
// little UI jumps when scrolling.
@@ -75,7 +78,7 @@ export type UpdateType =
export const createChangeManager = (
view: EditorView,
currentDoc: CurrentDoc
currentDoc: DocumentContainer
): ChangeManager => {
/**
* Calculate the screen coordinates of each entry (change or comment),
@@ -152,7 +155,7 @@ export const createChangeManager = (
/**
* Add a comment (thread) to the ShareJS doc when it's created
*/
const addComment = (offset: number, length: number, threadId: string) => {
const addComment = (offset: number, length: number, threadId: ThreadId) => {
currentDoc.submitOp({
c: view.state.doc.sliceString(offset, offset + length),
p: offset,
@@ -164,14 +167,14 @@ export const createChangeManager = (
* Remove a comment (thread) from the range tracker when it's deleted
*/
const removeComment = (commentId: string) => {
currentDoc.ranges.removeCommentId(commentId)
currentDoc.ranges!.removeCommentId(commentId)
}
/**
* Remove tracked changes from the range tracker when they're accepted
*/
const acceptChanges = (changeIds: string[]) => {
currentDoc.ranges.removeChangeIds(changeIds)
currentDoc.ranges!.removeChangeIds(changeIds)
}
/**
@@ -179,7 +182,9 @@ export const createChangeManager = (
* and restore the original content
*/
const rejectChanges = (changeIds: string[]) => {
const changes: any[] = currentDoc.ranges.getChanges(changeIds)
const changes = currentDoc.ranges!.getChanges(
changeIds
) as Change<EditOperation>[]
if (changes.length === 0) {
return {}
@@ -242,38 +247,30 @@ export const createChangeManager = (
const changesToDispatch = changes.map(change => {
const { op } = change
const opType = 'i' in op ? 'i' : 'c' in op ? 'c' : 'd'
if (isInsertOperation(op)) {
const from = op.p
const content = op.i
const to = from + content.length
switch (opType) {
case 'd': {
return {
from: op.p,
to: op.p,
insert: op.d,
}
const text = view.state.doc.sliceString(from, to)
if (text !== content) {
throw new Error(
`Op to be removed (${JSON.stringify(
change.op
)}) does not match editor text '${text}'`
)
}
case 'i': {
const from = op.p
const content = op.i
const to = from + content.length
const text = view.state.doc.sliceString(from, to)
if (text !== content) {
throw new Error(
`Op to be removed (${JSON.stringify(
change.op
)}) does not match editor text '${text}'`
)
}
return { from, to, insert: '' }
}
default: {
throw new Error(`unknown change: ${JSON.stringify(change)}`)
return { from, to, insert: '' }
} else if (isDeleteOperation(op)) {
return {
from: op.p,
to: op.p,
insert: op.d,
}
} else {
throw new Error(`unknown change type: ${JSON.stringify(change)}`)
}
})
@@ -1,11 +1,11 @@
import { Range, RangeSet, RangeValue, Transaction } from '@codemirror/state'
import { CurrentDoc } from '../../../../../../types/current-doc'
import {
AnyOperation,
Change,
ChangeOperation,
CommentOperation,
} from '../../../../../../types/change'
import { ThreadId } from '../../../../../../types/review-panel/review-panel'
import { DocumentContainer } from '@/features/ide-react/editor/document-container'
export type StoredComment = {
text: string
@@ -20,14 +20,14 @@ export type StoredComment = {
* Find tracked comments within the range of the current transaction's changes
*/
export const findCommentsInCut = (
currentDoc: CurrentDoc,
currentDoc: DocumentContainer,
transaction: Transaction
) => {
const items: StoredComment[] = []
transaction.changes.iterChanges((fromA, toA) => {
const comments = currentDoc.ranges.comments
.filter(
const comments = currentDoc
.ranges!.comments.filter(
comment =>
fromA <= comment.op.p && comment.op.p + comment.op.c.length <= toA
)
@@ -55,7 +55,7 @@ export const findCommentsInPaste = (
storedComments: StoredComment[],
transaction: Transaction
) => {
const ops: ChangeOperation[] = []
const ops: CommentOperation[] = []
transaction.changes.iterChanges((fromA, toA, fromB, toB, inserted) => {
const insertedText = inserted.toString()
@@ -71,7 +71,7 @@ export const findCommentsInPaste = (
ops.push({
c: text,
p: fromB + offset,
t: comment.id,
t: comment.id as ThreadId,
})
}
}
@@ -93,13 +93,13 @@ class CommentRangeValue extends RangeValue {
* Find tracked comments with no content with the ranges of a transaction's changes
*/
export const findDetachedCommentsInChanges = (
currentDoc: CurrentDoc,
currentDoc: DocumentContainer,
transaction: Transaction
) => {
const items: Range<CommentRangeValue>[] = []
transaction.changes.iterChanges((fromA, toA) => {
for (const comment of currentDoc.ranges.comments) {
for (const comment of currentDoc.ranges!.comments) {
const content = comment.op.c
// TODO: handle comments that were never attached
@@ -124,7 +124,7 @@ export const findDetachedCommentsInChanges = (
* (used when restoring comments on paste)
*/
const submitOps = (
currentDoc: CurrentDoc,
currentDoc: DocumentContainer,
ops: AnyOperation[],
transaction: Transaction
) => {
@@ -133,14 +133,14 @@ const submitOps = (
}
// Check that comments still match text. Will throw error if not.
currentDoc.ranges.validate(transaction.state.doc.toString())
currentDoc.ranges!.validate(transaction.state.doc.toString())
}
/**
* Wait for the ShareJS doc to fire an event, then submit the operations.
*/
const submitOpsAfterEvent = (
currentDoc: CurrentDoc,
currentDoc: DocumentContainer,
eventName: string,
ops: AnyOperation[],
transaction: Transaction
@@ -161,7 +161,7 @@ const submitOpsAfterEvent = (
* Look through the comments stored on cut, and restore those in text that matches the pasted text.
*/
export const restoreCommentsOnPaste = (
currentDoc: CurrentDoc,
currentDoc: DocumentContainer,
transaction: Transaction,
storedComments: StoredComment[]
) => {
@@ -183,18 +183,18 @@ export const restoreCommentsOnPaste = (
* When undoing a change, find comments from the original content and restore them.
*/
export const restoreDetachedComments = (
currentDoc: CurrentDoc,
currentDoc: DocumentContainer,
transaction: Transaction,
storedComments: RangeSet<any>
) => {
const ops: ChangeOperation[] = []
const ops: CommentOperation[] = []
const cursor = storedComments.iter()
while (cursor.value) {
const { id } = cursor.value.comment
const comment = currentDoc.ranges.comments.find(item => item.id === id)
const comment = currentDoc.ranges!.comments.find(item => item.id === id)
// check that the comment still exists and is detached
if (comment && comment.op.c === '') {