def _write_error(self, io, error): """ Outputs an error message. """ message = "<error>{}</error>".format(decode(str(error))) io.error_line(message)
def write(self, string): # type: (str) -> None """ Writes a string to the stream. """ if self._closed: raise IOError("Cannot read from a closed input.") self._buffer += decode(string)
def _read_from_input(self, io): """ Read user input. """ ret = io.read_line(4096) if not ret: raise RuntimeError("Aborted") return decode(ret.strip())
def test_multibyte_support(ansi_bar, ansi_io): ansi_bar.start() ansi_bar.set_bar_character("■") ansi_bar.advance(3) output = [ " 0 [>---------------------------]", " 3 [■■■>------------------------]", ] expected = "\x0D" + "\x0D".join(output) assert decode(expected) == ansi_io.fetch_error()
def _autocomplete(self, io): # type: (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 = decode(subprocess.check_output(["stty", "-g"])).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("hl").fg("black").bg("white") io.error_output.formatter.add_style(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.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.error(ret[i:]) i = len(ret) if c == "\n": io.error(c) break num_matches = 0 continue else: io.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.error("\033[K") if num_matches > 0 and ofs != -1: # Save cursor position io.error("\0337") # Write highlighted text io.error("<hl>" + matches[ofs][i:] + "</hl>") # Restore cursor position io.error("\0338") subprocess.call(["stty", "{}".format(decode(stty_mode))]) return ret
def readline(): return encode(formatter.remove_format(decode( source_io.readline())))