Ejemplo n.º 1
0
def _restore(nvim: Nvim, win: Window, buf: Buffer,
             pos: NvimPos) -> Tuple[str, Optional[int]]:
    row, _ = pos
    ns = create_ns(nvim, ns=NS)
    marks = tuple(buf_get_extmarks(nvim, buf=buf, id=ns))
    if len(marks) != 2:
        return "", 0
    else:
        m1, m2 = marks
        after, *_ = buf_get_lines(nvim, buf=buf, lo=row, hi=row + 1)
        cur_row, cur_col = win_get_cursor(nvim, win=win)

        (_, lo), (_, hi) = m1.end, m2.begin

        binserted = encode(after)[lo:hi]
        inserted = decode(binserted)

        movement = cur_col - lo if cur_row == row and lo <= cur_col <= hi else None

        if inserted:
            buf_set_text(nvim,
                         buf=buf,
                         begin=m1.end,
                         end=m2.begin,
                         text=("", ))

        return inserted, movement
Ejemplo n.º 2
0
def _word(nvim: Nvim, is_inside: bool) -> None:
    win = cur_win(nvim)
    buf = win_get_buf(nvim, win=win)

    row, c = win_get_cursor(nvim, win=win)
    lines = buf_get_lines(nvim, buf=buf, lo=row, hi=row + 1)
    line = next(iter(lines))
    bline = line.encode()

    # position under cursor
    c = min(len(bline) - 1, c)
    col = len(bline[:c].decode()) + 1
    lhs, rhs = line[:col], line[col:]
    # undo col + 1
    offset = len(next(reversed(lhs), "").encode())

    ctx = gen_split(lhs, rhs, unifying_chars=UNIFIYING_CHARS)
    if not (ctx.word_lhs + ctx.word_rhs):
        words_lhs, words_rhs = ctx.syms_lhs, ctx.syms_rhs
    else:
        words_lhs, words_rhs = ctx.word_lhs, ctx.word_rhs

    c_lhs = c + offset - len(words_lhs.encode())
    c_rhs = c + offset + len(words_rhs.encode()) - 1

    if is_inside:
        mark1 = (row, c_lhs)
        mark2 = (row, c_rhs)
    else:
        mark1 = (row, c_lhs - 1)
        mark2 = (row, c_rhs + 1)

    set_visual_selection(nvim, win=win, mode="v", mark1=mark1, mark2=mark2)
Ejemplo n.º 3
0
def _word(nvim: Nvim, is_inside: bool) -> None:
    win = cur_win(nvim)
    buf = win_get_buf(nvim, win=win)

    row, col = win_get_cursor(nvim, win=win)
    line, *_ = buf_get_lines(nvim, buf=buf, lo=row, hi=row + 1)

    bline = encode(line)
    lhs, rhs = decode(bline[:col]), decode(bline[col:])
    ctx = gen_split(lhs, rhs, unifying_chars=UNIFIYING_CHARS)

    if not (ctx.word_lhs + ctx.word_rhs):
        words_lhs, words_rhs = ctx.syms_lhs, ctx.syms_rhs
    else:
        words_lhs, words_rhs = ctx.word_lhs, ctx.word_rhs

    c_lhs = max(col - len(encode(words_lhs)), 0)
    c_rhs = max(col + len(encode(words_rhs)) - 1, 0)

    if is_inside:
        mark1 = (row, c_lhs)
        mark2 = (row, c_rhs)
    else:
        mark1 = (row, max(0, c_lhs - 1))
        mark2 = (row, min(len(bline), c_rhs + 1))

    set_visual_selection(nvim, win=win, mode="v", mark1=mark1, mark2=mark2)
Ejemplo n.º 4
0
 def it() -> Iterator[Tuple[Window, Tuple[int, int]]]:
     wins = list_wins(nvim)
     for win in wins:
         buf = win_get_buf(nvim, win=win)
         if buf == ctx.buf:
             row, col = win_get_cursor(nvim, win)
             yield win, (row, col)
Ejemplo n.º 5
0
def _surround(nvim: Nvim) -> None:
    lhs: str = nvim.vvars["char"]
    rhs = _CHAR_PAIRS.get(lhs)

    if rhs:
        win = cur_win(nvim)
        buf = win_get_buf(nvim, win=win)
        row, col = win_get_cursor(nvim, win=win)
        lines = buf_get_lines(nvim, buf=buf, lo=row, hi=row + 1)
        line = next(iter(lines))

        def cont() -> None:
            new_col = col + len(lhs.encode())
            nvim.api.set_vvar("char", lhs + cast(str, rhs))
            set_cur = lambda: win_set_cursor(
                nvim, win=win, row=row, col=new_col)
            go(async_call(nvim, set_cur))

        if rhs == lhs:
            is_even = line.count(lhs) % 2 == 0
            if is_even:
                cont()
        else:
            counts = Counter(line)
            if counts[lhs] >= counts[rhs]:
                cont()
