Skip to content

Commit 48a12ab

Browse files
committed
simplify create_hunks_from_lcs
1 parent 3ae83d5 commit 48a12ab

File tree

1 file changed

+74
-128
lines changed

1 file changed

+74
-128
lines changed

text/diff_util/hunks.rs

Lines changed: 74 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
use crate::diff_util::constants::NO_NEW_LINE_AT_END_OF_FILE;
22

3-
use super::{change::{Change, ChangeData}, file_data::FileData};
3+
use super::{
4+
change::{Change, ChangeData},
5+
file_data::FileData,
6+
};
47

58
#[derive(Clone, Debug)]
69
pub struct Hunk {
@@ -46,10 +49,6 @@ impl Hunk {
4649
}
4750
}
4851

49-
pub fn kind(&self) -> &Change {
50-
&self.kind
51-
}
52-
5352
pub fn ln1_start(&self) -> usize {
5453
self.ln1_start
5554
}
@@ -89,7 +88,6 @@ impl Hunk {
8988
}
9089
}
9190
Change::Substitute(_) => {
92-
9391
println!("{}c{}", self.f1_range(), self.f2_range());
9492

9593
for i in self.ln1_start..self.ln1_end {
@@ -278,133 +276,81 @@ impl Hunks {
278276
&mut self.hunks[index]
279277
}
280278

281-
pub fn create_hunks_from_lcs(&mut self, lcs_indices: &Vec<i32>, num_lines1: usize, num_lines2: usize) {
282-
let mut curr_line1 = 0;
283-
let mut curr_line2 = 0;
284-
let mut prev_i = 0;
285-
let mut prev_l = 0;
286-
let mut block_start_1 = 0;
287-
let mut block_start_2 = 0;
288-
let max_index_2 = lcs_indices.iter().max().unwrap();
289-
lcs_indices.iter().enumerate().filter(|(_i, l)| **l != -1).for_each(|(i, l)| {
290-
// check if we reach the end of the block
291-
if (i - prev_i > 1) || (*l as usize - prev_l > 1) || (l == max_index_2) {
292-
let hunk_start_1 = curr_line1;
293-
let hunk_start_2 = curr_line2;
294-
295-
// handle delete lines from lines1
296-
let mut has_deleted_lines = false;
297-
while curr_line1 < block_start_1 {
298-
curr_line1 += 1;
299-
}
300-
if curr_line1 != hunk_start_1 {
301-
has_deleted_lines = true;
302-
}
303-
304-
// handle added lines from lines2
305-
let mut has_added_lines = false;
306-
while curr_line2 < block_start_2 {
307-
curr_line2 += 1;
308-
}
309-
if curr_line2 != hunk_start_2 {
310-
has_added_lines = true;
311-
}
312-
313-
// Add the hunk
314-
if has_deleted_lines && has_added_lines {
315-
self.hunks.push(Hunk {
316-
kind: Change::Substitute(ChangeData::new(hunk_start_1, hunk_start_2)),
317-
changes: vec![Change::default()],
318-
ln2_start: hunk_start_2,
319-
ln1_start: hunk_start_1,
320-
ln2_end: curr_line2,
321-
ln1_end: curr_line1,
322-
});
323-
} else if has_deleted_lines {
324-
let mut changes: Vec<Change> = Vec::new();
325-
for i in hunk_start_1+1..curr_line1 {
326-
changes.push(Change::Delete(ChangeData::new(i, i+1)));
327-
}
328-
self.hunks.push(Hunk {
329-
kind: Change::Delete(ChangeData::new(hunk_start_1, hunk_start_2)),
330-
changes: vec![Change::default()],
331-
ln2_start: hunk_start_2,
332-
ln1_start: hunk_start_1,
333-
ln2_end: curr_line2,
334-
ln1_end: curr_line1,
335-
});
336-
} else if has_added_lines {
337-
self.hunks.push(Hunk {
338-
kind: Change::Insert(ChangeData::new(hunk_start_1, hunk_start_2)),
339-
changes: vec![Change::default()],
340-
ln2_start: hunk_start_2,
341-
ln1_start: hunk_start_1,
342-
ln2_end: curr_line2,
343-
ln1_end: curr_line1,
344-
});
345-
}
346-
347-
// position current line directly after previous block end
348-
curr_line1 = prev_i + 1;
349-
curr_line2 = prev_l + 1;
350-
351-
// new block start
352-
block_start_1 = i;
353-
block_start_2 = *l as usize;
279+
pub fn create_hunks_from_lcs(
280+
&mut self,
281+
lcs_indices: &Vec<i32>,
282+
num_lines1: usize,
283+
num_lines2: usize,
284+
) {
285+
let mut hunk_start1 = 0;
286+
let mut hunk_end1 = 0;
287+
let mut hunk_start2 = 0;
288+
let mut hunk_end2 = 0;
289+
let mut prev_val = 0 as i32;
290+
for i in 0..lcs_indices.len() {
291+
if ((lcs_indices[i] == -1) && (prev_val != -1)) {
292+
// We reach a new deletion/substitution block
293+
hunk_start1 = i;
294+
hunk_start2 = if prev_val == 0 {
295+
0
296+
} else {
297+
(prev_val + 1) as usize
298+
};
299+
} else if (prev_val != -1) && (lcs_indices[i] != -1) && (lcs_indices[i] != prev_val + 1) {
300+
// there was an insertion (but no deletion)
301+
// no -1 values but a bump in the values, eg [136, 145]
302+
hunk_start1 = i;
303+
hunk_start2 = (prev_val + 1) as usize;
304+
hunk_end1 = i;
305+
hunk_end2 = lcs_indices[i] as usize;
306+
self.add_hunk(hunk_start1, hunk_end1, hunk_start2, hunk_end2);
354307
}
355-
prev_i = i;
356-
prev_l = *l as usize;
357-
358-
});
359-
360-
// Get last hunk (if any) after the last lcs block
361-
let mut has_deleted_lines = false;
362-
curr_line1 = prev_i + 1;
363-
let hunk_start_1 = curr_line1;
364-
while curr_line1 < num_lines1 {
365-
curr_line1 += 1;
366-
}
367-
if curr_line1 != hunk_start_1 {
368-
has_deleted_lines = true;
308+
if (lcs_indices[i] != -1) && (prev_val == -1) {
309+
// we reach the end of deletion/substitution block
310+
hunk_end1 = i;
311+
hunk_end2 = lcs_indices[i] as usize;
312+
self.add_hunk(hunk_start1, hunk_end1, hunk_start2, hunk_end2);
313+
}
314+
prev_val = lcs_indices[i];
369315
}
370316

371-
let mut has_added_lines = false;
372-
curr_line2 = prev_l + 1;
373-
let hunk_start_2 = curr_line2;
374-
while curr_line2 < num_lines2 {
375-
curr_line2 += 1;
376-
}
377-
if curr_line2 != hunk_start_2 {
378-
has_added_lines = true;
317+
// final hunk: we might have only -1 at the end
318+
if lcs_indices[lcs_indices.len() - 1] == -1 {
319+
hunk_end1 = num_lines1;
320+
hunk_end2 = num_lines2;
321+
self.add_hunk(hunk_start1, hunk_end1, hunk_start2, hunk_end2);
322+
} else if lcs_indices[lcs_indices.len() - 1] < ((num_lines2 - 1) as i32) {
323+
// there might be some insertions after the last lcs block
324+
hunk_start1 = num_lines1 - 1;
325+
hunk_end1 = num_lines1 - 1;
326+
hunk_start2 = (lcs_indices[lcs_indices.len() - 1] + 1) as usize;
327+
hunk_end2 = num_lines2;
328+
self.add_hunk(hunk_start1, hunk_end1, hunk_start2, hunk_end2);
379329
}
330+
}
380331

381-
if has_deleted_lines && has_added_lines {
382-
self.hunks.push(Hunk {
383-
kind: Change::Substitute(ChangeData::new(hunk_start_1, hunk_start_2)),
384-
changes: vec![Change::default()],
385-
ln2_start: hunk_start_2,
386-
ln1_start: hunk_start_1,
387-
ln2_end: curr_line2,
388-
ln1_end: curr_line1,
389-
});
390-
} else if has_deleted_lines {
391-
self.hunks.push(Hunk {
392-
kind: Change::Delete(ChangeData::new(hunk_start_1, hunk_start_2)),
393-
changes: vec![Change::default()],
394-
ln2_start: hunk_start_2,
395-
ln1_start: hunk_start_1,
396-
ln2_end: curr_line2,
397-
ln1_end: curr_line1,
398-
});
399-
} else if has_added_lines {
400-
self.hunks.push(Hunk {
401-
kind: Change::Insert(ChangeData::new(hunk_start_1, hunk_start_2)),
402-
changes: vec![Change::default()],
403-
ln2_start: hunk_start_2,
404-
ln1_start: hunk_start_1,
405-
ln2_end: curr_line2,
406-
ln1_end: curr_line1,
407-
});
332+
pub fn add_hunk(
333+
&mut self,
334+
hunk_start1: usize,
335+
hunk_end1: usize,
336+
hunk_start2: usize,
337+
hunk_end2: usize,
338+
) {
339+
let kind: Change;
340+
if hunk_start1 == hunk_end1 {
341+
kind = Change::Insert(ChangeData::new(hunk_start1, hunk_start2));
342+
} else if hunk_start2 == hunk_end2 {
343+
kind = Change::Delete(ChangeData::new(hunk_start1, hunk_start2));
344+
} else {
345+
kind = Change::Substitute(ChangeData::new(hunk_start1, hunk_start2));
408346
}
347+
self.hunks.push(Hunk {
348+
kind,
349+
changes: vec![Change::default()],
350+
ln2_start: hunk_start2,
351+
ln1_start: hunk_start1,
352+
ln2_end: hunk_end2,
353+
ln1_end: hunk_end1,
354+
});
409355
}
410356
}

0 commit comments

Comments
 (0)