@@ -495,28 +495,53 @@ impl Selection {
495495
496496 /// Normalizes a `Selection`.
497497 fn normalize(mut self) -> Self {
498− let primary = self.ranges[self.primary_index];
498+ let mut primary = self.ranges[self.primary_index];
499499 self.ranges.sort_unstable_by_key(Range::from);
500+
501+ self.ranges.dedup_by(|curr_range, prev_range| {
502+ if prev_range.overlaps(curr_range) {
503+ let new_range = curr_range.merge(*prev_range);
504+ if prev_range == &primary || curr_range == &primary {
505+ primary = new_range;
506+ }
507+ *prev_range = new_range;
508+ true
509+ } else {
510+ false
511+ }
512+ });
513+
500514 self.primary_index = self
501515 .ranges
502516 .iter()
503517 .position(|&range| range == primary)
504518 .unwrap();
505519
506− let mut prev_i = 0;
507− for i in 1..self.ranges.len() {
508− if self.ranges[prev_i].overlaps(&self.ranges[i]) {
509− self.ranges[prev_i] = self.ranges[prev_i].merge(self.ranges[i]);
520+ self
521+ }
522+
523+ // Merges all ranges that are consecutive
524+ pub fn merge_consecutive_ranges(mut self) -> Self {
525+ let mut primary = self.ranges[self.primary_index];
526+
527+ self.ranges.dedup_by(|curr_range, prev_range| {
528+ if prev_range.to() == curr_range.from() {
529+ let new_range = curr_range.merge(*prev_range);
530+ if prev_range == &primary || curr_range == &primary {
531+ primary = new_range;
532+ }
533+ *prev_range = new_range;
534+ true
510535 } else {
511− prev_i += 1;
512− self.ranges[prev_i] = self.ranges[i];
536+ false
513537 }
514− if i == self.primary_index {
515− self.primary_index = prev_i;
516− }
517− }
538+ });
518539
519− self.ranges.truncate(prev_i + 1);
540+ self.primary_index = self
541+ .ranges
542+ .iter()
543+ .position(|&range| range == primary)
544+ .unwrap();
520545
521546 self
522547 }
@@ -1132,6 +1157,52 @@ mod test {
11321157 &["", "abcd", "efg", "rs", "xyz"]
11331158 );
11341159 }
1160+
1161+ #[test]
1162+ fn test_merge_consecutive_ranges() {
1163+ let selection = Selection::new(
1164+ smallvec![
1165+ Range::new(0, 1),
1166+ Range::new(1, 10),
1167+ Range::new(15, 20),
1168+ Range::new(25, 26),
1169+ Range::new(26, 30)
1170+ ],
1171+ 4,
1172+ );
1173+
1174+ let result = selection.merge_consecutive_ranges();
1175+
1176+ assert_eq!(
1177+ result.ranges(),
1178+ &[Range::new(0, 10), Range::new(15, 20), Range::new(25, 30)]
1179+ );
1180+ assert_eq!(result.primary_index, 2);
1181+
1182+ let selection = Selection::new(smallvec![Range::new(0, 1)], 0);
1183+ let result = selection.merge_consecutive_ranges();
1184+
1185+ assert_eq!(result.ranges(), &[Range::new(0, 1)]);
1186+ assert_eq!(result.primary_index, 0);
1187+
1188+ let selection = Selection::new(
1189+ smallvec![
1190+ Range::new(0, 1),
1191+ Range::new(1, 5),
1192+ Range::new(5, 8),
1193+ Range::new(8, 10),
1194+ Range::new(10, 15),
1195+ Range::new(18, 25)
1196+ ],
1197+ 3,
1198+ );
1199+
1200+ let result = selection.merge_consecutive_ranges();
1201+
1202+ assert_eq!(result.ranges(), &[Range::new(0, 15), Range::new(18, 25)]);
1203+ assert_eq!(result.primary_index, 0);
1204+ }
1205+
11351206 #[test]
11361207 fn test_selection_contains() {
11371208 fn contains(a: Vec<(usize, usize)>, b: Vec<(usize, usize)>) -> bool {