* Given a pair of lines from a diff, returns more granular changes to the * lines. Attempts to only return changes that are useful. The current heuristic * is to only show granular changes if the ratio of change to unchanged parts in * the line is below a threshold, otherwise the lines have chang
(
context: Context,
lineA: string | null,
lineB: string | null
)
| 14 | * enough for the granular diffs to not be useful. |
| 15 | */ |
| 16 | function getChangesInLine( |
| 17 | context: Context, |
| 18 | lineA: string | null, |
| 19 | lineB: string | null |
| 20 | ): Change[] | null { |
| 21 | const { HIGHLIGHT_LINE_CHANGES } = context; |
| 22 | |
| 23 | if (!HIGHLIGHT_LINE_CHANGES || lineA === null || lineB === null) { |
| 24 | return null; |
| 25 | } |
| 26 | |
| 27 | // Drop the prefix |
| 28 | const lineTextA = lineA.slice(1); |
| 29 | const lineTextB = lineB.slice(1); |
| 30 | const changes = diffWords(lineTextA, lineTextB, { |
| 31 | ignoreCase: false, |
| 32 | ignoreWhitespace: false, |
| 33 | }); |
| 34 | |
| 35 | // Count how many words changed vs total words. Note that a replacement gets |
| 36 | // double counted. |
| 37 | let changedWords = 0; |
| 38 | let totalWords = 0; |
| 39 | for (const { added, removed, count } of changes) { |
| 40 | if (added || removed) { |
| 41 | changedWords += count ?? 0; |
| 42 | } else { |
| 43 | totalWords += count ?? 0; |
| 44 | } |
| 45 | } |
| 46 | if (changedWords > totalWords * HIGHLIGHT_CHANGE_RATIO) { |
| 47 | return null; |
| 48 | } |
| 49 | |
| 50 | return changes; |
| 51 | } |
| 52 | |
| 53 | export function getChangesInLines( |
| 54 | context: Context, |
no test coverage detected