     )
 
   lint: (onChange) ->
-    return if @progress onChange
     return if @editor isnt @linter.activeEditor
-    @progress onChange, true
-    @lint true unless onChange
 
-    scopes = @editor.scopeDescriptorForBufferPosition(@editor.getCursorBufferPosition()).scopes
-    scopes.push '*' # Ensure that everything can be linted with a wildcard.
-    promises = @lintResults onChange, scopes
-    Promise.all(promises).then =>
-      @progress onChange, false
-    .catch ->
-      console.error arguments[0].stack
-      @progress onChange, false
+    # When linting is triggered by a save we need to also run back through and
+    # run the linters that trigger on the fly.
+    if not onChange
+      @lint true
+
+    @_promiseLock(onChange, =>
+      scopes = @editor.scopeDescriptorForBufferPosition(@editor.getCursorBufferPosition()).scopes
+      scopes.push '*' # Ensure that everything can be linted with a wildcard.
+      return Promise.all(@lintResults(onChange, scopes))
+    )
+    undefined
 
   lintResults: (onChange, scopes) ->
     return @linter.linters.map (linter) =>

      throw new Error('Missing "type". found keys', Object.keys(r))

  return results

class EditorLinter
  constructor: (@linter, @editor) ->

        # catch any exceptions thrown by `linter.lint`
        resolve(linter.lint(@editor, @buffer))
      ).then(validateResults)
      .catch(showError)
      .then((results) =>
        if linter.scope is 'project' then @linter.messagesProject.set linter, results
        else @messages.set linter, results

        @emitter.emit 'did-update'
        @linter.view.render() if @editor is @linter.activeEditor
      )

  _promiseLock: (onChange, callback) ->
    key = if onChange then 'inProgressFly' else 'inProgress'

    return if @[key]
    @[key] = true
    callback().catch(showError).then( =>
      @[key] = false
    )

  destroy: ->
    @emitter.emit 'did-destroy'
