| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248 |
- namespace Terminal.Gui.Views;
- internal class HistoryText
- {
- private readonly List<HistoryTextItemEventArgs> _historyTextItems = [];
- private int _idxHistoryText = -1;
- private readonly List<List<Cell>> _originalCellsList = [];
- public bool HasHistoryChanges => _idxHistoryText > -1;
- public bool IsFromHistory { get; private set; }
- public void Add (List<List<Cell>> lines, Point curPos, TextEditingLineStatus lineStatus = TextEditingLineStatus.Original)
- {
- if (lineStatus == TextEditingLineStatus.Original && _historyTextItems.Count > 0 && _historyTextItems.Last ().LineStatus == TextEditingLineStatus.Original)
- {
- return;
- }
- if (lineStatus == TextEditingLineStatus.Replaced && _historyTextItems.Count > 0 && _historyTextItems.Last ().LineStatus == TextEditingLineStatus.Replaced)
- {
- return;
- }
- if (_historyTextItems.Count == 0 && lineStatus != TextEditingLineStatus.Original)
- {
- throw new ArgumentException ("The first item must be the original.");
- }
- if (_idxHistoryText >= 0 && _idxHistoryText + 1 < _historyTextItems.Count)
- {
- _historyTextItems.RemoveRange (
- _idxHistoryText + 1,
- _historyTextItems.Count - _idxHistoryText - 1
- );
- }
- _historyTextItems.Add (new (lines, curPos, lineStatus));
- _idxHistoryText++;
- }
- public event EventHandler<HistoryTextItemEventArgs>? ChangeText;
- public void Clear (List<List<Cell>> cellsList)
- {
- _historyTextItems.Clear ();
- _idxHistoryText = -1;
- _originalCellsList.Clear ();
- // Save a copy of the original, not the reference
- foreach (List<Cell> cells in cellsList)
- {
- _originalCellsList.Add ([.. cells]);
- }
- OnChangeText (null);
- }
- public bool IsDirty (List<List<Cell>> cellsList)
- {
- if (cellsList.Count != _originalCellsList.Count)
- {
- return true;
- }
- for (var r = 0; r < cellsList.Count; r++)
- {
- List<Cell> cells = cellsList [r];
- List<Cell> originalCells = _originalCellsList [r];
- if (cells.Count != originalCells.Count)
- {
- return true;
- }
- for (var c = 0; c < cells.Count; c++)
- {
- Cell cell = cells [c];
- Cell originalCell = originalCells [c];
- if (!cell.Equals (originalCell))
- {
- return true;
- }
- }
- }
- return false;
- }
- public void Redo ()
- {
- if (_historyTextItems?.Count > 0 && _idxHistoryText < _historyTextItems.Count - 1)
- {
- IsFromHistory = true;
- _idxHistoryText++;
- var historyTextItem = new HistoryTextItemEventArgs (_historyTextItems [_idxHistoryText]) { IsUndoing = false };
- ProcessChanges (ref historyTextItem);
- IsFromHistory = false;
- }
- }
- public void ReplaceLast (List<List<Cell>> lines, Point curPos, TextEditingLineStatus lineStatus)
- {
- HistoryTextItemEventArgs? found = _historyTextItems.FindLast (x => x.LineStatus == lineStatus);
- if (found is { })
- {
- found.Lines = lines;
- found.CursorPosition = curPos;
- }
- }
- public void Undo ()
- {
- if (_historyTextItems?.Count > 0 && _idxHistoryText > 0)
- {
- IsFromHistory = true;
- _idxHistoryText--;
- var historyTextItem = new HistoryTextItemEventArgs (_historyTextItems [_idxHistoryText]) { IsUndoing = true };
- ProcessChanges (ref historyTextItem);
- IsFromHistory = false;
- }
- }
- private void OnChangeText (HistoryTextItemEventArgs? lines) { ChangeText?.Invoke (this, lines!); }
- private void ProcessChanges (ref HistoryTextItemEventArgs historyTextItem)
- {
- if (historyTextItem.IsUndoing)
- {
- if (_idxHistoryText - 1 > -1
- && (_historyTextItems [_idxHistoryText - 1].LineStatus == TextEditingLineStatus.Added
- || _historyTextItems [_idxHistoryText - 1].LineStatus == TextEditingLineStatus.Removed
- || (historyTextItem.LineStatus == TextEditingLineStatus.Replaced && _historyTextItems [_idxHistoryText - 1].LineStatus == TextEditingLineStatus.Original)
- || (historyTextItem.LineStatus == TextEditingLineStatus.Attribute && _historyTextItems [_idxHistoryText - 1].LineStatus == TextEditingLineStatus.Original)))
- {
- _idxHistoryText--;
- while (_historyTextItems [_idxHistoryText].LineStatus == TextEditingLineStatus.Added
- && _historyTextItems [_idxHistoryText - 1].LineStatus == TextEditingLineStatus.Removed)
- {
- _idxHistoryText--;
- }
- historyTextItem = new (_historyTextItems [_idxHistoryText]);
- historyTextItem.IsUndoing = true;
- historyTextItem.FinalCursorPosition = historyTextItem.CursorPosition;
- }
- if (historyTextItem.LineStatus == TextEditingLineStatus.Removed && _historyTextItems [_idxHistoryText + 1].LineStatus == TextEditingLineStatus.Added)
- {
- historyTextItem.RemovedOnAdded =
- new (_historyTextItems [_idxHistoryText + 1]);
- }
- if ((historyTextItem.LineStatus == TextEditingLineStatus.Added && _historyTextItems [_idxHistoryText - 1].LineStatus == TextEditingLineStatus.Original)
- || (historyTextItem.LineStatus == TextEditingLineStatus.Removed && _historyTextItems [_idxHistoryText - 1].LineStatus == TextEditingLineStatus.Original)
- || (historyTextItem.LineStatus == TextEditingLineStatus.Added && _historyTextItems [_idxHistoryText - 1].LineStatus == TextEditingLineStatus.Removed))
- {
- if (!historyTextItem.Lines [0]
- .SequenceEqual (_historyTextItems [_idxHistoryText - 1].Lines [0])
- && historyTextItem.CursorPosition == _historyTextItems [_idxHistoryText - 1].CursorPosition)
- {
- historyTextItem.Lines [0] =
- new (_historyTextItems [_idxHistoryText - 1].Lines [0]);
- }
- if (historyTextItem.LineStatus == TextEditingLineStatus.Added && _historyTextItems [_idxHistoryText - 1].LineStatus == TextEditingLineStatus.Removed)
- {
- historyTextItem.FinalCursorPosition =
- _historyTextItems [_idxHistoryText - 2].CursorPosition;
- }
- else
- {
- historyTextItem.FinalCursorPosition =
- _historyTextItems [_idxHistoryText - 1].CursorPosition;
- }
- }
- else
- {
- historyTextItem.FinalCursorPosition = historyTextItem.CursorPosition;
- }
- OnChangeText (historyTextItem);
- while (_historyTextItems [_idxHistoryText].LineStatus == TextEditingLineStatus.Removed
- || _historyTextItems [_idxHistoryText].LineStatus == TextEditingLineStatus.Added)
- {
- _idxHistoryText--;
- }
- }
- else if (!historyTextItem.IsUndoing)
- {
- if (_idxHistoryText + 1 < _historyTextItems.Count
- && (historyTextItem.LineStatus == TextEditingLineStatus.Original
- || _historyTextItems [_idxHistoryText + 1].LineStatus == TextEditingLineStatus.Added
- || _historyTextItems [_idxHistoryText + 1].LineStatus == TextEditingLineStatus.Removed))
- {
- _idxHistoryText++;
- historyTextItem = new (_historyTextItems [_idxHistoryText]);
- historyTextItem.IsUndoing = false;
- historyTextItem.FinalCursorPosition = historyTextItem.CursorPosition;
- }
- if (historyTextItem.LineStatus == TextEditingLineStatus.Added && _historyTextItems [_idxHistoryText - 1].LineStatus == TextEditingLineStatus.Removed)
- {
- historyTextItem.RemovedOnAdded =
- new (_historyTextItems [_idxHistoryText - 1]);
- }
- if ((historyTextItem.LineStatus == TextEditingLineStatus.Removed && _historyTextItems [_idxHistoryText + 1].LineStatus == TextEditingLineStatus.Replaced)
- || (historyTextItem.LineStatus == TextEditingLineStatus.Removed && _historyTextItems [_idxHistoryText + 1].LineStatus == TextEditingLineStatus.Original)
- || (historyTextItem.LineStatus == TextEditingLineStatus.Added && _historyTextItems [_idxHistoryText + 1].LineStatus == TextEditingLineStatus.Replaced))
- {
- if (historyTextItem.LineStatus == TextEditingLineStatus.Removed
- && !historyTextItem.Lines [0]
- .SequenceEqual (_historyTextItems [_idxHistoryText + 1].Lines [0]))
- {
- historyTextItem.Lines [0] =
- new (_historyTextItems [_idxHistoryText + 1].Lines [0]);
- }
- historyTextItem.FinalCursorPosition =
- _historyTextItems [_idxHistoryText + 1].CursorPosition;
- }
- else
- {
- historyTextItem.FinalCursorPosition = historyTextItem.CursorPosition;
- }
- OnChangeText (historyTextItem);
- while (_historyTextItems [_idxHistoryText].LineStatus == TextEditingLineStatus.Removed
- || _historyTextItems [_idxHistoryText].LineStatus == TextEditingLineStatus.Added)
- {
- _idxHistoryText++;
- }
- }
- }
- }
|