@@ -1,4 +1,4 @@
1−use crate::graphemes::next_grapheme_boundary;
1+use crate::graphemes;
2use crate::selection::Range;
2use crate::selection::Range;
3use crate::state::{Direction, Granularity, Mode, State};
3use crate::state::{Direction, Granularity, Mode, State};
4use crate::transaction::{ChangeSet, Transaction};
4use crate::transaction::{ChangeSet, Transaction};
@@ -53,7 +53,10 @@ pub fn append_mode(state: &mut State, _count: usize) {
53 let text = &state.doc.slice(..);
53 let text = &state.doc.slice(..);
54 state.selection = state.selection.transform(|range| {
54 state.selection = state.selection.transform(|range| {
55 // TODO: to() + next char
55 // TODO: to() + next char
56− Range::new(range.from(), next_grapheme_boundary(text, range.to()))
58+ graphemes::next_grapheme_boundary(text, range.to()),
@@ -75,3 +78,30 @@ pub fn insert_char(state: &mut State, c: char) {
75 transaction.apply(state);
78 transaction.apply(state);
76 // TODO: need to store into history if successful
79 // TODO: need to store into history if successful
82+// TODO: handle indent-aware delete
83+pub fn delete_char_backward(state: &mut State, count: usize) {
84+ let text = &state.doc.slice(..);
85+ let transaction = Transaction::change_by_selection(state, |range| {
87+ graphemes::nth_prev_grapheme_boundary(text, range.head, count),
92+ transaction.apply(state);
93+ // TODO: need to store into history if successful
96+pub fn delete_char_forward(state: &mut State, count: usize) {
97+ let text = &state.doc.slice(..);
98+ let transaction = Transaction::change_by_selection(state, |range| {
100+ graphemes::nth_next_grapheme_boundary(text, range.head, count),
105+ transaction.apply(state);
106+ // TODO: need to store into history if successful