<commit_before>import re
import sublime, sublime_plugin
from .coqtop import Coqtop, find_coqtop

class CoqtopManager:
    coqtop_view = None

    def __init__(self):
        self.coqtop = None
        self.ready = False
        self.output_width = 78
        self.sentence_no = 0
        self.last_output = ""
        self.expect_success = False
        self.retry_on_empty = None
        self.ignore_replies = 0
        self.theorem = None

        self.redirect_view = None
        self.editor_view = None
        self.autorun_point = None
        self.autorun_forward = True
        self.autorun_enabled = False

        self.debug = False
        self.position = 0
        self.stack = []
        self.scope = 'toplevel'

        self.settings = sublime.load_settings('Sublime-Coq.sublime-settings')
        self.settings.add_on_change('coq_debug', self._update_debug)
        self._update_debug()

    def _update_debug(self):
        flags = self.settings.get('coq_debug')

        self.debug = 'manager' in flags
        if self.coqtop is not None:
            self.coqtop.debug = 'coqtop' in flags

    def start(self):
        path = self.settings.get('coqtop_path') or find_coqtop()
        if path is None:
            sublime.error_message('Cannot find Coqtop.')
            return False        
        pwd = sublime.Window.folders(sublime.active_window())[0]
        args = ["-R", pwd, ""]
        args = self.settings.get('coqtop_args') + args
        debug = 'coqtop' in self.settings.get('coq_debug')

        self.coqtop = Coqtop(self, path, args, debug)
        return True

    def stop(self):
        if self.coqtop is not None:
            self.ready = False
            self.coqtop.kill()

    def send(self, statement, expect_success=False, retry_on_empty=None,
             redirect_view=None, need_output_width=None):
        self.ready = False

        if self.redirect_view != redirect_view:
            self.redirect_view = redirect_view

        if need_output_width is not None and self.output_width != need_output_width:
            self.output_width = need_output_width
            self.ignore_replies = 1
            statement = 'Set Printing Width {:d}. {}'\
                        .format(self.output_width, statement)

        output_view = self.redirect_view or self.coqtop_view
        sentence_no = self.sentence_no
        def show_progress():
            if not self.ready and self.sentence_no == sentence_no:
                output_view.run_command('coq_output', {'output': 'Running...'})
        sublime.set_timeout_async(show_progress, 100)

        self.expect_success = expect_success
        self.retry_on_empty = retry_on_empty
        self.coqtop.send(statement)

    def receive(self, output, prompt):
        self.ready = True
        self.sentence_no += 1

        output = output.strip()
        if not output:
            if self.ignore_replies > 0:
                self.ignore_replies -= 1
                return

            if self.retry_on_empty:
                self.send(self.retry_on_empty, redirect_view=self.redirect_view)
            else:
                output = "Done."

        # Clean up some useless messages
        output = re.sub(r'''
            \AToplevel\ input,.+\n
        |   \ \(ID\ \d+\)
        |   \(dependent\ evars:\ \(printing\ disabled\)\ \)<commit_msg>Removed "Done." output<commit_after>import re
import sublime, sublime_plugin
from .coqtop import Coqtop, find_coqtop

class CoqtopManager:
    coqtop_view = None

    def __init__(self):
        self.coqtop = None
        self.ready = False
        self.output_width = 78
        self.sentence_no = 0
        self.last_output = ""
        self.expect_success = False
        self.retry_on_empty = None
        self.ignore_replies = 0
        self.theorem = None

        self.redirect_view = None
        self.editor_view = None
        self.autorun_point = None
        self.autorun_forward = True
        self.autorun_enabled = False

        self.debug = False
        self.position = 0
        self.stack = []
        self.scope = 'toplevel'

        self.settings = sublime.load_settings('Sublime-Coq.sublime-settings')
        self.settings.add_on_change('coq_debug', self._update_debug)
        self._update_debug()

    def _update_debug(self):
        flags = self.settings.get('coq_debug')

        self.debug = 'manager' in flags
        if self.coqtop is not None:
            self.coqtop.debug = 'coqtop' in flags

    def start(self):
        path = self.settings.get('coqtop_path') or find_coqtop()
        if path is None:
            sublime.error_message('Cannot find Coqtop.')
            return False        
        pwd = sublime.Window.folders(sublime.active_window())[0]
        args = ["-R", pwd, ""]
        args = self.settings.get('coqtop_args') + args
        debug = 'coqtop' in self.settings.get('coq_debug')

        self.coqtop = Coqtop(self, path, args, debug)
        return True

    def stop(self):
        if self.coqtop is not None:
            self.ready = False
            self.coqtop.kill()

    def send(self, statement, expect_success=False, retry_on_empty=None,
             redirect_view=None, need_output_width=None):
        self.ready = False

        if self.redirect_view != redirect_view:
            self.redirect_view = redirect_view

        if need_output_width is not None and self.output_width != need_output_width:
            self.output_width = need_output_width
            self.ignore_replies = 1
            statement = 'Set Printing Width {:d}. {}'\
                        .format(self.output_width, statement)

        output_view = self.redirect_view or self.coqtop_view
        sentence_no = self.sentence_no
        def show_progress():
            if not self.ready and self.sentence_no == sentence_no:
                output_view.run_command('coq_output', {'output': 'Running...'})
        sublime.set_timeout_async(show_progress, 100)

        self.expect_success = expect_success
        self.retry_on_empty = retry_on_empty
        self.coqtop.send(statement)

    def receive(self, output, prompt):
        self.ready = True
        self.sentence_no += 1

        output = output.strip()
        if not output:
            if self.ignore_replies > 0:
                self.ignore_replies -= 1
                return

            if self.retry_on_empty:
                self.send(self.retry_on_empty, redirect_view=self.redirect_view)
            else:
                output = self.last_output

        # Clean up some useless messages
        output = re.sub(r'''
            \AToplevel\ input,.+\n
        |   \ \(ID\ \d+\)
        |   \(dependent\ evars:\ \(printing\ disabled\)\ \)
{'fraction_non_alphanumeric': 0.09683676514473291, 'fraction_numerical': 0.003879438973440764, 'mean_word_length': 1.965929203539823, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, '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': '53550', 'n_tokens_mistral': 2072, 'n_tokens_neox': 2000, 'n_words': 430}