Beispiel #1
0
    def run(self, edit):
        selections = list(self.view.sel())

        if not self.is_infos_valid(selections):
            SublimeHaskellExpandSelectionExpression.Infos = [
                ExpandSelectionInfo(self.view, s) for s in selections
            ]

        if not self.is_infos_valid(selections):
            Common.show_status_message(
                'Unable to retrieve expand selection info', False)
            return

        selinfo = [i.expand() for i in self.Infos]
        self.view.sel().clear()
        self.view.sel().add_all([sel.region for sel in selinfo])

        Common.output_panel(
            self.view.window(),
            '\n'.join([
                UnicodeOpers.use_unicode_operators(sel.typename)
                for sel in selinfo
            ]),
            panel_name='sublime_haskell_expand_selection_expression',
            syntax='Haskell-SublimeHaskell')
Beispiel #2
0
    def on_select(self, idx):
        if idx == -1:
            return
        package = self.packages[idx]

        Common.output_panel(self.window, package.detailed(),
                            'sublime_haskell_cabal_package')
Beispiel #3
0
    def mark(self):
        (cur, corrs) = self.get_corrections()

        self.view.add_regions('autofix', [corr.to_region(self.view) for corr in corrs], 'warning', 'dot', sublime.DRAW_OUTLINED)
        rgns = [cur.to_region(self.view)]
        self.view.add_regions('autofix_current', rgns, 'warning', 'dot')
        self.view.show(sublime.Region(rgns[0].a, rgns[-1].b))
        Common.output_panel(self.view.window(),
                            'Press {0}\n\n{1}'.format(self.keys(), self.message(cur)),
                            'sublime_haskell_auto_fix',
                            syntax='HaskellAutoFix')
Beispiel #4
0
def wait_for_chain_to_complete(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
    # stdout = ''
    collected_out = []
    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 len(collected_out) > 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)
    parse_output_messages_and_show(view, msg, cabal_project_dir, exit_code, ''.join(collected_out))
Beispiel #5
0
    def show_types(self, types):
        if not types:
            Common.show_status_message("Can't infer type", False)
            return

        types = sorted(filter(
            lambda t: t.region(self.view).contains(self.view.sel()[0]), types),
                       key=lambda t: t.region(self.view).size())
        self.output_view = Common.output_panel(self.view.window(),
                                               '',
                                               panel_name=TYPES_PANEL_NAME,
                                               syntax='Haskell-SublimeHaskell',
                                               panel_display=False)

        regions = []
        for typ in types:
            Common.output_text(self.output_view,
                               '{0}\n'.format(typ.show(self.view)),
                               clear=False)
            regions.append(
                sublime.Region(
                    self.output_view.size() - 1 -
                    len(UnicodeOpers.use_unicode_operators(typ.typename)),
                    self.output_view.size() - 1))
        self.output_view.add_regions('types', regions, 'comment', '',
                                     sublime.DRAW_OUTLINED)
        Common.show_panel(self.view.window(), panel_name=TYPES_PANEL_NAME)
Beispiel #6
0
 def write_output(window, text, base_dir):
     "Write text to Sublime's output panel."
     output_view = Common.output_panel(window,
                                       text,
                                       panel_name=OUTPUT_PANEL_NAME,
                                       panel_display=True)
     output_view.settings().set("result_base_dir", base_dir)
Beispiel #7
0
def write_output(view, text, cabal_project_dir, panel_display=False):
    "Write text to Sublime's output panel."
    global ERROR_VIEW
    ERROR_VIEW = Common.output_panel(view.window(), text,
                                     panel_name=OUTPUT_PANEL_NAME,
                                     syntax='HaskellOutputPanel',
                                     panel_display=panel_display)
    ERROR_VIEW.settings().set("RESULT_FILE_REGEX", RESULT_FILE_REGEX)
    ERROR_VIEW.settings().set("result_base_dir", cabal_project_dir)
Beispiel #8
0
 def show_types(self, types):
     if types:
         self.types = types
         self.output_view = Common.output_panel(self.view.window(), '',
                                                panel_name=TYPES_PANEL_NAME,
                                                syntax='Haskell-SublimeHaskell')
         self.view.window().show_quick_panel([t.typename for t in self.types], self.on_done, 0, -1, self.on_changed)
     else:
         Common.show_status_message("Can't infer type", False)
