Beispiel #1
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)
Beispiel #2
0
def _go_replace(nvim: Nvim, visual: VisualTypes) -> None:
    buf = cur_buf(nvim)
    if not writable(nvim, buf=buf):
        return
    else:
        linefeed = buf_linefeed(nvim, buf=buf)
        (r1, c1), (r2, c2) = operator_marks(nvim, buf=buf, visual_type=visual)
        lines = buf_get_lines(nvim, buf=buf, lo=r1, hi=r2 + 1)

        if len(lines) > 1:
            h, *_, t = lines
        else:
            h, *_ = t, *_ = lines

        begin = (r1, min(c1, max(0, len(encode(h)) - 1)))
        end = (r2, min(len(encode(t)), c2 + 1))

        text: str = nvim.funcs.getreg()
        new_lines = text.split(linefeed)
        if new_lines:
            n = new_lines.pop()
            if n:
                new_lines.append(n)
        nvim.options["undolevels"] = nvim.options["undolevels"]
        buf_set_text(nvim, buf=buf, begin=begin, end=end, text=new_lines)
Beispiel #3
0
    def cont() -> Iterator[Mark]:
        row, _ = pos
        len8 = tuple(accumulate(len(encode(line)) + _NL for line in new_lines))

        for r_idx, region in regions:
            r1, c1, r2, c2 = None, None, None, None
            last_len = 0

            for idx, l8 in enumerate(len8):
                x_shift = 0 if idx else len(encode(l0_before))

                if r1 is None:
                    if l8 > region.begin:
                        r1, c1 = idx + row, region.begin - last_len + x_shift
                    elif l8 == region.begin:
                        r1, c1 = idx + row + 1, x_shift

                if r2 is None:
                    if l8 > region.end:
                        r2, c2 = idx + row, region.end - last_len + x_shift
                    elif l8 == region.end:
                        r2, c2 = idx + row + 1, x_shift

                if r1 is not None and r2 is not None:
                    break

                last_len = l8

            assert (r1 is not None and c1 is not None) and (
                r2 is not None and c2 is not None
            ), pformat((region, new_lines))

            begin, end = (r1, c1), (r2, c2)
            mark = Mark(idx=r_idx, begin=begin, end=end, text=region.text)
            yield mark
Beispiel #4
0
    def gen_highlights(node: Node, pre: str, icon: str, name: str,
                       ignored: bool) -> Iterator[Highlight]:
        icon_begin = len(encode(pre))
        icon_end = icon_begin + len(encode(icon))
        text_begin = icon_end
        text_end = len(encode(name)) + text_begin

        if icon_group := search_icon_hl(node, ignored=ignored):
            hl = Highlight(group=icon_group, begin=icon_begin, end=icon_end)
            yield hl
Beispiel #5
0
def token_parser(context: ParserCtx, stream: TokenStream) -> Parsed:
    idx = 0
    raw_regions: MutableMapping[int, MutableSequence[Region]] = {}
    slices: MutableSequence[str] = []
    begins: MutableSequence[Tuple[int, Union[Begin, DummyBegin]]] = []
    bad_tokens: MutableSequence[Tuple[int, Token]] = []

    for token in stream:
        if isinstance(token, Unparsed):
            token = token
            bad_tokens.append((idx, token))
        elif isinstance(token, str):
            idx += len(encode(token))
            slices.append(token)
        elif isinstance(token, Begin):
            begins.append((idx, token))
        elif isinstance(token, DummyBegin):
            begins.append((idx, token))
        elif isinstance(token, End):
            if begins:
                pos, begin = begins.pop()
                if isinstance(begin, Begin):
                    acc = raw_regions.setdefault(begin.idx, [])
                    acc.append(Region(begin=pos, end=idx, text=""))
            else:
                bad_tokens.append((idx, token))
        else:
            never(token)

    bad_tokens.extend(begins)
    text = "".join(slices)
    min_key = min(raw_regions.keys(), key=lambda i:
                  (i == 0, i)) if raw_regions else -1
    cursor = next(
        iter(raw_regions.get(min_key, ())),
        Region(begin=len(encode(text)), end=0, text=""),
    ).begin

    if bad_tokens:
        tpl = """
        Bad tokens :: Most likely unbalanced `{…}` - ${bad_tokens}
        Parsed: |-
        ${text}
        Original: |-
        ${ctx}
        """
        msg = Template(dedent(tpl)).substitute(bad_tokens=bad_tokens,
                                               text=text,
                                               ctx=context.text)
        raise ParseError(msg)

    regions = tuple(_consolidate(text, regions=raw_regions))
    parsed = Parsed(text=text, cursor=cursor, regions=regions)
    return parsed
