Reconfigure doesn't re-run `StateField`'s `create`

Hi!

I have a state field, which depends on some configuration. I would like the configuration to be dynamic. I was hoping that I could put a myField.extension in a compartment, and reconfigure that compartment with a myField.init, where I override state. But it looks like the create function provided to StateFields doesn’t re-run on reconfiguration.

Here’s a minimal reproduction, with the code:

import {EditorState, Compartment, StateField} from "@codemirror/state"
import {EditorView, basicSetup} from "codemirror"

const field = StateField.define({
  create: (state) => {console.log("state field create"); return 0},
  update:(state, transaction) => {console.log(state); return state + 1}
})

const stateFieldConf = new Compartment

const autoLanguage = EditorState.transactionExtender.of(tr => {
  if (!tr.docChanged) return null
  console.log("dispatching reconfigure effect");
  return {
    effects: stateFieldConf.reconfigure(field.init((state) => {console.log("state field recreate"); return 1000 }))
  }
})

new EditorView({
  doc: 'console.log("hello")',
  extensions: [
    basicSetup,
    stateFieldConf.of(field.extension),
    autoLanguage
  ],
  parent: document.body
})

Note that as you type, “state field create” is only printed once, and “state field recreate” is never printed, even though the reconfigure effect is being dispatched.

I could listen to reconfigure effects in the state field’s update function, but I still need to pull the new config from somewhere, and trying to inspect the effect’s Extension value feels brittle.

Is this expected behavior? Do you have any recommendations for reconfiguring state fields?

Thanks!

For future reference, I solved this by putting the state field’s configuration in a facet.
If the state field’s update receives a transaction where transaction.reconfigured, the state field pulls the facet’s value, and if it has changed, resets itself.

I am still curious if excluding StateField create from reconfiguration is intended.

Yes. Reconfiguring the editor preserves the value of state fields that are present in both the old and new configuration (so that you don’t, say, lose your undo history every time you reconfigure something).

1 Like