get function

String get(
  1. String message, {
  2. bool validate(
    1. String
    )?,
  3. String? defaultsTo,
  4. @deprecated bool colon = true,
  5. bool chevron = true,
  6. bool color = true,
  7. bool allowMultiline = false,
  8. bool conceal = false,
  9. AnsiCode inputColor = cyan,
})

Prompt the user, and return the first line read. This is the core of Prompter, and the basis for all other functions.

A function to validate may be passed. If null, it defaults to checking if the string is not empty.

A default value may be given as defaultsTo. If present, the message will have ' ($defaultsTo)' append to it.

If chevron is true (default), then a > will be appended to the prompt.

If color is true (default), then pretty ANSI colors will be used in the prompt.

inputColor may be used to give a color to the user's input as they type.

If allowMultiline is true (default: false), then lines ending in a backslash (\) will be interpreted as a signal that another line of input is to come. This is helpful for building REPL's.

Implementation

String get(String message,
    {bool Function(String)? validate,
    String? defaultsTo,
    @deprecated bool colon = true,
    bool chevron = true,
    bool color = true,
    bool allowMultiline = false,
    bool conceal = false,
    AnsiCode inputColor = cyan}) {
  validate ??= (s) => s.trim().isNotEmpty;

  if (defaultsTo != null) {
    var oldValidate = validate;
    validate = (s) => s.trim().isEmpty || oldValidate(s);
  }

  var prefix = '?';
  var code = cyan;
  var currentChevron = '\u00BB';
  var oldEchoMode = stdin.echoMode;

  void writeIt() {
    var msg = color
        ? (code.wrap(prefix)! + ' ' + wrapWith(message, [darkGray, styleBold])!)
        : message;
    stdout.write(msg);
    if (defaultsTo != null) stdout.write(' ($defaultsTo)');
    if (chevron && colon) {
      stdout.write(
          color ? lightGray.wrap(' $currentChevron') : ' $currentChevron');
    }

    stdout.write(' ');

    if (ansiOutputEnabled) {
      // Clear the rest of line.
      // ^[[0K
      stdout.add([$esc, $lbracket, $0, $K]);
    }

    // stdout.write(color ? inputColor?.escape ?? '' : '');
  }

  while (true) {
    if (message.isNotEmpty) {
      writeIt();
    }

    var buf = StringBuffer();
    if (conceal) stdin.echoMode = false;

    while (true) {
      var line = stdin.readLineSync()!.trim();

      if (!line.endsWith('\\')) {
        buf.writeln(line);
        break;
      } else {
        buf.writeln(line.substring(0, line.length - 1));
      }

      clearLine();
    }

    if (conceal) {
      stdin.echoMode = oldEchoMode;
      stdout.writeln();
    }

    // Reset
    // stdout.write(color ? resetAll.escape : '');

    var line = buf.toString().trim();

    if (validate(line)) {
      String out;

      if (defaultsTo != null) {
        out = line.isEmpty ? defaultsTo : line;
      } else {
        out = line;
      }

      if (color) {
        var toWrite = line;
        if (conceal) {
          var asterisks = List.filled(line.length, $asterisk);
          toWrite = String.fromCharCodes(asterisks);
        }

        prefix = '\u2714';
        code = green;
        currentChevron = '\u2025';

        if (ansiOutputEnabled) stdout.add([$esc, $F]);
        goUpOneLine();
        clearLine();
        writeIt();
        // stdout.write(color ? darkGray.escape : '');
        stdout.writeln(color ? darkGray.wrap(toWrite) : toWrite);
        // stdout.write(color ? resetAll.escape : '');
      }

      return out;
    } else {
      code = red;
      prefix = '\u2717';
      if (ansiOutputEnabled) stdout.add([$esc, $F]);

      // Clear the line.
      goUpOneLine();
      clearLine();
    }
  }
}