Skip to content
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

Issue192 paired symbols, issue199 yaml support #231

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
3 changes: 3 additions & 0 deletions example/lib/03.change_language_theme/constants.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ import 'package:highlight/languages/go.dart';
import 'package:highlight/languages/java.dart';
import 'package:highlight/languages/python.dart';
import 'package:highlight/languages/scala.dart';
import 'package:highlight/languages/yaml.dart';

final builtinLanguages = {
'dart': dart,
'go': go,
'java': java,
'python': python,
'scala': scala,
'yaml': yaml,
};

const languageList = <String>[
Expand All @@ -18,6 +20,7 @@ const languageList = <String>[
'java',
'python',
'scala',
'yaml',
];

const themeList = <String>[
Expand Down
7 changes: 7 additions & 0 deletions lib/src/code_field/code_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import 'package:highlight/highlight_core.dart';
import '../../flutter_code_editor.dart';
import '../autocomplete/autocompleter.dart';
import '../code/code_edit_result.dart';
import '../code_modifiers/paired_symbols.dart';
import '../history/code_history_controller.dart';
import '../history/code_history_record.dart';
import '../single_line_comments/parser/single_line_comments.dart';
Expand Down Expand Up @@ -124,6 +125,12 @@ class CodeController extends TextEditingController {
IndentModifier(),
CloseBlockModifier(),
TabModifier(),
PairedSymbolsCodeModifier(openChar: '(', closeString: ')'),
PairedSymbolsCodeModifier(openChar: '{', closeString: '}'),
PairedSymbolsCodeModifier(openChar: '[', closeString: ']'),
PairedSymbolsCodeModifier(openChar: '"', closeString: '"'),
PairedSymbolsCodeModifier(openChar: '`', closeString: '`'),
PairedSymbolsCodeModifier(openChar: '\'', closeString: '\''),
alexeyinkin marked this conversation as resolved.
Show resolved Hide resolved
],
}) : _analyzer = analyzer,
_readOnlySectionNames = readOnlySectionNames,
Expand Down
30 changes: 30 additions & 0 deletions lib/src/code_modifiers/paired_symbols.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import 'package:flutter/services.dart';

import '../code_field/editor_params.dart';
import 'code_modifier.dart';

class PairedSymbolsCodeModifier extends CodeModifier {
alexeyinkin marked this conversation as resolved.
Show resolved Hide resolved
final String openChar;
final String closeString;

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

@override
TextEditingValue? updateString(
String text,
TextSelection sel,
EditorParams params,
) {
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,
),
);
}
}
7 changes: 7 additions & 0 deletions lib/src/folding/parsers/parser_factory.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import 'package:highlight/highlight_core.dart';
import 'package:highlight/languages/java.dart';
import 'package:highlight/languages/python.dart';
import 'package:highlight/languages/yaml.dart';

import 'abstract.dart';
import 'highlight.dart';
import 'indent.dart';
import 'java.dart';
import 'python.dart';

Expand All @@ -15,6 +17,11 @@ class FoldableBlockParserFactory {
if (mode == java) {
return JavaFoldableBlockParser();
}

if (mode == yaml) {
return IndentFoldableBlockParser();
}

return HighlightFoldableBlockParser();
}
}
167 changes: 167 additions & 0 deletions test/src/code_modifiers/paired_symbols_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
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_test/flutter_test.dart';

void main() {
test('Paired symbols modifier test', () {
const examples = [
//
_Example(
'Add paired symbols at the start of the string',
initialValue: TextEditingValue(
text: 'dict',
// \ cursor
selection: TextSelection.collapsed(offset: 0),
),
expected: TextEditingValue(
text: '{}dict',
// \ cursor
selection: TextSelection.collapsed(offset: 1),
),
openChar: '{',
closeString: '}',
),

_Example(
'Add paired symbols in the middle of the string',
initialValue: TextEditingValue(
text: 'print',
// \ cursor
selection: TextSelection.collapsed(offset: 3),
),
expected: TextEditingValue(
text: 'pri()nt',
// \ cursor
selection: TextSelection.collapsed(offset: 4),
),
openChar: '(',
closeString: ')',
),

_Example(
'Add paired symbols at the end of the string',
initialValue: TextEditingValue(
text: 'print',
// \ cursor
selection: TextSelection.collapsed(offset: 5),
),
expected: TextEditingValue(
text: 'print[]',
// \ cursor
selection: TextSelection.collapsed(offset: 6),
),
openChar: '[',
closeString: ']',
),

_Example(
'Add paired symbols with several close chars',
initialValue: TextEditingValue(
text: 'string',
// \ cursor
selection: TextSelection.collapsed(offset: 6),
),
expected: TextEditingValue(
text: 'string123',
// \ cursor
selection: TextSelection.collapsed(offset: 7),
),
openChar: '1',
closeString: '23',
),

_Example(
'Add paired symbols before same close char',
initialValue: TextEditingValue(
text: 'string)',
// \ cursor
selection: TextSelection.collapsed(offset: 6),
),
expected: TextEditingValue(
text: 'string())',
// \ cursor
selection: TextSelection.collapsed(offset: 7),
),
openChar: '(',
closeString: ')',
),

_Example(
'Empty initial string',
initialValue: TextEditingValue(
// ignore: avoid_redundant_argument_values
text: '',
// \ cursor
selection: TextSelection.collapsed(offset: 0),
),
expected: TextEditingValue(
text: '()',
// \ cursor
selection: TextSelection.collapsed(offset: 1),
),
openChar: '(',
closeString: ')',
),
];

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

final controller = CodeController(
modifiers: [modifier],
);

controller.value = example.initialValue;

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

expect(
controller.value,
example.expected,
reason: example.name,
);
}
});
}

TextEditingValue _addCharToSelectedPosition(
TextEditingValue value,
String char,
) {
final selection = value.selection;
final text = value.text;

final newText = text.substring(0, selection.start) +
char +
text.substring(selection.start);

return TextEditingValue(
text: newText,
selection: TextSelection.collapsed(
offset: selection.start + char.length,
),
);
}

class _Example {
final String name;
final TextEditingValue initialValue;
final TextEditingValue expected;
final String openChar;
final String closeString;

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