Delete the selection or the previous cluster (typical ‘backspace’ behavior).
(&mut self, cx: &Context)
| 205 | |
| 206 | /// Delete the selection or the previous cluster (typical ‘backspace’ behavior). |
| 207 | pub fn backdelete(&mut self, cx: &Context) { |
| 208 | if self.selection.is_collapsed() { |
| 209 | // Upstream cluster |
| 210 | if let Some(cluster) = self.selection.focus().logical_clusters(&self.layout)[0].clone() |
| 211 | { |
| 212 | let range = cluster.text_range(); |
| 213 | let end = range.end; |
| 214 | let start = if cluster.is_hard_line_break() || cluster.is_emoji() { |
| 215 | // For newline sequences and emoji, delete the previous cluster |
| 216 | range.start |
| 217 | } else { |
| 218 | // Otherwise, delete the previous character |
| 219 | let Some((start, _)) = self |
| 220 | .buffer |
| 221 | .get(..end) |
| 222 | .and_then(|str| str.char_indices().next_back()) |
| 223 | else { |
| 224 | return; |
| 225 | }; |
| 226 | start |
| 227 | }; |
| 228 | self.buffer.replace_range(start..end, ""); |
| 229 | self.update_layout(cx); |
| 230 | self.set_selection( |
| 231 | Cursor::from_byte_index(&self.layout, start, Affinity::Downstream).into(), |
| 232 | ); |
| 233 | } |
| 234 | } else { |
| 235 | self.delete_selection(cx); |
| 236 | } |
| 237 | } |
| 238 | |
| 239 | /// Delete the selection or back to the previous word boundary (typical ‘ctrl + backspace’ behavior). |
| 240 | pub fn backdelete_word(&mut self, cx: &Context) { |
no test coverage detected