Beispiel #1
0
def next_paragraph_start(view, pt, count=1, skip_empty=True):
    if row_at(view, pt) == last_row(view):
        if not view.line(view.size()).empty():
            return view.size() - 1

        return view.size()

    # skip empty rows before moving for the first time
    current_row = row_at(view, pt)
    if (view.line(view.text_point(current_row + 1, 0)).empty()
            and view.line(pt).empty()):
        pt, _ = _next_non_empty_row(view, pt)

    for i in range(count):
        pt, eof = _next_empty_row(view, pt)
        if eof:
            if view.line(pt).empty():
                return pt

            return pt - 1

        if skip_empty and (i != (count - 1)):
            pt, eof = _next_non_empty_row(view, pt)
            if eof:
                if not view.line(pt).empty():
                    return pt - 1

                return pt

    return pt
Beispiel #2
0
def prev_paragraph_start(view,
                         pt: int,
                         count: int = 1,
                         skip_empty: bool = True) -> int:
    # first row?
    if row_at(view, pt) == 0:
        return 0

    current_row = row_at(view, pt)
    if (view.line(view.text_point(current_row - 1, 0)).empty()
            and view.line(view.text_point(current_row, 0)).empty()):
        pt, bof = _prev_non_empty_row(view, pt)
        if bof:
            return 0

    for i in range(count):
        pt, bof = _prev_empty_row(view, pt)
        if bof:
            return 0

        if skip_empty and (count > 1) and (i != count - 1):
            pt, bof = _prev_non_empty_row(view, pt)
            if bof:
                return pt

    return view.text_point(row_at(view, pt), 0)
Beispiel #3
0
def _next_empty_row(view, pt):
    r = row_at(view, pt)
    while True:
        r += 1
        pt = view.text_point(r, 0)
        if row_at(view, pt) == last_row(view):
            return view.size(), True

        if view.line(pt).empty():
            return pt, False
    def f(view, s):
        if mode == INTERNAL_NORMAL:
            view.run_command('toggle_comment')
            if row_at(view, s.a) != row_at(view, view.size()):
                pt = next_non_blank(view, s.a)
            else:
                pt = next_non_blank(view, view.line(s.a).a)

            return Region(pt)

        return s
Beispiel #5
0
def _resolve_line_number(view, token, current: int) -> int:
    # Args:
    #   view (View): The view where the calculation is made.
    #   token (Token):
    #   current (int): Line number where we are now.
    if isinstance(token, TokenDot):
        return row_at(view, view.text_point(current, 0))

    if isinstance(token, TokenDigits):
        return max(int(token.content) - 1, -1)

    if isinstance(token, TokenPercent):
        return row_at(view, view.size())

    if isinstance(token, TokenDollar):
        return row_at(view, view.size())

    if isinstance(token, TokenOffset):
        return current + sum(token.content)

    if isinstance(token, TokenSearchForward):
        match = view.find(token.content, view.text_point(current, 0))
        if not match:
            raise ValueError('E385: Search hit BOTTOM without match for: ' + token.content)

        return row_at(view, match.a)

    if isinstance(token, TokenSearchBackward):
        match = reverse_search_by_pt(view, token.content, 0, view.text_point(current, 0))
        if not match:
            raise ValueError('E384: Search hit TOP without match for: ' + token.content)

        return row_at(view, match.a)

    if isinstance(token, TokenMark):
        if token.content == '<':
            sel = list(view.sel())[0]
            view.sel().clear()
            view.sel().add(sel)
            if sel.a < sel.b:
                return row_at(view, sel.a)
            else:
                return row_at(view, sel.a - 1)
        elif token.content == '>':
            sel = list(view.sel())[0]
            view.sel().clear()
            view.sel().add(sel)
            if sel.a < sel.b:
                return row_at(view, sel.b - 1)
            else:
                return row_at(view, sel.b)
        elif token.content in tuple('abcdefghijklmnopqrstuvwxyz'):
            mark = get_mark(view, token.content)
            if not isinstance(mark, Region):
                raise ValueError('E20: mark not set')

            return view.rowcol(mark.b)[0]

    raise NotImplementedError()