Beispiel #6
0
def _range_edit_trans(
    unifying_chars: AbstractSet[str],
    smart: bool,
    ctx: Context,
    primary: bool,
    lines: _Lines,
    edit: RangeEdit,
) -> EditInstruction:
    new_lines = edit.new_text.split(ctx.linefeed)

    if (primary and not isinstance(edit, ParsedEdit) and len(new_lines) <= 1
            and edit.begin == edit.end):
        return _edit_trans(unifying_chars,
                           smart=smart,
                           ctx=ctx,
                           lines=lines,
                           edit=edit)

    else:
        (r1, ec1), (r2, ec2) = sorted((edit.begin, edit.end))

        if edit.encoding == UTF16:
            c1 = len(
                encode(decode(lines.b_lines16[r1][:ec1 * 2], encoding=UTF16)))
            c2 = len(
                encode(decode(lines.b_lines16[r2][:ec2 * 2], encoding=UTF16)))
        elif edit.encoding == UTF8:
            c1 = len(lines.b_lines8[r1][:ec1])
            c2 = len(lines.b_lines8[r2][:ec2])
        else:
            raise ValueError(f"Unknown encoding -- {edit.encoding}")

        begin = r1, c1
        end = r2, c2

        lines_before = (edit.new_prefix.split(ctx.linefeed) if isinstance(
            edit, ParsedEdit) else new_lines)
        cursor_yoffset = (r2 - r1) + (len(lines_before) - 1)
        cursor_xpos = ((len(encode(lines_before[-1])) if len(lines_before) > 1
                        else len(lines.b_lines8[r2][:c1]) +
                        len(encode(lines_before[0]))) if primary else -1)

        inst = EditInstruction(
            primary=primary,
            begin=begin,
            end=end,
            cursor_yoffset=cursor_yoffset,
            cursor_xpos=cursor_xpos,
            new_lines=new_lines,
        )
        return inst
Beispiel #7
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)
Beispiel #8
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
Beispiel #9
0
def _parse(nvim: Nvim, buf: Buffer, stack: Stack, state: State,
           comp: Completion) -> Tuple[Edit, Sequence[Mark]]:
    if isinstance(comp.primary_edit, SnippetEdit):
        comment_str = buf_commentstr(nvim, buf=buf)
        clipboard = nvim.funcs.getreg()
        info = ParseInfo(visual="",
                         clipboard=clipboard,
                         comment_str=comment_str)
        if isinstance(comp.primary_edit, SnippetRangeEdit):
            row, col = comp.primary_edit.begin
            line, *_ = buf_get_lines(nvim, buf=buf, lo=row, hi=row + 1)
            line_before = decode(
                encode(line, encoding=comp.primary_edit.encoding)[:col])
            edit, marks = parse_range(
                context=state.context,
                snippet=comp.primary_edit,
                info=info,
                line_before=line_before,
            )
        else:
            edit, marks = parse_norm(
                stack.settings.match.unifying_chars,
                smart=stack.settings.completion.smart,
                context=state.context,
                snippet=comp.primary_edit,
                info=info,
            )
    else:
        edit, marks = comp.primary_edit, ()

    return edit, marks
Beispiel #10
0
def _shift(
    instructions: Iterable[EditInstruction],
) -> Tuple[Sequence[EditInstruction], _MarkShift]:
    row_shift = 0
    cols_shift: MutableMapping[int, int] = {}

    m_shift = _MarkShift(row=0)
    new_insts: MutableSequence[EditInstruction] = []
    for inst in instructions:
        (r1, c1), (r2, c2) = inst.begin, inst.end
        new_inst = EditInstruction(
            primary=inst.primary,
            begin=(r1 + row_shift, c1 + cols_shift.get(r1, 0)),
            end=(r2 + row_shift, c2 + cols_shift.get(r2, 0)),
            cursor_yoffset=inst.cursor_yoffset,
            cursor_xpos=inst.cursor_xpos,
            new_lines=inst.new_lines,
        )
        if new_inst.primary:
            m_shift = _MarkShift(row=row_shift)

        row_shift += (r2 - r1) + len(inst.new_lines) - 1
        f_length = len(encode(inst.new_lines[-1])) if inst.new_lines else 0
        cols_shift[r2] = -(c2 - c1) + f_length if r1 == r2 else -c2 + f_length

        new_insts.append(new_inst)

    return new_insts, m_shift
