line.dart 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. import 'dart:math';
  2. import 'package:meta/meta.dart';
  3. import 'package:xterm/buffer/line/line_bytedata_data.dart';
  4. import 'package:xterm/buffer/line/line_list_data.dart';
  5. import 'package:xterm/terminal/cursor.dart';
  6. import 'package:xterm/util/constants.dart';
  7. @sealed
  8. class BufferLine {
  9. BufferLine({int length = 64, bool isWrapped = false}) {
  10. _data = BufferLineData(length: length, isWrapped: isWrapped);
  11. }
  12. BufferLine.withDataFrom(BufferLine other) {
  13. _data = other.data;
  14. }
  15. late BufferLineData _data;
  16. BufferLineData get data => _data;
  17. bool get isWrapped => _data.isWrapped;
  18. set isWrapped(bool value) => _data.isWrapped = value;
  19. void ensure(int length) => _data.ensure(length);
  20. void insert(int index) {
  21. _invalidateCaches();
  22. _data.insert(index);
  23. }
  24. void insertN(int index, int count) {
  25. _invalidateCaches();
  26. _data.insertN(index, count);
  27. }
  28. void removeN(int index, int count) {
  29. _invalidateCaches();
  30. _data.removeN(index, count);
  31. }
  32. void clear() {
  33. _invalidateCaches();
  34. _data.clear();
  35. }
  36. void erase(Cursor cursor, int start, int end, [bool resetIsWrapped = false]) {
  37. _invalidateCaches();
  38. _data.erase(cursor, start, end);
  39. }
  40. void cellClear(int index) {
  41. _invalidateCaches();
  42. _data.cellClear(index);
  43. }
  44. void cellInitialize(
  45. int index, {
  46. required int content,
  47. required int width,
  48. required Cursor cursor,
  49. }) {
  50. _invalidateCaches();
  51. _data.cellInitialize(
  52. index,
  53. content: content,
  54. width: width,
  55. cursor: cursor,
  56. );
  57. }
  58. bool cellHasContent(int index) => _data.cellHasContent(index);
  59. int cellGetContent(int index) => _data.cellGetContent(index);
  60. void cellSetContent(int index, int content) {
  61. _invalidateCaches();
  62. _data.cellSetContent(index, content);
  63. }
  64. int cellGetFgColor(int index) => _data.cellGetFgColor(index);
  65. void cellSetFgColor(int index, int color) =>
  66. _data.cellSetFgColor(index, color);
  67. int cellGetBgColor(int index) => _data.cellGetBgColor(index);
  68. void cellSetBgColor(int index, int color) =>
  69. _data.cellSetBgColor(index, color);
  70. int cellGetFlags(int index) => _data.cellGetFlags(index);
  71. void cellSetFlags(int index, int flags) => _data.cellSetFlags(index, flags);
  72. int cellGetWidth(int index) => _data.cellGetWidth(index);
  73. void cellSetWidth(int index, int width) {
  74. _invalidateCaches();
  75. _data.cellSetWidth(index, width);
  76. }
  77. void cellClearFlags(int index) => _data.cellClearFlags(index);
  78. bool cellHasFlag(int index, int flag) => _data.cellHasFlag(index, flag);
  79. void cellSetFlag(int index, int flag) => _data.cellSetFlag(index, flag);
  80. void cellErase(int index, Cursor cursor) {
  81. _invalidateCaches();
  82. _data.cellErase(index, cursor);
  83. }
  84. int getTrimmedLength([int? cols]) => _data.getTrimmedLength(cols);
  85. void copyCellsFrom(
  86. covariant BufferLine src, int srcCol, int dstCol, int len) {
  87. _invalidateCaches();
  88. _data.copyCellsFrom(src.data, srcCol, dstCol, len);
  89. }
  90. void removeRange(int start, int end) {
  91. _invalidateCaches();
  92. _data.removeRange(start, end);
  93. }
  94. void clearRange(int start, int end) {
  95. _invalidateCaches();
  96. _data.clearRange(start, end);
  97. }
  98. String toDebugString(int cols) => _data.toDebugString(cols);
  99. void _invalidateCaches() {
  100. _searchStringCache = null;
  101. }
  102. String? _searchStringCache;
  103. String toSearchString(int cols) {
  104. if (_searchStringCache != null) {
  105. return _searchStringCache!;
  106. }
  107. final searchString = StringBuffer();
  108. final length = getTrimmedLength();
  109. for (int i = 0; i < max(cols, length); i++) {
  110. var code = cellGetContent(i);
  111. if (code == 0) {
  112. searchString.writeAll(List<String>.filled(cellGetWidth(i), ' '));
  113. } else {
  114. searchString.writeCharCode(code);
  115. }
  116. }
  117. _searchStringCache = searchString.toString();
  118. return _searchStringCache!;
  119. }
  120. }
  121. abstract class BufferLineData {
  122. factory BufferLineData({int length = 64, bool isWrapped = false}) {
  123. if (kIsWeb) {
  124. return ListBufferLineData(length, isWrapped);
  125. }
  126. return ByteDataBufferLineData(length, isWrapped);
  127. }
  128. bool get isWrapped;
  129. set isWrapped(bool value);
  130. void ensure(int length);
  131. void insert(int index);
  132. void insertN(int index, int count);
  133. void removeN(int index, int count);
  134. void clear();
  135. void erase(Cursor cursor, int start, int end, [bool resetIsWrapped = false]);
  136. void cellClear(int index);
  137. void cellInitialize(
  138. int index, {
  139. required int content,
  140. required int width,
  141. required Cursor cursor,
  142. });
  143. bool cellHasContent(int index);
  144. int cellGetContent(int index);
  145. void cellSetContent(int index, int content);
  146. int cellGetFgColor(int index);
  147. void cellSetFgColor(int index, int color);
  148. int cellGetBgColor(int index);
  149. void cellSetBgColor(int index, int color);
  150. int cellGetFlags(int index);
  151. void cellSetFlags(int index, int flags);
  152. int cellGetWidth(int index);
  153. void cellSetWidth(int index, int width);
  154. void cellClearFlags(int index);
  155. bool cellHasFlag(int index, int flag);
  156. void cellSetFlag(int index, int flag);
  157. void cellErase(int index, Cursor cursor);
  158. int getTrimmedLength([int? cols]);
  159. void copyCellsFrom(
  160. covariant BufferLineData src, int srcCol, int dstCol, int len);
  161. // int cellGetHash(int index);
  162. void removeRange(int start, int end);
  163. void clearRange(int start, int end);
  164. @nonVirtual
  165. String toDebugString(int cols) {
  166. final result = StringBuffer();
  167. final length = getTrimmedLength();
  168. for (int i = 0; i < max(cols, length); i++) {
  169. var code = cellGetContent(i);
  170. if (code == 0) {
  171. if (cellGetWidth(i) == 0) {
  172. code = '_'.runes.first;
  173. } else {
  174. code = cellGetWidth(i).toString().runes.first;
  175. }
  176. }
  177. result.writeCharCode(code);
  178. }
  179. return result.toString();
  180. }
  181. }