""" Interactive user inputs """importosimportshleximportsubprocessimporttempfilefrompathlibimportPathfrom.logimportlog
[docs]defchoice(question,choices=None,default=None):""" Ask user to make a choice. .. code-block:: accepted = cli2.choice('Accept terms?') == 'y' :param question: String question to ask :param choices: List of acceptable choices, y/n by default :param default: Default value for when the user does not add a value. """choices=[c.lower()forcinchoicesor['y','n']]ifdefault:choices_display=[c.upper()ifc==default.lower()elsecforcinchoices]else:choices_display=choicesquestion=question+f' ({"/".join(choices_display)})'tries=30whiletries:answer=input(question)ifnotansweranddefault:returndefaultifanswer.lower()inchoices:returnanswer.lower()tries-=1
[docs]defeditor(content=None):""" Open $EDITOR with content, return the result. Like git rebase -i does! - If a file path is given, edit in place. - Otherwise, write to a temporary file. - Anyway: return the written contents. :param content: Initial content if any, or a file path :return: The edited content after $EDITOR exit """editor=os.getenv('EDITOR','vim')ifPath(content).exists():# open directly on target pathfilepath=contenttmp=Noneelse:tmp=tempfile.NamedTemporaryFile(mode='w+',delete=False,suffix=".txt",)withtmpasf:f.write(content)f.flush()filepath=f.namecommand=f"{editor}{shlex.quote(str(filepath))}"try:subprocess.run(shlex.split(command),check=True)exceptsubprocess.CalledProcessErrorase:log.error(f"Error running Vim: {e}")returnNoneexceptFileNotFoundError:log.warn(f"Temporary file gone?? {filepath}")returnNoneelse:withopen(filepath,'r')asf:content=f.read()returncontentfinally:iftmp:try:os.remove(filepath)exceptOSErrorase:log.warn(f"Error deleting temporary file {filepath}: {e}")