Beispiel #11
0
def _lines(lines: Sequence[str]) -> _Lines:
    b_lines8 = tuple(map(encode, lines))
    return _Lines(
        lines=lines,
        b_lines8=b_lines8,
        b_lines16=tuple(encode(line, encoding=UTF16) for line in lines),
        len8=tuple(len(line) for line in b_lines8),
    )
Beispiel #12
0
def _entire(nvim: Nvim) -> None:
    win = cur_win(nvim)
    buf = win_get_buf(nvim, win=win)
    count = buf_line_count(nvim, buf=buf)
    last_line, *_ = buf_get_lines(nvim, buf=buf, lo=-2, hi=-1)
    mark1 = (0, 0)
    mark2 = (count - 1, len(encode(last_line)))
    set_visual_selection(nvim, win=win, mode="V", mark1=mark1, mark2=mark2)
Beispiel #13
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)
Beispiel #14
0
async def _run(
    nvim: Nvim, ctx: BufContext, attrs: Iterable[FmtAttrs], cwd: PurePath
) -> None:
    body = encode(ctx.linefeed.join(ctx.lines))
    path = Path(ctx.filename)
    with make_temp(path) as temp:
        temp.write_bytes(body)
        errs = [
            err
            async for err in aiterify(
                _fmt_output(attr, ctx=ctx, cwd=cwd, temp=temp) for attr in attrs
            )
            if err
        ]
        errors = (ctx.linefeed * 2).join(errs)
        if errors:

            def c1() -> None:
                set_preview_content(nvim, text=errors)
                write(nvim, LANG("prettier failed"))

            await async_call(nvim, c1)

        else:

            def c2() -> None:
                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)

                saved = {win: pos for win, pos in it()}

                lines = temp.read_text().split(ctx.linefeed)
                if lines:
                    l = lines.pop()
                    if l:
                        lines.append(l)
                buf_set_lines(nvim, buf=ctx.buf, lo=0, hi=-1, lines=lines)

                for win, (row, col) in saved.items():
                    new_row = min(row, len(lines) - 1)
                    with suppress(NvimError):
                        win_set_cursor(nvim, win=win, row=new_row, col=col)
                detect_tabs(nvim, buf=ctx.buf)

                prettiers = LANG("step join sep").join(attr.bin for attr in attrs)
                nice = LANG("prettier succeeded", prettiers=prettiers)
                write(nvim, nice)

            await async_call(nvim, c2)
Beispiel #15
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)
Beispiel #16
0
def now(nvim: Nvim, stack: Stack, args: Sequence[str]) -> None:
    try:
        ns = _parse_args(args)
    except ArgparseError as e:
        write(nvim, e, error=True)
    else:
        if not ns.shut_up:
            lo, hi = _HELO.chars
            chars = choice(range(lo, hi))
            star = (choice(_HELO.stars),)
            birds = " ".join(chain(star, sample(_HELO.cocks, k=chars), star))
            helo = choice(_HELO.helo)
            msg = f"{birds}  {helo}{linesep}"
            encoded = encode(msg)
            stdout.buffer.write(encoded)
            stdout.buffer.flush()
Beispiel #17
0
 async def cont() -> Optional[str]:
     async with self._lock:
         if self._bin and not self._proc:
             self._proc = await _proc(self._bin, cwd=cwd)
             if self._proc:
                 self._cwd = cwd
         if not self._proc:
             return None
         else:
             assert self._proc.stdin and self._proc.stdout
             try:
                 self._proc.stdin.write(encode(json))
                 self._proc.stdin.write(b"\n")
                 await self._proc.stdin.drain()
                 out = await self._proc.stdout.readline()
             except (ConnectionError, LimitOverrunError, ValueError):
                 return await self._clean()
             else:
                 return decode(out)
Beispiel #18
0
async def comp_lsp(
    nvim: Nvim,
    short_name: str,
    weight_adjust: float,
    context: Context,
    clients: AbstractSet[str],
) -> AsyncIterator[LSPcomp]:
    row, c = context.position
    col = len(encode(context.line_before[:c], encoding=UTF16)) // 2

    async for client, reply in async_request(nvim, "lsp_comp", clients, (row, col)):
        resp = cast(CompletionResponse, reply)
        yield parse(
            ExternLSP,
            client=client,
            short_name=short_name,
            weight_adjust=weight_adjust,
            resp=resp,
        )
