forked from akvelon/flutter-code-editor
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcode_lines_builder.dart
62 lines (53 loc) · 1.81 KB
/
code_lines_builder.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import 'package:collection/collection.dart';
import 'code_line.dart';
import 'code_lines.dart';
class CodeLinesBuilder {
static CodeLines textToCodeLines({
required String text,
required Map<int, bool> readonlyCommentsByLine,
}) {
final result = <CodeLine>[];
final lines = _splitText(text);
int charIndex = 0;
for (int lineIndex = 0; lineIndex < lines.length; lineIndex++) {
final line = lines[lineIndex];
final isReadOnly = _isLineReadonly(
containsReadonlyComment: readonlyCommentsByLine[lineIndex],
isLastLine: lineIndex == lines.length - 1,
isEmptyLine: line.isEmpty,
isPreviousLineReadonly: result.lastOrNull?.isReadOnly,
);
result.add(
CodeLine.fromTextAndStart(line, charIndex, isReadOnly: isReadOnly),
);
charIndex += line.length;
}
return CodeLines(result);
}
static List<String> _splitText(String text) {
final lines = text.split('\n');
final result = <String>[];
for (var lineIndex = 0; lineIndex < lines.length; lineIndex++) {
final line = lines[lineIndex];
final isLastLine = lineIndex == lines.length - 1;
final lineText = isLastLine ? line : '$line\n';
result.add(lineText);
}
return result;
}
static bool _isLineReadonly({
required bool? containsReadonlyComment,
required bool isLastLine,
required bool isEmptyLine,
required bool? isPreviousLineReadonly,
}) {
bool isReadOnly = containsReadonlyComment ?? false;
// If last line is empty, it inherits isReadOnly from the previous line.
// Otherwise, if we wanted a read-only document end, we could
// not use newline at the end of it as POSIX requires.
if (isLastLine && isEmptyLine) {
isReadOnly = isPreviousLineReadonly ?? false;
}
return isReadOnly;
}
}