<commit_before>#!/usr/bin/env python
# coding=utf-8

import codecs
import locale
import os
import signal
import sys
import time

import click

if codecs.lookup(locale.getpreferredencoding()).name == 'ascii':
    os.environ['LANG'] = 'en_US.utf-8'

from dots.interpreter import AsciiDotsInterpreter
from dots.callbacks import IOCallbacksStorage

from dots import terminalsize

try:
    import curses
except ImportError:
    curses = 'failed to import curses; running in compatibility mode'
    print(curses)
    compat_debug_default = True
else:
    compat_debug_default = False

terminal_lines = terminalsize.get_terminal_size()[1]
default_debug_lines = int(terminal_lines * 2 / 3)

interpreter = None

debug_ = True
autostep_debug_ = False


class DefaultIOCallbacks(IOCallbacksStorage):
    def __init__(self, ticks, silent, debug, compat_debug, debug_lines, autostep_debug, output_limit):
        super().__init__()

        # if it is zero or false, we don't want to stop
        self.ticks_left = ticks if ticks else float('inf')
        self.outputs_left = output_limit if output_limit else float('inf')

        self.silent = silent
        self.debug = debug
        self.compat_debug = compat_debug
        self.debug_lines = debug_lines
        self.autostep_debug = autostep_debug

        self.compat_logging_buffer = ''
        self.compat_logging_buffer_lines = terminal_lines - debug_lines - 1

        if self.debug and not self.compat_debug:
            self.logging_loc = 0
            self.logging_x = 1

            self.stdscr = curses.initscr()

            curses.start_color()

            curses.init_pair(1, curses.COLOR_RED, curses.COLOR_BLACK)
            curses.init_pair(2, curses.COLOR_GREEN, curses.COLOR_BLACK)
            curses.init_pair(3, curses.COLOR_YELLOW, curses.COLOR_BLACK)
            curses.init_pair(4, curses.COLOR_BLUE, curses.COLOR_BLACK)

            curses.noecho()

            curses.curs_set(False)

            self.win_program = curses.newwin(self.debug_lines, curses.COLS - 1, 0, 0)

            self.logging_pad = curses.newpad(1000, curses.COLS - 1)

            def signal_handler(signal, frame):
                self.on_finish()
                sys.exit(0)

            signal.signal(signal.SIGINT, signal_handler)

            self.first_tick = True
        else:
            self.first_tick = False

    def get_input(self):
        if not self.debug or self.compat_debug:
            if not sys.stdin.isatty():
                return input('')
            else:
                return input('?: ')
        else:
            return self.curses_input(self.stdscr, curses.LINES - 3, 2, '?: ')

    def curses_input(self, stdscr, r, c, prompt_string):
        curses.echo()
        stdscr.addstr(r, c, str(prompt_string), curses.A_REVERSE)
        stdscr.addstr(r + 1, c, " " * (curses.COLS - 1))
        stdscr.refresh()
        input_val = ""

        while len(input_val) <= 0:
            input_val = stdscr.getstr(r + 1, c, 20)

        return input_val

    def on_output(self, value):
        self.outputs_left -= 1

        # maximum output reached, we quit the prog
        if self.outputs_left == 0:
            self.on_finish()
            return

        # no printing mode
        if self.silent:
            return

        if not self.debug:
            print(value, end='', flush=True)
        elif self.compat_debug:
            self.compat_logging_buffer += value
            self.compat_logging_buffer = '\n'.join(
                self.compat_logging_buffer.split('\n')[:self.compat_logging_buffer_lines])
        else:
            self.logging_pad.addstr(self.logging_loc, self.logging_x, str(value))

            self.logging_pad.refresh(self.logging_loc - min(self.logging_loc, curses.LINES - self.debug_lines - 1), 0,
                                     self.debug_lines, 0, curses.LINES - 1, curses.COLS - 1)

            # FIXME: This should count the number of newlines instead
            if str(value).endswith('\n'):
                self.logging_loc += 1
                self.logging_x = 1
            else:
                self.logging_x += len(value)

    def on_finish(self):
        global interpreter

        if self.debug and not self.compat_debug:
            curses.nocbreak()<commit_msg>comments part1<commit_after>#!/usr/bin/env python
# coding=utf-8

import codecs
import locale
import os
import signal
import sys
import time

import click

if codecs.lookup(locale.getpreferredencoding()).name == 'ascii':
    os.environ['LANG'] = 'en_US.utf-8'

