Hide StateField decorations when replaced code is selected

I want to display widgets instead of some segments of the code (e.g. function headers); these widgets should allow the user to easily change aspects of the underlying code (e.g. the function name).

I am using a StateField to replace certain code segments with the widgets (by going through the syntaxTree and using Decoration.replace on the parts in question).

Currenlty I’m struggling with automatically hiding the widgets, whenever the user selects some portion of the replaced code (or enters the replaced code with his cursor).

Previously, I’ve achieved the same effect using a ViewPlugin and listening to update.selectionSet to determine the decorations that should no longer be displayed and provide a filtered decoration set; however I am a) not sure that this is a good solution and b) how to achieve the same with a StateField.

I hope I was able to explain my problem sufficiently.

2 Likes

State fields should be able to react to updates in much the same way — they see every transaction that comes through, and can look at the selection of the new state.

Thank you :+1:

Selecting the code under the widget now hides the widget, as intended.

However, this introduces a new issue. Since the widget influences the vertical layout, hiding it, sometimes influences the ongoing selection (because the lines get moved around and the cursor finds itself on top of a different line).

This sometimes deselects the underlying code, making the widget appear again, only to change the vertical layout once more, and so on.

Ultimately, this results in some kind of flickering effect, where the widget is hidden and shown in rapid succession.

A simple solution would be to wait until the user is “done” selecting before hiding/showing widgets; but I think there is no such event in CodeMirror to listen to, or is there?

Not on the state level. You can of course listen to mouse and touch events on the view.

Somehow none of the select events are firing, however the click event fires without any problems.

EditorView.domEventObservers({
    selectstart: () => console.log("selectstart"),
    select: () => console.log("select"),
    selectionchange: () => console.log("selectionchange"),
    click: () => console.log("click"),
}),