patryk
patryk

Reputation: 651

CodeMirror - get linting result from outside of the editor

I'm using the CodeMirror library which is awesome. The code editor that I'm istantiating is a part of a form and therefore I want to do a basic check with linting to see whether the user's input seems valid. Unless the code is fine, I don't want to process the form.

So the question is: is there a method on the CodeMirror editor instance that would allow me to retrieve the result of linting? I'm looking through the docs and Google but failed to find anything helpful. There's this performLint method that is added to the editor, however it does not return the results of linting.

Upvotes: 6

Views: 6155

Answers (4)

QuarkleMotion
QuarkleMotion

Reputation: 874

@Clem's answer led me in the right direction, though I did run into a few issues. The first was seeing Bad option: onUpdateLinting repeatedly in the console (See this reported Codemirror issue). The second was seeing the annotations array containing null entries sometimes. Here is my linting configuration passed into Codemirror that solves these issues. Note that I'm using react-codemirror2, but the options get passed into Codemirror in the same format. My component has an optional onLintingComplete callback that can be provided by the consuming component and you'll see that callback referenced below where it is passed the array of lint annotations:

  lint: onLintingComplete
    ? {
        onUpdateLinting: (_annotationsNotSorted, annotations) =>
          onLintingComplete(
            // sometimes codemirror includes null annotations in the array, so we want to filter these out
            annotations.filter(annotation => annotation != null)
          ),
        // This empty lint options object is needed here, see: https://github.com/codemirror/CodeMirror/issues/4198
        options: {}, 
      }
    : true,

Upvotes: 2

Clem
Clem

Reputation: 146

The updateLinting function in lint.js passes its annotations (and editor) to the onUpdateLinting option:

if (options.onUpdateLinting) options.onUpdateLinting(annotationsNotSorted, annotations, cm);

so all you have to do is have your handler as the lint option property:

lint: { onUpdateLinting: handleErrors }

Upvotes: 7

Phillipp Schwarz
Phillipp Schwarz

Reputation: 119

This is a hint for Dezzas Answer:

Write,

var errors = CodeMirror.lint.css(cm, options);

Otherwise, it will fail.

Upvotes: 2

Dezza
Dezza

Reputation: 136

There isn't a specific method to get the linting results, but there is a hook provided when you define a getAnnotations property in the lint options object.

Here's a basic options object that would trigger linting:

var codeMirrorOptions = {
    "lineNumbers": true,
    "indentWithTabs": true,
    "mode": "css",
    "gutters": ['CodeMirror-lint-markers'],
    "lint": true
}

You can specify an object (instead of a boolean) as the lint property:

"lint": {
    "getAnnotations": css_validator,
    "async": true 
}

Then, define your own validator function. This function can just call CodeMirror's bundled validator:

     function css_validator(cm, updateLinting, options) {
            // call the built in css linter from addon/lint/css-lint.js
            var errors = CodeMirror.lint.css(cm);

            updateLinting(errors);

        }

At this point you've replicated the behavior of lint:true -- but now the errors variable contains an array of lint errors. If errors.length == 0, no errors were found.

Note: this sample assumes you are linting CSS, but the same would apply for other types.

Upvotes: 11

Related Questions