from dots.interpreter import AsciiDotsInterpreter
from dots.callbacks import IOCallbacksStorage

from dots import terminalsize

try:
    import curses
except ImportError:
    curses = 'failed to import curses; running in compatibility mode'
    print(curses)
    compat_debug_default = True
else:
    compat_debug_default = False

terminal_lines = terminalsize.get_terminal_size()[1]
default_debug_lines = int(terminal_lines * 2 / 3)

interpreter = None

debug_ = True
autostep_debug_ = False


class DefaultIOCallbacks(IOCallbacksStorage):
    """The default class to manage the input and output of a dots program."""

    def __init__(self, ticks, silent, debug, compat_debug, debug_lines, autostep_debug, output_limit):
        super().__init__()

        # if it is zero or false, we don't want to stop
        self.ticks_left = ticks if ticks else float('inf')
        self.outputs_left = output_limit if output_limit else float('inf')

        self.silent = silent
        self.debug = debug
        self.compat_debug = compat_debug
        self.debug_lines = debug_lines
        self.autostep_debug = autostep_debug

        self.compat_logging_buffer = ''
        self.compat_logging_buffer_lines = terminal_lines - debug_lines - 1

        if self.debug and not self.compat_debug:
            self.logging_loc = 0
            self.logging_x = 1

            self.stdscr = curses.initscr()

            curses.start_color()

            curses.init_pair(1, curses.COLOR_RED, curses.COLOR_BLACK)
            curses.init_pair(2, curses.COLOR_GREEN, curses.COLOR_BLACK)
            curses.init_pair(3, curses.COLOR_YELLOW, curses.COLOR_BLACK)
            curses.init_pair(4, curses.COLOR_BLUE, curses.COLOR_BLACK)

            curses.noecho()

            # hides the cursor
            curses.curs_set(False)

            # defining the two main parts of the screen: the view of the program
            self.win_program = curses.newwin(self.debug_lines, curses.COLS - 1, 0, 0)
            # and pad for the output of the prog
            self.logging_pad = curses.newpad(1000, curses.COLS - 1)

            def signal_handler(signal, frame):
                self.on_finish()
                sys.exit(0)

            signal.signal(signal.SIGINT, signal_handler)

            self.first_tick = True
        else:
            self.first_tick = False

    def get_input(self):
        """Get an input from the user."""
        if not self.debug or self.compat_debug:
            if not sys.stdin.isatty():
                return input('')
            else:
                return input('?: ')
        else:
            return self.curses_input(self.stdscr, curses.LINES - 3, 2, '?: ')

    def curses_input(self, stdscr, r, c, prompt_string):
        """
        Get an input string with curses.
        """
        curses.echo()
        stdscr.addstr(r, c, str(prompt_string), curses.A_REVERSE)
        stdscr.addstr(r + 1, c, " " * (curses.COLS - 1))
        stdscr.refresh()
        input_val = ""

        while len(input_val) <= 0:
            input_val = stdscr.getstr(r + 1, c, 20)

        return input_val

    def on_output(self, value):
        self.outputs_left -= 1

        # maximum output reached, we quit the prog
        if self.outputs_left == 0:
            self.on_finish()
            return

        # no printing mode
        if self.silent:
            return

        if not self.debug:
            print(value, end='', flush=True)

        elif self.compat_debug:
            # we add the ouput to the buffer
            self.compat_logging_buffer += value
            # and we keep the maximum number of line to compat_logging_buffer_lines
            self.compat_logging_buffer = '\n'.join(
                self.compat_logging_buffer.split('\n')[:self.compat_logging_buffer_lines])

        else:
            # add the output string to the pad
            self.logging_pad.addstr(self.logging_loc, self.logging_x, str(value))

            self.logging_pad.refresh(self.logging_loc - min(self.logging_loc, curses.LINES - self.debug_lines - 1), 0,
                                     self.debug_lines, 0, curses.LINES - 1, curses.COLS - 1)

            # FIXME: This should count the number of newlines instead
            if str(value).endswith('\n'):
                self.logging_loc += 1
                self.logging_x = 1
            else:
                self.logging_x += len(value)

    def on_finish(self):
        global interpreter

        if self.debug and not self.compat_debug:
            curses.nocbreak()
{'fraction_non_alphanumeric': 0.0918782283767447, 'fraction_numerical': 0.008462468403121223, 'mean_word_length': 2.1185743660041125, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '702781', 'n_tokens_mistral': 2859, 'n_tokens_neox': 2712, 'n_words': 659}