Пример #1
0
    def run_build(self, view, project_name, project_dir, config):
        # Don't build if a build is already running for this project
        # We compare the project_name for simplicity (projects with same
        # names are of course possible, but unlikely, so we let them wait)
        if project_name in self.PROJECTS_BEING_BUILT:
            Logging.log("Waiting for build action on '%s' to complete." % project_name, Logging.LOG_WARNING)
            Common.show_status_message('Already building %s' % project_name, is_ok=False, priority=5)
            return

        # Set project as building
        self.PROJECTS_BEING_BUILT.add(project_name)

        Logging.log('project build tool: {0}'.format(Settings.get_project_setting(view, 'haskell_build_tool')),
                    Logging.LOG_DEBUG)
        Logging.log('settings build tool: {0}'.format(Settings.PLUGIN.haskell_build_tool), Logging.LOG_DEBUG)

        build_tool_name = Settings.get_project_setting(view, 'haskell_build_tool', Settings.PLUGIN.haskell_build_tool)
        if build_tool_name == 'stack' and not self.is_stack_project(project_dir):  # rollback to cabal
            build_tool_name = 'cabal'

        tool = self.BUILD_TOOL[build_tool_name]

        # Title of tool: Cabal, Stack
        tool_title = tool['name']
        # Title of action: Cleaning, Building, etc.
        action_title = config['message']
        # Tool name: cabal
        tool_name = tool['command']
        # Tool arguments (commands): build, clean, etc.
        tool_steps = config['steps'][build_tool_name]

        # Config override
        override_config = Settings.get_project_setting(view, 'active_stack_config')

        override_args = []
        if override_config:
            override_args = ['--stack-yaml', override_config]
        # Assemble command lines to run (possibly multiple steps)
        commands = [[tool_name] + override_args + step if isinstance(step, list) else step for step in tool_steps]

        Logging.log('running build commands: {0}'.format(commands), Logging.LOG_TRACE)

        def done_callback():
            # Set project as done being built so that it can be built again
            self.PROJECTS_BEING_BUILT.remove(project_name)

        # Run them
        msg = '{0} {1} with {2}\ncommands:\n{3}'.format(action_title, project_name, tool_title, commands)
        Logging.log(msg, Logging.LOG_DEBUG)
        Common.show_status_message_process(msg, priority=3)
        Utils.run_async('wait_for_chain_to_complete', self.wait_for_chain_to_complete, view, project_dir, msg, commands,
                        on_done=done_callback)
Пример #2
0
    def auto_build(self):
        current_project_dir, current_project_name = Common.locate_cabal_project_from_view(self.view)

        if current_project_name and current_project_dir:
            build_mode = Settings.get_project_setting(self.view.window().active_view(), 'auto_build_mode',
                                                      Settings.PLUGIN.auto_build_mode)

            build_command = self.MODE_BUILD_COMMAND.get(build_mode)
            if not build_command:
                Common.output_error(self.view.window(), "SublimeHaskell: invalid auto_build_mode '%s'" % build_mode)
                return

            # Duplicate the dictionary corresponding to the build command. We might modify it later.
            config = dict(self.BUILD_TOOL_CONFIG[build_command])
            addl_config = None

            if build_mode.endswith('-then-tests'):
                has_tests = False
                projects = self.get_projects()

                if current_project_name in projects and 'description' in projects[current_project_name]:
                    has_tests = projects[current_project_name]['description'].get('tests') is not None

                if has_tests:
                    addl_config = 'test'
            elif build_mode.endswith('-then-bench'):
                addl_config = 'bench'

            if addl_config is not None:
                for tool, steps in self.BUILD_TOOL_CONFIG[addl_config]['steps'].items():
                    config['steps'][tool].extend(steps)

            Logging.log('auto build: final config:\n{0}'.format(pprint.pformat(config)))

            self.run_build(current_project_name, current_project_dir, config)
Пример #3
0
    def auto_build(self):
        current_project_dir, current_project_name = Common.locate_cabal_project_from_view(self.view)

        if current_project_name and current_project_dir:
            build_mode = Settings.get_project_setting(self.view.window().active_view(), 'auto_build_mode',
                                                      Settings.PLUGIN.auto_build_mode)

            build_command = self.MODE_BUILD_COMMAND.get(build_mode)
            if not build_command:
                Common.output_error(self.view.window(), "SublimeHaskell: invalid auto_build_mode '%s'" % build_mode)
                return

            # Duplicate the dictionary corresponding to the build command. We might modify it later.
            config = dict(self.BUILD_TOOL_CONFIG[build_command])
            addl_config = None

            if build_mode.endswith('-then-tests'):
                has_tests = False
                projects = self.get_projects()

                if current_project_name in projects and 'description' in projects[current_project_name]:
                    has_tests = projects[current_project_name]['description'].get('tests') is not None

                if has_tests:
                    addl_config = 'test'
            elif build_mode.endswith('-then-bench'):
                addl_config = 'bench'

            if addl_config is not None:
                for tool, steps in self.BUILD_TOOL_CONFIG[addl_config]['steps'].items():
                    config['steps'][tool].extend(steps)

            Logging.log('auto build: final config:\n{0}'.format(pprint.pformat(config)))

            self.run_build(current_project_name, current_project_dir, config)
