| b69ab31 | | | 1 | /** |
| b69ab31 | | | 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. |
| b69ab31 | | | 3 | * |
| b69ab31 | | | 4 | * This source code is licensed under the MIT license found in the |
| b69ab31 | | | 5 | * LICENSE file in the root directory of this source tree. |
| b69ab31 | | | 6 | */ |
| b69ab31 | | | 7 | |
| b69ab31 | | | 8 | type HunkGroup = { |
| b69ab31 | | | 9 | common: string[]; |
| b69ab31 | | | 10 | removed: string[]; |
| b69ab31 | | | 11 | added: string[]; |
| b69ab31 | | | 12 | }; |
| b69ab31 | | | 13 | |
| b69ab31 | | | 14 | /** |
| b69ab31 | | | 15 | * We must find the groups within `lines` so that multiline sequences of |
| b69ab31 | | | 16 | * modified lines are displayed correctly. A group is defined by: |
| b69ab31 | | | 17 | * |
| b69ab31 | | | 18 | * - a sequence of 0 or more "common lines" that start with ' ' |
| b69ab31 | | | 19 | * - a sequence of 0 or more "removed lines" that start with '-' |
| b69ab31 | | | 20 | * - a sequence of 0 or more "added lines" that start with '+' |
| b69ab31 | | | 21 | * |
| b69ab31 | | | 22 | * Therefore, the end of a group is determined by either: |
| b69ab31 | | | 23 | * |
| b69ab31 | | | 24 | * - reaching the end of a list of lines |
| b69ab31 | | | 25 | * - encountering a "common line" after an "added" or "removed" line. |
| b69ab31 | | | 26 | */ |
| b69ab31 | | | 27 | export default function organizeLinesIntoGroups(lines: string[]): HunkGroup[] { |
| b69ab31 | | | 28 | const groups = []; |
| b69ab31 | | | 29 | let group = newGroup(); |
| b69ab31 | | | 30 | lines.forEach(fullLine => { |
| b69ab31 | | | 31 | const firstChar = fullLine.charAt(0); |
| b69ab31 | | | 32 | const line = fullLine.slice(1); |
| b69ab31 | | | 33 | if (firstChar === ' ') { |
| b69ab31 | | | 34 | if (hasDeltas(group)) { |
| b69ab31 | | | 35 | // This must be the start of a new group! |
| b69ab31 | | | 36 | groups.push(group); |
| b69ab31 | | | 37 | group = newGroup(); |
| b69ab31 | | | 38 | } |
| b69ab31 | | | 39 | group.common.push(line); |
| b69ab31 | | | 40 | } else if (firstChar === '-') { |
| b69ab31 | | | 41 | group.removed.push(line); |
| b69ab31 | | | 42 | } else if (firstChar === '+') { |
| b69ab31 | | | 43 | group.added.push(line); |
| b69ab31 | | | 44 | } |
| b69ab31 | | | 45 | }); |
| b69ab31 | | | 46 | |
| b69ab31 | | | 47 | groups.push(group); |
| b69ab31 | | | 48 | |
| b69ab31 | | | 49 | return groups; |
| b69ab31 | | | 50 | } |
| b69ab31 | | | 51 | |
| b69ab31 | | | 52 | function hasDeltas(group: HunkGroup): boolean { |
| b69ab31 | | | 53 | return group.removed.length !== 0 || group.added.length !== 0; |
| b69ab31 | | | 54 | } |
| b69ab31 | | | 55 | |
| b69ab31 | | | 56 | function newGroup(): HunkGroup { |
| b69ab31 | | | 57 | return { |
| b69ab31 | | | 58 | common: [], |
| b69ab31 | | | 59 | removed: [], |
| b69ab31 | | | 60 | added: [], |
| b69ab31 | | | 61 | }; |
| b69ab31 | | | 62 | } |