Example #1
0
 def flush(self):
     self.finish_wrapping()
     term.home_cursor()
     buf = self.textBuf
     for i in range(len(buf)):
         for j in range(len(buf[i])):
             c = buf[i][j]
             write_char(c.char, c.fg_color, c.bg_color, c.text_style)
         if i < len(buf) - 1:
             write_char('\n', c.fg_color, c.bg_color, c.text_style)
         else:
             term.fill_to_eol_with_bg_color()
     term.flush()
Example #2
0
 def first_draw(self):
     env = self.env
     for i in range(env.hdr.screen_height_units - 1):
         write_char('\n', env.fg_color, env.bg_color, env.text_style)
     term.fill_to_eol_with_bg_color()
     term.home_cursor()
Example #3
0
    def get_line_of_input(self, prompt='', prefilled=''):
        env = self.env

        for c in prompt:
            self.write_unwrapped(
                [ScreenChar(c, env.fg_color, env.bg_color, env.text_style)])
        self.flush()
        self.update_seen_lines()

        row, col = env.cursor[env.current_window]

        term.home_cursor()
        term.cursor_down(row)
        term.cursor_right(col)
        term.set_color(env.fg_color, env.bg_color)
        if line_empty(self.textBuf[row][col:]):
            term.fill_to_eol_with_bg_color()
        term.show_cursor()

        col = max(
            0, col - len(prefilled)
        )  # TODO: prefilled is a seldom-used old and crusty feature, but make unicode safe
        env.cursor[env.current_window] = row, col

        class CursorLine(object):
            def __init__(self, cursor_start, chars):
                self.cursor = cursor_start
                self.chars = chars

            def backspace(self):
                if self.cursor == 0:
                    return
                self.left()
                self.delete_char()

            def delete_char(self):
                del self.chars[self.cursor:self.cursor + 1]
                self.refresh_rest_of_line(is_delete=True)

            def refresh_rest_of_line(self, is_delete=False):
                rest = self.chars[self.cursor:]
                term.puts(''.join(rest))
                to_back_up = len(rest)
                if is_delete:
                    term.puts(' ')
                    to_back_up += 1
                if to_back_up:
                    term.cursor_left(to_back_up)

            def left(self):
                if self.cursor > 0:
                    self.cursor -= 1
                    term.cursor_left()

            def right(self):
                if self.cursor < len(self.chars):
                    self.cursor += 1
                    term.cursor_right()

            def home(self):
                while self.cursor > 0:
                    self.left()

            def end(self):
                while self.cursor != len(self.chars):
                    self.right()

            def kill_left(self):
                while self.chars[:self.cursor]:
                    self.backspace()

            def kill_right(self):
                while self.chars[self.cursor:]:
                    self.delete_char()

            def insert(self, c):
                self.chars.insert(self.cursor, c)
                term.puts(c)
                self.cursor += 1
                self.refresh_rest_of_line()

        cursor_start = len(prefilled)
        cursor_line = CursorLine(cursor_start, [c for c in prefilled])

        max_input_len = 120  # 120 char limit seen on gargoyle
        c = term.getch_or_esc_seq()
        while c != '\n' and c != '\r':
            if c == '\b' or c == '\x7f':
                cursor_line.backspace()

            # normal edit keys and a bit of readline flavor

            # left arrow or C-b
            elif c == '\x1b[D' or c == '\x02':
                cursor_line.left()

            # right arrow or C-f
            elif c == '\x1b[C' or c == '\x06':
                cursor_line.right()

            # home or C-a
            elif c == '\x1b[H' or c == '\x01':
                cursor_line.home()

            # end or C-e
            elif c == '\x1b[F' or c == '\x05':
                cursor_line.end()

            # delete or C-d
            elif c == '\x1b[3~' or c == '\x04':
                cursor_line.delete_char()

            # C-u, kill left of cursor
            elif c == '\x15':
                cursor_line.kill_left()

            # C-u, kill right of cursor
            elif c == '\x0b':
                cursor_line.kill_right()

            else:
                if is_valid_inline_char(c) and len(
                        cursor_line.chars) < max_input_len:
                    if c == '\t':
                        if len(cursor_line.chars) + 4 <= max_input_len:
                            for i in range(4):
                                cursor_line.insert(' ')
                    else:
                        cursor_line.insert(c)

            c = term.getch_or_esc_seq()

        term.hide_cursor()
        term.flush()
        for c in cursor_line.chars:
            self.write_unwrapped(
                [ScreenChar(c, env.fg_color, env.bg_color, env.text_style)])
        self.new_line_via_spaces(env.fg_color, env.bg_color, env.text_style)
        term.home_cursor()
        return ''.join(cursor_line.chars)
Example #4
0
 def overwrite_line_with(self, new_line):
     term.clear_line()
     for c in new_line:
         write_char(c.char, c.fg_color, c.bg_color, c.text_style)
     term.fill_to_eol_with_bg_color()