Пример #4
0
 def is_visible(self):
     project_builder = Settings.get_project_setting(
         self.window.active_view(), 'haskell_build_tool',
         Settings.PLUGIN.haskell_build_tool)
     return super().is_visible and project_builder and project_builder in [
         'cabal', 'cabal-new-build'
     ]
Пример #5
0
    def run_build(self, project_name, project_dir, config):
        # Don't build if a build is already running for this project
        # We compare the project_name for simplicity (projects with same
        # names are of course possible, but unlikely, so we let them wait)
        if project_name in self.PROJECTS_BEING_BUILT:
            Logging.log("Waiting for build action on '%s' to complete." % project_name, Logging.LOG_WARNING)
            Common.sublime_status_message('Already building {0}'.format(project_name))
            return

        # Set project as building
        self.PROJECTS_BEING_BUILT.add(project_name)

        Logging.log('project build tool: {0}'.format(Settings.get_project_setting(self.view, 'haskell_build_tool')),
                    Logging.LOG_DEBUG)
        Logging.log('settings build tool: {0}'.format(Settings.PLUGIN.haskell_build_tool), Logging.LOG_DEBUG)

        build_tool_name = Settings.get_project_setting(self.view, 'haskell_build_tool', Settings.PLUGIN.haskell_build_tool)
        if build_tool_name == 'stack' and not self.is_stack_project(project_dir):  # rollback to cabal
            build_tool_name = 'cabal'

        tool = self.BUILD_TOOL[build_tool_name]

        # Title of tool: Cabal, Stack
        tool_title = tool['name']
        # Title of action: Cleaning, Building, etc.
        action_title = config['message']
        # Tool name: cabal
        tool_name = tool['command']
        # Tool arguments (commands): build, clean, etc.
        tool_steps = config['steps'][build_tool_name]

        # Config override
        override_args = []
        override_config = Settings.get_project_setting(self.view, 'active_stack_config') if tool_name == 'stack' else ''
        if override_config:
            override_args = ['--stack-yaml', override_config]
        # Assemble command lines to run (possibly multiple steps)
        commands = [[tool_name] + override_args + step if isinstance(step, list) else step for step in tool_steps]

        Logging.log('running build commands: {0}'.format(commands), Logging.LOG_TRACE)

        # Run them
        ## banner = '{0} {1} with {2}\ncommands:\n{3}'.format(action_title, project_name, tool_title, commands)
        banner = '{0} {1} with {2}'.format(action_title, project_name, tool_title)
        Logging.log(banner, Logging.LOG_DEBUG)
        Utils.run_async('wait_for_chain_to_complete', self.wait_for_chain_to_complete, self.view, project_name, project_dir,
                        banner, commands)
Пример #6
0
    def on_done(self, idx):
        if idx >= 0:
            view = self.window.active_view()

            project_builder = Settings.get_project_setting(
                view, 'haskell_build_tool', Settings.PLUGIN.haskell_build_tool)
            (pkg, comp, target) = self.args[self.targets[idx]]
            if project_builder in ['cabal', 'cabal-new-build']:
                repl_target = ':'.join([comp, target])
            elif project_builder in ['stack']:
                repl_target = ':'.join(
                    [pkg, comp, target] if comp != 'lib' else [pkg, comp])

            external_id = 'Haskell_{0}_repl_{1}'.format(
                project_builder, repl_target).translate(self.FILE_NAME_TRANS)
            repl_views = list(sublimerepl.manager.find_repl(external_id))
            if not repl_views:
                repl_cmd_args = []
                ghci_opts = Settings.get_project_setting(
                    view, 'ghci_opts', Settings.PLUGIN.ghci_opts)
                if ghci_opts:
                    repl_cmd_args += ['--ghci-options=' + ghci_opts]
                else:
                    ghc_opts = Settings.get_project_setting(
                        view, 'ghc_opts', Settings.PLUGIN.ghc_opts)
                    if ghc_opts:
                        repl_cmd_args += ['--ghc-options' + ghc_opts]

                repl_cmd_args.append(repl_target)
                repl_cmd_args = repl_wrapper_cmd(project_builder,
                                                 repl_cmd_args)
                Logging.log('repl cmd args: {0}'.format(repl_cmd_args),
                            Logging.LOG_DEBUG)

                self.window.run_command(
                    "repl_open",
                    repl_args(cmd=repl_cmd_args,
                              cwd=self.project_dir,
                              loaded=self.project_dir,
                              external_id=external_id))
            else:
                # Already have a REPL for this project, switch focus to it.
                for repl in repl_views:
                    win = repl.view.window()
                    if win:
                        win.focus_view(repl.view)
