autoCloseOpenUI function

String autoCloseOpenUI(
  1. String text
)

Autocloser: make partial (mid-stream) text syntactically valid by appending the minimal closing quote and brackets. Brackets inside strings do not count, a trailing comma is dropped, and a trailing backslash inside an unfinished string is dropped before closing it.

Implementation

String autoCloseOpenUI(String text) {
  var s = text.trimRight();
  while (s.endsWith(',')) {
    s = s.substring(0, s.length - 1).trimRight();
  }
  final stack = <String>[];
  String? quote;
  var escaped = false;
  for (var i = 0; i < s.length; i++) {
    final c = s[i];
    if (quote != null) {
      if (escaped) {
        escaped = false;
      } else if (c == '\\') {
        escaped = true;
      } else if (c == quote) {
        quote = null;
      }
      continue;
    }
    if (c == '"' || c == "'") {
      quote = c;
    } else if (c == '(' || c == '[' || c == '{') {
      stack.add(c);
    } else if (c == ')' || c == ']' || c == '}') {
      const pairs = {'(': ')', '[': ']', '{': '}'};
      if (stack.isNotEmpty && pairs[stack.last] == c) stack.removeLast();
    }
  }
  final buf = StringBuffer(s);
  if (quote != null) {
    if (buf.toString().endsWith('\\')) {
      // Drop the dangling escape before closing the string.
      final t = buf.toString();
      buf.clear();
      buf.write(t.substring(0, t.length - 1));
    }
    buf.write(quote);
  }
  const closers = {'(': ')', '[': ']', '{': '}'};
  for (var i = stack.length - 1; i >= 0; i--) {
    buf.write(closers[stack[i]]);
  }
  return buf.toString();
}