Fix cursor rendering & placement on append mode.

This commit is contained in:
Blaž Hrastnik 2020-10-01 18:44:12 +09:00
parent d9d59cd209
commit 5945815d97
3 changed files with 28 additions and 2 deletions

View File

@ -20,6 +20,8 @@ pub struct State {
pub selection: Selection, pub selection: Selection,
pub mode: Mode, pub mode: Mode,
pub restore_cursor: bool,
// //
pub syntax: Option<Syntax>, pub syntax: Option<Syntax>,
} }
@ -46,6 +48,7 @@ pub fn new(doc: Rope) -> Self {
selection: Selection::single(0, 0), selection: Selection::single(0, 0),
mode: Mode::Normal, mode: Mode::Normal,
syntax: None, syntax: None,
restore_cursor: false,
} }
} }

View File

@ -127,7 +127,7 @@ fn render(&mut self) {
.ranges() .ranges()
.iter() .iter()
// TODO: limit selection to one in viewport // TODO: limit selection to one in viewport
.filter(|range| !range.is_empty()) // && range.overlaps(&Range::new(start, end + 1)) // .filter(|range| !range.is_empty()) // && range.overlaps(&Range::new(start, end + 1))
.copied() .copied()
.collect(); .collect();
@ -178,6 +178,7 @@ fn render(&mut self) {
let grapheme = Cow::from(grapheme); let grapheme = Cow::from(grapheme);
let width = grapheme_width(&grapheme) as u16; let width = grapheme_width(&grapheme) as u16;
// TODO: this should really happen as an after pass
let style = if visible_selections let style = if visible_selections
.iter() .iter()
.any(|range| range.contains(char_index)) .any(|range| range.contains(char_index))
@ -188,6 +189,15 @@ fn render(&mut self) {
style style
}; };
let style = if visible_selections
.iter()
.any(|range| range.head == char_index)
{
style.clone().bg(Color::Rgb(255, 255, 255))
} else {
style
};
// TODO: paint cursor heads except primary // TODO: paint cursor heads except primary
self.surface.set_string( self.surface.set_string(

View File

@ -186,6 +186,7 @@ pub fn insert_mode(view: &mut View, _count: usize) {
// inserts at the end of each selection // inserts at the end of each selection
pub fn append_mode(view: &mut View, _count: usize) { pub fn append_mode(view: &mut View, _count: usize) {
view.state.mode = Mode::Insert; view.state.mode = Mode::Insert;
view.state.restore_cursor = true;
// TODO: as transaction // TODO: as transaction
let text = &view.state.doc.slice(..); let text = &view.state.doc.slice(..);
@ -268,8 +269,20 @@ pub fn open_below(view: &mut View, _count: usize) {
// O inserts a new line before each line with a selection // O inserts a new line before each line with a selection
pub fn normal_mode(view: &mut View, _count: usize) { pub fn normal_mode(view: &mut View, _count: usize) {
// TODO: if leaving append mode, move cursor back by 1
view.state.mode = Mode::Normal; view.state.mode = Mode::Normal;
// if leaving append mode, move cursor back by 1
if view.state.restore_cursor {
let text = &view.state.doc.slice(..);
view.state.selection = view.state.selection.transform(|range| {
Range::new(
range.from(),
graphemes::prev_grapheme_boundary(text, range.to()),
)
});
view.state.restore_cursor = false;
}
} }
// TODO: insert means add text just before cursor, on exit we should be on the last letter. // TODO: insert means add text just before cursor, on exit we should be on the last letter.