Ejemplo n.º 6
0
def _marks(nvim: Nvim, ns: int, win: Window, buf: Buffer) -> Iterator[ExtMark]:
    cursor = win_get_cursor(nvim, win=win)
    for idx, mark in enumerate(_ls_marks(nvim, ns=ns, buf=buf)):
        if not idx and mark.begin == cursor and mark.end == cursor:
            _del_marks(nvim, buf=buf, id=ns, marks=(mark, ))
        else:
            yield mark
Ejemplo n.º 7
0
def _restore_pos(nvim: Nvim) -> None:
    win = cur_win(nvim)
    buf = win_get_buf(nvim, win=win)
    row, _ = win_get_cursor(nvim, win=win)
    pos: Optional[int] = buf_get_var(nvim, buf=buf, key=BUF_VAR_NAME)

    if pos is not None:
        win_set_cursor(nvim, win=win, row=row, col=pos)
Ejemplo n.º 8
0
def _comment_single(nvim: Nvim) -> None:
    win = cur_win(nvim)
    buf = win_get_buf(nvim, win=win)
    if not writable(nvim, buf=buf):
        return
    else:
        row, _ = win_get_cursor(nvim, win=win)
        lines = buf_get_lines(nvim, buf=buf, lo=row, hi=row + 1)
        lhs, rhs = buf_commentstr(nvim, buf=buf)
        new_lines = _toggle_comment(lhs, rhs, lines=lines)
        buf_set_lines(nvim, buf=buf, lo=row, hi=row + 1, lines=new_lines)
Ejemplo n.º 9
0
def _line(nvim: Nvim, is_inside: bool) -> None:
    win = cur_win(nvim)
    buf = win_get_buf(nvim, win=win)
    row, _ = win_get_cursor(nvim, win=win)
    lines = buf_get_lines(nvim, buf=buf, lo=row, hi=row + 1)
    line = next(iter(lines))
    lhs, rhs = (_p_inside if is_inside else _p_around)(line)

    set_visual_selection(nvim,
                         win=win,
                         mode="v",
                         mark1=(row, lhs),
                         mark2=(row, rhs))
Ejemplo n.º 10
0
def _rename(nvim: Nvim) -> None:
    win = cur_win(nvim)
    buf = win_get_buf(nvim, win=win)
    row, col = win_get_cursor(nvim, win=win)
    line, *_ = buf_get_lines(nvim, buf=buf, lo=row, hi=row + 1)
    b_line = encode(line)
    lhs, rhs = decode(b_line[:col]), decode(b_line[col:])
    split = gen_split(lhs=lhs, rhs=rhs, unifying_chars=UNIFIYING_CHARS)
    word = split.word_lhs + split.word_rhs
    ans = ask(nvim, question=LANG("rename: "), default=word)

    if ans:
        nvim.lua.vim.lsp.buf.rename(ans)
Ejemplo n.º 11
0
def redraw(nvim: Nvim, state: State, focus: Optional[PurePath]) -> None:
    focus_row = state.derived.path_row_lookup.get(focus) if focus else None

    ns = nvim.api.create_namespace(FM_NAMESPACE)
    use_extmarks = nvim.funcs.has("nvim-0.6")

    for win, buf in find_fm_windows(nvim):
        p_count = buf_line_count(nvim, buf=buf)
        n_count = len(state.derived.lines)
        row, col = win_get_cursor(nvim, win=win)
        (r1, c1), (r2, c2) = operator_marks(nvim, buf=buf, visual_type=None)

        try:
            hashed_lines = _DECODER(
                buf_get_var(nvim, buf=buf, key=_FM_HASH_VAR))
        except DecodeError:
            hashed_lines = ("", )

        if focus_row is not None:
            new_row: Optional[int] = focus_row + 1
        elif row >= n_count:
            new_row = n_count
        elif p_count != n_count:
            new_row = row + 1
        else:
            new_row = None

        a1 = Atomic()
        a1.buf_set_option(buf, "modifiable", True)

        a2 = _update(
            use_extmarks,
            buf=buf,
            ns=ns,
            derived=state.derived,
            hashed_lines=hashed_lines,
        )

        a3 = Atomic()
        a3.buf_set_option(buf, "modifiable", False)
        a3.call_function("setpos", ("'<", (buf.number, r1 + 1, c1 + 1, 0)))
        a3.call_function("setpos", ("'>", (buf.number, r2 + 1, c2 + 1, 0)))
        if new_row is not None:
            a3.win_set_cursor(win, (new_row, col))

        try:
            (a1 + a2 + a3).commit(nvim)
        except NvimError as e:
            raise UnrecoverableError(e)
