Example #1
0
 def pause_scroll_for_user_input(self):
     # TODO: mark last paused line, set it up so such lines get
     # marked with a plus when still in the buffer, to help your
     # eye track the scroll.
     self.flush()
     if not buf_empty(self.textBuf):
         term_width, term_height = term.get_size()
         if term_width - self.env.hdr.screen_width_units > 0:
             term.home_cursor()
             term.cursor_down(term_height-1)
             # we reserve a one unit right margin for this status char
             term.cursor_right(self.env.hdr.screen_width_units)
             term.write_char_with_color('+', self.env.fg_color, self.env.bg_color)
         term.getch_or_esc_seq()
     self.update_seen_lines()
Example #2
0
 def right(self):
     if self.cursor < len(self.chars):
         self.cursor += 1
         term.cursor_right()
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)