예제 #1
0
    def read_input(self):
        # Read the character
        c = self.stdscr.getch()

        # Either ESC or ALT+<some key>
        if c == util.KEY_ESC:
            n = self.stdscr.getch()
            if n == -1:
                # Escape key
                return
            c = [c, n]

        # We remove the tab count if the key wasn't a tab
        if c != util.KEY_TAB:
            self.tab_count = 0

        # We clear the input string and send it to the command parser on ENTER
        if c in [curses.KEY_ENTER, util.KEY_ENTER2]:
            if self.input:
                if self.input.endswith('\\'):
                    self.input = self.input[:-1]
                    self.input_cursor -= 1
                self.add_line('{!yellow,black,bold!}>>>{!input!} %s' % self.input)
                self.do_command(self.input)
                if len(self.input_history) == INPUT_HISTORY_SIZE:
                    # Remove the oldest input history if the max history size
                    # is reached.
                    del self.input_history[0]
                if self.console_config['cmdline']['ignore_duplicate_lines']:
                    if len(self.input_history) > 0:
                        if self.input_history[-1] != self.input:
                            self.input_history.append(self.input)
                    else:
                        self.input_history.append(self.input)
                else:
                    self.input_history.append(self.input)
                self.input_history_index = len(self.input_history)
                self.input = ''
                self.input_incomplete = ''
                self.input_cursor = 0
                self.stdscr.refresh()

        # Run the tab completer function
        elif c == util.KEY_TAB:
            # Keep track of tab hit count to know when it's double-hit
            self.tab_count += 1

            if self.tab_completer:
                # We only call the tab completer function if we're at the end of
                # the input string on the cursor is on a space
                if (
                    self.input_cursor == len(self.input)
                    or self.input[self.input_cursor] == ' '
                ):
                    self.input, self.input_cursor = self.tab_completer(
                        self.input, self.input_cursor, self.tab_count
                    )

        # We use the UP and DOWN keys to cycle through input history
        elif c == curses.KEY_UP:
            if self.input_history_index - 1 >= 0:
                if self.input_history_index == len(self.input_history):
                    # We're moving from non-complete input so save it just incase
                    # we move back down to it.
                    self.input_incomplete = self.input
                # Going back in the history
                self.input_history_index -= 1
                self.input = self.input_history[self.input_history_index]
                self.input_cursor = len(self.input)
        elif c == curses.KEY_DOWN:
            if self.input_history_index + 1 < len(self.input_history):
                # Going forward in the history
                self.input_history_index += 1
                self.input = self.input_history[self.input_history_index]
                self.input_cursor = len(self.input)
            elif self.input_history_index + 1 == len(self.input_history):
                # We're moving back down to an incomplete input
                self.input_history_index += 1
                self.input = self.input_incomplete
                self.input_cursor = len(self.input)

        # Cursor movement
        elif c == curses.KEY_LEFT:
            if self.input_cursor:
                self.input_cursor -= 1
        elif c == curses.KEY_RIGHT:
            if self.input_cursor < len(self.input):
                self.input_cursor += 1
        elif c == curses.KEY_HOME:
            self.input_cursor = 0
        elif c == curses.KEY_END:
            self.input_cursor = len(self.input)

        # Scrolling through buffer
        elif c == curses.KEY_PPAGE:
            self.display_lines_offset += self.rows - 3
            # We substract 3 for the unavailable lines and 1 extra due to len(self.lines)
            if self.display_lines_offset > (len(self.lines) - 4 - self.rows):
                self.display_lines_offset = len(self.lines) - 4 - self.rows

            self.refresh()
        elif c == curses.KEY_NPAGE:
            self.display_lines_offset -= self.rows - 3
            if self.display_lines_offset < 0:
                self.display_lines_offset = 0
            self.refresh()

        # Delete a character in the input string based on cursor position
        elif c in [curses.KEY_BACKSPACE, util.KEY_BACKSPACE2]:
            if self.input and self.input_cursor > 0:
                self.input = (
                    self.input[: self.input_cursor - 1]
                    + self.input[self.input_cursor :]
                )
                self.input_cursor -= 1
        # Delete a word when alt+backspace is pressed
        elif c == [util.KEY_ESC, util.KEY_BACKSPACE2] or c == [
            util.KEY_ESC,
            curses.KEY_BACKSPACE,
        ]:
            self.input, self.input_cursor = delete_alt_backspace(
                self.input, self.input_cursor
            )
        elif c == curses.KEY_DC:
            if self.input and self.input_cursor < len(self.input):
                self.input = (
                    self.input[: self.input_cursor]
                    + self.input[self.input_cursor + 1 :]
                )

        # A key to add to the input string
        else:
            if c > 31 and c < 256:
                # Emulate getwch
                stroke = chr(c)
                uchar = '' if PY2 else stroke
                while not uchar:
                    try:
                        uchar = stroke.decode(self.encoding)
                    except UnicodeDecodeError:
                        c = self.stdscr.getch()
                        stroke += chr(c)

                if uchar:
                    if self.input_cursor == len(self.input):
                        self.input += uchar
                    else:
                        # Insert into string
                        self.input = (
                            self.input[: self.input_cursor]
                            + uchar
                            + self.input[self.input_cursor :]
                        )

                    # Move the cursor forward
                    self.input_cursor += 1

        self.refresh()
예제 #2
0
    def handle_read(self, c):
        """
        Return False when key was swallowed, i.e. we recognised
        the key and no further action by other components should
        be performed.
        """
        if self.activate_input:
            if not self.input_active:
                if c in [curses.KEY_LEFT, curses.KEY_RIGHT, curses.KEY_HOME,
                         curses.KEY_END, curses.KEY_ENTER, util.KEY_ENTER2]:
                    self.input_active = True
                    return util.ReadState.READ
                else:
                    return util.ReadState.IGNORED
            elif c == util.KEY_ESC:
                self.input_active = False
                return util.ReadState.READ

        if c == util.KEY_TAB and self.complete:
            # Keep track of tab hit count to know when it's double-hit
            self.tab_count += 1
            if self.tab_count > 1:
                second_hit = True
                self.tab_count = 0
            else:
                second_hit = False

            # We only call the tab completer function if we're at the end of
            # the input string on the cursor is on a space
            if self.cursor == len(self.value) or self.value[self.cursor] == ' ':
                if self.opts:
                    prev = self.opt_off
                    self.opt_off += self.width - 3
                    # now find previous double space, best guess at a split point
                    # in future could keep opts unjoined to get this really right
                    self.opt_off = self.opts.rfind('  ', 0, self.opt_off) + 2
                    if second_hit and self.opt_off == prev:  # double tap and we're at the end
                        self.opt_off = 0
                else:
                    opts = self.do_complete(self.value)
                    if len(opts) == 1:  # only one option, just complete it
                        self.value = opts[0]
                        self.cursor = len(opts[0])
                        self.tab_count = 0
                    elif len(opts) > 1:
                        prefix = os.path.commonprefix(opts)
                        if prefix:
                            self.value = prefix
                            self.cursor = len(prefix)

                    if len(opts) > 1 and second_hit:  # display multiple options on second tab hit
                        sp = self.value.rfind(os.sep) + 1
                        self.opts = '  '.join([o[sp:] for o in opts])

        # Cursor movement
        elif c == curses.KEY_LEFT:
            self.cursor = max(0, self.cursor - 1)
        elif c == curses.KEY_RIGHT:
            self.cursor = min(len(self.value), self.cursor + 1)
        elif c == curses.KEY_HOME:
            self.cursor = 0
        elif c == curses.KEY_END:
            self.cursor = len(self.value)

        # Delete a character in the input string based on cursor position
        elif c == curses.KEY_BACKSPACE or c == util.KEY_BACKSPACE2:
            if self.value and self.cursor > 0:
                self.value = self.value[:self.cursor - 1] + self.value[self.cursor:]
                self.cursor -= 1
        elif c == [util.KEY_ESC, util.KEY_BACKSPACE2] or c == [util.KEY_ESC, curses.KEY_BACKSPACE]:
            self.value, self.cursor = delete_alt_backspace(self.value, self.cursor)
        elif c == curses.KEY_DC:
            if self.value and self.cursor < len(self.value):
                self.value = self.value[:self.cursor] + self.value[self.cursor + 1:]
        elif c > 31 and c < 256:
            # Emulate getwch
            stroke = chr(c)
            uchar = ''
            while not uchar:
                try:
                    uchar = stroke.decode(self.parent.encoding)
                except UnicodeDecodeError:
                    c = self.parent.parent.stdscr.getch()
                    stroke += chr(c)
            if uchar:
                if self.cursor == len(self.value):
                    self.value += uchar
                else:
                    # Insert into string
                    self.value = self.value[:self.cursor] + uchar + self.value[self.cursor:]
                # Move the cursor forward
                self.cursor += 1

        else:
            self.opts = None
            self.opt_off = 0
            self.tab_count = 0
            return util.ReadState.IGNORED
        return util.ReadState.READ
예제 #3
0
    def read_input(self):
        # Read the character
        c = self.stdscr.getch()

        # Either ESC or ALT+<some key>
        if c == util.KEY_ESC:
            n = self.stdscr.getch()
            if n == -1:
                # Escape key
                return
            c = [c, n]

        # We remove the tab count if the key wasn't a tab
        if c != util.KEY_TAB:
            self.tab_count = 0

        # We clear the input string and send it to the command parser on ENTER
        if c in [curses.KEY_ENTER, util.KEY_ENTER2]:
            if self.input:
                if self.input.endswith('\\'):
                    self.input = self.input[:-1]
                    self.input_cursor -= 1
                self.add_line('{!yellow,black,bold!}>>>{!input!} %s' % self.input)
                self.do_command(self.input)
                if len(self.input_history) == INPUT_HISTORY_SIZE:
                    # Remove the oldest input history if the max history size
                    # is reached.
                    del self.input_history[0]
                if self.console_config['cmdline']['ignore_duplicate_lines']:
                    if len(self.input_history) > 0:
                        if self.input_history[-1] != self.input:
                            self.input_history.append(self.input)
                    else:
                        self.input_history.append(self.input)
                else:
                    self.input_history.append(self.input)
                self.input_history_index = len(self.input_history)
                self.input = ''
                self.input_incomplete = ''
                self.input_cursor = 0
                self.stdscr.refresh()

        # Run the tab completer function
        elif c == util.KEY_TAB:
            # Keep track of tab hit count to know when it's double-hit
            self.tab_count += 1

            if self.tab_completer:
                # We only call the tab completer function if we're at the end of
                # the input string on the cursor is on a space
                if self.input_cursor == len(self.input) or self.input[self.input_cursor] == ' ':
                    self.input, self.input_cursor = self.tab_completer(self.input, self.input_cursor, self.tab_count)

        # We use the UP and DOWN keys to cycle through input history
        elif c == curses.KEY_UP:
            if self.input_history_index - 1 >= 0:
                if self.input_history_index == len(self.input_history):
                    # We're moving from non-complete input so save it just incase
                    # we move back down to it.
                    self.input_incomplete = self.input
                # Going back in the history
                self.input_history_index -= 1
                self.input = self.input_history[self.input_history_index]
                self.input_cursor = len(self.input)
        elif c == curses.KEY_DOWN:
            if self.input_history_index + 1 < len(self.input_history):
                # Going forward in the history
                self.input_history_index += 1
                self.input = self.input_history[self.input_history_index]
                self.input_cursor = len(self.input)
            elif self.input_history_index + 1 == len(self.input_history):
                # We're moving back down to an incomplete input
                self.input_history_index += 1
                self.input = self.input_incomplete
                self.input_cursor = len(self.input)

        # Cursor movement
        elif c == curses.KEY_LEFT:
            if self.input_cursor:
                self.input_cursor -= 1
        elif c == curses.KEY_RIGHT:
            if self.input_cursor < len(self.input):
                self.input_cursor += 1
        elif c == curses.KEY_HOME:
            self.input_cursor = 0
        elif c == curses.KEY_END:
            self.input_cursor = len(self.input)

        # Scrolling through buffer
        elif c == curses.KEY_PPAGE:
            self.display_lines_offset += self.rows - 3
            # We substract 3 for the unavailable lines and 1 extra due to len(self.lines)
            if self.display_lines_offset > (len(self.lines) - 4 - self.rows):
                self.display_lines_offset = len(self.lines) - 4 - self.rows

            self.refresh()
        elif c == curses.KEY_NPAGE:
            self.display_lines_offset -= self.rows - 3
            if self.display_lines_offset < 0:
                self.display_lines_offset = 0
            self.refresh()

        # Delete a character in the input string based on cursor position
        elif c in [curses.KEY_BACKSPACE, util.KEY_BACKSPACE2]:
            if self.input and self.input_cursor > 0:
                self.input = self.input[:self.input_cursor - 1] + self.input[self.input_cursor:]
                self.input_cursor -= 1
        # Delete a word when alt+backspace is pressed
        elif c == [util.KEY_ESC, util.KEY_BACKSPACE2] or c == [util.KEY_ESC, curses.KEY_BACKSPACE]:
            self.input, self.input_cursor = delete_alt_backspace(self.input, self.input_cursor)
        elif c == curses.KEY_DC:
            if self.input and self.input_cursor < len(self.input):
                self.input = self.input[:self.input_cursor] + self.input[self.input_cursor + 1:]

        # A key to add to the input string
        else:
            if c > 31 and c < 256:
                # Emulate getwch
                stroke = chr(c)
                uchar = ''
                while not uchar:
                    try:
                        uchar = stroke.decode(self.encoding)
                    except UnicodeDecodeError:
                        c = self.stdscr.getch()
                        stroke += chr(c)

                if uchar:
                    if self.input_cursor == len(self.input):
                        self.input += uchar
                    else:
                        # Insert into string
                        self.input = self.input[:self.input_cursor] + uchar + self.input[self.input_cursor:]

                    # Move the cursor forward
                    self.input_cursor += 1

        self.refresh()
