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))
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()
def run_chain(self, cmds, fly_mode=False): ParseOutput.MARKER_MANAGER.clear_error_marks() if self.filename: self.fly_mode = fly_mode if not self.fly_mode: Common.hide_panel(self.view.window()) if cmds: self.status_msg = Common.status_message_process(self.caption + ': ' + self.filename) self.status_msg.start() self.commands = cmds self.go_chain() else: sublime.error_message('Empty command chain (check_lint.run_chain)') else: print('run_chain: no file name? {0}'.format(self.filename))
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)
def do_prettify(view, edit, indenter, indenter_options): try: Common.hide_panel(view.window(), panel_name=FILTER_OUTPUT_PANEL_NAME) regions = [] for region in view.sel(): regions.append(sublime.Region(region.a, region.b)) selection = region if not region.empty() else sublime.Region( 0, view.size()) # Newline conversion seems dubious here, but... leave it alone for the time being. sel_str = view.substr(selection).replace('\r\n', '\n') with ProcHelper.ProcHelper(indenter + indenter_options) as proc: if proc.process is not None: _, out, err = proc.wait(sel_str) # stylish-haskell does not have a non-zero exit code if it errors out! (Surprise!) # Not sure about hindent, but this seems like a safe enough test. # # Also test if the contents actually changed so break the save-indent-save-indent-... loop if # the user enabled prettify_on_save. if not err: if out not in [selection, sel_str]: view.replace(edit, selection, out) else: indent_err = ' '.join(indenter) stderr_out = '\n'.join([ "{0} failed, stderr contents:".format(indent_err), "-" * 40, "" ]) + err report_error(view, stderr_out) else: report_error(view, proc.process_err) view.sel().clear() # Questionable whether regions should be re-activated: stylish-haskell usually adds whitespace, which makes # the selection nonsensical. # # However, there are other plugins that get fired after SublimeHaskell that don't like it when you kill all of the # selection regions from underneath their feet. for region in regions: view.sel().add(region) except OSError: report_error(view, 'Exception executing {0}'.format(' '.join(indenter))) traceback.print_exc()
def run_chain(self, cmds, fly_mode=False): ParseOutput.MARKER_MANAGER.clear_error_marks() if self.filename: self.fly_mode = fly_mode if not self.fly_mode: Common.hide_panel(self.view.window()) if cmds: self.status_msg = Common.status_message_process(self.caption + ': ' + self.filename) self.status_msg.start() self.commands = cmds self.go_chain() else: sublime.error_message( 'Empty command chain (check_lint.run_chain)') else: print('run_chain: no file name? {0}'.format(self.filename))
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)
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 run(self, edit): SourceHaskellTypeCache().hide(self.view.file_name()) Common.hide_panel(self.view.window(), panel_name=TYPES_PANEL_NAME)
def unmark(self): self.view.erase_regions('autofix') self.view.erase_regions('autofix_current') window = self.view.window() Common.hide_panel(window, panel_name='sublime_haskell_auto_fix')
def run(self, edit): FILE_TYPES.hide(self.view.file_name()) Common.hide_panel(self.view.window(), panel_name=TYPES_PANEL_NAME)
def run(self, edit, **_kwargs): SourceHaskellTypeCache().hide(self.view.file_name()) Common.hide_panel(self.view.window(), panel_name=TYPES_PANEL_NAME)