예제 #1
0
def _find_root(nvim: Nvim, _pattern: Any, filename: str,
               bufnr: int) -> Optional[str]:
    pattern: Optional[RootPattern] = _DECODER(_pattern)
    path = Path(filename)

    if not pattern:
        return str(get_cwd(nvim))
    else:
        for parent in path.parents:
            for member in parent.iterdir():
                name = member.name
                if name in pattern.exact:
                    return str(parent)
                else:
                    for glob in pattern.glob:
                        if fnmatch(name, glob):
                            return str(parent)
        else:
            if pattern.fallback is RPFallback.none:
                return None
            elif pattern.fallback is RPFallback.cwd:
                return str(get_cwd(nvim))
            elif pattern.fallback is RPFallback.home:
                return str(Path.home())
            elif pattern.fallback is RPFallback.parent:
                return str(path.parent)
            else:
                never(pattern)
예제 #2
0
def _sys_trash(nvim: Nvim) -> Callable[[Iterable[str]], None]:
    cwd = get_cwd(nvim)

    def cont(paths: Iterable[str]) -> None:
        def c1() -> None:
            cmd = "trash"
            if which(cmd):
                command = (cmd, "--", *paths)
                check_call(command,
                           stdin=DEVNULL,
                           stdout=PIPE,
                           stderr=PIPE,
                           cwd=cwd)
            else:
                raise LookupError(LANG("sys_trash_err"))

        def c2() -> None:
            try:
                c1()
            except (CalledProcessError, LookupError) as e:
                threadsafe_call(nvim, write, nvim, e, error=True)
            except Exception as e:
                log.exception("%s", e)
            else:
                enqueue_event(_refresh, True)

        pool.submit(c2)

    return cont
예제 #3
0
파일: markers.py 프로젝트: ms-jpq/chadtree
 def it() -> Iterator[PurePath]:
     cwd = get_cwd(nvim)
     for q in nvim.funcs.getqflist():
         bufnr = q["bufnr"]
         bufname = nvim.funcs.bufname(bufnr)
         if resolved := resolve_path(cwd, path=bufname):
             yield resolved
예제 #4
0
def _open(
    nvim: Nvim, state: State, settings: Settings, args: Sequence[str]
) -> Optional[Stage]:
    """
    Toggle sidebar
    """

    try:
        opts = _parse_args(args)
    except ArgparseError as e:
        write(nvim, e, error=True)
        return None
    else:
        if opts.version_ctl:
            if which("git"):
                try:
                    cwd = version_ctl_toplv(state.root.path)
                    new_state = new_root(
                        nvim, state=state, settings=settings, new_cwd=cwd, indices=set()
                    )
                except CalledProcessError:
                    write(nvim, LANG("cannot find version ctl root"), error=True)
                    return None
            else:
                write(nvim, LANG("cannot find version ctl root"), error=True)
                return None
        else:
            new_state = state

        raw_path = opts.path
        if raw_path:
            path = realpath(
                raw_path if isabs(raw_path) else join(get_cwd(nvim), raw_path)
            )
            if not exists(path):
                write(nvim, LANG("path not exist", path=path))
                return None
            else:
                next_state = (
                    maybe_path_above(
                        nvim, state=new_state, settings=settings, path=path
                    )
                    or new_state
                )
                _open_fm_window(
                    nvim, settings=settings, opts=opts, width=next_state.width
                )
                return Stage(next_state, focus=path)
        else:
            curr = find_current_buffer_name(nvim)
            stage = new_current_file(
                nvim, state=new_state, settings=settings, current=curr
            )
            _open_fm_window(nvim, settings=settings, opts=opts, width=new_state.width)
            return (
                Stage(stage.state, focus=curr)
                if stage
                else Stage(new_state, focus=curr)
            )
