def maybe_install(nvim: Nvim) -> None: UPDATE_LOG.parent.mkdir(parents=True, exist_ok=True) try: coded = UPDATE_LOG.read_text() before: datetime = decode(datetime, coded, decoders=(datetime_str_decoder, )) except (FileNotFoundError, DecodeError): before = datetime(year=1949, month=9, day=21, tzinfo=timezone.utc) now = datetime.now(tz=timezone.utc) diff = now - before if diff.days > 7: ans = ask_mc( nvim, question=LANG("update?"), answers=LANG("ask yes/no"), answer_key={ 1: 1, 2: 2 }, ) if ans: coded = encode(now, encoders=(datetime_str_encoder, )) UPDATE_LOG.write_text(coded) if ans == 1: open_term(nvim, executable, INSTALL_SCRIPT, "deps", "packages")
def open_file(nvim: Nvim, state: State, settings: Settings, path: PurePath, click_type: ClickType) -> Optional[Stage]: mime, _ = guess_type(path.name, strict=False) m_type, _, _ = (mime or "").partition(altsep or sep) question = LANG("mime_warn", name=path.name, mime=str(mime)) go = (ask_mc( nvim, question=question, answers=LANG("ask_yesno"), answer_key={ 1: True, 2: False }, ) if m_type in settings.mime.warn and path.suffix not in settings.mime.allow_exts else True) if go: new_state = forward(state, settings=settings, current=path) _show_file(nvim, state=new_state, settings=settings, click_type=click_type) return Stage(new_state, focus=path) else: return None
def maybe_install(nvim: Nvim) -> None: UPDATE_LOG.parent.mkdir(parents=True, exist_ok=True) try: coded = UPDATE_LOG.read_text() except FileNotFoundError: before = 0.0 else: before = float(coded) now = time() diff = now - before if diff > (7 * 24 * 3600): ans = ask_mc( nvim, question=LANG("update?"), answers=LANG("ask yes/no"), answer_key={ 1: 1, 2: 2 }, ) if ans: coded = str(now) UPDATE_LOG.write_text(coded) if ans == 1: open_term( nvim, Path(executable).resolve(strict=True), INSTALL_SCRIPT, "deps", "packages", )
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)
def _operation( nvim: Nvim, *, state: State, settings: Settings, is_visual: bool, nono: AbstractSet[str], op_name: str, action: Callable[[Mapping[str, str]], None], ) -> Optional[Stage]: root = state.root.path node = next(indices(nvim, state=state, is_visual=is_visual), None) selection = state.selection unified = unify_ancestors(selection) if not unified or not node: write(nvim, LANG("nothing_select"), error=True) return None elif not unified.isdisjoint(nono): write(nvim, LANG("operation not permitted on root"), error=True) return None else: pre_operations = {src: _find_dest(src, node) for src in unified} pre_existing = {s: d for s, d in pre_operations.items() if exists(d)} new_operations: MutableMapping[str, str] = {} while pre_existing: source, dest = pre_existing.popitem() rel_dest = display_path(dest, state=state) resp = ask(nvim, question=LANG("path_exists_err"), default=rel_dest) new_dest = join(root, resp) if resp else None if not new_dest: pre_existing[source] = dest break elif exists(new_dest): pre_existing[source] = new_dest else: new_operations[source] = new_dest if pre_existing: msg = linesep.join( f"{display_path(s, state=state)} -> {display_path(d, state=state)}" for s, d in sorted(pre_existing.items(), key=lambda t: strxfrm(t[0]))) write( nvim, LANG("paths already exist", operation=op_name, paths=msg), error=True, ) return None else: operations: Mapping[str, str] = { **pre_operations, **new_operations } msg = linesep.join( f"{display_path(s, state=state)} -> {display_path(d, state=state)}" for s, d in sorted(operations.items(), key=lambda t: strxfrm(t[0]))) question = LANG("confirm op", operation=op_name, paths=msg) ans = ask_mc( nvim, question=question, answers=LANG("ask_yesno"), answer_key={ 1: True, 2: False }, ) if not ans: return None else: try: action(operations) except Exception as e: write(nvim, e, error=True) return refresh(nvim, state=state, settings=settings) else: paths = { dirname(p) for p in chain(operations.keys(), operations.values()) } index = state.index | paths new_selection = {*operations.values()} new_state = forward( state, settings=settings, index=index, selection=new_selection, paths=paths, ) kill_buffers(nvim, paths=selection) return Stage(new_state)
def _operation( nvim: Nvim, *, state: State, settings: Settings, is_visual: bool, nono: AbstractSet[PurePath], op_name: str, is_move: bool, action: Callable[[Executor, Mapping[PurePath, PurePath]], None], ) -> Optional[Stage]: node = next(indices(nvim, state=state, is_visual=is_visual), None) selection = state.selection unified = unify_ancestors(selection) if not unified or not node: write(nvim, LANG("nothing_select"), error=True) return None elif not unified.isdisjoint(nono): write(nvim, LANG("operation not permitted on root"), error=True) return None else: pre_operations = {src: _find_dest(src, node) for src in unified} pre_existing = { s: d for s, d in pre_operations.items() if exists(d, follow=False) } new_operations: MutableMapping[PurePath, PurePath] = {} while pre_existing: source, dest = pre_existing.popitem() resp = ask(nvim, question=LANG("path_exists_err"), default=dest.name) new_dest = dest.parent / resp if resp else None if not new_dest: pre_existing[source] = dest break elif exists(new_dest, follow=False): pre_existing[source] = new_dest else: new_operations[source] = new_dest if pre_existing: msg = linesep.join( f"{display_path(s, state=state)} -> {display_path(d, state=state)}" for s, d in sorted(pre_existing.items(), key=lambda t: strxfrm(str(t[0])))) write( nvim, LANG("paths already exist", operation=op_name, paths=msg), error=True, ) return None else: operations = {**pre_operations, **new_operations} msg = linesep.join( f"{display_path(s, state=state)} -> {display_path(d, state=state)}" for s, d in sorted(operations.items(), key=lambda t: strxfrm(str(t[0])))) question = LANG("confirm op", operation=op_name, paths=msg) ans = ask_mc( nvim, question=question, answers=LANG("ask_yesno"), answer_key={ 1: True, 2: False }, ) if not ans: return None else: try: action(state.pool, operations) except Exception as e: write(nvim, e, error=True) return refresh(nvim, state=state, settings=settings) else: paths = { p.parent for p in chain(operations.keys(), operations.values()) } index = state.index | paths new_selection = {*operations.values()} new_state = forward( state, settings=settings, index=index, selection=new_selection, paths=paths, ) focus = next( iter( sorted( new_selection, key=lambda p: tuple(map(strxfrm, p.parts)), ), ), None, ) if is_move: kill_buffers( nvim, last_used=new_state.window_order, paths=selection, reopen={}, ) lsp_moved(nvim, paths=operations) else: lsp_created(nvim, paths=new_selection) return Stage(new_state, focus=focus)