Пример #7
0
def run_build(view, project_name, project_dir, config):
    # Don't build if a build is already running for this project
    # We compare the project_name for simplicity (projects with same
    # names are of course possible, but unlikely, so we let them wait)
    if project_name in PROJECTS_BEING_BUILT:
        Logging.log(
            "Waiting for build action on '%s' to complete." % project_name,
            Logging.LOG_WARNING)
        Common.show_status_message('Already building %s' % project_name,
                                   is_ok=False,
                                   priority=5)
        return

    # Set project as building
    PROJECTS_BEING_BUILT.add(project_name)

    build_tool_name = Settings.PLUGIN.haskell_build_tool
    if build_tool_name == 'stack' and not is_stack_project(
            project_dir):  # rollback to cabal
        build_tool_name = 'cabal'

    tool = BUILD_TOOL[build_tool_name]

    # Title of tool: Cabal, Stack
    tool_title = tool['name']
    # Title of action: Cleaning, Building, etc.
    action_title = config['message']
    # Tool name: cabal
    tool_name = tool['command']
    # Tool arguments (commands): build, clean, etc.
    tool_steps = config['steps'][build_tool_name]

    # Config override
    override_config = Settings.get_project_setting(view, 'stack_config_file')

    override_args = []
    if override_config:
        override_args = ['--stack-yaml', override_config]
    # Assemble command lines to run (possibly multiple steps)
    commands = [[tool_name] + step + override_args for step in tool_steps]

    Logging.log('running build commands: {0}'.format(commands),
                Logging.LOG_TRACE)

    def done_callback():
        # Set project as done being built so that it can be built again
        PROJECTS_BEING_BUILT.remove(project_name)

    # Run them
    ParseOutput.run_chain_build_thread(view,
                                       project_dir,
                                       '{0} {1} with {2}'.format(
                                           action_title, project_name,
                                           tool_title),
                                       commands,
                                       on_done=done_callback)
Пример #8
0
    def limit_messages(self, view):
        show_only = Settings.get_project_setting(view, 'show_only', Settings.PLUGIN.show_only)
        show_errors = show_only.get('errors', True)
        show_warnings = show_only.get('warnings', True)
        show_hints = show_only.get('hints', True)

        self.messages = [msg for msg in self.messages if (msg.level == 'error' and show_errors) or \
                                                         (msg.level == 'warning' and show_warnings) or \
                                                         (msg.level == 'hint' and show_hints) or \
                                                         msg.level == 'uncategorized']
Пример #9
0
    def limit_messages(self, view):
        show_only = Settings.get_project_setting(view, 'show_only',
                                                 Settings.PLUGIN.show_only)
        show_errors = show_only.get('errors', True)
        show_warnings = show_only.get('warnings', True)
        show_hints = show_only.get('hints', True)

        self.messages = [msg for msg in self.messages if (msg.level == 'error' and show_errors) or \
                                                         (msg.level == 'warning' and show_warnings) or \
                                                         (msg.level == 'hint' and show_hints) or \
                                                         msg.level == 'uncategorized']
Пример #10
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()
Пример #11
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()
Пример #12
0
 def run(self, **_kwargs):
     options = Settings.get_project_setting(self.view, 'stack_config_file_list', [])
     self.view.window().show_quick_panel(options, self.on_done)
Пример #13
0
def hsdev_lint(view):
    lint_options = Settings.get_project_setting(view, 'lint_opts', Settings.PLUGIN.lint_opts)
    return (BackendMgr.active_backend().lint, file_as_file_list, {'hlint': lint_options})
Пример #14
0
 def is_visible(self):
     project_builder = Settings.get_project_setting(self.window.active_view(), 'haskell_build_tool',
                                                    Settings.PLUGIN.haskell_build_tool)
     return super().is_visible and project_builder and project_builder in ['cabal', 'cabal-new-build']
Пример #15
0
def hsdev_check(view):
    ghc_options = Settings.get_project_setting(view, 'ghc_opts', Settings.PLUGIN.ghc_opts)
    return (BackendMgr.active_backend().check, file_as_file_list, {'ghc': ghc_options})
Пример #16
0
def hsdev_check(view):
    ghc_options = Settings.get_project_setting(view, 'ghc_opts',
                                               Settings.PLUGIN.ghc_opts)
    return (BackendMgr.active_backend().check, file_as_file_list, {
        'ghc': ghc_options
    })
Пример #17
0
 def run(self, edit, **_kwargs):
     stylish_options = Settings.get_project_setting(
         self.view, 'stylish_options', Settings.PLUGIN.stylish_options)
     do_prettify(self.view, edit, ['stylish-haskell'], stylish_options)
Пример #18
0
 def run(self, edit, **_kwargs):
     hindent_options = Settings.get_project_setting(
         self.view, 'hindent_options', Settings.PLUGIN.hindent_options)
     do_prettify(self.view, edit, ['hindent'], hindent_options)
Пример #19
0
def hsdev_lint(view):
    lint_options = Settings.get_project_setting(view, 'lint_opts',
                                                Settings.PLUGIN.lint_opts)
    return (BackendMgr.active_backend().lint, file_as_file_list, {
        'hlint': lint_options
    })
Пример #20
0
    def on_done(self, idx):
        options = Settings.get_project_setting(self.view, 'stack_config_file_list')
        selected = options[idx]

        Settings.set_project_setting(self.view, 'active_stack_config', selected)