Source code for ion._core

"""The ion package's catch-all module.

You should only add code to this module when you are unable to find ANY other
module to add it to.
"""

from __future__ import annotations

import logging
from subprocess import PIPE, Popen
import sys
import termios
from textwrap import wrap
import tty
from typing import Iterator


logger = logging.getLogger(__name__)


[docs]def getch(prompt: str = None) -> str: """Reads a single character from stdin. Args: prompt: prompt that is presented to user. Returns: The single character that was read. """ if prompt: sys.stdout.write(prompt) sys.stdout.flush() fd = sys.stdin.fileno() old_settings = termios.tcgetattr(fd) try: tty.setraw(sys.stdin.fileno()) ch = sys.stdin.read(1) finally: termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) return ch
[docs]def ewrap( multiline_msg: str, width: int = 80, indent: int = 0 ) -> Iterator[str]: """A better version of textwrap.wrap().""" for msg in multiline_msg.split("\n"): if not msg: yield "" continue msg = (" " * indent) + msg i = 0 while i < len(msg) and msg[i] == " ": i += 1 spaces = " " * i for m in wrap( msg, width, subsequent_indent=spaces, drop_whitespace=True ): yield m
[docs]def efill(multiline_msg: str, width: int = 80, indent: int = 0) -> str: """A better version of textwrap.fill().""" return "\n".join(ewrap(multiline_msg, width, indent))
[docs]def confirm(prompt: str) -> bool: """Prompt user for 'y' or 'n' answer. Returns: True iff the user responds to the @prompt with 'y'. """ prompt += " (y/n): " y_or_n = input(prompt) return y_or_n == "y"
def box(title: str) -> str: """Wraps @title in a pretty ASCII box.""" middle = f"| {title} |" top = bottom = "+" + ("-" * (len(middle) - 2)) + "+" return f"{top}\n{middle}\n{bottom}"
[docs]def copy_to_clipboard(clip: str) -> None: """Copys a clip to the system clipboard. Args: clip: The clip that gets copied into the clipboard. """ if _command_exists("xclip"): tool = "xclip" cmd_list = ["xclip", "-sel", "clip"] elif _command_exists("pbcopy"): tool = "pbcopy" cmd_list = ["pbcopy"] else: logger.warning("Neither xclip nor pbcopy are installed.") return popen = Popen(cmd_list, stdin=PIPE) popen.communicate(input=clip.encode()) logger.info("Copied %s into clipboard using %s.", clip, tool)
def _command_exists(cmd: str) -> bool: """Returns True iff the shell command ``cmd`` exists.""" popen = Popen("hash {}".format(cmd), shell=True, stdout=PIPE, stderr=PIPE) return popen.wait() == 0