Esempio n. 1
0
    def _execute_action(
        self, action, context, additional_locals={}, compiled_action=None
    ):
        mark_to_use = "`"
        with vim_helper.save_mark(mark_to_use):
            vim_helper.set_mark_from_pos(mark_to_use, vim_helper.get_cursor_pos())

            cursor_line_before = vim_helper.buf.line_till_cursor

            locals = {"context": context}

            locals.update(additional_locals)

            snip = self._eval_code(action, locals, compiled_action)

            if snip.cursor.is_set():
                vim_helper.buf.cursor = Position(
                    snip.cursor._cursor[0], snip.cursor._cursor[1]
                )
            else:
                new_mark_pos = vim_helper.get_mark_pos(mark_to_use)

                cursor_invalid = False

                if vim_helper._is_pos_zero(new_mark_pos):
                    cursor_invalid = True
                else:
                    vim_helper.set_cursor_from_pos(new_mark_pos)
                    if cursor_line_before != vim_helper.buf.line_till_cursor:
                        cursor_invalid = True

                if cursor_invalid:
                    raise PebkacError(
                        "line under the cursor was modified, but "
                        + '"snip.cursor" variable is not set; either set set '
                        + '"snip.cursor" to new cursor position, or do not '
                        + "modify cursor line"
                    )

        return snip
Esempio n. 2
0
    def _do_edit(self, cmd, ctab=None):
        if self._done:
            # do as what parent class do
            TabStop._do_edit(self, cmd, ctab)
            return

        ctype, line, col, cmd_text = cmd

        cursor = vim_helper.get_cursor_pos()
        [buf_num, cursor_line] = map(int, cursor[0:2])

        # trying to get what user inputted in current buffer
        if ctype == "I":
            self._input_chars.append(cmd_text)
        elif ctype == "D":
            line_text = vim_helper.buf[cursor_line - 1]
            self._input_chars = list(line_text[self._start.col:col])

        inputted_text = "".join(self._input_chars)

        if not self._input_chars:
            return

        # if there are more than 9 selection candidates,
        # may need to wait for 2 inputs to determine selection number
        is_all_digits = True
        has_selection_terminator = False

        # input string sub string of pure digits
        inputted_text_for_num = inputted_text
        for [i, s] in enumerate(self._input_chars):
            if s == " ":  # treat space as a terminator for selection
                has_selection_terminator = True
                inputted_text_for_num = inputted_text[0:i]
            elif not s.isdigit():
                is_all_digits = False

        should_continue_input = False
        if is_all_digits or has_selection_terminator:
            index_strs = [
                str(index)
                for index in list(range(1,
                                        len(self._choice_list) + 1))
            ]
            matched_index_strs = list(
                filter(lambda s: s.startswith(inputted_text_for_num),
                       index_strs))
            remained_choice_list = []
            if len(matched_index_strs) == 0:
                remained_choice_list = []
            elif has_selection_terminator:
                if inputted_text_for_num:
                    num = int(inputted_text_for_num)
                    remained_choice_list = list(self._choice_list)[num - 1:num]
            elif len(matched_index_strs) == 1:
                num = int(inputted_text_for_num)
                remained_choice_list = list(self._choice_list)[num - 1:num]
            else:
                should_continue_input = True
        else:
            remained_choice_list = []

        if should_continue_input:
            # will wait for further input
            return

        buf = vim_helper.buf
        if len(remained_choice_list) == 0:
            # no matched choice, should quit selection and go on with inputted text
            overwrite_text = inputted_text_for_num
            self._done = True
        elif len(remained_choice_list) == 1:
            # only one match
            matched_choice = remained_choice_list[0]
            overwrite_text = matched_choice
            self._done = True

        if overwrite_text is not None:
            old_end_col = self._end.col

            # change _end.col, thus `overwrite` won't alter texts after this tabstop
            displayed_text_end_col = self._start.col + len(inputted_text)
            self._end.col = displayed_text_end_col
            self.overwrite(buf, overwrite_text)

            # notify all tabstops those in the same line and after this to adjust their positions
            pivot = Position(line, old_end_col)
            diff_col = displayed_text_end_col - old_end_col
            self._parent._child_has_moved(self._parent.children.index(self),
                                          pivot, Position(0, diff_col))

            vim_helper.set_cursor_from_pos(
                [buf_num, cursor_line, self._end.col + 1])