Skip to content

Commit

Permalink
Retain changesets in StateField (#31)
Browse files Browse the repository at this point in the history
  • Loading branch information
tmcw authored Jun 12, 2024
1 parent 2ce7b9b commit 3b3a97f
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 12 deletions.
8 changes: 6 additions & 2 deletions src/completionDecoration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,13 @@ export const completionDecoration = StateField.define<CompletionState>({
update(state: CompletionState, transaction: Transaction) {
for (const effect of transaction.effects) {
if (effect.is(addSuggestions)) {
const { changeSpecs, index } = effect.value;

// NOTE: here we're adjusting the decoration range
// to refer to locations in the document _after_ we've
// inserted the text.
const decorations = Decoration.set(
effect.value.suggestions.map((suggestionRange) => {
changeSpecs[index]!.map((suggestionRange) => {
const range = ghostMark.range(
suggestionRange.absoluteStartPos,
suggestionRange.absoluteEndPos,
Expand All @@ -39,9 +41,10 @@ export const completionDecoration = StateField.define<CompletionState>({
}),
);

// TODO
return {
index,
decorations,
changeSpecs,
reverseChangeSet: effect.value.reverseChangeSet,
};
}
Expand All @@ -59,6 +62,7 @@ export const completionDecoration = StateField.define<CompletionState>({
// of a mismatch between it and the new document and new
// document length
return {
...state,
decorations: state.decorations.map(transaction.changes),
reverseChangeSet: state.reverseChangeSet.map(transaction.changes),
};
Expand Down
8 changes: 4 additions & 4 deletions src/completionRequester.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,18 +128,18 @@ export function completionRequester() {
// check the end of the line with the end of the completion
const changeSpecs = completionsToChangeSpec(completionResult);

const firstSpec = changeSpecs.at(0);
const index = 0;
const firstSpec = changeSpecs.at(index);
if (!firstSpec) return;

const insertChangeSet = ChangeSet.of(firstSpec, state.doc.length);

const reverseChangeSet = insertChangeSet.invert(state.doc);

update.view.dispatch({
changes: insertChangeSet,
effects: addSuggestions.of({
index,
reverseChangeSet,
suggestions: firstSpec,
changeSpecs,
}),
annotations: [
copilotIgnore.of(null),
Expand Down
9 changes: 3 additions & 6 deletions src/effects.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import { type ChangeSet, StateEffect } from "@codemirror/state";
import type { SimpleChangeSpec } from "./types.js";
import { StateEffect } from "@codemirror/state";
import type { AddSuggestionsState } from "./types.js";

// Effects to tell StateEffect what to do with GhostText
export const addSuggestions = StateEffect.define<{
reverseChangeSet: ChangeSet;
suggestions: SimpleChangeSpec[];
}>();
export const addSuggestions = StateEffect.define<AddSuggestionsState>();
export const acceptSuggestion = StateEffect.define<null>();
export const clearSuggestion = StateEffect.define<null>();
12 changes: 12 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,23 @@
import type { ChangeSet } from "@codemirror/state";
import type { DecorationSet } from "@codemirror/view";

/**
* We dispatch an effect that updates the CompletionState.
* CompletionState is null if no completions are displayed.
*/
export type CompletionState = null | {
index: number;
reverseChangeSet: ChangeSet;
changeSpecs: SimpleChangeSpec[][];
decorations: DecorationSet;
};

export type AddSuggestionsState = {
reverseChangeSet: ChangeSet;
changeSpecs: SimpleChangeSpec[][];
index: number;
};

export interface GhostText {
text: string;
displayPos: number;
Expand Down

0 comments on commit 3b3a97f

Please sign in to comment.