def create_io( self, input: Optional[Input] = None, output: Optional[Output] = None, error_output: Optional[Output] = None, ) -> IO: io = super().create_io(input, output, error_output) # Set our own CLI styles formatter = io.output.formatter formatter.set_style("c1", Style("cyan")) formatter.set_style("c2", Style("default", options=["bold"])) formatter.set_style("info", Style("blue")) formatter.set_style("comment", Style("green")) formatter.set_style("warning", Style("yellow")) formatter.set_style("debug", Style("default", options=["dark"])) formatter.set_style("success", Style("green")) # Dark variants formatter.set_style("c1_dark", Style("cyan", options=["dark"])) formatter.set_style("c2_dark", Style("default", options=["bold", "dark"])) formatter.set_style("success_dark", Style("green", options=["dark"])) io.output.set_formatter(formatter) io.error_output.set_formatter(formatter) self._io = io return io
def io(): io = BufferedIO() io.output.formatter.set_style("c1_dark", Style("cyan", options=["dark"])) io.output.formatter.set_style("c2_dark", Style("default", options=["bold", "dark"])) io.output.formatter.set_style("success_dark", Style("green", options=["dark"])) io.output.formatter.set_style("warning", Style("yellow")) return io
def create_io( self, input: Input | None = None, output: Output | None = None, error_output: Output | None = None, ) -> IO: io = super().create_io(input, output, error_output) io.output.formatter.set_style("info", Style("blue").bold()) io.error_output.formatter.set_style("info", Style("blue").bold()) return io
def init_styles(self, io: "IO") -> None: from cleo.formatters.style import Style for color in self.colors: style = Style(color) io.output.formatter.set_style(color, style) io.error_output.formatter.set_style(color, style)
def add_style( # type: ignore[misc] io: IO | Formatter, name: str, foreground: str | Style | None = None, background: str | None = None, options: list[str] | None = None, *, style: Style | None = None, ) -> None: """ Add a style to a Cleo IO or Formatter instance. """ if style is not None: assert foreground is None and background is None and options is None elif isinstance(foreground, Style): style = foreground assert background is None and options is None else: style = Style(foreground, background, options) if isinstance(io, IO): io.output.formatter.set_style(name, style) io.error_output.formatter.set_style(name, style) elif isinstance(io, Formatter): io.set_style(name, style) else: raise TypeError(f'expected IO|Formatter, got {type(io).__name__}')
def create_io( self, input: Optional[Input] = None, output: Optional[Output] = None, error_output: Optional[Output] = None, ) -> IO: io = super().create_io(input, output, error_output) # Remove when support for Python 3.6 is removed # https://github.com/python-poetry/poetry/issues/3412 if ( not PY37 and hasattr(io.output, "_stream") and hasattr(io.output._stream, "buffer") and io.output._stream.encoding != "utf-8" ): import io as io_ io.output._stream = io_.TextIOWrapper( io.output._stream.buffer, encoding="utf-8" ) # Set our own CLI styles formatter = io.output.formatter formatter.set_style("c1", Style("cyan")) formatter.set_style("c2", Style("default", options=["bold"])) formatter.set_style("info", Style("blue")) formatter.set_style("comment", Style("green")) formatter.set_style("warning", Style("yellow")) formatter.set_style("debug", Style("default", options=["dark"])) formatter.set_style("success", Style("green")) # Dark variants formatter.set_style("c1_dark", Style("cyan", options=["dark"])) formatter.set_style("c2_dark", Style("default", options=["bold", "dark"])) formatter.set_style("success_dark", Style("green", options=["dark"])) io.output.set_formatter(formatter) io.error_output.set_formatter(formatter) self._io = io return io
def io_decorated(): io = BufferedIO(decorated=True) io.output.formatter.set_style("c1", Style("cyan")) io.output.formatter.set_style("success", Style("green")) return io
def _autocomplete(self, io: IO) -> str: """ Autocomplete a question. """ autocomplete = self._autocomplete_values ret = "" i = 0 ofs = -1 matches = [x for x in autocomplete] num_matches = len(matches) stty_mode = subprocess.check_output(["stty", "-g"]).decode().rstrip("\n") # Disable icanon (so we can read each keypress) and echo (we'll do echoing here instead) subprocess.check_output(["stty", "-icanon", "-echo"]) # Add highlighted text style style = Style(options=["reverse"]) io.error_output.formatter.set_style("hl", style) # Read a keypress while True: c = io.read(1) # Backspace character if c == "\177": if num_matches == 0 and i != 0: i -= 1 # Move cursor backwards io.write_error("\033[1D") if i == 0: ofs = -1 matches = [x for x in autocomplete] num_matches = len(matches) else: num_matches = 0 # Pop the last character off the end of our string ret = ret[:i] # Did we read an escape sequence elif c == "\033": c += io.read(2) # A = Up Arrow. B = Down Arrow if c[2] == "A" or c[2] == "B": if c[2] == "A" and ofs == -1: ofs = 0 if num_matches == 0: continue ofs += -1 if c[2] == "A" else 1 ofs = (num_matches + ofs) % num_matches elif ord(c) < 32: if c == "\t" or c == "\n": if num_matches > 0 and ofs != -1: ret = matches[ofs] # Echo out remaining chars for current match io.write_error(ret[i:]) i = len(ret) if c == "\n": io.write_error(c) break num_matches = 0 continue else: io.write_error(c) ret += c i += 1 num_matches = 0 ofs = 0 for value in autocomplete: # If typed characters match the beginning chunk of value (e.g. [AcmeDe]moBundle) if value.startswith(ret) and i != len(value): num_matches += 1 matches[num_matches - 1] = value # Erase characters from cursor to end of line io.write_error("\033[K") if num_matches > 0 and ofs != -1: # Save cursor position io.write_error("\0337") # Write highlighted text io.write_error("<hl>" + matches[ofs][i:] + "</hl>") # Restore cursor position io.write_error("\0338") subprocess.call(["stty", "{}".format(stty_mode)]) return ret