Add transpose for multi-select
Resolves one of the polish items in
@@ -63,6 +63,16 @@ enum CharacterEncoding {
const UTF8_BOM: &str = "\u{feff}";
+fn last_selection_region(regions: &[SelRegion]) -> Option<&SelRegion> {
+ for region in regions.iter().rev() {
+ if !region.is_caret() {
+ return Some(region);
+ }
+ }
+
+ None
+}
+
pub struct Editor {
text: Rope,
encoding: CharacterEncoding,
@@ -877,9 +887,20 @@ impl Editor {
}
}
+ fn sel_region_to_interval_and_rope(&self, region: &SelRegion) -> (Interval, Rope) {
+ let as_interval = Interval::new_closed_open(region.min(), region.max());
+ let interval_rope = Rope::from(self.text.slice_to_string(
+ as_interval.start(), as_interval.end()));
+ (as_interval, interval_rope)
+ }
+
fn do_transpose(&mut self) {
let mut builder = delta::Builder::new(self.text.len());
let mut last = 0;
+ let mut optional_previous_selection : Option<(Interval, Rope)> =
+ last_selection_region(self.view.sel_regions()).map(
+ |ref region| self.sel_region_to_interval_and_rope(region));
+
for region in self.view.sel_regions() {
if region.is_caret() {
let middle = region.end;
@@ -895,8 +916,11 @@ impl Editor {
last = end;
}
}
+ } else if let Some(previous_selection) = optional_previous_selection {
+ let current_interval = self.sel_region_to_interval_and_rope(&region);
+ builder.replace(current_interval.0, previous_selection.1);
+ optional_previous_selection = Some(current_interval);
}
- // TODO: handle else case by rotating non-caret regions.
}
if !builder.is_empty() {
self.this_edit_type = EditType::Other;