Ejemplo n.º 12
0
def _norm_mv(nvim: Nvim, up: bool) -> None:
    win = cur_win(nvim)
    buf = win_get_buf(nvim, win=win)
    row, _ = win_get_cursor(nvim, win=win)
    lines = buf_line_count(nvim, buf=buf)

    if not writable(nvim, buf=buf):
        return
    else:
        if up:
            if row:
                nvim.command(f"move -2")
        else:
            if row < lines - 1:
                nvim.command(f"move +1")
Ejemplo n.º 13
0
def _go_replace_line(nvim: Nvim) -> None:
    win = cur_win(nvim)
    buf = win_get_buf(nvim, win=win)
    if not writable(nvim, buf=buf):
        return
    else:
        linefeed = buf_linefeed(nvim, buf=buf)
        row, _ = win_get_cursor(nvim, win=win)
        body: str = nvim.funcs.getreg()
        new_lines = body.split(linefeed)
        if new_lines:
            n = new_lines.pop()
            if n:
                new_lines.append(n)

        buf_set_lines(nvim, buf=buf, lo=row, hi=row + 1, lines=new_lines)
Ejemplo n.º 14
0
def _toggle_case(nvim: Nvim) -> None:
    win = cur_win(nvim)
    row, col = win_get_cursor(nvim, win=win)
    buf = win_get_buf(nvim, win=win)
    if writable(nvim, buf=buf):
        line, *_ = buf_get_lines(nvim, buf=buf, lo=row, hi=row + 1)
        bline = encode(line)
        before, after = bline[:col], bline[col:]
        if after:
            cur, *post = after
            pt = decode(bytes((cur, )))
            swapped = _swap_case(pt)
            new = decode(before) + swapped + decode(bytes(post))
            pos = len(before) + len(encode(swapped))
            buf_set_lines(nvim, buf=buf, lo=row, hi=row + 1, lines=(new, ))
            win_set_cursor(nvim, win=win, row=row, col=pos)
Ejemplo n.º 15
0
def _toggle_case(nvim: Nvim) -> None:
    win = cur_win(nvim)
    row, col = win_get_cursor(nvim, win=win)
    buf = win_get_buf(nvim, win=win)
    if not writable(nvim, buf=buf):
        return
    else:
        line, *_ = buf_get_lines(nvim, buf=buf, lo=row, hi=row + 1)
        bline = line.encode()
        before, after = bline[:col], bline[col:]
        cur, *post = after
        pt = bytes((cur,)).decode()
        swapped = _swap_case(pt)
        new = before.decode() + swapped + bytes(post).decode()
        pos = len(before) + len(swapped.encode())
        buf_set_lines(nvim, buf=buf, lo=row, hi=row + 1, lines=(new,))
        win_set_cursor(nvim, win=win, row=row, col=pos)
Ejemplo n.º 16
0
def _indent(nvim: Nvim) -> None:
    win = cur_win(nvim)
    buf = win_get_buf(nvim, win)
    row, _ = win_get_cursor(nvim, win)
    tabsize: int = buf_get_option(nvim, buf=buf, key="tabstop")

    lines = buf_get_lines(nvim, buf=buf, lo=0, hi=-1)
    before, curr, after = lines[:row], lines[row], lines[row + 1:]
    init_lv = p_indent(curr, tabsize=tabsize)

    top = row - _p_inside(init_lv, tabsize=tabsize, lines=reversed(before))
    btm = row + _p_inside(init_lv, tabsize=tabsize, lines=after)

    set_visual_selection(nvim,
                         win=win,
                         mode="V",
                         mark1=(top, 0),
                         mark2=(btm, 0))
Ejemplo n.º 17
0
def _set_trimmed(nvim: Nvim, win: Window, buf: Buffer) -> None:
    row, col = win_get_cursor(nvim, win=win)
    lines = buf_get_lines(nvim, buf=buf, lo=0, hi=-1)
    new_lines = [
        decode(encode(line)[:col]) +
        decode(encode(line)[col:]).rstrip() if r == row else line.rstrip()
        for r, line in enumerate(lines)
    ]

    while new_lines:
        line = new_lines.pop()
        if line or len(new_lines) <= row:
            new_lines.append(line)
            break
    if len(new_lines) < len(lines):
        new_lines.append("")

    if new_lines != lines:
        buf_set_lines(nvim, buf=buf, lo=0, hi=-1, lines=new_lines)
        win_set_cursor(nvim, win=win, row=row, col=col)
