Ejemplo n.º 1
0
    def test_render_scroll_pgup_keystroke(self):
        """
        Test we render properly when stuck to the bottom
        """
        os.environ['TERM'] = 'dumb'
        app = Logria(None, False, False)

        # Fake window size: 10 x 100
        app.height = 10
        app.width = 100

        # Set fake previous render
        app.last_row = app.height - 3  # simulate the last row we can render to
        app.current_end = 40  # Simulate the last message rendered

        # Set fake messages
        app.messages = [str(x) for x in range(100)]

        # Set positional booleans
        app.manually_controlled_line = False
        app.stick_to_top = True
        app.stick_to_bottom = True

        # Scroll action
        resolve_keypress(app, 'KEY_PPAGE')

        start, end = determine_position(app, app.messages)
        self.assertEqual(start, 25)
        self.assertEqual(end, 33)
        app.stop()
Ejemplo n.º 2
0
    def main(self, stdscr) -> None:
        """
        Main program loop, handles user control and logical flow
        """
        curses.use_default_colors()
        self.stdscr = stdscr
        stdscr.keypad(1)
        height, width = stdscr.getmaxyx()  # Get screen size

        # Save these values
        self.height = height
        self.width = width - 1

        # Setup Output window
        output_start_row = 0  # Leave space for top border
        output_height = height - 3  # Leave space for command line
        self.last_row = output_height - output_start_row  # The last row we can write to
        # Create the window with these sizes
        self.outwin = curses.newwin(output_height, width - 1, output_start_row,
                                    0)
        self.outwin.refresh()

        # Setup Command line
        self.build_command_line()

        # Update the command line status
        reset_regex_status(self)

        # Disable cursor:
        curses.curs_set(0)

        # If the streams do not exist, create them
        if not self.streams:
            setup_streams(self)

        # Start the main app loop
        while True:
            # Update messages from the input stream's queues, track time
            t_0 = time.perf_counter()
            new_messages: int = 0
            for stream in self.streams:
                while not stream.stderr.empty():
                    message = stream.stderr.get()
                    self.stderr_messages.append(message)
                    new_messages += 1

                while not stream.stdout.empty():
                    message = stream.stdout.get()
                    self.stdout_messages.append(message)
                    new_messages += 1
            # Prevent this loop from taking up 100% of the CPU dedicated to the main thread by delaying loops
            t_1 = time.perf_counter() - t_0
            # Don't delay if the queue processing took too long
            time.sleep(max(0, self.poll_rate - t_1))

            # Calculate new poll rate
            if self.smart_poll_rate:
                self.handle_smart_poll_rate(t_1, new_messages)

            # Since this is the first run, set the visible stream to the one that has the most messages
            if self.first_run and (len(self.stdout_messages) > 0
                                   or len(self.stderr_messages) > 0):
                self.first_run = False
                # Default to stdout unless stderr has more messages
                if len(self.stdout_messages) >= len(self.stderr_messages):
                    self.messages = self.stdout_messages
                else:
                    self.messages = self.stderr_messages

            try:
                # Get keypress, raise curses.error if nothing detected
                keypress = self.command_line.getkey()
                resolve_keypress(self, keypress)
            except curses.error:
                if self.exit_val == -1:
                    return
                # If we have an active filter/parser, process it/them
                if self.parser:
                    # This may block if there are a lot of messages
                    process_parser(self)
                if self.func_handle:
                    # This may block if there are a lot of messages
                    process_matches(self)
                # Always try to render
                self.render_text_in_output()