Exemple #1
0
def parse_output_messages_and_show(view, msg, base_dir, exit_code, stderr):
    '''Parse errors and display resulting errors'''

    # The process has terminated; parse and display the output:
    parsed_messages = ParseOutput.parse_output_messages(view, base_dir, stderr)
    # The unparseable part (for other errors)
    unparsable = Regexes.OUTPUT_REGEX.sub('', stderr).strip()

    # Set global error list
    ParseOutput.set_global_error_messages(parsed_messages)

    # If we couldn't parse any messages, just show the stderr
    # Otherwise the parsed errors and the unparsable stderr remainder
    outputs = []

    if parsed_messages:
        outputs += [ParseOutput.format_output_messages(parsed_messages)]
        if unparsable:
            outputs += ['', '']
    if unparsable:
        outputs += ["Collected output:\n", unparsable]

    ParseOutput.show_output_result_text(view, msg, '\n'.join(outputs),
                                        exit_code, base_dir)
    sublime.set_timeout(
        lambda: ParseOutput.mark_messages_in_views(parsed_messages), 0)
    def on_autofix(self, corrections):
        output_messages = [
            ParseOutput.OutputMessage(
                m['source']['file'],
                HsResultParse.parse_region(m['region']).to_zero_based(),
                m['level'].capitalize() + ': ' +
                m['note']['message'].replace('\n', '\n  '), m['level'])
            for m in self.messages
        ]

        self.corrections = corrections
        for corr in self.corrections:
            corr.message_region.to_zero_based()
        self.corrections_dict = dict(
            ((os.path.normpath(c.file), c.message_region.start.line,
              c.message_region.start.column), c) for c in self.corrections)

        for omsg in output_messages:
            okey = (os.path.normpath(omsg.filename), omsg.region.start.line,
                    omsg.region.start.column)
            if okey in self.corrections_dict:
                omsg.correction = self.corrections_dict[okey]

        ParseOutput.set_global_error_messages(output_messages)
        output_text = ParseOutput.format_output_messages(output_messages)
        if Settings.PLUGIN.show_error_window:
            sublime.set_timeout(lambda: ParseOutput.write_output(self.view,
                                                                 output_text,
                                                                 Common.get_cabal_project_dir_of_file(self.filename) or \
                                                                     os.path.dirname(self.filename),
                                                                 panel_display=not self.fly_mode and len(output_messages)),
                                0)
        sublime.set_timeout(
            lambda: ParseOutput.mark_messages_in_views(output_messages), 0)