Ejemplo n.º 18
0
def _indent(nvim: Nvim) -> None:
    win = cur_win(nvim)
    buf = win_get_buf(nvim, win)
    row, _ = win_get_cursor(nvim, win)
    tabsize: int = buf_get_option(nvim, buf=buf, key="tabstop")

    lines = buf_get_lines(nvim, buf=buf, lo=0, hi=-1)
    before, curr, after = lines[:row], lines[row], lines[row + 1:]
    init_lv = p_indent(curr, tabsize=tabsize)

    top = row - _p_inside(init_lv, tabsize=tabsize, lines=reversed(before))
    btm = row + _p_inside(init_lv, tabsize=tabsize, lines=after)

    lines = deque(buf_get_lines(nvim, buf=buf, lo=top, hi=btm + 1))
    while lines:
        if line := lines.popleft():
            lines.appendleft(line)
            break
        else:
            top += 1
Ejemplo n.º 19
0
def _virt_text(nvim: Nvim, ghost: GhostText, text: str) -> None:
    if ghost.enabled:
        lhs, rhs = ghost.context
        overlay, *_ = text.splitlines() or ("", )
        virt_text = lhs + overlay + rhs

        ns = create_ns(nvim, ns=_NS)
        win = cur_win(nvim)
        buf = win_get_buf(nvim, win=win)
        row, col = win_get_cursor(nvim, win=win)
        mark = ExtMark(
            idx=1,
            begin=(row, col),
            end=(row, col),
            meta={
                "virt_text_pos": "overlay",
                "hl_mode": "combine",
                "virt_text": ((virt_text, ghost.highlight_group), ),
            },
        )
        clear_ns(nvim, buf=buf, id=ns)
        buf_set_extmarks(nvim, buf=buf, id=ns, marks=(mark, ))
Ejemplo n.º 20
0
def indices(nvim: Nvim, state: State, is_visual: bool) -> Iterator[Node]:
    win = cur_win(nvim)
    buf = win_get_buf(nvim, win=win)

    if not is_fm_buffer(nvim, buf=buf):
        return None
    else:
        row, _ = win_get_cursor(nvim, win=win)
        node = _row_index(state, row)
        if node:
            yield node

        if is_visual:
            (row1, _), (row2, _) = operator_marks(nvim,
                                                  buf=buf,
                                                  visual_type=None)

            for r in range(row1, row2 + 1):
                if r != row:
                    node = _row_index(state, r)
                    if node:
                        yield node
Ejemplo n.º 21
0
def redraw(nvim: Nvim, state: State, focus: Optional[str]) -> None:
    derived, current = state.derived, state.current
    focus_row = derived.path_row_lookup.get(focus) if focus else None
    current_row = derived.path_row_lookup.get(current or "")

    cwin = cur_win(nvim)
    ns = nvim.api.create_namespace(FM_NAMESPACE)

    for win, buf in find_fm_windows(nvim):
        p_count = buf_line_count(nvim, buf=buf)
        n_count = len(state.derived.lines)
        row, col = win_get_cursor(nvim, win=win)
        (r1, c1), (r2, c2) = operator_marks(nvim, buf=buf, visual_type=None)

        if focus_row is not None:
            new_row: Optional[int] = focus_row + 1
        elif win != cwin and current_row is not None:
            new_row = current_row + 1
        elif row >= n_count:
            new_row = n_count
        elif p_count != n_count:
            new_row = row + 1
        else:
            new_row = None

        a1 = Atomic()
        a1.buf_set_option(buf, "modifiable", True)

        a2 = _update(nvim, buf=buf, ns=ns, derived=derived)

        a3 = Atomic()
        a3.buf_set_option(buf, "modifiable", False)
        a3.call_function("setpos", ("'<", (buf.number, r1 + 1, c1 + 1, 0)))
        a3.call_function("setpos", ("'>", (buf.number, r2 + 1, c2 + 1, 0)))
        if new_row is not None:
            a3.win_set_cursor(win, (new_row, col))

        (a1 + a2 + a3).commit(nvim)
Ejemplo n.º 22
0
def _record_pos(nvim: Nvim) -> None:
    win = cur_win(nvim)
    buf = win_get_buf(nvim, win=win)
    _, col = win_get_cursor(nvim, win=win)
    buf_set_var(nvim, buf=buf, key=BUF_VAR_NAME, val=col)