Beispiel #9
0
    def run(self, edit, **_kwargs):
        selections = list(self.view.sel())

        if not self.is_infos_valid(selections):
            SublimeHaskellExpandSelectionExpression.Infos = [ExpandSelectionInfo(self.view, s) for s in selections]

        if not self.is_infos_valid(selections):
            Common.sublime_status_message('Unable to retrieve expand selection info')
            return

        selinfo = [i.expand() for i in self.Infos]
        self.view.sel().clear()
        self.view.sel().add_all([sel.region for sel in selinfo])

        Common.output_panel(self.view.window(),
                            '\n'.join([UnicodeOpers.use_unicode_operators(sel.typename) for sel in selinfo]),
                            panel_name='sublime_haskell_expand_selection_expression',
                            syntax='Haskell-SublimeHaskell')
Beispiel #10
0
 def show_types(self, types):
     if types:
         self.types = types
         self.output_view = Common.output_panel(self.view.window(), '',
                                                panel_name=TYPES_PANEL_NAME,
                                                syntax='Haskell-SublimeHaskell')
         self.view.window().show_quick_panel([t.typename for t in self.types], self.on_done, 0, -1, self.on_changed)
     else:
         Common.sublime_status_message("Can't infer type")
Beispiel #11
0
def report_error(view, errmsg):
    window = view.window()
    output_view = Common.output_panel(window, FILTER_OUTPUT_PANEL_NAME)
    output_view.run_command('sublime_haskell_output_text', {
        'text': errmsg,
        'clear': 'yes'
    })
    Common.show_panel(window, FILTER_OUTPUT_PANEL_NAME)
    output_view.sel().clear()
    output_view.sel().add(sublime.Region(0, 0))
Beispiel #12
0
 def make_message_panel(self, view, text, cabal_project_dir, panel_out):
     '''Create the message panel for error/warnings/hints/uncategorized errors'''
     self.message_panel = Common.output_panel(view.window(),
                                              text,
                                              panel_name=OUTPUT_PANEL_NAME,
                                              syntax='HaskellOutputPanel',
                                              panel_display=panel_out)
     self.message_panel.settings().set("result_file_regex",
                                       Regexes.RESULT_FILE_REGEX)
     self.message_panel.settings().set("result_base_dir", cabal_project_dir)
Beispiel #13
0
    def __init__(self, project, project_dir, opt_args):
        if debug_any():
            print('Starting \'ghc-mod\' for project {0}'.format(project))

        self.ghcmod = None
        self.action_lock = None
        self.stderr_drain = None
        self.cmd = []
        self.diag_prefix = 'ghc-mod: project ' + project

        win = sublime.active_window()
        msg = 'Error and diagnostic output from ' + self.diag_prefix
        banner = '~' * len(msg)
        self.output_panel = Common.output_panel(
            win,
            panel_name=self.diag_prefix,
            text='\n'.join([banner, msg, banner, '', '']))
        panel_settings = self.output_panel.settings()
        panel_settings.set("auto_indent", False)
        panel_settings.set("smart_indent", False)

        # if self.exec_with is not None:
        #     if self.exec_with == 'cabal':
        #         cmd += ['cabal']
        #     elif self.exec_with == 'stack':
        #         cmd += ['stack']

        self.cmd += ['ghc-mod']

        # if self.exec_with is not None:
        #     cmd += ['--']

        self.cmd += [
            '-b', '\\n', '--line-prefix',
            self.GHCMOD_OUTPUT_MARKER + ',' + self.GHCMOD_ERROR_MARKER
        ]
        self.cmd += opt_args
        self.cmd += ['legacy-interactive']

        if debug_any():
            print('ghc-mod command: {0}'.format(self.cmd))

        self.ghcmod = ProcHelper.ProcHelper(self.cmd, cwd=project_dir)
        if self.ghcmod.process is not None:
            self.ghcmod.process.stdin = io.TextIOWrapper(
                self.ghcmod.process.stdin, 'utf-8')
            self.ghcmod.process.stdout = io.TextIOWrapper(
                self.ghcmod.process.stdout, 'utf-8')
            self.action_lock = threading.Lock()
            self.stderr_drain = OutputCollector.DescriptorDrain(
                self.diag_prefix, self.ghcmod.process.stderr)
            self.stderr_drain.start()
        else:
            Logging.log('Did not start ghc-mod ({0}) successfully.'.format(
                self.diag_prefix))
