From bef8acc3c3bcefd0c3d7ff1e3dc83c831e29341e Mon Sep 17 00:00:00 2001 From: Ethan Dalool Date: Wed, 9 Dec 2020 07:20:26 -0800 Subject: [PATCH] Add tempeditor.py. --- tempeditor.py | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 tempeditor.py diff --git a/tempeditor.py b/tempeditor.py new file mode 100644 index 0000000..e7e1693 --- /dev/null +++ b/tempeditor.py @@ -0,0 +1,75 @@ +import argparse +import os +import shlex +import subprocess +import sys +import tempfile + +from voussoirkit import pipeable +from voussoirkit import subproctools +from voussoirkit import winwhich + +class NoEditor(Exception): + pass + +class BadStatus(Exception): + pass + +def tempeditor(initial_text=None): + editor = os.environ.get('EDITOR') + if not editor: + raise NoEditor('You do not have an EDITOR variable.') + + command = shlex.split(editor) + command[0] = winwhich.which(command[0]) + + file = tempfile.TemporaryFile('r+', encoding='utf-8', prefix='tempeditor-', delete=False) + command.append(file.name) + + if initial_text: + file.write(initial_text) + + # The text editor may not be allowed to write to the file while Python has + # the file handle, so let's close it and re-open after the user is finished. + file.close() + + status = subprocess.check_call(command) + if status == 0: + handle = open(file.name, 'r', encoding='utf-8') + text = handle.read() + handle.close() + + try: + os.remove(file.name) + except Exception: + pass + + if status == 0: + return text + else: + raise BadStatus(subproctools.format_command(command), status) + +def tempeditor_argparse(args): + initial_text = '\n'.join(pipeable.input(args.initial_text)) if args.initial_text else None + try: + text = tempeditor(initial_text=initial_text) + pipeable.output(text) + return 0 + except NoEditor as exc: + pipeable.stderr(exc) + return 1 + except BadStatus as exc: + pipeable.stderr(f'Command {exc.args[0]} returned status {exc.args[1]}.') + return 1 + +def main(argv): + parser = argparse.ArgumentParser(description=__doc__) + + parser.add_argument('--text', dest='initial_text', default=None) + parser.set_defaults(func=tempeditor_argparse) + + args = parser.parse_args(argv) + return args.func(args) + +if __name__ == '__main__': + raise SystemExit(main(sys.argv[1:]))