Thank you, @marijn! This got me (I think) on the right track. I’m now doing something along these lines:
import { Completion, snippet } from "@codemirror/autocomplete";
import { EditorView } from "@codemirror/view";
function insertSnippet(text: string, view: EditorView) {
const { dispatch, state } = view;
const { to, from } = state.selection.ranges[0];
snippet(text)(
{ dispatch, state },
null as unknown as Completion, // remove as after the patch is published
from,
to
);
}