on master help sign in
Fix cursor rendering & placement on append mode.
5945815Blaž Hrastnik
helix-core/src/state.rs+3
@@ -20,6 +20,8 @@ pub struct State {
20 pub selection: Selection,
20 pub selection: Selection,
21 pub mode: Mode,
21 pub mode: Mode,
22
22
23+ pub restore_cursor: bool,
24+
23 //
25 //
24 pub syntax: Option<Syntax>,
26 pub syntax: Option<Syntax>,
25}
27}
@@ -46,6 +48,7 @@ impl State {
46 selection: Selection::single(0, 0),
48 selection: Selection::single(0, 0),
47 mode: Mode::Normal,
49 mode: Mode::Normal,
48 syntax: None,
50 syntax: None,
51+ restore_cursor: false,
49 }
52 }
50 }
53 }
51
54
helix-term/src/editor.rs+11−1
@@ -127,7 +127,7 @@ impl Editor {
127 .ranges()
127 .ranges()
128 .iter()
128 .iter()
129 // TODO: limit selection to one in viewport
129 // TODO: limit selection to one in viewport
130− .filter(|range| !range.is_empty()) // && range.overlaps(&Range::new(start, end + 1))
130+ // .filter(|range| !range.is_empty()) // && range.overlaps(&Range::new(start, end + 1))
131 .copied()
131 .copied()
132 .collect();
132 .collect();
133
133
@@ -178,6 +178,7 @@ impl Editor {
178 let grapheme = Cow::from(grapheme);
178 let grapheme = Cow::from(grapheme);
179 let width = grapheme_width(&grapheme) as u16;
179 let width = grapheme_width(&grapheme) as u16;
180
180
181+ // TODO: this should really happen as an after pass
181 let style = if visible_selections
182 let style = if visible_selections
182 .iter()
183 .iter()
183 .any(|range| range.contains(char_index))
184 .any(|range| range.contains(char_index))
@@ -188,6 +189,15 @@ impl Editor {
188 style
189 style
189 };
190 };
190
191
192+ let style = if visible_selections
193+ .iter()
194+ .any(|range| range.head == char_index)
195+ {
196+ style.clone().bg(Color::Rgb(255, 255, 255))
197+ } else {
198+ style
199+ };
200+
191 // TODO: paint cursor heads except primary
201 // TODO: paint cursor heads except primary
192
202
193 self.surface.set_string(
203 self.surface.set_string(
helix-view/src/commands.rs+14−1
@@ -186,6 +186,7 @@ pub fn insert_mode(view: &mut View, _count: usize) {
186// inserts at the end of each selection
186// inserts at the end of each selection
187pub fn append_mode(view: &mut View, _count: usize) {
187pub fn append_mode(view: &mut View, _count: usize) {
188 view.state.mode = Mode::Insert;
188 view.state.mode = Mode::Insert;
189+ view.state.restore_cursor = true;
189
190
190 // TODO: as transaction
191 // TODO: as transaction
191 let text = &view.state.doc.slice(..);
192 let text = &view.state.doc.slice(..);
@@ -268,8 +269,20 @@ pub fn open_below(view: &mut View, _count: usize) {
268// O inserts a new line before each line with a selection
269// O inserts a new line before each line with a selection
269
270
270pub fn normal_mode(view: &mut View, _count: usize) {
271pub fn normal_mode(view: &mut View, _count: usize) {
271− // TODO: if leaving append mode, move cursor back by 1
272 view.state.mode = Mode::Normal;
272 view.state.mode = Mode::Normal;
273+
274+ // if leaving append mode, move cursor back by 1
275+ if view.state.restore_cursor {
276+ let text = &view.state.doc.slice(..);
277+ view.state.selection = view.state.selection.transform(|range| {
278+ Range::new(
279+ range.from(),
280+ graphemes::prev_grapheme_boundary(text, range.to()),
281+ )
282+ });
283+
284+ view.state.restore_cursor = false;
285+ }
273}
286}
274
287
275// TODO: insert means add text just before cursor, on exit we should be on the last letter.
288// TODO: insert means add text just before cursor, on exit we should be on the last letter.