예제 #5
0
파일: autocmds.py 프로젝트: ms-jpq/coq-nvim
def _new_cwd(nvim: Nvim, stack: Stack) -> None:
    cwd = get_cwd(nvim)

    async def cont() -> None:
        s = state(cwd=cwd)
        await stack.ctdb.swap(s.cwd)

    go(nvim, aw=cont())
예제 #6
0
def _remove(
    nvim: Nvim,
    state: State,
    settings: Settings,
    is_visual: bool,
    yeet: Callable[[Executor, Iterable[PurePath]], None],
) -> Optional[Stage]:
    cwd, root = get_cwd(nvim), state.root.path
    nono = {cwd, root} | ancestors(cwd) | ancestors(root)

    selection = state.selection or {
        node.path
        for node in indices(nvim, state=state, is_visual=is_visual)
    }
    unified = unify_ancestors(selection)

    if not unified:
        return None
    elif not unified.isdisjoint(nono):
        write(nvim, LANG("operation not permitted on root"), error=True)
        return None
    else:
        display_paths = linesep.join(
            sorted((display_path(path, state=state) for path in unified),
                   key=strxfrm))

        question = LANG("ask_trash", display_paths=display_paths)
        ans = ask_mc(
            nvim,
            question=question,
            answers=LANG("ask_yesno"),
            answer_key={
                1: True,
                2: False
            },
        )

        if not ans:
            return None
        else:
            try:
                yeet(state.pool, unified)
            except Exception as e:
                write(nvim, e, error=True)
                return refresh(nvim, state=state, settings=settings)
            else:
                paths = {path.parent for path in unified}
                new_state = forward(state,
                                    settings=settings,
                                    selection=set(),
                                    paths=paths)

                kill_buffers(nvim,
                             last_used=new_state.window_order,
                             paths=selection,
                             reopen={})
                lsp_removed(nvim, paths=unified)
                return Stage(new_state)
예제 #7
0
def _changedir(nvim: Nvim, state: State, settings: Settings) -> Stage:
    """
    Follow cwd update
    """

    cwd = get_cwd(nvim)
    chdir(cwd)
    new_state = new_root(nvim, state=state, settings=settings, new_cwd=cwd)
    return Stage(new_state)
예제 #8
0
def _refocus(nvim: Nvim, state: State, settings: Settings,
             is_visual: bool) -> Stage:
    """
    Follow cwd update
    """

    cwd = get_cwd(nvim)
    new_state = new_root(nvim, state=state, settings=settings, new_cwd=cwd)
    focus = new_state.root.path
    return Stage(new_state, focus=focus)
예제 #9
0
파일: linter.py 프로젝트: hecjhs/nvim2
def current_ctx(nvim: Nvim) -> Tuple[str, BufContext]:
    cwd = get_cwd(nvim)
    buf = cur_buf(nvim)
    filename = buf_name(nvim, buf=buf)
    filetype = buf_filetype(nvim, buf=buf)
    tabsize: int = buf_get_option(nvim, buf=buf, key="tabstop")
    lines: Sequence[str] = buf_get_lines(nvim, buf=buf, lo=0, hi=-1)
    return cwd, BufContext(
        buf=buf, filename=filename, filetype=filetype, tabsize=tabsize, lines=lines
    )
예제 #10
0
def initial(nvim: Nvim, pool: Executor, settings: Settings) -> State:
    cwd = get_cwd(nvim)
    session_store = (Path(nvim.funcs.stdpath("cache")) /
                     "chad_sessions" if settings.xdg else SESSION_DIR)

    session = (load_session(cwd, session_store=session_store)
               if settings.session else None)
    index = session.index if session and session.index is not None else {cwd}

    show_hidden = (session.show_hidden
                   if session and session.show_hidden is not None else
                   settings.show_hidden)
    enable_vc = (session.enable_vc if session and session.enable_vc is not None
                 else settings.version_ctl.enable)

    selection: Selection = set()
    node = new(pool, root=cwd, index=index)
    marks = markers(nvim)
    vc = VCStatus()

    current = None
    filter_pattern = None

    derived = render(
        node,
        settings=settings,
        index=index,
        selection=selection,
        filter_pattern=filter_pattern,
        markers=marks,
        vc=vc,
        show_hidden=show_hidden,
        current=current,
    )

    state = State(
        pool=pool,
        session_store=session_store,
        index=index,
        selection=selection,
        filter_pattern=filter_pattern,
        show_hidden=show_hidden,
        follow=settings.follow,
        enable_vc=enable_vc,
        width=settings.width,
        root=node,
        markers=marks,
        vc=vc,
        current=current,
        derived=derived,
        window_order={},
    )
    return state
