def lint(view, view_has_changed, lock, reason=None):
    """Lint the view with the given id.

    This method is called asynchronously by queue.Daemon when a lint
    request is pulled off the queue.
    """
    # We call `get_linters_for_view` first and unconditionally for its
    # side-effect. Yeah, it's a *getter* LOL.
    with lock:  # We're already debounced, so races are actually unlikely.
        linters = get_linters_for_view(view)

    linters = [linter for linter in linters if linter.should_lint(reason)]
    if not linters:
        return

    # Very, very unlikely that `view_has_changed` is already True at this
    # point, but it also implements the kill_switch, so we ask here
    if view_has_changed():  # abort early
        return

    bid = view.buffer_id()

    if persist.settings.get('kill_old_processes'):
        kill_active_popen_calls(bid)

    events.broadcast(events.LINT_START, {'buffer_id': bid})

    with remember_runtime("Linting '{}' took {{:.2f}}s".format(
            util.canonical_filename(view))):
        sink = partial(group_by_filename_and_update, bid, view_has_changed)
        backend.lint_view(linters, view, view_has_changed, sink)

    events.broadcast(events.LINT_END, {'buffer_id': bid})
Exemplo n.º 2
0
    def check_syntax(self, view):
        """
        Check and return if view's syntax has changed.

        If the syntax has changed, a new linter is assigned.
        """
        if not view:
            return

        vid = view.id()
        syntax = util.get_syntax(view)

        # Syntax either has never been set or just changed
        if vid not in self.view_syntax or self.view_syntax[vid] != syntax:
            bid = view.buffer_id()
            persist.errors[bid].clear()
            for linter in persist.view_linters.get(vid, []):
                events.broadcast(events.LINT_RESULT, {
                    'buffer_id': bid,
                    'linter_name': linter.name,
                    'errors': []
                })

            self.view_syntax[vid] = syntax
            self.linted_views.discard(vid)
            Linter.assign(view)
            return True
        else:
            return False
Exemplo n.º 3
0
def lint(view, view_has_changed, lock):
    """Lint the view with the given id.

    This method is called asynchronously by queue.Daemon when a lint
    request is pulled off the queue.
    """
    # We call `get_linters_for_view` first and unconditionally for its
    # side-effect. Yeah, it's a *getter* LOL.
    with lock:  # We're already debounced, so races are actually unlikely.
        linters = get_linters_for_view(view)

    if not linters:
        return

    # Very, very unlikely that `view_has_changed` is already True at this
    # point, but it also implements the kill_switch, so we ask here
    if view_has_changed():  # abort early
        return

    bid = view.buffer_id()
    events.broadcast(events.LINT_START, {'buffer_id': bid})

    next = partial(update_buffer_errors, bid, view_has_changed)
    backend.lint_view(linters, view, view_has_changed, next)

    events.broadcast(events.LINT_END, {'buffer_id': bid})
Exemplo n.º 4
0
def lint(view, view_has_changed, lock, reason):
    # type: (sublime.View, ViewChangedFn, threading.Lock, Reason) -> None
    """Lint the view with the given id.

    This function MUST run on a thread because it blocks!
    """
    linters = list(elect.assignable_linters_for_view(view, reason))
    with lock:
        _assign_linters_to_view(view, {linter['name'] for linter in linters})

    runnable_linters = list(elect.filter_runnable_linters(linters))
    if not runnable_linters:
        return

    window = view.window()
    bid = view.buffer_id()
    filename = util.get_filename(view)

    # Very, very unlikely that `view_has_changed` is already True at this
    # point, but it also implements the kill_switch, so we ask here
    if view_has_changed():  # abort early
        return

    if persist.settings.get('kill_old_processes'):
        kill_active_popen_calls(bid)

    events.broadcast(events.LINT_START, {'buffer_id': bid})

    with remember_runtime("Linting '{}' took {{:.2f}}s".format(
            util.canonical_filename(view))):
        sink = partial(group_by_filename_and_update, window, filename,
                       view_has_changed, reason)
        backend.lint_view(runnable_linters, view, view_has_changed, sink)

    events.broadcast(events.LINT_END, {'buffer_id': bid})
Exemplo n.º 5
0
    def check_syntax(self, view):
        """
        Check and return if view's syntax has changed.

        If the syntax has changed, a new linter is assigned.
        """
        if not view:
            return

        vid = view.id()
        syntax = util.get_syntax(view)

        # Syntax either has never been set or just changed
        if vid not in self.view_syntax or self.view_syntax[vid] != syntax:
            bid = view.buffer_id()
            persist.errors[bid].clear()
            for linter in persist.view_linters.get(vid, []):
                events.broadcast(events.LINT_RESULT, {
                    'buffer_id': bid,
                    'linter_name': linter.name,
                    'errors': []
                })

            self.view_syntax[vid] = syntax
            self.linted_views.discard(vid)
            Linter.assign(view)
            return True
        else:
            return False
