linter icon indicating copy to clipboard operation
linter copied to clipboard

Linter seems to be running before scope are available

Open onelivesleft opened this issue 6 years ago • 5 comments

I'm using scopes in my linter, but they aren't working correctly. When I load a file the linter displays warnings for lines as though they had no scope information. As soon as I hit a key and trigger the onChange event the warnings disappear. My thought is that when the linter first scans the file it does so before the grammar is established, and so the scope commands don't work. How do I get the linter to run after the grammar has defined all the scopes for cursor positions in the file?

Example: I'm looping over the lines in the file. At the start of the loop I check if I'm in a multiline string, and if so we skip to the next line.

        while (i < lineCount)
          line = editor.lineTextForBufferRow(i)
          scopes = editor.scopeDescriptorForBufferPosition([i, 0])
          if 'string.quoted.other.multiline.lua' in scopes.scopes
            i += 1
            continue
          ...rest of linter logic

The continue here never triggers when the file is first loaded, but it does trigger as soon as a change is made.

onelivesleft avatar Sep 11 '17 23:09 onelivesleft

Hi @onelivesleft

Linter follows the assumption that the scopes are set by Atom core using the grammars available. Atom core makes sure to set the grammar, title and similar props before passing it on to the listeners. If you are having scope lag then the grammar might not be written in the correct way

steelbrain avatar Sep 12 '17 00:09 steelbrain

I think it's a pretty basic grammar file, you can see it here: https://github.com/onelivesleft/atom-tabletopsimulator-lua/blob/master/grammars/tts_lua.cson

The linter warnings also disappear as soon as you click on any of them.

onelivesleft avatar Sep 12 '17 00:09 onelivesleft

I've got a work-around for the time being:

onLoad: (event) ->
  editor = event.item
  view = atom.views.getView(editor)
  f = () ->
    atom.commands.dispatch(view, 'linter:lint')
  delay = 0
  while delay < 1000
    delay += 100
    setTimeout f, delay

So after the file loads it spams the linter for a second, clearing it as quick as it can. The linter still visibly pops up for a small amount of time, so it isn't great, but it's better than false error messages sitting on the screen, and underlining the file in the tree view.

onelivesleft avatar Sep 14 '17 15:09 onelivesleft

A better cludge looks to be toggling the linter off immediately then on again after a second:

onLoad: (event) ->
  editor = event.item
  view = atom.views.getView(editor)
  atom.commands.dispatch(view, 'linter:toggle')
  f = () ->
    atom.commands.dispatch(view, 'linter:toggle')
    atom.commands.dispatch(view, 'linter:lint')
  f()
  setTimeout f, 1000

onelivesleft avatar Oct 01 '17 16:10 onelivesleft

@steelbrain I don't know if something changed since the linter was first written, but I've experienced what @onelivesleft describes for as long as I've used linter-spell for LaTeX.

To reproduce, you can install language-latex, linter-spell-latex, and open a file called foo.tex with the contents

\usepackage{graphicx}

The file can't be open in a tab before that, or it will be fine. The issue only occurs when opening it in new tab from the tree view.

In my case, adding this to lint() in ./lib/editor-linter.js fixes the spelling issues. The did-tokenize event is marked as experimental, but it's been there for a couple of years now.

lint(onChange: boolean = false) {
    if (!this.editor.tokenizedBuffer.fullyTokenized) {
      this.editor.emitter.once('did-tokenize', () => { this.emitter.emit('should-lint', onChange) });
      return;
    }
    this.emitter.emit('should-lint', onChange)
  }

I haven't tested anything extensively yet mind, and there may be a cleaner way to ensure the buffer is fully tokenized.

Aerijo avatar Jun 14 '18 01:06 Aerijo