Setting editor state via setState()

I’ve been trying to implement an open file function in my project using FileReader and the editor.setState() function without much success.

In one of my CodeMirror 5 projects, I could use editor.setValue to append the contents to the editor.

function loadfile(input) {
    const reader = new FileReader()
    reader.onload = function(e) {
      editor.setValue(e.target.result);
    }
    reader.readAsText(input.files[0]);
};

In CodeMirror 6, I assume that I would have to create a new EditorState with the document set to the output of the FileReader object. Then you would set the editor state with editor.setState() with the new EditorState as its argument.

Here is what I have so far, but it doesn’t seem to work as intended.

editor.ts:

function loadfile(input: { files: Blob[]; } | undefined) {
  const reader = new FileReader()
  reader.onload = function(e) {
    const newState = EditorState.create({
      doc: e.target!.result as string,
      extensions: [ 
        markdown({
          base: markdownLanguage,
          codeLanguages: languages
        }),
        basicDarkTheme,
        lineNumbers(),
        highlightActiveLineGutter(),
        highlightSpecialChars(),
        history(),
        foldGutter(),
        drawSelection(),
        dropCursor(),
        EditorState.allowMultipleSelections.of(true),
        indentOnInput(),
        syntaxHighlighting(basicDarkHighlightStyle, {fallback: true}),
        bracketMatching(),
        closeBrackets(),
        autocompletion(),
        rectangularSelection(),
        crosshairCursor(),
        highlightActiveLine(),
        highlightSelectionMatches(),
        keymap.of([
          ...closeBracketsKeymap,
          ...defaultKeymap,
          ...searchKeymap,
          ...historyKeymap,
          ...foldKeymap,
          ...completionKeymap,
          ...[indentWithTab]
        ]),
        EditorView.updateListener.of(function(e) {
        clearTimeout(previewDelay);
        previewDelay = window.setTimeout(updatePreview, 250);
      })
    ]
    });
    editor.setState(newState);
  }
  reader.readAsText(input!.files[0]);
};

const file = document.getElementById('open')!.onload = () => {
  loadfile(this!);
}

index.html:

<input type="file" id="open">

I’ve read the migration guide, the docs, and numerous resources for hours but nothing has clicked in. I feel that the fault here would be the lack of understanding of how this system works. If I can get some hints or guidance, that would be great.

Thanks!

There’s not much about setState that can go wrong, but you didn’t mention what your problem is beyond “without much success”. Make sure editor is the actual editor instance in the page, I guess.

Basically, I went through a whole bunch of resources and solutions but I still couldn’t figure it out.

When I click on the choose file button and open my example file (test.md), the editor state doesn’t change even though it’s supposed to be set to the state of the opened file. There aren’t any errors when I start my Electron app and the dev tools console doesn’t show any errors as well, so it’s a little difficult to pinpoint the problem.

And yeah, the editor variable holds the EditorView which is the only editor instance in my page - and that works fine.

Finally solved it!

So I went back to my File System Access API attempt to see if I could get it to work since Electron had some issues with it. Guess it was much simpler than I thought.

How I set up the open file function was probably the biggest culprit. Also, making sure the doc property actually contains the opened files’ contents was also important. The File System Access API made more sense than FileReader in terms of basic implementation, so that’s a plus. It looks like this wasn’t really a CodeMirror issue now that I think of it.

I still don’t know what went wrong with my FileReader implementation, however it seems like the File System Access API was the way to go for my use case.

Anyways, thanks for the help Marjin!