def wait_ghcmod_and_parse(view, filename, msg, cmds_with_args,
                          alter_messages_cb):
    sublime.set_timeout(lambda: ParseOutput.hide_output(view), 0)

    parsed_messages = []

    file_dir = os.path.dirname(filename)

    all_cmds_successful = True
    all_cmds_outputs = []

    for (cmd, args) in cmds_with_args:
        stdout = GHCIMod.call_ghcmod_and_wait(args, filename)

        # stdout contains NULL as line endings within one message
        # error_output_regex using indents to determine one message scope
        # Replace NULLs to indents
        out = stdout.replace('\0', '\n  ')

        success = len(out.strip()) == 0

        if not success:
            all_cmds_outputs.append(out)
            Logging.log(
                u"ghc-mod %s didn't exit with success on '%s'" %
                (u' '.join(cmd), filename), Logging.LOG_ERROR)

        all_cmds_successful &= success

        for parsed in ParseOutput.parse_output_messages(view, file_dir, out):
            parsed_messages.append((cmd, parsed))

    if alter_messages_cb:
        alter_messages_cb(parsed_messages)

    concated_messages = [m[1] for m in parsed_messages]

    # Set global error list
    ParseOutput.set_global_error_messages(concated_messages)

    sublime.set_timeout(
        lambda: ParseOutput.mark_messages_in_views(concated_messages), 0)

    output_text = (ParseOutput.format_output_messages(concated_messages)
                   if parsed_messages else '\n'.join(all_cmds_outputs))

    exit_code = 0 if all_cmds_successful else 1

    ParseOutput.show_output_result_text(view, msg, output_text, exit_code,
                                        file_dir)
    def on_autofix(self, corrections):
        # Oh, this looks pretty ugly. But, list comprehensions are supposedly faster than loops. And since this is
        # is supporting Haskell, why not use the functional approach? :-)
        output_messages = [ParseOutput.OutputMessage(msg.get('source', {}).get('file', '<no file/command line/OPTIONS_GHC>'),
                                                     HsResultParse.parse_region(msg.get('region')).to_zero_based() \
                                                       if msg.get('region') is not None else Symbols.Region(0),
                                                     msg.get('level', 'uncategorized').capitalize() + ': ' + \
                                                       msg.get('note', {}).get('message', '').replace('\n', '\n  '),
                                                     msg.get('level', 'uncategorized'))
                           for msg in self.msgs]

        # Hack alert: Region and Position.to_zero_based() return the original object (self) after updating it. 'and' returns the
        # right hand side, which is never None or a false value.
        self.corrections_dict = dict(
            ((os.path.normpath(c.file), c.message_region.start.line,
              c.message_region.start.column), c) for c in [
                  corr.message_region.to_zero_based() and corr
                  for corr in corrections or []
              ])

        for omsg in output_messages:
            okey = (os.path.normpath(omsg.filename), omsg.region.start.line,
                    omsg.region.start.column)
            if okey in self.corrections_dict:
                omsg.correction = self.corrections_dict[okey]

        ParseOutput.set_global_error_messages(output_messages)
        output_text = ParseOutput.format_output_messages(output_messages)
        if Settings.PLUGIN.show_error_window:
            cabal_proj_dir = Common.get_cabal_project_dir_of_file(
                self.filename) or os.path.dirname(self.filename)
            panel_display = not self.fly_mode and output_messages
            sublime.set_timeout(
                lambda: ParseOutput.write_output(
                    self.view, output_text, cabal_proj_dir, panel_display), 0)
        sublime.set_timeout(
            lambda: ParseOutput.mark_messages_in_views(output_messages), 0)
Exemple #5
0
    def wait_for_chain_to_complete(self, view, cabal_project_dir, msg, cmds,
                                   on_done):
        '''Chains several commands, wait for them to complete, then parse and display
        the resulting errors.'''

        # First hide error panel to show that something is going on
        sublime.set_timeout(lambda: hide_output(view), 0)

        # run and wait commands, fail on first fail
        # exit_code has scope outside of the loop
        # stdout = ''
        collected_out = []
        exit_code = 0
        output_log = Common.output_panel(
            view.window(),
            '',
            panel_name=BUILD_LOG_PANEL_NAME,
            panel_display=Settings.PLUGIN.show_output_window)
        for cmd in cmds:
            Common.output_text(output_log, ' '.join(cmd) + '...\n')

            # Don't tie stderr to stdout, since we're interested in the error messages
            out = OutputCollector.OutputCollector(output_log,
                                                  cmd,
                                                  cwd=cabal_project_dir)
            exit_code, cmd_out = out.wait()
            collected_out.append(cmd_out)

            # Bail if the command failed...
            if exit_code != 0:
                break

        if collected_out or exit_code == 0:
            # We're going to show the errors in the output panel...
            Common.hide_panel(view.window(), panel_name=BUILD_LOG_PANEL_NAME)

        # Notify UI thread that commands are done
        sublime.set_timeout(on_done, 0)
        the_stderr = ''.join(collected_out)

        # The process has terminated; parse and display the output:
        parsed_messages = ParseOutput.parse_output_messages(
            view, cabal_project_dir, the_stderr)
        # The unparseable part (for other errors)
        unparsable = Regexes.OUTPUT_REGEX.sub('', the_stderr).strip()

        # Set global error list
        ParseOutput.set_global_error_messages(parsed_messages)

        # If we couldn't parse any messages, just show the stderr
        # Otherwise the parsed errors and the unparsable stderr remainder
        outputs = []

        if parsed_messages:
            outputs += [ParseOutput.format_output_messages(parsed_messages)]
            if unparsable:
                outputs += ['', '']
        if unparsable:
            outputs += ["Collected output:\n", unparsable]

        ParseOutput.show_output_result_text(view, msg, '\n'.join(outputs),
                                            exit_code, cabal_project_dir)
        sublime.set_timeout(
            lambda: ParseOutput.mark_messages_in_views(parsed_messages), 0)