def force_redraw():
    for bid, errors in persist.errors.items():
        for linter_name, linter_errors in group_by_linter(errors).items():
            events.broadcast(events.LINT_RESULT, {
                'buffer_id': bid,
                'linter_name': linter_name,
                'errors': linter_errors
            })
Exemplo n.º 7
0
def force_redraw():
    for bid, errors in persist.errors.items():
        for linter_name, linter_errors in group_by_linter(errors).items():
            events.broadcast(events.LINT_RESULT, {
                'buffer_id': bid,
                'linter_name': linter_name,
                'errors': linter_errors
            })
Exemplo n.º 8
0
def force_redraw():
    for filename, errors in persist.file_errors.items():
        for linter_name, linter_errors in group_by_linter(errors).items():
            events.broadcast(
                events.LINT_RESULT, {
                    'filename': filename,
                    'linter_name': linter_name,
                    'errors': linter_errors
                })
Exemplo n.º 9
0
def update_file_errors(filename, linter, errors, reason=None):
    # type: (FileName, LinterName, List[LintError], Optional[Reason]) -> None
    """Persist lint error changes and broadcast."""
    update_errors_store(filename, linter, errors)
    events.broadcast(
        events.LINT_RESULT, {
            'filename': filename,
            'linter_name': linter,
            'errors': errors,
            'reason': reason
        })
Exemplo n.º 10
0
def update_buffer_errors(bid, linter, errors, reason=None):
    # type: (Bid, LinterName, List[LintError], Optional[Reason]) -> None
    """Persist lint error changes and broadcast."""
    update_errors_store(bid, linter, errors)
    events.broadcast(
        events.LINT_RESULT, {
            'buffer_id': bid,
            'linter_name': linter,
            'errors': errors,
            'reason': reason
        })
Exemplo n.º 11
0
def update_buffer_errors(bid, view_has_changed, linter, errors):
    """Persist lint error changes and broadcast."""
    if view_has_changed():  # abort early
        return

    update_errors_store(bid, linter.name, errors)
    events.broadcast(events.LINT_RESULT, {
        'buffer_id': bid,
        'linter_name': linter.name,
        'errors': errors
    })
Exemplo n.º 12
0
def update_buffer_errors(bid, view_has_changed, linter, errors):
    # type: (Bid, ViewChangedFn, Linter, List[LintError]) -> None
    """Persist lint error changes and broadcast."""
    if view_has_changed():  # abort early
        return

    update_errors_store(bid, linter.name, errors)
    events.broadcast(events.LINT_RESULT, {
        'buffer_id': bid,
        'linter_name': linter.name,
        'errors': errors
    })
Exemplo n.º 13
0
    def lint(self, view, view_has_changed):
        """Lint the view with the given id.

        This method is called asynchronously by queue.Daemon when a lint
        request is pulled off the queue.
        """
        if view_has_changed():  # abort early
            return

        events.broadcast(events.LINT_START, {'buffer_id': view.buffer_id()})

        next = partial(self.highlight, view, view_has_changed)
        backend.lint_view(view, view_has_changed, next)

        events.broadcast(events.LINT_END, {'buffer_id': view.buffer_id()})
Exemplo n.º 14
0
    def lint(self, view, view_has_changed):
        """Lint the view with the given id.

        This method is called asynchronously by queue.Daemon when a lint
        request is pulled off the queue.
        """
        if view_has_changed():  # abort early
            return

        events.broadcast(events.LINT_START, {'buffer_id': view.buffer_id()})

        next = partial(self.highlight, view, view_has_changed)
        backend.lint_view(view, view_has_changed, next)

        events.broadcast(events.LINT_END, {'buffer_id': view.buffer_id()})
Exemplo n.º 15
0
def update_buffer_errors(bid, view_has_changed, linter, errors):
    """Persist lint error changes and broadcast."""
    if view_has_changed():  # abort early
        return

    all_errors = [
        error
        for error in persist.errors[bid] if error['linter'] != linter.name
    ] + errors
    persist.errors[bid] = all_errors

    events.broadcast(events.LINT_RESULT, {
        'buffer_id': bid,
        'linter_name': linter.name,
        'errors': errors
    })
Exemplo n.º 16
0
def update_on_filename_change(old_filename, new_filename):
    # type: (FileName, FileName) -> None
    # update the error store
    if old_filename in persist.file_errors:
        errors = persist.file_errors.pop(old_filename)
        persist.file_errors[new_filename] = errors

    # update the affected filenames
    if old_filename in persist.affected_filenames_per_filename:
        filenames = persist.affected_filenames_per_filename.pop(old_filename)
        persist.affected_filenames_per_filename[new_filename] = filenames

    # notify the views
    events.broadcast('renamed_file', {
        'new_filename': new_filename,
        'old_filename': old_filename
    })