Beispiel #19
0
def _contextual_edit_trans(ctx: Context, lines: _Lines,
                           edit: ContextualEdit) -> EditInstruction:
    row, col = ctx.position
    old_prefix_lines = edit.old_prefix.split(ctx.linefeed)
    old_suffix_lines = edit.old_suffix.split(ctx.linefeed)

    r1 = row - (len(old_prefix_lines) - 1)
    r2 = row + (len(old_suffix_lines) - 1)

    c1 = (lines.len8[r1] - len(encode(old_prefix_lines[0]))
          if len(old_prefix_lines) > 1 else col -
          len(encode(old_prefix_lines[0])))
    c2 = (len(encode(old_suffix_lines[-1])) if len(old_prefix_lines) > 1 else
          col + len(encode(old_suffix_lines[0])))

    begin = r1, c1
    end = r2, c2

    new_lines = edit.new_text.split(ctx.linefeed)
    new_prefix_lines = edit.new_prefix.split(ctx.linefeed)
    cursor_yoffset = -len(old_prefix_lines) + len(new_prefix_lines)
    cursor_xpos = (len(encode(new_prefix_lines[-1]))
                   if len(new_prefix_lines) > 1 else
                   len(encode(ctx.line_before)) -
                   len(encode(old_prefix_lines[-1])) +
                   len(encode(new_prefix_lines[0])))

    inst = EditInstruction(
        primary=True,
        begin=begin,
        end=end,
        cursor_yoffset=cursor_yoffset,
        cursor_xpos=cursor_xpos,
        new_lines=new_lines,
    )
    return inst
Beispiel #20
0
def _p_inside(line: str) -> Tuple[int, int]:
    lhs = len(encode(line)) - len(encode(line.lstrip()))
    rhs = len(encode(line.rstrip())) - 1
    return lhs, rhs
Beispiel #21
0
def context(
    nvim: Nvim, db: BDB, options: MatchOptions, state: State, manual: bool
) -> Context:
    with Atomic() as (atomic, ns):
        ns.scr_col = atomic.call_function("screencol", ())
        ns.buf = atomic.get_current_buf()
        ns.name = atomic.buf_get_name(0)
        ns.line_count = atomic.buf_line_count(0)
        ns.filetype = atomic.buf_get_option(0, "filetype")
        ns.commentstring = atomic.buf_get_option(0, "commentstring")
        ns.fileformat = atomic.buf_get_option(0, "fileformat")
        ns.tabstop = atomic.buf_get_option(0, "tabstop")
        ns.expandtab = atomic.buf_get_option(0, "expandtab")
        ns.cursor = atomic.win_get_cursor(0)
        atomic.commit(nvim)

    scr_col = ns.scr_col
    buf = cast(Buffer, ns.buf)
    (r, col) = cast(Tuple[int, int], ns.cursor)
    row = r - 1
    pos = (row, col)
    buf_line_count = ns.line_count
    filename = normcase(cast(str, ns.name))
    filetype = cast(str, ns.filetype)
    comment_str = cast(str, ns.commentstring)
    tabstop = ns.tabstop
    expandtab = cast(bool, ns.expandtab)
    linefeed = cast(Literal["\n", "\r", "\r\n"], LFfmt[cast(str, ns.fileformat)].value)

    lo = max(0, row - options.proximate_lines)
    hi = min(buf_line_count, row + options.proximate_lines + 1)
    lines = buf_get_lines(nvim, buf=buf, lo=lo, hi=hi)
    if DEBUG:
        db_line_count, db_lit = db.lines(buf.number, lo=lo, hi=hi)
        db_lines = tuple(db_lit)
        assert db_line_count in {
            buf_line_count - 1,
            buf_line_count,
            buf_line_count + 1,
        }, (db_line_count, buf_line_count)
        assert tuple(
            "" if idx == row else line for idx, line in enumerate(db_lines, start=lo)
        ) == tuple(
            "" if idx == row else line for idx, line in enumerate(lines, start=lo)
        ), linesep.join(
            unified_diff(lines, db_lines)
        )

    r = row - lo
    line = lines[r]
    lines_before, lines_after = lines[:r], lines[r + 1 :]

    lhs, _, rhs = comment_str.partition("%s")
    b_line = encode(line)
    before, after = decode(b_line[:col]), decode(b_line[col:])
    split = gen_split(lhs=before, rhs=after, unifying_chars=options.unifying_chars)

    ctx = Context(
        manual=manual,
        change_id=state.change_id,
        commit_id=state.commit_id,
        cwd=state.cwd,
        buf_id=buf.number,
        filename=filename,
        filetype=filetype,
        line_count=buf_line_count,
        linefeed=linefeed,
        tabstop=tabstop,
        expandtab=expandtab,
        comment=(lhs, rhs),
        position=pos,
        scr_col=scr_col,
        line=split.lhs + split.rhs,
        line_before=split.lhs,
        line_after=split.rhs,
        lines=lines,
        lines_before=lines_before,
        lines_after=lines_after,
        words=split.word_lhs + split.word_rhs,
        words_before=split.word_lhs,
        words_after=split.word_rhs,
        syms=split.syms_lhs + split.syms_rhs,
        syms_before=split.syms_lhs,
        syms_after=split.syms_rhs,
        ws_before=split.ws_lhs,
        ws_after=split.ws_rhs,
    )
    return ctx
