Skip to content

Instantly share code, notes, and snippets.

Last active January 28, 2022 05:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save s-zeid/cb35ee68134bc4fe5878ccdd154189bc to your computer and use it in GitHub Desktop.
Save s-zeid/cb35ee68134bc4fe5878ccdd154189bc to your computer and use it in GitHub Desktop.
(moved to Use Vim to browse archives supported by p7zip
#!/usr/bin/env python3
"""A tar(1)-like interface for 7z(1)."""
import argparse
import os
import subprocess
import sys
from typing import *
from typing import IO, BinaryIO
def print_bytes(
*values: bytes,
sep: bytes = b" ",
end: bytes = b"\n",
file: BinaryIO = None,
if file is None:
file = sys.stdout.buffer
first = True
for v in values:
if not first:
first = False
if end:
def run(
cmd: List[str],
pipe: bool = True,
stdin: Union[IO[Any], int] = None,
) -> subprocess.CompletedProcess:
stdout=subprocess.PIPE if pipe else None,
def main(argv: List[str]) -> int:
p = argparse.ArgumentParser(description=__doc__)
c = p.add_argument_group("commands")
m = c.add_mutually_exclusive_group()
m.add_argument("-c", "--create", action="store_true",
help="create a new archive")
m.add_argument("-r", "--append", action="store_true",
help="append files to the archive")
m.add_argument("-t", "--list", action="store_true",
help="list the archive's contents")
m.add_argument("-u", "--update", action="store_true",
help="append files which are newer")
m.add_argument("-x", "--extract", "--get", action="store_true",
help="extract the archive or files from it")
p.add_argument("-f", "--file", dest="archive", metavar="ARCHIVE", default="-",
help="the archive to manipulate")
p.add_argument("files", nargs=argparse.REMAINDER,
help="the files to maniuplate")
p.add_argument("-O", "--to-stdout", action="store_true",
help="write files to standard output")
p.add_argument("-P", "--absolute-names", action="store_true",
help="store leading slashes when creating archives")
p.add_argument("--hep", dest="_hep_easter_egg", action="store_true",
options = p.parse_args(argv[1:])
if options._hep_easter_egg:
print("Hep! Hep! I'm covered in sawlder! ... Eh? Nobody comes.")
print("--Red Green,")
return 0
have_command = any([
options.list, options.extract, options.update, options.append, options.create
if not have_command:
p.error("a command must be given")
if options.archive == "-":
p.error("7z does not support reading archives from standard input")
if options.list:
r = run(["7z", "l", "-slt", options.archive] + options.files)
have_files = False
filename = None
for l in r.stdout.splitlines():
if l == b"----------":
have_files = True
if have_files and l.startswith(b"Path = "):
if filename is not None:
filename = None
filename = l[7:]
if filename is not None and l.startswith(b"Folder = "):
if l[-1] == ord(b"+"):
filename = None
if filename is not None:
return 0
if options.extract:
so_arg = ["-so"] if options.to_stdout else []
run(["7z", "x"] + so_arg + [options.archive] + options.files, pipe=not bool(so_arg))
return 0
if options.update:
run(["7z", "u", options.archive] + options.files)
return 0
if options.append or options.create:
if options.create and os.path.exists(options.archive):
run(["7z", "a", options.archive] + options.files)
return 0
raise RuntimeError("BUG: unreachable code reached")
except subprocess.CalledProcessError as exc:
if exc.stdout:
return exc.returncode
except SystemExit as exc:
return exc.code
if __name__ == "__main__":
except KeyboardInterrupt:
if [ $# -lt 1 ]; then
echo "usage: $(basename -- "$0") <archive> [{vim option} [...]]" >&2
echo >&2
echo "Browse a 7z(1)-compatible archive in Vim." >&2
exit 2
export _7ZVIM_ARCHIVE="$1"
exec vim +'let g:tar_cmd="7zt"' +'call tar#Browse($_7ZVIM_ARCHIVE)' "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment