#!/usr/bin/env python3 import argparse import os import sys import os.path as path from subprocess import call # Yeah XDG stuff does not really matter here defaultstore = path.join(os.getenv("HOME"), ".bookmarks") class Bookmarks(): def __init__(self, storepath=None): self.storepath = storepath or defaultstore self.store = {} if not path.exists(self.storepath): return with open(self.storepath, "r") as f: for line in f: # This breaks support for spaces in name and path line = line.split(" ") self.store[line[0]] = line[1][:-1] def save(self, name, path): if not name in self.store: # Easy just append with open(self.storepath, "a") as f: f.write(f"{name} {path}\n") return # Truncate it with open(self.storepath, "w") as f: for (k, v) in self.store.items(): # self.store should contain it's old values to we can jump to # something we are saving to if k == name: v = path f.write(f"{k} {v}\n") def load(self, name): parts = name.split(":") name = parts[0] p = self.store[name] if len(parts) > 1: p = path.join(p, parts[1]) return p def list(self): for (k, v) in self.store.items(): print(f"{k} => {v}") parser = argparse.ArgumentParser() parser.add_argument("--save", "-s", help="Save current location with name, if '.' pwd is used as name") parser.add_argument("--path", "-p", help="Specifies if `dest` is a real path and not a bookmark", action="store_true") parser.add_argument("--list", "-l", help="List bookmarks", action="store_true") parser.add_argument("--edit", "-e", help="Edit bookmark file with $EDITRO", action="store_true") parser.add_argument("--print", "-d", help="Just print the resulting path", action="store_true") parser.add_argument("dest", nargs="?", help="Where to go") args = parser.parse_args() if args.edit: editor = os.environ.get("EDITOR", "vi") ret = call([editor, defaultstore]) sys.exit(ret) bm = Bookmarks() if args.list: bm.list() # Whether to save if args.save: name = args.save if args.save != "." else os.getcwd() bm.save(name, os.getcwd()) if args.dest: where = bm.load(args.dest) if not args.path else args.dest if args.print: print(where) else: with open("/tmp/where", "w") as f: f.write(where) # This means zsh should go here sys.exit(3)