on master help sign in
Clamp character movement to line.
13d1ea5Blaž Hrastnik
helix-core/src/state.rs+14−3
@@ -147,12 +147,23 @@ impl State {
147 ) -> usize {
147 ) -> usize {
148 let text = &self.doc;
148 let text = &self.doc;
149 match (dir, granularity) {
149 match (dir, granularity) {
150− // TODO: clamp movement to line, prevent moving onto \n at the end
151 (Direction::Backward, Granularity::Character) => {
150 (Direction::Backward, Granularity::Character) => {
151+ // Clamp to line
152+ let line = text.char_to_line(pos);
153+ let start = text.line_to_char(line);
154+ std::cmp::max(
152− nth_prev_grapheme_boundary(&text.slice(..), pos, count)
155+ nth_prev_grapheme_boundary(&text.slice(..), pos, count),
156+ start,
157+ )
153 }
158 }
154 (Direction::Forward, Granularity::Character) => {
159 (Direction::Forward, Granularity::Character) => {
160+ // Clamp to line
161+ let line = text.char_to_line(pos);
162+ let start = text.line_to_char(line);
163+ let len = text.line(line).len_chars();
164+ // convert to 0-indexed, subtract another 1 because len_chars() counts \n
165+ let end = start + len.saturating_sub(2);
155− nth_next_grapheme_boundary(&text.slice(..), pos, count)
166+ std::cmp::min(nth_next_grapheme_boundary(&text.slice(..), pos, count), end)
156 }
167 }
157 (Direction::Forward, Granularity::Word) => {
168 (Direction::Forward, Granularity::Word) => {
158 Self::move_next_word_start(&text.slice(..), pos)
169 Self::move_next_word_start(&text.slice(..), pos)