<commit_before>import sublime

from .base import BaseCommand
from .exec_flow import ExecFlowCommand
from ..logger import Logger
from ..helpers import get_flow_bin, prepare_arguments

logger = Logger()


class FlowtypeCheckContents(BaseCommand):
    """Run Flow check-contents."""

    def get_cmd(self):
        """Construct cli command."""
        try:
            flow_bin = get_flow_bin()
        except ValueError as e:
            logger.logger.error('check_contents %s' % e)
            return

        arguments = prepare_arguments(self.view)

        cmd = [
            flow_bin, 'check-contents',
            '--from', 'nuclide',
            '--quiet', '--json', arguments.file_name
        ]

        return cmd

    def handle_process(self, returncode, stdout, error):
        """Handle the output from the threaded process."""
        self.view.erase_regions('flow_type_highlights')

        if type(error) is bytes:
            error = error.decode('utf-8')

        if returncode != 0:
            logger.logger.error('check_contents %s' % error)
            return

        passed = stdout.get('passed', False)
        errors = stdout.get('errors', [])
        flow_version = stdout.get('flowVersion', '')

        # No errors
        if passed:
            self.view.erase_status('flow_errors')
            self.view.set_status(
                'flow_type', 'Flow %s: no errors' % flow_version)
            return

        # Errors
        regions = []
        error_per_line = {}
        for error in errors:
            legend = []
            full_description = []
            messages = error.get('message', [])
            operation = messages[0]

            if operation:
                row = int(operation['line']) - 1
                col = int(operation['start']) - 1
                endcol = int(operation['end'])

                start = self.view.text_point(row, col)
                stop = self.view.text_point(row, endcol)

                regions.append(sublime.Region(start, stop))

            for message in messages:
                legend.append(message['descr'])

            full_description.append('{} {}'.format(
                row + 1, operation['context']))
            full_description.append(' '.join(legend))

            error_per_line[row + 1] = ' '.join(legend)

        self.view.add_regions(
            'flow_type_highlights',
            regions, 'string', 'dot',
            sublime.DRAW_NO_FILL
        )

        cursor_position = self.view.sel()[0].begin()
        row, col = self.view.rowcol(cursor_position)
        error_description = error_per_line.get(row + 1, '')

        self.view.erase_status('flow_errors')
        if error_description:
            self.view.set_status(
                'flow_type', 'Flow error: {}'.format(error_description))
        else:
            self.view.set_status(
                'flow_errors', 'Flow {}: {} error{}'.format(<commit_msg>Clear persistant previous row error description in status when cursor on a non errored line.<commit_after>import sublime

from .base import BaseCommand
from .exec_flow import ExecFlowCommand
from ..logger import Logger
from ..helpers import get_flow_bin, prepare_arguments

logger = Logger()


class FlowtypeCheckContents(BaseCommand):
    """Run Flow check-contents."""

    def get_cmd(self):
        """Construct cli command."""
        try:
            flow_bin = get_flow_bin()
        except ValueError as e:
            logger.logger.error('check_contents %s' % e)
            return

        arguments = prepare_arguments(self.view)

        cmd = [
            flow_bin, 'check-contents',
            '--from', 'nuclide',
            '--quiet', '--json', arguments.file_name
        ]

        return cmd

    def handle_process(self, returncode, stdout, error):
        """Handle the output from the threaded process."""
        self.view.erase_regions('flow_type_highlights')

        if type(error) is bytes:
            error = error.decode('utf-8')

        if returncode != 0:
            logger.logger.error('check_contents %s' % error)
            return

        passed = stdout.get('passed', False)
        errors = stdout.get('errors', [])
        flow_version = stdout.get('flowVersion', '')

        # No errors
        if passed:
            self.view.erase_status('flow_errors')
            self.view.erase_status('flow_single_error')
            self.view.set_status(
                'flow_errors', 'Flow %s: no errors' % flow_version)
            return

        # Errors
        regions = []
        error_per_line = {}
        for error in errors:
            legend = []
            full_description = []
            messages = error.get('message', [])
            operation = messages[0]

            if operation:
                row = int(operation['line']) - 1
                col = int(operation['start']) - 1
                endcol = int(operation['end'])

                start = self.view.text_point(row, col)
                stop = self.view.text_point(row, endcol)

                regions.append(sublime.Region(start, stop))

            for message in messages:
                legend.append(message['descr'])

            full_description.append('{} {}'.format(
                row + 1, operation['context']))
            full_description.append(' '.join(legend))

            error_per_line[row + 1] = ' '.join(legend)

        self.view.add_regions(
            'flow_type_highlights',
            regions, 'string', 'dot',
            sublime.DRAW_NO_FILL
        )

        cursor_position = self.view.sel()[0].begin()
        row, col = self.view.rowcol(cursor_position)
        error_description = error_per_line.get(row + 1, '')

        self.view.erase_status('flow_errors')
        self.view.erase_status('flow_single_error')
        if error_description:
            self.view.set_status(
                'flow_single_error',
                'Flow error: {}'.format(error_description))
        else:
            self.view.set_status(
                'flow_errors', 'Flow {}: {} error{}'.format(
{'fraction_non_alphanumeric': 0.11860503372265176, 'fraction_numerical': 0.0029610133245599607, 'mean_word_length': 1.862523540489642, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1062588', 'n_tokens_mistral': 1723, 'n_tokens_neox': 1639, 'n_words': 361}