private void UndoStack_PropertyChanged(object sender, PropertyChangedEventArgs e) { switch (e.PropertyName) { case nameof(this._document.UndoStack.SizeLimit): // HACK: UndoStack のサイズ変更を起点にファイルのリロードを検知 // たまたま ViewModel 側でサスペンドしているため実現できるが、 // 内部実装レベルで依存しており条件として非常に脆い。 this._baseDocument = new(this._document); break; case nameof(this._document.UndoStack.IsOriginalFile) when this._document.UndoStack.IsOriginalFile: break; default: return; } try { this.ChangeList.Clear(); this.ChangeList.Add(LineChangeInfo.Empty); var lastEnd = 0; var diff = new MyersDiffAlgorithm(this._baseDocument, this._document); foreach (var edit in diff.Edits) { var change = new LineChangeInfo(edit.Change, edit.BeginA, edit.EndA); this.ChangeList.InsertRange(this.ChangeList.Count, edit.BeginB - lastEnd, LineChangeInfo.Empty); if (edit.EndB == edit.BeginB) { this.ChangeList[^ 1] = change;
void ReloadDocument(TextDocument document, string newContent) { var diff = new MyersDiffAlgorithm(new StringSequence(document.Text), new StringSequence(newContent)); document.Replace(0, document.TextLength, newContent, diff.GetEdits().ToOffsetChangeMap()); document.UndoStack.ClearAll(); }
void SetupInitialFileState(bool update) { if (baseDocument == null) { if (update) { changeList.Transform(TransformLineChangeInfo); } else { changeList.InsertRange(0, document.LineCount + 1, LineChangeInfo.EMPTY); } } else { changeList.Clear(); Dictionary <string, int> hashes = new Dictionary <string, int>(); MyersDiffAlgorithm diff = new MyersDiffAlgorithm( new DocumentSequence(baseDocument, hashes), new DocumentSequence(document, hashes) ); changeList.Add(LineChangeInfo.EMPTY); int lastEndLine = 0; foreach (Edit edit in diff.GetEdits()) { int beginLine = edit.BeginB; int endLine = edit.EndB; changeList.InsertRange(changeList.Count, beginLine - lastEndLine, LineChangeInfo.EMPTY); if (endLine == beginLine) { changeList[changeList.Count - 1] = new LineChangeInfo(edit.EditType, edit.BeginA, edit.EndA); } else { changeList.InsertRange(changeList.Count, endLine - beginLine, new LineChangeInfo(edit.EditType, edit.BeginA, edit.EndA)); } lastEndLine = endLine; } changeList.InsertRange(changeList.Count, textDocument.LineCount - lastEndLine, LineChangeInfo.EMPTY); } OnChangeOccurred(EventArgs.Empty); }
void ReloadDocument(TextDocument document, string newContent) { var diff = new MyersDiffAlgorithm(new StringSequence(document.Text), new StringSequence(newContent)); document.Replace(0, document.TextLength, newContent, diff.GetEdits().ToOffsetChangeMap()); if (this.ClearUndoStackOnSwitch || documentFirstLoad) { document.UndoStack.ClearAll(); } if (documentFirstLoad) { documentFirstLoad = false; } }
public Patch(string exExpected, string exActual) { _a = new StringLinesSequence(exExpected ?? string.Empty); _b = new StringLinesSequence(exActual ?? string.Empty); _ma = new MyersDiffAlgorithm(_a, _b); }