Beispiel #6
0
def _resolve_line_number(view, token, current):
    # type: (...) -> int
    # Args:
    #   view (View): The view where the calculation is made.
    #   token (Token):
    #   current (int): Line number where we are now.
    if isinstance(token, TokenDot):
        return row_at(view, view.text_point(current, 0))

    if isinstance(token, TokenDigits):
        return max(int(token.content) - 1, -1)

    if isinstance(token, TokenPercent):
        return row_at(view, view.size())

    if isinstance(token, TokenDollar):
        return row_at(view, view.size())

    if isinstance(token, TokenOffset):
        return current + sum(token.content)

    if isinstance(token, TokenSearchForward):
        match = view.find(token.content, view.text_point(current, 0))
        if not match:
            raise ValueError('pattern not found')

        return row_at(view, match.a)

    if isinstance(token, TokenSearchBackward):
        match = reverse_search_by_pt(view, token.content, 0,
                                     view.text_point(current, 0))
        if not match:
            raise ValueError('pattern not found')

        return row_at(view, match.a)

    if isinstance(token, TokenMark):
        if token.content == '<':
            sel = list(view.sel())[0]
            view.sel().clear()
            view.sel().add(sel)
            if sel.a < sel.b:
                return row_at(view, sel.a)
            else:
                return row_at(view, sel.a - 1)
        elif token.content == '>':
            sel = list(view.sel())[0]
            view.sel().clear()
            view.sel().add(sel)
            if sel.a < sel.b:
                return row_at(view, sel.b - 1)
            else:
                return row_at(view, sel.b)
        elif token.content in tuple('abcdefghijklmnopqrstuvwxyz'):
            return view.rowcol(
                get_mark_as_encoded_address(view, token.content).b)[0]

    raise NotImplementedError()
        def f(view, s):
            if mode == INTERNAL_NORMAL:
                end = view.text_point(row_at(view, s.b) + (count - 1), 0)
                begin = view.line(s.b).a

                row_at_end = row_at(view, end)
                row_at_size = row_at(view, view.size())

                if ((row_at_end == row_at_size) and (view.substr(begin - 1) == '\n')):
                    begin -= 1

                return Region(begin, view.full_line(end).b)

            return s
Beispiel #8
0
def _prev_empty_row(view, pt):
    r = row_at(view, pt)
    while True:
        r -= 1
        if r == 0:
            return 0, True

        pt = view.text_point(r, 0)
        if view.line(pt).empty():
            return pt, False
Beispiel #9
0
def _next_non_empty_row(view, pt):
    r = row_at(view, pt)
    while True:
        r += 1
        reg = view.line(view.text_point(r, 0))
        if r >= last_row(view):
            return view.size(), True

        if not reg.empty():
            return reg.a, False
Beispiel #10
0
def _prev_non_empty_row(view, pt):
    r = row_at(view, pt)
    while True:
        r -= 1
        reg = view.line(view.text_point(r, 0))
        # stop if we hit the first row
        if r <= 0:
            return 0, True

        if not reg.empty():
            return reg.a, False
Beispiel #11
0
    def get_visual_repeat_data(self):
        # Return the data needed to restore visual selections.
        #
        # Before repeating a visual mode command in normal mode.
        #
        # Returns:
        #   3-tuple (lines, chars, mode)
        if self.mode not in (VISUAL, VISUAL_LINE):
            return

        first = self.view.sel()[0]
        lines = (row_at(self.view, first.end()) -
                 row_at(self.view, first.begin()))

        if lines > 0:
            chars = col_at(self.view, first.end())
        else:
            chars = first.size()

        return (lines, chars, self.mode)
Beispiel #12
0
def lines(view, s, count=1):
    """
    Return a region spanning @count full lines.

    Assumes we're operating in INTERNAL_NORMAL mode.

    @view
      Target view.
    @s
      Selection in @view taken as starting point.
    @count
      Number of lines to include in returned region.
    """
    # assumes INTERNAL_NORMAL mode.
    a = view.line(s.b).a
    b = view.text_point(row_at(view, s.b) + (count - 1), 0)
    # make sure we remove the last line if needed
    if ((row_at(view, b) == last_row(view)) and (view.substr(a - 1) == '\n')):
        a -= 1

    return Region(a, view.full_line(b).b)