예제 #4
0
    def handle_read(self, c):
        """
        Return False when key was swallowed, i.e. we recognised
        the key and no further action by other components should
        be performed.
        """
        if self.activate_input:
            if not self.input_active:
                if c in [
                        curses.KEY_LEFT,
                        curses.KEY_RIGHT,
                        curses.KEY_HOME,
                        curses.KEY_END,
                        curses.KEY_ENTER,
                        util.KEY_ENTER2,
                ]:
                    self.input_active = True
                    return util.ReadState.READ
                else:
                    return util.ReadState.IGNORED
            elif c == util.KEY_ESC:
                self.input_active = False
                return util.ReadState.READ

        if c == util.KEY_TAB and self.complete:
            # Keep track of tab hit count to know when it's double-hit
            self.tab_count += 1
            if self.tab_count > 1:
                second_hit = True
                self.tab_count = 0
            else:
                second_hit = False

            # We only call the tab completer function if we're at the end of
            # the input string on the cursor is on a space
            if self.cursor == len(
                    self.value) or self.value[self.cursor] == ' ':
                if self.opts:
                    prev = self.opt_off
                    self.opt_off += self.width - 3
                    # now find previous double space, best guess at a split point
                    # in future could keep opts unjoined to get this really right
                    self.opt_off = self.opts.rfind('  ', 0, self.opt_off) + 2
                    if (second_hit and self.opt_off
                            == prev):  # double tap and we're at the end
                        self.opt_off = 0
                else:
                    opts = self.do_complete(self.value)
                    if len(opts) == 1:  # only one option, just complete it
                        self.value = opts[0]
                        self.cursor = len(opts[0])
                        self.tab_count = 0
                    elif len(opts) > 1:
                        prefix = os.path.commonprefix(opts)
                        if prefix:
                            self.value = prefix
                            self.cursor = len(prefix)

                    if (len(opts) > 1 and second_hit
                        ):  # display multiple options on second tab hit
                        sp = self.value.rfind(os.sep) + 1
                        self.opts = '  '.join([o[sp:] for o in opts])

        # Cursor movement
        elif c == curses.KEY_LEFT:
            self.cursor = max(0, self.cursor - 1)
        elif c == curses.KEY_RIGHT:
            self.cursor = min(len(self.value), self.cursor + 1)
        elif c == curses.KEY_HOME:
            self.cursor = 0
        elif c == curses.KEY_END:
            self.cursor = len(self.value)

        # Delete a character in the input string based on cursor position
        elif c == curses.KEY_BACKSPACE or c == util.KEY_BACKSPACE2:
            if self.value and self.cursor > 0:
                self.value = self.value[:self.cursor -
                                        1] + self.value[self.cursor:]
                self.cursor -= 1
        elif c == [util.KEY_ESC, util.KEY_BACKSPACE2] or c == [
                util.KEY_ESC,
                curses.KEY_BACKSPACE,
        ]:
            self.value, self.cursor = delete_alt_backspace(
                self.value, self.cursor)
        elif c == curses.KEY_DC:
            if self.value and self.cursor < len(self.value):
                self.value = self.value[:self.
                                        cursor] + self.value[self.cursor + 1:]
        elif c > 31 and c < 256:
            # Emulate getwch
            stroke = chr(c)
            uchar = '' if PY2 else stroke
            while not uchar:
                try:
                    uchar = stroke.decode(self.parent.encoding)
                except UnicodeDecodeError:
                    c = self.parent.parent.stdscr.getch()
                    stroke += chr(c)
            if uchar:
                if self.cursor == len(self.value):
                    self.value += uchar
                else:
                    # Insert into string
                    self.value = (self.value[:self.cursor] + uchar +
                                  self.value[self.cursor:])
                # Move the cursor forward
                self.cursor += 1

        else:
            self.opts = None
            self.opt_off = 0
            self.tab_count = 0
            return util.ReadState.IGNORED
        return util.ReadState.READ