@valtown/codemirror-codeium
Version:
codemirror integration for codeium
73 lines • 3.07 kB
JavaScript
import { StateField, } from "@codemirror/state";
import { Decoration, EditorView } from "@codemirror/view";
import { addSuggestions, acceptSuggestion, clearSuggestion, } from "./effects.js";
import { codeiumConfig } from "./config.js";
const ghostMark = Decoration.mark({ class: "cm-ghostText" });
/**
* Note that the completion _text_ is not actually a decoration!
* The text is very real, and actually inserted into the editor.
* The completion decoration is just a decoration that matches
* the same range as the completion text, and changes how it looks.
*/
export const completionDecoration = StateField.define({
create(_state) {
return null;
},
update(state, transaction) {
const config = transaction.state.facet(codeiumConfig);
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 ranges = changeSpecs[index].map((suggestionRange) => {
const range = ghostMark.range(suggestionRange.absoluteStartPos, suggestionRange.absoluteEndPos);
return range;
});
const widgetPos = ranges.at(-1)?.to;
const decorations = Decoration.set([
...ranges,
...(widgetPos !== undefined &&
changeSpecs.length > 1 &&
config.widgetClass
? [
Decoration.widget({
widget: new config.widgetClass(index, changeSpecs.length),
side: 1,
}).range(widgetPos),
]
: []),
]);
return {
index,
decorations,
changeSpecs,
reverseChangeSet: effect.value.reverseChangeSet,
};
}
if (effect.is(acceptSuggestion)) {
return null;
}
if (effect.is(clearSuggestion)) {
return null;
}
}
if (state) {
// If we ever have a state that is being updated,
// map it through the new changes to avoid the potential
// 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),
};
}
return state;
},
provide: (field) => EditorView.decorations.from(field, (value) => {
return value?.decorations || Decoration.none;
}),
});
//# sourceMappingURL=completionDecoration.js.map