Beispiel #13
0
    def restore_visual_data(self, data):
        rows, chars, old_mode = data
        first = self.view.sel()[0]

        if old_mode == VISUAL:
            if rows > 0:
                end = self.view.text_point(
                    row_at(self.view, first.b) + rows, chars)
            else:
                end = first.b + chars

            self.view.sel().add(Region(first.b, end))
            self.mode = VISUAL

        elif old_mode == VISUAL_LINE:
            rows, _, old_mode = data
            begin = self.view.line(first.b).a
            end = self.view.text_point(
                row_at(self.view, begin) + (rows - 1), 0)
            end = self.view.full_line(end).b
            self.view.sel().add(Region(begin, end))
            self.mode = VISUAL_LINE
Beispiel #14
0
def inner_lines(view, s, count=1):
    """
    Return a region spanning @count inner lines.

    Inner lines are lines excluding leading/trailing whitespace at outer ends.

    Assumes we're operating in INTERNAL_NORMAL mode.

    @view
      Target view.
    @s
      Selection in @view taken as starting point.
    @count
      Number of lines to include in returned region.
    """
    end = view.text_point(row_at(view, s.b) + (count - 1), 0)
    begin = view.line(s.b).a
    begin = next_non_blank(view, begin)

    return Region(begin, view.line(end).b)
Beispiel #15
0
def _resolve_line_reference(view, line_reference, current: int = 0) -> int:
    # Args:
    #   view (View): The view where the calculation is made.
    #   line_reference (list): The sequence of tokens defining the line range to be calculated.
    #   current (int): Line number where we are now.
    last_token = None
    # XXX: what happens if there is no selection in the view?
    current = row_at(view, view.sel()[0].b)
    for token in line_reference:
        # Make sure a search forward doesn't overlap with
        # a match obtained right before this search.
        if isinstance(last_token, TokenOfSearch) and isinstance(token, TokenOfSearch):
            if isinstance(token, TokenSearchForward):
                current += 1

        current = _resolve_line_number(view, token, current)

        last_token = token

    return current
Beispiel #16
0
def _resolve_line_number(view, token, current):
    # type: (...) -> int
    # Args:
    #   view (View): The view where the calculation is made.
    #   token (Token):
    #   current (int): Line number where we are now.
    if isinstance(token, TokenDot):
        return row_at(view, view.text_point(current, 0))

    if isinstance(token, TokenDigits):
        return max(int(token.content) - 1, -1)

    if isinstance(token, TokenPercent):
        return row_at(view, view.size())

    if isinstance(token, TokenDollar):
        return row_at(view, view.size())

    if isinstance(token, TokenOffset):
        return current + sum(token.content)

    if isinstance(token, TokenSearchForward):
        match = view.find(token.content, view.text_point(current, 0))
        if not match:
            raise ValueError('pattern not found')

        return row_at(view, match.a)

    if isinstance(token, TokenSearchBackward):
        match = reverse_search_by_pt(view, token.content, 0,
                                     view.text_point(current, 0))
        if not match:
            raise ValueError('pattern not found')

        return row_at(view, match.a)

    if isinstance(token, TokenMark):
        if token.content == '<':
            sel = list(view.sel())[0]
            view.sel().clear()
            view.sel().add(sel)
            if sel.a < sel.b:
                return row_at(view, sel.a)
            else:
                return row_at(view, sel.a - 1)
        elif token.content == '>':
            sel = list(view.sel())[0]
            view.sel().clear()
            view.sel().add(sel)
            if sel.a < sel.b:
                return row_at(view, sel.b - 1)
            else:
                return row_at(view, sel.b)
        elif token.content in tuple('abcdefghijklmnopqrstuvwxyz'):
            # The state class is intentionally imported here instead of at the
            # begining of the file to avoid circular imports errors. The State
            # needs to refactored and replaced with some less god-like
            from NeoVintageous.nv.state import State
            address = State(view).marks.get_as_encoded_address(token.content)

            return view.rowcol(address.b)[0]

    raise NotImplementedError()