using System.Collections.Immutable; namespace Masuit.Tools.TextDiff; internal static class DifferBuilder { /// /// 添加上下文,直到它是唯一的,不要让模式扩展到Match_MaxBits之外 /// /// /// /// /// /// /// /// internal static (int start1, int length1, int start2, int length2) AddContext(this ImmutableList.Builder diffListBuilder, string text, int start1, int length1, int start2, int length2, short patchMargin = 4) { if (text.Length == 0) { return (start1, length1, start2, length2); } var pattern = text.Substring(start2, length1); var padding = 0; while (text.IndexOf(pattern, StringComparison.Ordinal) != text.LastIndexOf(pattern, StringComparison.Ordinal) && pattern.Length < TextDiffConstants.MatchMaxBits - patchMargin - patchMargin) { padding += patchMargin; var begin = Math.Max(0, start2 - padding); pattern = text[begin..Math.Min(text.Length, start2 + length1 + padding)]; } padding += patchMargin; var begin1 = Math.Max(0, start2 - padding); var prefix = text[begin1..start2]; if (prefix.Length != 0) { diffListBuilder.Insert(0, TextDiffer.Equal(prefix)); } var begin2 = start2 + length1; var length = Math.Min(text.Length, start2 + length1 + padding) - begin2; var suffix = text.Substring(begin2, length); if (suffix.Length != 0) { diffListBuilder.Add(TextDiffer.Equal(suffix)); } start1 -= prefix.Length; start2 -= prefix.Length; length1 = length1 + prefix.Length + suffix.Length; length2 = length2 + prefix.Length + suffix.Length; return (start1, length1, start2, length2); } }