def run_recorder(shell, prompt, aliases=None, envvars=None): commands = [] prefix = '(' + style('REC', fg='red') + ') ' while True: formatted_prompt = prefix + format_prompt(THEMES[prompt]) + ' ' command = click.prompt(formatted_prompt, prompt_suffix='').strip() if command == STOP_COMMAND: break elif command == PREVIEW_COMMAND: echo_rec_buffer(commands) elif command == UNDO_COMMAND: if commands and click.confirm( 'Remove command? "{}"'.format(commands[-1].strip())): commands.pop() secho('Removed command.', bold=True) echo_rec_buffer(commands) else: echo('No commands in buffer. Doing nothing.') elif command == 'python': commands.append('```python\n') console = PythonRecorderConsole() console.interact() commands.extend(console.commands) commands.append('```\n\n') elif command in HELP_COMMANDS: print_recorder_instructions() else: commands.append(command + '\n\n') run_command(command, shell=shell, aliases=aliases, envvars=envvars, test_mode=TESTING) return commands
def magictype(text, prompt_template="default", speed=1): """Echo each character in ``text`` as keyboard characters are pressed. Characters are echo'd ``speed`` characters at a time. """ echo_prompt(prompt_template) cursor_position = 0 with raw_mode(): while True: char = text[cursor_position:cursor_position + speed] in_char = getchar() if in_char in {ESC, CTRLC}: echo(carriage_return=True) raise click.Abort() elif in_char == BACKSPACE: if cursor_position > 0: echo("\b \b", nl=False) cursor_position -= 1 elif in_char in RETURNS: # Only return at end of command if cursor_position >= len(text): echo("\r", nl=True) break elif in_char == CTRLZ and hasattr(signal, "SIGTSTP"): # Background process os.kill(0, signal.SIGTSTP) # When doitlive is back in foreground, clear the terminal # and resume where we left off click.clear() echo_prompt(prompt_template) echo(text[:cursor_position], nl=False) else: if cursor_position < len(text): echo(char, nl=False) increment = min([speed, len(text) - cursor_position]) cursor_position += increment
def completion(): """Output completion (to be eval'd). For bash or zsh, add the following to your .bashrc or .zshrc: eval "$(doitlive completion)" For fish, add the following to ~/.config/fish/completions/doitlive.fish: eval (doitlive completion) """ shell = env.get('SHELL', None) if env.get('SHELL', None): echo( click_completion.get_code( shell=shell.split(os.sep)[-1], prog_name='doitlive' ) ) else: echo( 'Please ensure that the {SHELL} environment ' 'variable is set.'.format(SHELL=style('SHELL', bold=True)) ) sys.exit(1)
def preview_themes(): secho("Theme previews:", bold=True) echo() for name, template in THEMES.items(): echo('"{}" theme:'.format(name)) echo(format_prompt(template), nl=False) echo(" command arg1 arg2 ... argn") echo()
def stealthmode(state, is_run): if not is_run: return 0 continue_loop = True echo("\r", nl=True) while continue_loop: continue_loop = regularrun(**state) return 1
def wait_for(chars): while True: in_char = getchar() if in_char in {ESC, CTRLC}: echo(carriage_return=True) raise click.Abort() if in_char in chars: echo() return in_char
def run_command(cmd, shell=None, aliases=None, envvars=None, extra_commands=None, test_mode=False): shell = shell or get_default_shell() command_as_list = shlex.split(ensure_utf8(cmd)) if len(command_as_list) and command_as_list[0] == "cd": cwd = os.getcwd() # Save cwd directory = cmd.split()[1].strip() if directory == "-": # Go back to $OLDPWD directory = os.environ.get("OLDPWD", directory) try: os.chdir(os.path.expandvars(os.path.expanduser(directory))) except OSError: echo("No such file or directory: {}".format(directory)) else: os.environ["OLDPWD"] = cwd else: # Need to make a temporary command file so that $ENV are used correctly # and that shell built-ins, e.g. "source" work with NamedTemporaryFile("w") as fp: fp.write("#!{0}\n".format(shell)) fp.write("# -*- coding: utf-8 -*-\n") # Make aliases work in bash: if "bash" in shell: fp.write("shopt -s expand_aliases\n") # Write envvars and aliases write_commands(fp, "export", envvars) write_commands(fp, "alias", aliases) if extra_commands: for command in extra_commands: line = "{}\n".format(command) fp.write(ensure_utf8(line)) cmd_line = cmd + "\n" fp.write(ensure_utf8(cmd_line)) fp.flush() try: if test_mode: output = subprocess.check_output([shell, fp.name]) echo(output) else: return subprocess.call([shell, fp.name]) except KeyboardInterrupt: pass
def record(session_file, shell, prompt, alias, envvar): """Record a session file. If no argument is passed, commands are written to ./session.sh. When you are finished recording, run the "stop" command. """ if os.path.exists(session_file): click.confirm( 'File "{0}" already exists. Overwrite?'.format(session_file), abort=True, default=False, ) secho("We'll do it live!", fg="red", bold=True) filename = click.format_filename(session_file) secho("RECORDING SESSION: {}".format(filename), fg="yellow", bold=True) print_recorder_instructions() click.pause() click.clear() cwd = os.getcwd() # Save cwd # Run the recorder commands = run_recorder(shell, prompt, aliases=alias, envvars=envvar) os.chdir(cwd) # Reset cwd secho("FINISHED RECORDING SESSION", fg="yellow", bold=True) secho("Writing to {0}...".format(filename), fg="cyan") with open(session_file, "w", encoding="utf-8") as fp: fp.write(HEADER_TEMPLATE.format(shell=shell, prompt=prompt)) write_directives(fp, "alias", alias) write_directives(fp, "env", envvar) fp.write("\n") fp.write("".join(commands)) fp.write("\n") play_cmd = style("doitlive play {}".format(filename), bold=True) echo("Done. Run {} to play back your session.".format(play_cmd))
def echo_rec_buffer(commands): if commands: echo("Current commands in buffer:\n") for cmd in commands: echo(" " + cmd, nl=False) # commands already have newlines else: echo("No commands in buffer.")
def echo_rec_buffer(commands): if commands: echo('Current commands in buffer:\n') for cmd in commands: echo(' ' + cmd, nl=False) # commands already have newlines else: echo('No commands in buffer.')
def regulartype(prompt_template="default"): """Echo each character typed. Unlike magictype, this echos the characters the user is pressing. Returns: command_string | The command to be passed to the shell to run. This is | typed by the user. """ echo_prompt(prompt_template) command_string = "" cursor_position = 0 with raw_mode(): while True: in_char = getchar() if in_char in {ESC, CTRLC}: echo(carriage_return=True) raise click.Abort() elif in_char == TAB: echo("\r", nl=True) return in_char elif in_char == BACKSPACE: if cursor_position > 0: echo("\b \b", nl=False) command_string = command_string[:-1] cursor_position -= 1 elif in_char in RETURNS: echo("\r", nl=True) return command_string elif in_char == CTRLZ and hasattr(signal, "SIGTSTP"): # Background process os.kill(0, signal.SIGTSTP) # When doitlive is back in foreground, clear the terminal # and resume where we left off click.clear() echo_prompt(prompt_template) else: echo(in_char, nl=False) command_string += in_char cursor_position += 1
def run_recorder(shell, prompt, aliases=None, envvars=None): commands = [] prefix = "(" + style("REC", fg="red") + ") " while True: formatted_prompt = prefix + format_prompt(THEMES[prompt]) + " " command = click.prompt(formatted_prompt, prompt_suffix="").strip() if command == STOP_COMMAND: break elif command == PREVIEW_COMMAND: echo_rec_buffer(commands) elif command == UNDO_COMMAND: if commands and click.confirm('Remove command? "{}"'.format( commands[-1].strip())): commands.pop() secho("Removed command.", bold=True) echo_rec_buffer(commands) else: echo("No commands in buffer. Doing nothing.") elif command == "python": commands.append("```python\n") console = PythonRecorderConsole() console.interact() commands.extend(console.commands) commands.append("```\n\n") elif command in HELP_COMMANDS: print_recorder_instructions() else: commands.append(command + "\n\n") run_command( command, shell=shell, aliases=aliases, envvars=envvars, test_mode=TESTING, ) return commands
def print_recorder_instructions(): echo() echo("INSTRUCTIONS:") echo("Enter " + style("{}".format(STOP_COMMAND), bold=True) + " when you are done recording.") echo("To preview the commands in the buffer, enter {}.".format( style(PREVIEW_COMMAND, bold=True))) echo("To undo the last command in the buffer, enter {}.".format( style(UNDO_COMMAND, bold=True))) echo("To view this help message again, enter {}.".format( style(HELP_COMMANDS[0], bold=True))) echo()
def list_themes(): secho("Available themes:", bold=True) echo(" ".join(THEMES.keys()))
def print_recorder_instructions(): echo() echo('INSTRUCTIONS:') echo('Enter ' + style('{}'.format(STOP_COMMAND), bold=True) + ' when you are done recording.') echo('To preview the commands in the buffer, enter {}.' .format(style(PREVIEW_COMMAND, bold=True))) echo('To undo the last command in the buffer, enter {}.' .format(style(UNDO_COMMAND, bold=True))) echo('To view this help message again, enter {}.' .format(style(HELP_COMMANDS[0], bold=True))) echo()
def list_themes(): secho('Available themes:', bold=True) echo(' '.join(THEMES.keys()))