Skip to content
Open
27 changes: 15 additions & 12 deletions lib/src/code_field/code_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import 'package:meta/meta.dart';
import '../../flutter_code_editor.dart';
import '../autocomplete/autocompleter.dart';
import '../code/code_edit_result.dart';
import '../code_modifiers/paired_symbols.dart';
import '../code/key_event.dart';
import '../code_modifiers/insertion.dart';
import '../history/code_history_controller.dart';
import '../history/code_history_record.dart';
import '../search/controller.dart';
Expand Down Expand Up @@ -136,6 +137,18 @@ class CodeController extends TextEditingController {
EnterKeyIntent: EnterKeyAction(controller: this),
};

static const defaultCodeModifiers = [
IndentModifier(),
CloseBlockModifier(),
TabModifier(),
InsertionCodeModifier.backticks,
InsertionCodeModifier.braces,
InsertionCodeModifier.brackets,
InsertionCodeModifier.doubleQuotes,
InsertionCodeModifier.parentheses,
InsertionCodeModifier.singleQuotes,
];

CodeController({
String? text,
Mode? language,
Expand All @@ -150,17 +163,7 @@ class CodeController extends TextEditingController {
this.readOnly = false,
this.stringMap,
this.params = const EditorParams(),
this.modifiers = const [
IndentModifier(),
CloseBlockModifier(),
TabModifier(),
PairedSymbolsCodeModifier(openChar: '(', closeString: ')'),
PairedSymbolsCodeModifier(openChar: '{', closeString: '}'),
PairedSymbolsCodeModifier(openChar: '[', closeString: ']'),
PairedSymbolsCodeModifier(openChar: '"', closeString: '"'),
PairedSymbolsCodeModifier(openChar: '`', closeString: '`'),
PairedSymbolsCodeModifier(openChar: '\'', closeString: '\''),
],
this.modifiers = defaultCodeModifiers,
}) : _analyzer = analyzer,
_readOnlySectionNames = readOnlySectionNames,
_code = Code.empty,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,32 @@ import 'package:flutter/services.dart';
import '../code_field/editor_params.dart';
import 'code_modifier.dart';

class PairedSymbolsCodeModifier extends CodeModifier {
class InsertionCodeModifier extends CodeModifier {
final String openChar;
final String closeString;

const PairedSymbolsCodeModifier({
const InsertionCodeModifier({
required this.openChar,
required this.closeString,
}) : super(openChar);

static const backticks =
InsertionCodeModifier(openChar: '`', closeString: '`');

static const braces = InsertionCodeModifier(openChar: '{', closeString: '}');

static const brackets =
InsertionCodeModifier(openChar: '[', closeString: ']');

static const doubleQuotes =
InsertionCodeModifier(openChar: '"', closeString: '"');

static const parentheses =
InsertionCodeModifier(openChar: '(', closeString: ')');

static const singleQuotes =
InsertionCodeModifier(openChar: '\'', closeString: '\'');

@override
TextEditingValue? updateString(
String text,
Expand Down
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need two tests:

  1. A unit test to InsertionCodeModifer with 1 and 23 strings.
  2. A test on CodeController that if created with the default parameters it handles all 6 pairs of characters.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import 'package:flutter/material.dart';
import 'package:flutter_code_editor/flutter_code_editor.dart';
import 'package:flutter_code_editor/src/code_modifiers/paired_symbols.dart';
import 'package:flutter_code_editor/src/code_modifiers/insertion.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
test('Paired symbols modifier test', () {
test('Insertion modifier test', () {
const examples = [
//
_Example(
'Add paired symbols at the start of the string',
'Add close char at the start of the string',
initialValue: TextEditingValue(
text: 'dict',
// \ cursor
Expand All @@ -19,12 +19,11 @@ void main() {
// \ cursor
selection: TextSelection.collapsed(offset: 1),
),
openChar: '{',
closeString: '}',
inputChar: '{',
),

_Example(
'Add paired symbols in the middle of the string',
'Add close char in the middle of the string',
initialValue: TextEditingValue(
text: 'print',
// \ cursor
Expand All @@ -35,12 +34,11 @@ void main() {
// \ cursor
selection: TextSelection.collapsed(offset: 4),
),
openChar: '(',
closeString: ')',
inputChar: '(',
),

_Example(
'Add paired symbols at the end of the string',
'Add close char at the end of the string',
initialValue: TextEditingValue(
text: 'print',
// \ cursor
Expand All @@ -51,12 +49,11 @@ void main() {
// \ cursor
selection: TextSelection.collapsed(offset: 6),
),
openChar: '[',
closeString: ']',
inputChar: '[',
),

_Example(
'Add paired symbols with several close chars',
'Add close with several close chars',
initialValue: TextEditingValue(
text: 'string',
// \ cursor
Expand All @@ -67,12 +64,12 @@ void main() {
// \ cursor
selection: TextSelection.collapsed(offset: 7),
),
openChar: '1',
closeString: '23',
inputChar: '1',
insertedString: '23',
),

_Example(
'Add paired symbols before same close char',
'Add close char before same close char',
initialValue: TextEditingValue(
text: 'string)',
// \ cursor
Expand All @@ -83,8 +80,7 @@ void main() {
// \ cursor
selection: TextSelection.collapsed(offset: 7),
),
openChar: '(',
closeString: ')',
inputChar: '(',
),

_Example(
Expand All @@ -100,26 +96,41 @@ void main() {
// \ cursor
selection: TextSelection.collapsed(offset: 1),
),
openChar: '(',
closeString: ')',
inputChar: '(',
),
];

for (final example in examples) {
final modifier = PairedSymbolsCodeModifier(
openChar: example.openChar,
closeString: example.closeString,
);

final controller = CodeController(
modifiers: [modifier],
);
final additionalModifier = example.insertedString != null
? InsertionCodeModifier(
openChar: example.inputChar,
closeString: example.insertedString!,
)
: null;

if (additionalModifier != null &&
CodeController.defaultCodeModifiers.any(
(e) =>
e is InsertionCodeModifier && e.openChar == example.inputChar,
)) {
fail('Modifier for ${example.inputChar} already exists');
}

late CodeController controller;

if (additionalModifier == null) {
controller = CodeController();
} else {
controller = CodeController(
modifiers: CodeController.defaultCodeModifiers + [additionalModifier],
);
}

controller.value = example.initialValue;

controller.value = _addCharToSelectedPosition(
controller.value,
example.openChar,
example.inputChar,
);

expect(
Expand Down Expand Up @@ -154,14 +165,14 @@ class _Example {
final String name;
final TextEditingValue initialValue;
final TextEditingValue expected;
final String openChar;
final String closeString;
final String inputChar;
final String? insertedString;

const _Example(
this.name, {
required this.initialValue,
required this.expected,
required this.openChar,
required this.closeString,
required this.inputChar,
this.insertedString,
});
}