Skip to content

Automatically insert pair character for brackets, square braces, angle brackets, parentheses, quotes #192

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
alexeyinkin opened this issue Feb 16, 2023 · 2 comments · Fixed by #290 · May be fixed by #231
Closed

Automatically insert pair character for brackets, square braces, angle brackets, parentheses, quotes #192

alexeyinkin opened this issue Feb 16, 2023 · 2 comments · Fixed by #290 · May be fixed by #231
Labels

Comments

@alexeyinkin
Copy link
Contributor

No description provided.

@ivanmem
Copy link

ivanmem commented May 23, 2024

Pull request 231 works great! But they lack automatic removal of these same pairs of characters.
@Malarg Any ideas on how to implement this?

@ivanmem
Copy link

ivanmem commented May 31, 2024

I wrote an example of how it would also erase characters, but CodeModifier.updateString will need to be modified (added String newText)

  @override
  TextEditingValue? updateString(
    String text,
    String newText,
    TextSelection sel,
    EditorParams params,
  ) {
    if (newText.length > text.length) {
      final replaced =
          replace(text, sel.start, sel.end, '$openChar$closeString');
      return replaced.copyWith(
        selection: TextSelection(
          baseOffset: replaced.selection.baseOffset - closeString.length,
          extentOffset: replaced.selection.extentOffset - closeString.length,
        ),
      );
    }
    if (text.length - 1 == newText.length && text.length > sel.start) {
      final char = text[sel.start - 1];
      final nextChar = text[sel.start];
      if (char == openChar && nextChar == closeString) {
        final replaced = replace(text, sel.start - 1, sel.start + 1, '');
        return replaced;
      }
    }
    return null;
  }
abstract class CodeModifier {
  final String char;
  final bool insert;
  final bool remove;

  const CodeModifier(
    this.char, {
    this.insert = true,
    this.remove = false,
  });

  // Helper to insert [str] in [text] between [start] and [end]
  TextEditingValue replace(String text, int start, int end, String str) {
    final len = str.length;
    return TextEditingValue(
      text: text.replaceRange(start, end, str),
      selection: TextSelection(
        baseOffset: start + len,
        extentOffset: start + len,
      ),
    );
  }

  TextEditingValue? updateString(
    String text,
    String newText,
    TextSelection sel,
    EditorParams params,
  );
}

And change the code a little in code_controller.dart:

  int? _removedLoc(String a, String b) {
    final sel = selection;

    if (a.length - 1 != b.length || sel.start != sel.end || sel.start == -1) {
      return null;
    }

    return sel.start - 1;
  }

  void updateLoc(CodeModifier modifier) {
    final val = modifier.updateString(
      text,
      newValue.text,
      selection,
      params,
    );
    if (val != null) {
      // Update newValue
      newValue = newValue.copyWith(
        text: val.text,
        selection: val.selection,
      );
    }
  }

  final loc = _insertedLoc(text, newValue.text);
  if (loc != null) {
    final char = newValue.text[loc];
    final modifier = _modifierMap[char];
    if (modifier != null && modifier.insert) {
      updateLoc(modifier);
    }
  } else {
    final removedLoc = _removedLoc(text, newValue.text);
    if (removedLoc != null) {
      final char = text[removedLoc];
      final modifier = _modifierMap[char];
      if (modifier != null && modifier.remove) {
        updateLoc(modifier);
      }
    }
  }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
2 participants