예제 #11
0
파일: runtime.py 프로젝트: ms-jpq/coq-nvim
def stack(pool: Executor, nvim: Nvim) -> Stack:
    settings = _settings(nvim)
    pum_width = nvim.options["pumwidth"]
    vars_dir = Path(
        nvim.funcs.stdpath("cache")) / "coq" if settings.xdg else VARS
    s = state(cwd=get_cwd(nvim), pum_width=pum_width)
    bdb, sdb, idb, tdb, ctdb, tmdb = (
        BDB(pool),
        SDB(pool, vars_dir=vars_dir),
        IDB(pool),
        TDB(pool),
        CTDB(pool, vars_dir=vars_dir, cwd=s.cwd),
        TMDB(pool),
    )
    reviewer = Reviewer(
        icons=settings.display.icons,
        options=settings.match,
        db=idb,
    )
    supervisor = Supervisor(
        pool=pool,
        nvim=nvim,
        vars_dir=vars_dir,
        match=settings.match,
        comp=settings.completion,
        limits=settings.limits,
        reviewer=reviewer,
    )
    workers = {
        *_from_each_according_to_their_ability(
            settings,
            bdb=bdb,
            sdb=sdb,
            tdb=tdb,
            ctdb=ctdb,
            tmdb=tmdb,
            supervisor=supervisor,
        )
    }
    stack = Stack(
        settings=settings,
        lru=LRU(size=settings.match.max_results),
        metrics={},
        bdb=bdb,
        sdb=sdb,
        idb=idb,
        tdb=tdb,
        ctdb=ctdb,
        tmdb=tmdb,
        supervisor=supervisor,
        workers=workers,
    )
    return stack
예제 #12
0
def initial(nvim: Nvim, settings: Settings) -> State:
    cwd = get_cwd(nvim)

    session = load_session(cwd, use_xdg=settings.xdg) if settings.session else None
    index = session.index if session and session.index is not None else {cwd}

    show_hidden = (
        session.show_hidden
        if session and session.show_hidden is not None
        else settings.show_hidden
    )
    enable_vc = (
        session.enable_vc
        if session and session.enable_vc is not None
        else settings.version_ctl.enable
    )

    selection: Selection = set()
    node = new(cwd, index=index)
    qf = quickfix(nvim)
    vc = VCStatus()

    current = None
    filter_pattern = None

    derived = render(
        node,
        settings=settings,
        index=index,
        selection=selection,
        filter_pattern=filter_pattern,
        qf=qf,
        vc=vc,
        show_hidden=show_hidden,
        current=current,
    )

    state = State(
        index=index,
        selection=selection,
        filter_pattern=filter_pattern,
        show_hidden=show_hidden,
        follow=settings.follow,
        enable_vc=enable_vc,
        width=settings.width,
        root=node,
        qf=qf,
        vc=vc,
        current=current,
        derived=derived,
    )
    return state
예제 #13
0
def quickfix(nvim: Nvim) -> QuickFix:
    cwd = get_cwd(nvim)
    ql = nvim.funcs.getqflist()

    def it() -> Iterator[str]:
        for q in ql:
            bufnr = q["bufnr"]
            filename = nvim.funcs.bufname(bufnr)
            yield join(cwd, filename)

    filenames = tuple(it())
    parents = (ancestor for fullname in filenames for ancestor in ancestors(fullname))
    locations = Counter(chain(filenames, parents))
    qf = QuickFix(locations=locations)
    return qf