Beispiel #14
0
    def stack_exec(self, arg):
        args = shlex.split(arg)
        if any(map(lambda arg: arg.startswith('-'), args)) and '--' not in args:
            args.insert(0, '--')
        cmdargs = ['stack', 'exec'] + args
        window = self.view.window()
        runv = Common.output_panel(window, panel_name=SublimeHaskellStackExec.OUTPUT_PANEL_NAME)
        pretty_cmdargs = 'Running \'{0}\''.format(' '.join(cmdargs))
        runv.run_command('insert', {'characters': '{0}\n{1}\n'.format(pretty_cmdargs, '-' * len(pretty_cmdargs))})

        SublimeHaskellStackExec.SExecRunner(runv, cmdargs).start()
Beispiel #15
0
def show_declaration_info_panel(view, decl):
    info = decl.detailed()
    panel = Common.output_panel(view.window(), info, 'sublime_haskell_symbol_info_panel', syntax='HaskellSymbolInfo')
    panel.settings().set('result_file_regex', SYMBOL_FILE_REGEX)
    panel.settings().erase('location')
    panel.settings().erase('package')
    panel.settings().erase('module')
    if decl.has_source_location():
        panel.settings().set('location', decl.get_source_location())
    if decl.by_cabal():
        panel.settings().set('package', decl.defined_module().location.package.package_id())
        panel.settings().set('module', decl.defined_module().name)
Beispiel #16
0
    def on_program_args(self, args):
        view = self.window.active_view()
        view_settings = view.settings()
        run_args = (view_settings or {}).get('subhask_run_args', {})
        run_args[self.exec_name] = args
        view_settings.set('subhask_run_args', run_args)
        project_builder = Settings.get_project_setting(view, 'haskell_build_tool', Settings.PLUGIN.haskell_build_tool)
        cmd_list = ProcHelper.exec_wrapper_cmd(project_builder, [self.exec_name] + shlex.split(args))

        Common.hide_panel(self.window, panel_name=OUTPUT_PANEL_NAME)
        outview = Common.output_panel(self.window, panel_name=OUTPUT_PANEL_NAME)

        pretty_cmdargs = 'Running \'{0}\' in {1}'.format(' '.join(cmd_list), self.exec_base_dir)
        outview.run_command('insert', {'characters': '{0}\n{1}\n'.format(pretty_cmdargs, '-' * len(pretty_cmdargs))})
        self.ExecRunner(outview, cmd_list, self.exec_base_dir).start()
Beispiel #17
0
    def on_program_args(self, args):
        view = self.window.active_view()
        view_settings = view.settings()
        run_args = (view_settings or {}).get('subhask_run_args', {})
        run_args[self.exec_name] = args
        view_settings.set('subhask_run_args', run_args)
        project_builder = Settings.get_project_setting(view, 'haskell_build_tool', Settings.PLUGIN.haskell_build_tool)
        cmd_list = ProcHelper.exec_wrapper_cmd(project_builder, [self.exec_name] + shlex.split(args))

        Common.hide_panel(self.window, panel_name=OUTPUT_PANEL_NAME)
        outview = Common.output_panel(self.window, panel_name=OUTPUT_PANEL_NAME)

        pretty_cmdargs = 'Running \'{0}\' in {1}'.format(' '.join(cmd_list), self.exec_base_dir)
        outview.run_command('insert', {'characters': '{0}\n{1}\n'.format(pretty_cmdargs, '-' * len(pretty_cmdargs))})
        self.ExecRunner(outview, cmd_list, self.exec_base_dir).start()
