value property
The current value stored in this notifier.
When the value is replaced with something that is not equal to the old value as evaluated by the equality operator ==, this class notifies its listeners.
Implementation
@override
T get value => _value;
Implementation
@override
set value(TextEditingValue newValue) {
final TextEditingValue oldValue = super.value;
const pairs = {'(': ')', '{': '}', '[': ']', '"': '"', "'": "'"};
final openers = pairs.keys.toSet();
final closers = pairs.values.toSet();
if (newValue.text.length == oldValue.text.length + 1 &&
newValue.selection.baseOffset > 0) {
final cursorPos = newValue.selection.baseOffset;
final inserted = newValue.text[cursorPos - 1];
if (openers.contains(inserted)) {
final closing = pairs[inserted]!;
final before = newValue.text.substring(0, cursorPos);
final after = newValue.text.substring(cursorPos);
super.value = TextEditingValue(
text: '$before$closing$after',
selection: TextSelection.collapsed(offset: cursorPos),
);
return;
}
if (closers.contains(inserted)) {
final oldCursorPos = oldValue.selection.baseOffset;
if (oldCursorPos < oldValue.text.length) {
final charAfterCursor = oldValue.text[oldCursorPos];
if (charAfterCursor == inserted) {
super.value = TextEditingValue(
text: oldValue.text,
selection: TextSelection.collapsed(offset: oldCursorPos + 1),
);
return;
}
}
}
}
if (newValue.text.length > oldValue.text.length &&
newValue.selection.baseOffset > 0 &&
newValue.text
.substring(0, newValue.selection.baseOffset)
.endsWith('\n')) {
final cursorPosition = newValue.selection.baseOffset;
final textBeforeCursor = newValue.text.substring(0, cursorPosition);
final textAfterCursor = newValue.text.substring(cursorPosition);
final lines = textBeforeCursor.split('\n');
if (lines.length < 2) {
super.value = newValue;
return;
}
final prevLine = lines[lines.length - 2];
final indentMatch = RegExp(r'^\s*').firstMatch(prevLine);
final prevIndent = indentMatch?.group(0) ?? '';
final shouldIndent = RegExp(r'[:{[(]\s*$').hasMatch(prevLine);
final extraIndent = shouldIndent ? ' ' * Shared().tabSize : '';
final indent = prevIndent + extraIndent;
final openToClose = {'{': '}', '(': ')', '[': ']'};
final trimmedPrev = prevLine.trimRight();
final lastChar = trimmedPrev.isNotEmpty
? trimmedPrev[trimmedPrev.length - 1]
: null;
final trimmedNext = textAfterCursor.trimLeft();
final nextChar = trimmedNext.isNotEmpty ? trimmedNext[0] : null;
final isBracketOpen = openToClose.containsKey(lastChar);
final isNextClosing = isBracketOpen && openToClose[lastChar] == nextChar;
String newText;
int newOffset;
if (isBracketOpen && isNextClosing) {
newText = '$textBeforeCursor$indent\n$prevIndent$textAfterCursor';
newOffset = cursorPosition + indent.length;
} else {
newText = '$textBeforeCursor$indent$textAfterCursor';
newOffset = cursorPosition + indent.length;
}
super.value = TextEditingValue(
text: newText,
selection: TextSelection.collapsed(offset: newOffset),
);
return;
}
super.value = newValue;
}