예제 #14
0
파일: delete.py 프로젝트: chaudum/chadtree
def _remove(
    nvim: Nvim,
    state: State,
    settings: Settings,
    is_visual: bool,
    yeet: Callable[[Iterable[str]], None],
) -> Optional[Stage]:
    cwd, root = get_cwd(nvim), state.root.path
    nono = {cwd, root} | ancestors(cwd) | ancestors(root)

    selection = state.selection or {
        node.path
        for node in indices(nvim, state=state, is_visual=is_visual)
    }
    unified = unify_ancestors(selection)

    if not unified:
        return None
    elif not unified.isdisjoint(nono):
        write(nvim, LANG("operation not permitted on root"), error=True)
        return None
    else:
        display_paths = linesep.join(
            sorted((display_path(path, state=state) for path in unified),
                   key=strxfrm))

        question = LANG("ask_trash", display_paths=display_paths)
        resp: int = nvim.funcs.confirm(question, LANG("ask_yesno"), 2)
        ans = resp == 1

        if not ans:
            return None
        else:
            try:
                yeet(unified)
            except Exception as e:
                write(nvim, e, error=True)
                return refresh(nvim, state=state, settings=settings)
            else:
                paths = {dirname(path) for path in unified}
                new_state = forward(state,
                                    settings=settings,
                                    selection=set(),
                                    paths=paths)

                kill_buffers(nvim, paths=selection)
                return Stage(new_state)
예제 #15
0
def _cut(nvim: Nvim, state: State, settings: Settings,
         is_visual: bool) -> Optional[Stage]:
    """
    Cut selected
    """

    cwd, root = get_cwd(nvim), state.root.path
    nono = {cwd, root} | ancestors(cwd) | ancestors(root)
    return _operation(
        nvim,
        state=state,
        settings=settings,
        is_visual=is_visual,
        nono=nono,
        op_name=LANG("cut"),
        action=cut,
    )
예제 #16
0
def _open_sys(nvim: Nvim, state: State, settings: Settings, is_visual: bool) -> None:
    """
    Open using finder / dolphin, etc
    """

    node = next(indices(nvim, state=state, is_visual=is_visual), None)
    if not node:
        return None
    else:
        cwd = get_cwd(nvim)

        def cont() -> None:
            try:
                _open_gui(cast(Node, node).path, cwd=cwd)
            except (CalledProcessError, LookupError) as e:
                threadsafe_call(nvim, write, nvim, e, error=True)
            except Exception as e:
                log.exception("%s", e)

        pool.submit(cont)
예제 #17
0
def vc_refresh(nvim: Nvim, state: State, settings: Settings) -> None:
    """
    VC Refresh
    """

    if state.enable_vc:
        cwd = get_cwd(nvim)

        def cont() -> None:
            if _lock.locked():
                pass
            else:
                with _lock:
                    try:
                        vc = status(state.pool, cwd=cwd)
                    except Exception as e:
                        log.exception("%s", e)
                    else:
                        enqueue_event(_set_vc, vc)

        state.pool.submit(cont)
