Avoiding reparsing during autocompletion input

It seems like @codemirror/autocomplete just displays the suggestions on top of the editor, but the text you are writing during the autocompletion is still very much inserted directly into the document.

While this works fine for autocompleting variable and function names it is less than ideal for cases where you can search for labels associated with an identifier, e.g. when typing wd:Mount Everest should suggest wd:Q513 you do not want wd:Mount to be highlighted as a prefixed name and Everest to result in a parsing error. Another point is that the labels may contain strings that look like syntax elements e.g. typing wd:http:// should suggest wd:Q8777 but this is very difficult when you cannot differentiate between what was written before and after the autocompletion has been triggered.

So I think I would really like a system where you can explicitly start an autocompletion at a certain point, everything the user writes while the autocompletion is active is written to a new edit buffer (but this is just an implementation detail from the user interface it still looks like you’re writing into the document), writing into this edit buffer does not trigger a reparsing / rehighlighting of the document. Only when the user confirms the autocompletion (by pressing enter or clicking on a suggestion) the new text is inserted into the document.

Sidenote: I think this would also be better for collaborative editing since it would reduce superfluous updates.

Well, build it. You’ll probably want to use EditorView.inputHandler and showTooltip in the process. But I can imagine something like that working really poorly with composition input.

You make a good point that I probably don’t want to implement my own edit widget. Especially because I want all the regular stuff like text selection and key bindings to still work.

Would it be possible to somehow tell CodeMirror to stop reparsing the document? So that edits would simply be inserted in the current syntax tree node without changing anything else? And then somehow resuming the parsing?

No, that does not exist.

But given how modular CodeMirror is, I think pulling something like this off should definitely be possible, right? I guess I’d have to wrap the language extension and the highlighting extension.

If @codemirror/language exported the TreeHighlighter class I could subclass it and do something like the following in update:

  update(update: ViewUpdate) {
    if (disableParsing) {
      for (const trans of update.transactions) {
        this.decorations = this.decorations.map(trans.changes.desc);
      }
      return;
    }
    super.update(update);
  }

I am not quite sure though how one could wrap the language extension to do a similar short-circuiting.

You can’t subclass stuff from this library, in general. This would have to be a completely separate implementation.