Beispiel #22
0
def _p_around(line: str) -> Tuple[int, int]:
    return 0, len(encode(line))
Beispiel #23
0
    SnippetEdit,
    SnippetGrammar,
    SnippetRangeEdit,
)
from .consts import SNIP_LINE_SEP
from .parsers.lsp import tokenizer as lsp_tokenizer
from .parsers.snu import tokenizer as snu_tokenizer
from .parsers.types import Parsed, ParseInfo, Region


@dataclass(frozen=True)
class ParsedEdit(BaseRangeEdit):
    new_prefix: str


_NL = len(encode(SNIP_LINE_SEP))


def _indent(context: Context, line_before: str, snippet: str) -> str:
    indent = indent_to_line(context, line_before=line_before)
    expanded = expand_tabs(context, text=snippet)
    lines = tuple(
        lhs + rhs
        for lhs, rhs in zip(chain(("",), repeat(indent)), expanded.splitlines(True))
    )
    indented = "".join(lines)
    return indented


def _marks(
    pos: NvimPos,
Beispiel #24
0
def _comp_done(nvim: Nvim, stack: Stack, event: Mapping[str, Any]) -> None:
    data = event.get("user_data")
    if data:
        try:
            uid = _UDECODER(data)
        except DecodeError:
            pass
        else:
            s = state()
            if metric := stack.metrics.get(uid):
                row, col = s.context.position
                buf = cur_buf(nvim)
                ns = create_ns(nvim, ns=NS)
                clear_ns(nvim, buf=buf, id=ns)
                before, *_ = buf_get_lines(nvim, buf=buf, lo=row, hi=row + 1)
                e1 = ExtMark(
                    idx=1,
                    begin=(row, 0),
                    end=(row, col),
                    meta={},
                )
                e2 = ExtMark(
                    idx=2,
                    begin=(row, col),
                    end=(row, len(encode(before))),
                    meta={},
                )
                buf_set_extmarks(nvim, buf=buf, id=ns, marks=(e1, e2))

                async def cont() -> None:
                    if metric:
                        new_metric = await _resolve(nvim,
                                                    stack=stack,
                                                    metric=metric)

                        async def c2() -> None:
                            if isinstance((extern := new_metric.comp.extern),
                                          ExternLSP):
                                await cmd(nvim, extern=extern)

                        def c1() -> None:
                            if new_metric.comp.uid in stack.metrics:
                                inserted_at = edit(
                                    nvim,
                                    stack=stack,
                                    state=s,
                                    metric=new_metric,
                                    synthetic=False,
                                )
                                ins_pos = inserted_at or (-1, -1)
                                state(
                                    inserted_pos=ins_pos,
                                    last_edit=new_metric,
                                    commit_id=uuid4(),
                                )
                                go(nvim, aw=c2())
                            else:
                                log.warn("%s", "delayed completion")

                        await async_call(nvim, c1)

                go(nvim, aw=cont())
Beispiel #25
0
    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

    while lines:
        if line := lines.pop():
            lines.append(line)
            break
        else:
            btm -= 1

    if lines:
        *_, btm_line = lines
        mark1, mark2 = (top, 0), (btm, len(encode(btm_line)))
    else:
        mark1, mark2 = (row, 0), (row, len(encode(curr)))

    set_visual_selection(nvim, win=win, mode="V", mark1=mark1, mark2=mark2)


keymap.o("ii") << f"<cmd>lua {NAMESPACE}.{_indent.name}()<cr>"
keymap.v("ii") << rf"<c-\><c-n><cmd>lua {NAMESPACE}.{_indent.name}()<cr>"