예제 #18
0
def _open(nvim: Nvim, state: State, settings: Settings,
          args: Sequence[str]) -> Optional[Stage]:
    """
    Toggle sidebar
    """

    try:
        opts = _parse_args(args)
    except ArgparseError as e:
        write(nvim, e, error=True)
        return None
    else:
        if opts.version_ctl:
            if which("git"):
                try:
                    cwd = version_ctl_toplv(state.root.path)
                    new_state = new_root(nvim,
                                         state=state,
                                         settings=settings,
                                         new_cwd=cwd,
                                         indices=set())
                except CalledProcessError:
                    write(nvim,
                          LANG("cannot find version ctl root"),
                          error=True)
                    return None
            else:
                write(nvim, LANG("cannot find version ctl root"), error=True)
                return None
        else:
            new_state = state

        if opts.path:
            path = opts.path if opts.path.is_absolute(
            ) else get_cwd(nvim) / opts.path
            if not exists(path, follow=True):
                new(state.pool, paths=(path, ))
            next_state = (maybe_path_above(
                nvim, state=new_state, settings=settings, path=path)
                          or new_state)
            _open_fm_window(
                nvim,
                settings=settings,
                opts=opts,
                window_order=new_state.window_order,
                width=next_state.width,
            )
            open_file(
                nvim,
                state=state,
                settings=settings,
                path=path,
                click_type=ClickType.primary,
            )
            return Stage(next_state, focus=path)
        else:
            curr = find_current_buffer_path(nvim)
            stage = (new_current_file(
                nvim, state=new_state, settings=settings, current=curr)
                     if curr else None)
            _open_fm_window(
                nvim,
                settings=settings,
                opts=opts,
                window_order=new_state.window_order,
                width=new_state.width,
            )
            return (Stage(stage.state, focus=curr)
                    if stage else Stage(new_state, focus=curr))
예제 #19
0
def snips(nvim: Nvim, stack: Stack, args: Sequence[str]) -> None:
    buf = cur_buf(nvim)
    ft = buf_filetype(nvim, buf=buf)

    try:
        ns = _parse_args(args, filetype=ft or "*")
    except ArgparseError as e:
        write(nvim, e, error=True)

    else:
        if ns.action == "ls":
            cwd = get_cwd(nvim)

            async def c1() -> None:
                _, mtimes = await user_mtimes(
                    nvim, user_path=stack.settings.clients.snippets.user_path
                )
                preview = tuple(
                    fmt_path(cwd, path=path, is_dir=False)
                    for path in sorted(mtimes, key=pathsort_key)
                )

                def cont() -> None:
                    if mtimes:
                        set_preview(nvim, syntax="", preview=preview)
                    else:
                        write(nvim, LANG("no snippets found"))

                await async_call(nvim, cont)

            go(nvim, aw=c1())

        elif ns.action == "cd":

            async def c2() -> None:
                paths = await snippet_paths(
                    nvim, user_path=stack.settings.clients.snippets.user_path
                )
                if paths:
                    path, *_ = paths
                    path.mkdir(parents=True, exist_ok=True)
                    await async_call(nvim, lambda: chdir(nvim, path))
                else:
                    assert False

            go(nvim, aw=c2())

        elif ns.action == "compile":

            async def c3() -> None:
                await awrite(nvim, LANG("waiting..."))
                try:
                    await compile_user_snippets(nvim, stack=stack)
                except (LoadError, ParseError) as e:
                    preview = str(e).splitlines()

                    def cont() -> None:
                        set_preview(nvim, syntax="", preview=preview)
                        write(nvim, LANG("snip parse fail"))

                    await async_call(nvim, cont)
                else:
                    await awrite(nvim, LANG("snip parse succ"))

            go(nvim, aw=c3())

        elif ns.action == "edit":

            async def c4() -> None:
                paths, mtimes = await user_mtimes(
                    nvim, user_path=stack.settings.clients.snippets.user_path
                )
                path, *_ = paths
                exts = {path.stem: path for path in mtimes}
                snip_path = exts.get(ns.filetype, path / f"{ns.filetype}.snip")
                snip_path.parent.mkdir(parents=True, exist_ok=True)

                def cont() -> None:
                    escaped = nvim.funcs.fnameescape(normcase(snip_path))
                    nvim.feedkeys(f":edit {escaped}", "n", False)

                await async_call(nvim, cont)

            go(nvim, aw=c4())

        else:
            assert False