Fix cursor position when inserting newlines on a repeated excerpt
Unified · Split
| @@ -1,7 +1,7 @@ | |||
| 1 | [package] | 1 | [package] |
| 2 | name = "editor" | 2 | name = "editor" |
| 3 | version = "0.1.0" | 3 | version = "0.1.0" |
| 4 | edition = "2018" | 4 | edition = "2021" |
| 5 | 5 | ||
| 6 | [lib] | 6 | [lib] |
| 7 | path = "src/editor.rs" | 7 | path = "src/editor.rs" |
| @@ -1216,7 +1216,6 @@ impl Editor { · 1215 unmodified lines | |||
| 1216 | } | 1216 | } |
| 1217 | } | 1217 | } |
| 1218 | 1218 | ||
| 1219 | let mut new_selections = Vec::with_capacity(old_selections.len()); | ||
| 1220 | self.buffer.update(cx, |buffer, cx| { | 1219 | self.buffer.update(cx, |buffer, cx| { |
| 1221 | let mut delta = 0_isize; | 1220 | let mut delta = 0_isize; |
| 1222 | let mut pending_edit: Option<PendingEdit> = None; | 1221 | let mut pending_edit: Option<PendingEdit> = None; |
| @@ -1259,31 +1258,27 @@ impl Editor { · 36 unmodified lines | |||
| 1259 | } | 1258 | } |
| 1260 | buffer.edit_with_autoindent(pending.ranges, new_text, cx); | 1259 | buffer.edit_with_autoindent(pending.ranges, new_text, cx); |
| 1261 | 1260 | ||
| 1262 | let mut delta = 0_isize; | 1261 | let buffer = buffer.read(cx); |
| 1263 | new_selections.extend(old_selections.into_iter().map( | 1262 | self.selections = self |
| 1264 | |(id, range, indent, insert_extra_newline)| { | 1263 | .selections |
| 1265 | let start = (range.start as isize + delta) as usize; | 1264 | .iter() |
| 1266 | let end = (range.end as isize + delta) as usize; | 1265 | .cloned() |
| 1267 | let text_before_cursor_len = indent as usize + 1; | 1266 | .zip(old_selections) |
| 1268 | let cursor = start + text_before_cursor_len; | 1267 | .map(|(mut new_selection, (_, _, _, insert_extra_newline))| { |
| 1269 | let text_len = if insert_extra_newline { | 1268 | if insert_extra_newline { |
| 1270 | text_before_cursor_len * 2 | 1269 | let mut cursor = new_selection.start.to_point(&buffer); |
| 1271 | } else { | 1270 | cursor.row -= 1; |
| 1272 | text_before_cursor_len | 1271 | cursor.column = buffer.line_len(cursor.row); |
| 1273 | }; | 1272 | let anchor = buffer.anchor_after(cursor); |
| 1274 | delta += text_len as isize - (end - start) as isize; | 1273 | new_selection.start = anchor.clone(); |
| 1275 | Selection { | 1274 | new_selection.end = anchor; |
| 1276 | id, | ||
| 1277 | start: cursor, | ||
| 1278 | end: cursor, | ||
| 1279 | reversed: false, | ||
| 1280 | goal: SelectionGoal::None, | ||
| 1281 | } | 1275 | } |
| 1282 | }, | 1276 | new_selection |
| 1283 | )) | 1277 | }) |
| 1278 | .collect(); | ||
| 1284 | }); | 1279 | }); |
| 1285 | 1280 | ||
| 1286 | self.update_selections(new_selections, Some(Autoscroll::Fit), cx); | 1281 | self.request_autoscroll(Autoscroll::Fit, cx); |
| 1287 | self.end_transaction(cx); | 1282 | self.end_transaction(cx); |
| 1288 | 1283 | ||
| 1289 | #[derive(Default)] | 1284 | #[derive(Default)] |
| @@ -6186,7 +6181,17 @@ mod tests { · 4896 unmodified lines | |||
| 6186 | DisplayPoint::new(1, 2)..DisplayPoint::new(1, 2), | 6181 | DisplayPoint::new(1, 2)..DisplayPoint::new(1, 2), |
| 6187 | DisplayPoint::new(2, 5)..DisplayPoint::new(2, 5), | 6182 | DisplayPoint::new(2, 5)..DisplayPoint::new(2, 5), |
| 6188 | ] | 6183 | ] |
| 6189 | ) | 6184 | ); |
| 6185 | |||
| 6186 | view.newline(&Newline, cx); | ||
| 6187 | assert_eq!(view.text(cx), "aaaa\nbX\nbbX\nb\nbX\nbbX\nb\ncccc"); | ||
| 6188 | assert_eq!( | ||
| 6189 | view.selected_display_ranges(cx), | ||
| 6190 | &[ | ||
| 6191 | DisplayPoint::new(2, 0)..DisplayPoint::new(2, 0), | ||
| 6192 | DisplayPoint::new(6, 0)..DisplayPoint::new(6, 0), | ||
| 6193 | ] | ||
| 6194 | ); | ||
| 6190 | }); | 6195 | }); |
| 6191 | } | 6196 | } |
| 6192 | 6197 | ||