Пример #1
0
async def install() -> int:
    cols, _ = get_terminal_size()
    sep = cols * "="

    errors: MutableSequence[str] = []
    tasks = chain(_git(), _pip(), _gem(), _npm(), _go(), _script())
    for fut in as_completed(tasks):
        for debug, proc in await fut:
            args = join(map(str, proc.args))
            if proc.returncode == 0:
                msg = LANG("proc succeeded", args=args)
                print(
                    msg,
                    debug,
                    decode(proc.stderr),
                    decode(proc.stdout),
                    sep,
                    sep=linesep,
                )
            else:
                errors.append(args)
                msg = LANG("proc failed", code=proc.returncode, args=args)
                print(
                    msg,
                    debug,
                    decode(proc.stderr),
                    decode(proc.stdout),
                    sep,
                    sep=linesep,
                    file=stderr,
                )

    if errors:
        print(linesep.join(errors))
    return bool(errors)
Пример #2
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)
Пример #3
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)
Пример #4
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
Пример #5
0
async def _fmt_output(
    attr: FmtAttrs, ctx: BufContext, cwd: PurePath, temp: Path
) -> str:
    arg_info = join(chain((attr.bin,), attr.args))

    try:
        args = arg_subst(attr.args, ctx=ctx, tmp_name=str(temp))
    except ParseError:
        return LANG("grammar error", text=arg_info)
    else:
        if not which(attr.bin):
            return LANG("missing", thing=attr.bin)
        else:
            stdin = temp.read_bytes() if attr.type is FmtType.stream else None
            proc = await call(
                attr.bin,
                *args,
                stdin=stdin,
                cwd=cwd,
                check_returncode=set(),
            )
            if attr.type is FmtType.stream:
                temp.write_bytes(proc.stdout)

            if proc.returncode == attr.exit_code:
                return ""
            else:
                heading = LANG("proc failed", code=proc.returncode, args=arg_info)
                print_out = ctx.linefeed.join((heading, decode(proc.stderr)))
                return print_out
Пример #6
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)
Пример #7
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
Пример #8
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
Пример #9
0
 def cont() -> Iterator[_Pane]:
     for line in decode(proc.out).strip().splitlines():
         pane_id, pane_active, window_active = line.split(" ")
         pane = _Pane(
             uid=pane_id,
             pane_active=bool(int(pane_active)),
             window_active=bool(int(window_active)),
         )
         yield pane
Пример #10
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)
Пример #11
0
async def run(*args: str) -> str:
    if not args:
        return ""
    else:
        try:
            proc = await call(
                "ctags",
                "--sort=no",
                "--output-format=json",
                f"--fields={_FIELDS}",
                *args,
                check_returncode=set(),
            )
        except (FileNotFoundError, PermissionError):
            return ""
        else:
            return decode(proc.out)
Пример #12
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)
Пример #13
0
async def _screenshot(
    unifying_chars: AbstractSet[str], uid: str
) -> Tuple[str, Iterator[str]]:
    try:
        proc = await call(
            "tmux",
            "capture-pane",
            "-p",
            "-t",
            uid,
            check_returncode=set(),
        )
    except OSError:
        return uid, iter(())
    else:
        if proc.code:
            return uid, iter(())
        else:
            words = coalesce(decode(proc.out), unifying_chars=unifying_chars)
            return uid, words
Пример #14
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
Пример #15
0
def _version(timeout: float) -> str:
    with urlopen(_VER, timeout=timeout) as resp:
        return decode(resp.read())