Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
86 lines
2.4 KiB
PHP
86 lines
2.4 KiB
PHP
<?php
|
||
|
||
declare(strict_types=1);
|
||
|
||
namespace LIT\MCP\Integrations\Divi\Release;
|
||
|
||
defined('ABSPATH') || exit;
|
||
|
||
/** A small line diff (longest common subsequence) for wp lit-mcp divi-check --diff. */
|
||
final class LineDiff
|
||
{
|
||
/**
|
||
* @param list<string> $old
|
||
* @param list<string> $new
|
||
* @return list<string> " kept", "- removed", "+ added"; "…" between changes more than 2 × $context lines apart.
|
||
*/
|
||
public static function lines(array $old, array $new, int $context = 2): array
|
||
{
|
||
$operations = self::operations($old, $new);
|
||
$keep = [];
|
||
foreach ($operations as $i => [$op]) {
|
||
if ($op === ' ') {
|
||
continue;
|
||
}
|
||
for ($j = max(0, $i - $context); $j <= min(count($operations) - 1, $i + $context); ++$j) {
|
||
$keep[$j] = true;
|
||
}
|
||
}
|
||
|
||
$lines = [];
|
||
$last = null;
|
||
foreach ($operations as $i => [$op, $line]) {
|
||
if (! isset($keep[$i])) {
|
||
continue;
|
||
}
|
||
if ($last !== null && $i > $last + 1) {
|
||
$lines[] = '…';
|
||
}
|
||
$lines[] = $op . ' ' . $line;
|
||
$last = $i;
|
||
}
|
||
|
||
return $lines;
|
||
}
|
||
|
||
/**
|
||
* @param list<string> $a
|
||
* @param list<string> $b
|
||
* @return list<array{0: string, 1: string}>
|
||
*/
|
||
private static function operations(array $a, array $b): array
|
||
{
|
||
$n = count($a);
|
||
$m = count($b);
|
||
$lcs = array_fill(0, $n + 1, array_fill(0, $m + 1, 0));
|
||
for ($i = $n - 1; $i >= 0; --$i) {
|
||
for ($j = $m - 1; $j >= 0; --$j) {
|
||
$lcs[$i][$j] = $a[$i] === $b[$j] ? $lcs[$i + 1][$j + 1] + 1 : max($lcs[$i + 1][$j], $lcs[$i][$j + 1]);
|
||
}
|
||
}
|
||
|
||
$operations = [];
|
||
$i = 0;
|
||
$j = 0;
|
||
while ($i < $n && $j < $m) {
|
||
if ($a[$i] === $b[$j]) {
|
||
$operations[] = [' ', $a[$i]];
|
||
++$i;
|
||
++$j;
|
||
} elseif ($lcs[$i + 1][$j] >= $lcs[$i][$j + 1]) {
|
||
$operations[] = ['-', $a[$i++]];
|
||
} else {
|
||
$operations[] = ['+', $b[$j++]];
|
||
}
|
||
}
|
||
while ($i < $n) {
|
||
$operations[] = ['-', $a[$i++]];
|
||
}
|
||
while ($j < $m) {
|
||
$operations[] = ['+', $b[$j++]];
|
||
}
|
||
|
||
return $operations;
|
||
}
|
||
}
|