DifferBuilder.cs 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. using System.Collections.Immutable;
  2. namespace Masuit.Tools.TextDiff;
  3. internal static class DifferBuilder
  4. {
  5. /// <summary>
  6. /// 添加上下文,直到它是唯一的,不要让模式扩展到Match_MaxBits之外
  7. /// </summary>
  8. /// <param name="diffListBuilder"></param>
  9. /// <param name="text"></param>
  10. /// <param name="length2"></param>
  11. /// <param name="patchMargin"></param>
  12. /// <param name="start1"></param>
  13. /// <param name="length1"></param>
  14. /// <param name="start2"></param>
  15. internal static (int start1, int length1, int start2, int length2) AddContext(this ImmutableList<TextDiffer>.Builder diffListBuilder, string text, int start1, int length1, int start2, int length2, short patchMargin = 4)
  16. {
  17. if (text.Length == 0)
  18. {
  19. return (start1, length1, start2, length2);
  20. }
  21. var pattern = text.Substring(start2, length1);
  22. var padding = 0;
  23. while (text.IndexOf(pattern, StringComparison.Ordinal) != text.LastIndexOf(pattern, StringComparison.Ordinal) && pattern.Length < TextDiffConstants.MatchMaxBits - patchMargin - patchMargin)
  24. {
  25. padding += patchMargin;
  26. var begin = Math.Max(0, start2 - padding);
  27. pattern = text[begin..Math.Min(text.Length, start2 + length1 + padding)];
  28. }
  29. padding += patchMargin;
  30. var begin1 = Math.Max(0, start2 - padding);
  31. var prefix = text[begin1..start2];
  32. if (prefix.Length != 0)
  33. {
  34. diffListBuilder.Insert(0, TextDiffer.Equal(prefix));
  35. }
  36. var begin2 = start2 + length1;
  37. var length = Math.Min(text.Length, start2 + length1 + padding) - begin2;
  38. var suffix = text.Substring(begin2, length);
  39. if (suffix.Length != 0)
  40. {
  41. diffListBuilder.Add(TextDiffer.Equal(suffix));
  42. }
  43. start1 -= prefix.Length;
  44. start2 -= prefix.Length;
  45. length1 = length1 + prefix.Length + suffix.Length;
  46. length2 = length2 + prefix.Length + suffix.Length;
  47. return (start1, length1, start2, length2);
  48. }
  49. }