Example #1
0
    def update(self):
        line, col = vim_cursor()
        line -= 1
        abs_pos = Position(line,col)
        if self._abs_pos:
            self._moved = abs_pos - self._abs_pos
        self._abs_pos = abs_pos

        # Update buffer infos
        cols = len(as_unicode(vim.current.buffer[line]))
        if self._cols:
            self._dcols = cols - self._cols
        self._cols = cols

        lines = len(vim.current.buffer)
        if self._lines:
            self._dlines = lines - self._lines
        self._lines = lines

        # Check if the buffer has changed in any ways
        self._text_changed = False
        # does it have more lines?
        if self._dlines:
            self._text_changed = True
        # did we stay in the same line and it has more columns now?
        elif not self.moved.line and self._dcols:
            self._text_changed = True
        # If the length didn't change but we moved a column, check if
        # the char under the cursor has changed (might be one char tab).
        elif self.moved.col == 1:
            self._text_changed = self._cline != as_unicode(vim.current.buffer[line])
        self._lline = self._cline
        self._cline = as_unicode(vim.current.buffer[line])
Example #2
0
    def cursor_moved(self):
        self._vstate.update()

        if not self._vstate.buf_changed and not self._expect_move_wo_change:
            self._check_if_still_inside_snippet()

        if not self._ctab:
            return

        if self._vstate.buf_changed and self._ctab:
            # Detect a carriage return
            if self._vstate.moved.col <= 0 and self._vstate.moved.line == 1:
                # Multiple things might have happened: either the user entered
                # a newline character or pasted some text which means we have
                # to copy everything he entered on the last line and keep the
                # indent vim chose for this line.
                lline = as_unicode(vim.current.buffer[self._vstate.ppos.line])

                # Another thing that might have happened is that a word
                # wrapped, in this case the last line is shortened and we must
                # delete what Vim deleted there
                line_was_shortened = len(self._vstate.last_line) > len(lline)

                # Another thing that might have happened is that vim has
                # adjusted the indent of the last line and therefore the line
                # effectively got longer. This means a newline was entered and
                # we quite definitively do not want the indent that vim added
                line_was_lengthened = len(lline) > len(self._vstate.last_line)

                user_didnt_enter_newline = len(lline) != self._vstate.ppos.col
                cline = as_unicode(vim.current.buffer[self._vstate.pos.line])
                if line_was_lengthened:
                    this_entered = vim.current.line[:self._vstate.pos.col]
                    self._chars_entered('\n' + cline + this_entered, 1)
                if line_was_shortened and user_didnt_enter_newline:
                    nchars_deleted_in_lline = self._vstate.ppos.col - len(lline)
                    self._backspace(nchars_deleted_in_lline)
                    nchars_wrapped_from_lline_after_cursor = \
                            len(self._vstate.last_line) - self._vstate.ppos.col
                    self._chars_entered('\n' + cline
                        [:len(cline)-nchars_wrapped_from_lline_after_cursor], 1)
                else:
                    pentered = lline[self._vstate.ppos.col:]
                    this_entered = vim.current.line[:self._vstate.pos.col]

                    self._chars_entered(pentered + '\n' + this_entered)
            elif self._vstate.moved.line == 0 and self._vstate.moved.col<0:
                # Some deleting was going on
                self._backspace(-self._vstate.moved.col)
            elif self._vstate.moved.line < 0:
                # Backspace over line end
                self._backspace(1)
            else:
                line = as_unicode(vim.current.line)

                chars = line[self._vstate.pos.col - self._vstate.moved.col:
                             self._vstate.pos.col]
                self._chars_entered(chars)

        self._expect_move_wo_change = False
Example #3
0
 def __init__(self, trigger, value, descr, options, globals):
     self._t = as_unicode(trigger)
     self._v = as_unicode(value)
     self._d = as_unicode(descr)
     self._opts = options
     self._matched = ""
     self._last_re = None
     self._globals = globals
Example #4
0
    def select_span(self, r):
        self._unmap_select_mode_mapping()

        delta = r.end - r.start
        lineno, col = r.start.line, r.start.col

        set_vim_cursor(lineno + 1, col)

        if delta.line == delta.col == 0:
            if col == 0 or vim.eval("mode()") != 'i' and \
                    col < len(as_unicode(vim.current.buffer[lineno])):
                feedkeys(r"\<Esc>i")
            else:
                feedkeys(r"\<Esc>a")
        else:
            # If a tabstop immediately starts with a newline, the selection
            # must start after the last character in the current line. But if
            # we are in insert mode and <Esc> out of it, we cannot go past the
            # last character with move_one_right and therefore cannot
            # visual-select this newline. We have to hack around this by adding
            # an extra space which we can select.  Note that this problem could
            # be circumvent by selecting the tab backwards (that is starting
            # at the end); one would not need to modify the line for this.
            if col >= len(as_unicode(vim.current.buffer[lineno])):
                vim.current.buffer[lineno] += " "

            if delta.line:
                move_lines = "%ij" % delta.line
            else:
                move_lines = ""
            # Depending on the current mode and position, we
            # might need to move escape out of the mode and this
            # will move our cursor one left
            if col != 0 and vim.eval("mode()") == 'i':
                move_one_right = "l"
            else:
                move_one_right = ""

            # After moving to the correct line, we go back to column 0
            # and select right from there. Note that the we have to select
            # one column less since vim's visual selection is including the
            # ending while Python slicing is excluding the ending.
            if r.end.col == 0 and not len(as_unicode(vim.current.buffer[r.end.line])):
                # Selecting should end on an empty line -> Select the previous
                # line till its end
                do_select = "k$"
            elif r.end.col > 1:
                do_select = "0%il" % (r.end.col-1)
            else:
                do_select = "0"

            move_cmd = LangMapTranslator().translate(
                r"\<Esc>%sv%s%s\<c-g>" % (move_one_right, move_lines, do_select)
            )

            feedkeys(move_cmd)
Example #5
0
    def _get_before_after(self):
        """ Returns the text before and after the cursor as a
        tuple.
        """
        lineno, col = vim.current.window.cursor  # Note: we want byte position here

        line = vim.current.line

        # Get the word to the left of the current edit position
        before, after = as_unicode(line[:col]), as_unicode(line[col:])

        return before, after
Example #6
0
    def reset(self, test_error=False):
        self._test_error = test_error
        self._snippets = {}
        self._visual_content = as_unicode("")

        while len(self._csnippets):
            self._current_snippet_is_done()

        self._reinit()
Example #7
0
    def _ask_snippets(self, snippets):
        """ Given a list of snippets, ask the user which one they
        want to use, and return it.
        """
        # make a python list
        display = [ "%i: %s" % (i+1,s.description) for i,s in enumerate(snippets)]

        try:
            # let vim_string format it as a vim list
            rv = vim.eval(make_suitable_for_vim(as_unicode("inputlist(%s)") % vim_string(display)))
            if rv is None or rv == '0':
                return None
            rv = int(rv)
            if rv > len(snippets):
                rv = len(snippets)
            return snippets[rv-1]
        except vim.error as e:
            if str(e) == 'invalid expression':
                return None
            raise
Example #8
0
 def _vim_line_with_eol(ln):
     return as_unicode(vim.current.buffer[ln] + '\n')