def _get_line_diff(self, line_number, before, after):
     """
     Use precise diffing for tracking changes in single line.
     """
     if before == "":
         for change in self._get_diff(line_number, line_number + 1, [after]):
             yield change
     else:
         for change in diff(before, after):
             yield (change[0], line_number, change[2], change[3])
예제 #2
0
    def _cursor_moved(self):
        """Called whenever the cursor moved."""
        self._should_update_textobjects = False

        self._vstate.remember_position()
        if vim_helper.eval("mode()") not in "in":
            return

        if self._ignore_movements:
            self._ignore_movements = False
            return

        if self._active_snippets:
            cstart = self._active_snippets[0].start.line
            cend = (
                self._active_snippets[0].end.line + self._vstate.diff_in_buffer_length
            )
            ct = vim_helper.buf[cstart : cend + 1]
            lt = self._vstate.remembered_buffer
            pos = vim_helper.buf.cursor

            lt_span = [0, len(lt)]
            ct_span = [0, len(ct)]
            initial_line = cstart

            # Cut down on lines searched for changes. Start from behind and
            # remove all equal lines. Then do the same from the front.
            if lt and ct:
                while (
                    lt[lt_span[1] - 1] == ct[ct_span[1] - 1]
                    and self._vstate.ppos.line < initial_line + lt_span[1] - 1
                    and pos.line < initial_line + ct_span[1] - 1
                    and (lt_span[0] < lt_span[1])
                    and (ct_span[0] < ct_span[1])
                ):
                    ct_span[1] -= 1
                    lt_span[1] -= 1
                while (
                    lt_span[0] < lt_span[1]
                    and ct_span[0] < ct_span[1]
                    and lt[lt_span[0]] == ct[ct_span[0]]
                    and self._vstate.ppos.line >= initial_line
                    and pos.line >= initial_line
                ):
                    ct_span[0] += 1
                    lt_span[0] += 1
                    initial_line += 1
            ct_span[0] = max(0, ct_span[0] - 1)
            lt_span[0] = max(0, lt_span[0] - 1)
            initial_line = max(cstart, initial_line - 1)

            lt = lt[lt_span[0] : lt_span[1]]
            ct = ct[ct_span[0] : ct_span[1]]

            try:
                rv, es = guess_edit(initial_line, lt, ct, self._vstate)
                if not rv:
                    lt = "\n".join(lt)
                    ct = "\n".join(ct)
                    es = diff(lt, ct, initial_line)
                self._active_snippets[0].replay_user_edits(es, self._ctab)
            except IndexError:
                # Rather do nothing than throwing an error. It will be correct
                # most of the time
                pass

        self._check_if_still_inside_snippet()
        if self._active_snippets:
            self._active_snippets[0].update_textobjects(vim_helper.buf)
            self._vstate.remember_buffer(self._active_snippets[0])