|
6 | 6 |
|
7 | 7 | use Jfcherng\Diff\Renderer\AbstractRenderer;
|
8 | 8 | use Jfcherng\Diff\Utility\SequenceMatcher;
|
9 |
| -use Jfcherng\Utility\LevenshteinDistance; |
| 9 | +use Jfcherng\Utility\LevenshteinDistance as LD; |
10 | 10 | use Jfcherng\Utility\MbString;
|
11 | 11 | use RuntimeException;
|
12 | 12 |
|
@@ -243,56 +243,46 @@ protected function renderChangedExtentCharLevel(MbString $mbFromLine, MbString $
|
243 | 243 | // we prefer the char-level diff but if there is an exception like
|
244 | 244 | // "line too long", we fallback to line-level diff.
|
245 | 245 | try {
|
246 |
| - $editInfo = LevenshteinDistance::calculate( |
| 246 | + $editInfo = LD::calculate( |
247 | 247 | $mbFromLine->get(),
|
248 | 248 | $mbToLine->get(),
|
249 |
| - LevenshteinDistance::PROGRESS_SIMPLE |
| 249 | + true, |
| 250 | + LD::PROGRESS_MERGE_NEIGHBOR |
250 | 251 | );
|
251 | 252 | } catch (RuntimeException $e) {
|
252 | 253 | return $this->renderChangedExtentLineLevel($mbFromLine, $mbToLine);
|
253 | 254 | }
|
254 | 255 |
|
255 | 256 | // start to render
|
256 |
| - foreach ($editInfo['progresses'] as $step => $operation) { |
| 257 | + foreach ($editInfo['progresses'] as [$operation, $position,, $length]) { |
257 | 258 | switch ($operation) {
|
| 259 | + // default never happens though |
| 260 | + default: |
258 | 261 | // copy, render nothing
|
259 |
| - case LevenshteinDistance::OP_COPY: |
260 |
| - --$fromEditPos; |
261 |
| - --$toEditPos; |
| 262 | + case LD::OP_COPY: |
| 263 | + $fromEditPos -= $length; |
| 264 | + $toEditPos -= $length; |
262 | 265 | break;
|
263 | 266 | // delete, render 'from'
|
264 |
| - case LevenshteinDistance::OP_DELETE: |
265 |
| - --$fromEditPos; |
266 |
| - $mbFromLine->str_enclose_i(self::CLOSURES, $fromEditPos, 1); |
| 267 | + case LD::OP_DELETE: |
| 268 | + $fromEditPos -= $length; |
| 269 | + $mbFromLine->str_enclose_i(self::CLOSURES, $fromEditPos, $length); |
267 | 270 | break;
|
268 | 271 | // insert, render 'to'
|
269 |
| - case LevenshteinDistance::OP_INSERT: |
270 |
| - --$toEditPos; |
271 |
| - $mbToLine->str_enclose_i(self::CLOSURES, $toEditPos, 1); |
| 272 | + case LD::OP_INSERT: |
| 273 | + $toEditPos -= $length; |
| 274 | + $mbToLine->str_enclose_i(self::CLOSURES, $toEditPos, $length); |
272 | 275 | break;
|
273 | 276 | // replace, render both
|
274 |
| - case LevenshteinDistance::OP_REPLACE: |
275 |
| - --$fromEditPos; |
276 |
| - $mbFromLine->str_enclose_i(self::CLOSURES, $fromEditPos, 1); |
277 |
| - --$toEditPos; |
278 |
| - $mbToLine->str_enclose_i(self::CLOSURES, $toEditPos, 1); |
| 277 | + case LD::OP_REPLACE: |
| 278 | + $fromEditPos -= $length; |
| 279 | + $mbFromLine->str_enclose_i(self::CLOSURES, $fromEditPos, $length); |
| 280 | + $toEditPos -= $length; |
| 281 | + $mbToLine->str_enclose_i(self::CLOSURES, $toEditPos, $length); |
279 | 282 | break;
|
280 | 283 | }
|
281 | 284 | }
|
282 | 285 |
|
283 |
| - // check for editPos, render for the string head |
284 |
| - // Note: at least, one of the editPos must be zero |
285 |
| - assert($fromEditPos === 0 || $toEditPos === 0); |
286 |
| - |
287 |
| - // render the string head |
288 |
| - if ($fromEditPos !== $toEditPos) { |
289 |
| - if ($fromEditPos === 0) { |
290 |
| - $mbToLine->str_enclose_i(self::CLOSURES, 0, $toEditPos); |
291 |
| - } else { |
292 |
| - $mbFromLine->str_enclose_i(self::CLOSURES, 0, $fromEditPos); |
293 |
| - } |
294 |
| - } |
295 |
| - |
296 | 286 | // cleanup redundant tags
|
297 | 287 | $mbFromLine->str_replace_i(self::CLOSURES[1] . self::CLOSURES[0], '');
|
298 | 288 | $mbToLine->str_replace_i(self::CLOSURES[1] . self::CLOSURES[0], '');
|
|
0 commit comments