Beispiel #18
0
    def wait_for_chain_to_complete(self, view, cabal_project_name,
                                   cabal_project_dir, banner, cmds):
        '''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
        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:
            if isinstance(cmd, list):
                Common.output_text(output_log, ' '.join(cmd) + '\u2026\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()
            elif callable(cmd):
                Common.output_text(
                    output_log, 'Function/method {0}\n'.format(cmd.__name__))
                exit_code, cmd_out = cmd(cabal_project_dir)
            else:
                # Clearly something not a list or callable:
                pass

            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
        self.PROJECTS_BEING_BUILT.remove(cabal_project_name)
        ParseOutput.MARKER_MANAGER.mark_compiler_output(
            view, banner, cabal_project_dir, ''.join(collected_out), exit_code)
Beispiel #19
0
    def show_types(self, types):
        if not types:
            Common.sublime_status_message("Can't infer type")
            return

        self.types = types
        self.output_view = Common.output_panel(self.view.window(), '',
                                               panel_name=TYPES_PANEL_NAME,
                                               syntax='Haskell-SublimeHaskell',
                                               panel_display=False)
        regions = []
        for typ in self.types:
            Common.output_text(self.output_view, '{0}\n'.format(typ.show(self.view)), clear=False)
            regions.append(sublime.Region(self.output_view.size() - 1 - len(UnicodeOpers.use_unicode_operators(typ.typename)),
                                          self.output_view.size() - 1))
        self.output_view.add_regions('types', regions, 'comment', '', sublime.DRAW_OUTLINED)
        Common.show_panel(self.view.window(), panel_name=TYPES_PANEL_NAME)
Beispiel #20
0
    def wait_for_chain_to_complete(self, view, cabal_project_name, cabal_project_dir, banner, cmds):
        '''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
        Common.hide_panel(view.window(), panel_name=OUTPUT_PANEL_NAME)

        # run and wait commands, fail on first fail
        # exit_code has scope outside of the loop
        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)
        try:
            for cmd in cmds:
                if isinstance(cmd, list):
                    Common.output_text(output_log, ' '.join(cmd) + '\u2026\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()
                elif callable(cmd):
                    Common.output_text(output_log, 'Function/method {0}\n'.format(cmd.__name__))
                    exit_code, cmd_out = cmd(cabal_project_dir)
                else:
                    # Clearly something not a list or callable:
                    pass

                collected_out.append(cmd_out)
                # Bail if the command failed...
                if exit_code != 0:
                    break

            if exit_code == 0:
                # Hide the build panel if successful
                Common.hide_panel(view.window(), panel_name=BUILD_LOG_PANEL_NAME)
        finally:
            self.PROJECTS_BEING_BUILT.remove(cabal_project_name)

        # Execute post-build steps in the UI thread (paranoia)
        sublime.set_timeout(functools.partial(self.post_build, banner, cabal_project_dir, collected_out, exit_code), 0)
Beispiel #21
0
    def wait_for_chain_to_complete(self, view, cabal_project_name, cabal_project_dir, banner, cmds):
        '''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
        Common.hide_panel(view.window(), panel_name=OUTPUT_PANEL_NAME)

        # run and wait commands, fail on first fail
        # exit_code has scope outside of the loop
        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)
        try:
            for cmd in cmds:
                if isinstance(cmd, list):
                    Common.output_text(output_log, ' '.join(cmd) + '\u2026\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()
                elif callable(cmd):
                    Common.output_text(output_log, 'Function/method {0}\n'.format(cmd.__name__))
                    exit_code, cmd_out = cmd(cabal_project_dir)
                else:
                    # Clearly something not a list or callable:
                    pass

                collected_out.append(cmd_out)
                # Bail if the command failed...
                if exit_code != 0:
                    break

            if exit_code == 0:
                # Hide the build panel if successful
                Common.hide_panel(view.window(), panel_name=BUILD_LOG_PANEL_NAME)
        finally:
            self.PROJECTS_BEING_BUILT.remove(cabal_project_name)

        # Execute post-build steps in the UI thread (paranoia)
        sublime.set_timeout(functools.partial(self.post_build, banner, cabal_project_dir, collected_out, exit_code), 0)
Beispiel #22
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)
 def make_message_panel(self, view, text, cabal_project_dir, panel_out):
     '''Create the message panel for error/warnings/hints/uncategorized errors'''
     self.message_panel = Common.output_panel(view.window(), text, panel_name=OUTPUT_PANEL_NAME, syntax='HaskellOutputPanel',
                                              panel_display=panel_out)
     self.message_panel.settings().set("result_file_regex", Regexes.RESULT_FILE_REGEX)
     self.message_panel.settings().set("result_base_dir", cabal_project_dir)