Exemplo n.º 17
0
    def highlight(self, view, view_has_changed, linter, errors):
        """
        Highlight any errors found during a lint of the given view.

        This method is called by Linter.lint_view after linting is finished.
        """
        if view_has_changed():  # abort early
            return

        bid = view.buffer_id()
        all_errors = [error for error in persist.errors[bid]
                      if error['linter'] != linter.name] + errors
        persist.errors[bid] = all_errors

        events.broadcast(events.LINT_RESULT, {
            'buffer_id': bid,
            'linter_name': linter.name,
            'errors': errors
        })
Exemplo n.º 18
0
    def highlight(self, view, view_has_changed, linter, errors):
        """
        Highlight any errors found during a lint of the given view.

        This method is called by Linter.lint_view after linting is finished.
        """
        if view_has_changed():  # abort early
            return

        bid = view.buffer_id()
        all_errors = [
            error
            for error in persist.errors[bid] if error['linter'] != linter.name
        ] + errors
        persist.errors[bid] = all_errors

        events.broadcast(events.LINT_RESULT, {
            'buffer_id': bid,
            'linter_name': linter.name,
            'errors': errors
        })
Exemplo n.º 19
0
def lint(view, view_has_changed, lock):
    """Lint the view with the given id.

    This method is called asynchronously by queue.Daemon when a lint
    request is pulled off the queue.
    """
    # We call `get_linters_for_view` first and unconditionally for its
    # side-effect. Yeah, it's a *getter* LOL.
    with lock:  # We're already debounced, so races are actually unlikely.
        linters = get_linters_for_view(view)

    linters = [linter for linter in linters if not skip_linter(linter, view)]
    if not linters:
        return

    # Very, very unlikely that `view_has_changed` is already True at this
    # point, but it also implements the kill_switch, so we ask here
    if view_has_changed():  # abort early
        return

    if not environment_is_ready():
        hit(view)
        return

    bid = view.buffer_id()

    if persist.settings.get('kill_old_processes'):
        kill_active_popen_calls(bid)

    events.broadcast(events.LINT_START, {'buffer_id': bid})
    start_time = time.time()

    next = partial(update_buffer_errors, bid, view_has_changed)
    backend.lint_view(linters, view, view_has_changed, next)

    end_time = time.time()
    runtime = end_time - start_time
    logger.info('Linting buffer {} took {:.2f}s'.format(bid, runtime))
    remember_runtime(runtime)
    events.broadcast(events.LINT_END, {'buffer_id': bid})
Exemplo n.º 20
0
def lint(view, view_has_changed, lock):
    """Lint the view with the given id.

    This method is called asynchronously by queue.Daemon when a lint
    request is pulled off the queue.
    """
    if view_has_changed():  # abort early
        return

    bid = view.buffer_id()

    # We're already debounced, so races are actually unlikely
    with lock:
        linters = get_linters_for_view(view)

    if linters:
        events.broadcast(events.LINT_START, {'buffer_id': bid})

        next = partial(update_buffer_errors, bid, view_has_changed)
        backend.lint_view(linters, view, view_has_changed, next)

        events.broadcast(events.LINT_END, {'buffer_id': bid})
Exemplo n.º 21
0
def lint(view, view_has_changed, lock, reason=None):
    # type: (sublime.View, ViewChangedFn, threading.Lock, Optional[str]) -> None
    """Lint the view with the given id.

    This method is called asynchronously by queue.Daemon when a lint
    request is pulled off the queue.
    """
    # We call `get_linters_for_view` first and unconditionally for its
    # side-effect. Yeah, it's a *getter* LOL.
    with lock:  # We're already debounced, so races are actually unlikely.
        linters = get_linters_for_view(view)

    linters = [
        linter for linter in linters
        if linter.should_lint(reason)]
    if not linters:
        return

    # Very, very unlikely that `view_has_changed` is already True at this
    # point, but it also implements the kill_switch, so we ask here
    if view_has_changed():  # abort early
        return

    bid = view.buffer_id()

    if persist.settings.get('kill_old_processes'):
        kill_active_popen_calls(bid)

    events.broadcast(events.LINT_START, {'buffer_id': bid})

    with remember_runtime(
        "Linting '{}' took {{:.2f}}s".format(util.canonical_filename(view))
    ):
        sink = partial(group_by_filename_and_update, bid, view_has_changed)
        backend.lint_view(linters, view, view_has_changed, sink)

    events.broadcast(events.LINT_END, {'buffer_id': bid})