|
1 | 1 | use crate::diff_util::constants::NO_NEW_LINE_AT_END_OF_FILE; |
2 | 2 |
|
3 | | -use super::{change::{Change, ChangeData}, file_data::FileData}; |
| 3 | +use super::{ |
| 4 | + change::{Change, ChangeData}, |
| 5 | + file_data::FileData, |
| 6 | +}; |
4 | 7 |
|
5 | 8 | #[derive(Clone, Debug)] |
6 | 9 | pub struct Hunk { |
@@ -46,10 +49,6 @@ impl Hunk { |
46 | 49 | } |
47 | 50 | } |
48 | 51 |
|
49 | | - pub fn kind(&self) -> &Change { |
50 | | - &self.kind |
51 | | - } |
52 | | - |
53 | 52 | pub fn ln1_start(&self) -> usize { |
54 | 53 | self.ln1_start |
55 | 54 | } |
@@ -89,7 +88,6 @@ impl Hunk { |
89 | 88 | } |
90 | 89 | } |
91 | 90 | Change::Substitute(_) => { |
92 | | - |
93 | 91 | println!("{}c{}", self.f1_range(), self.f2_range()); |
94 | 92 |
|
95 | 93 | for i in self.ln1_start..self.ln1_end { |
@@ -278,133 +276,81 @@ impl Hunks { |
278 | 276 | &mut self.hunks[index] |
279 | 277 | } |
280 | 278 |
|
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); |
354 | 307 | } |
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]; |
369 | 315 | } |
370 | 316 |
|
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); |
379 | 329 | } |
| 330 | + } |
380 | 331 |
|
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)); |
408 | 346 | } |
| 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 | + }); |
409 | 355 | } |
410 | 356 | } |
0 commit comments