on master help sign in
Improve dedent behavior, make kill_to_line_end behave like emacs (#1173)
c08d2faWindSoilder
helix-term/src/commands.rs+15−4
@@ -173,6 +173,10 @@ impl Command {
173 self.doc
173 self.doc
174 }
174 }
175
175
176+ pub fn fun(&self) -> fn(&mut Context) {
177+ self.fun
178+ }
179+
176 #[rustfmt::skip]
180 #[rustfmt::skip]
177 commands!(
181 commands!(
178 no_op, "Do nothing",
182 no_op, "Do nothing",
@@ -603,8 +607,15 @@ fn kill_to_line_end(cx: &mut Context) {
603
607
604 let selection = doc.selection(view.id).clone().transform(|range| {
608 let selection = doc.selection(view.id).clone().transform(|range| {
605 let line = range.cursor_line(text);
609 let line = range.cursor_line(text);
606− let pos = line_end_char_index(&text, line);
610+ let line_end_pos = line_end_char_index(&text, line);
611+ let pos = range.cursor(text);
612+
607− range.put_cursor(text, pos, true)
613+ let mut new_range = range.put_cursor(text, line_end_pos, true);
614+ // don't want to remove the line separator itself if the cursor doesn't reach the end of line.
615+ if pos != line_end_pos {
616+ new_range.head = line_end_pos;
617+ }
618+ new_range
608 });
619 });
609 delete_selection_insert_mode(doc, view, &selection);
620 delete_selection_insert_mode(doc, view, &selection);
610}
621}
@@ -3503,12 +3514,12 @@ fn open(cx: &mut Context, open: Open) {
3503}
3514}
3504
3515
3505// o inserts a new line after each line with a selection
3516// o inserts a new line after each line with a selection
3506−fn open_below(cx: &mut Context) {
3517+pub(crate) fn open_below(cx: &mut Context) {
3507 open(cx, Open::Below)
3518 open(cx, Open::Below)
3508}
3519}
3509
3520
3510// O inserts a new line before each line with a selection
3521// O inserts a new line before each line with a selection
3511−fn open_above(cx: &mut Context) {
3522+pub(crate) fn open_above(cx: &mut Context) {
3512 open(cx, Open::Above)
3523 open(cx, Open::Above)
3513}
3524}
3514
3525
helix-term/src/ui/editor.rs+13
@@ -1023,6 +1023,19 @@ impl Component for EditorView {
1023 (Mode::Insert, Mode::Normal) => {
1023 (Mode::Insert, Mode::Normal) => {
1024 // if exiting insert mode, remove completion
1024 // if exiting insert mode, remove completion
1025 self.completion = None;
1025 self.completion = None;
1026+
1027+ let last_cmd = self.last_insert.0.fun();
1028+ const OPEN_BELOW_FUN: fn(&mut commands::Context) = commands::open_below;
1029+ const OPEN_ABOVE_FUN: fn(&mut commands::Context) = commands::open_above;
1030+ // For user friendly,
1031+ // Remove whitespaces if we go from insert mode(through open below/above) to normal mode without any keys in between.
1032+ // Example: `o<esc>`.
1033+ if matches!(last_cmd, OPEN_BELOW_FUN | OPEN_ABOVE_FUN)
1034+ && self.last_insert.1.len() == 1
1035+ {
1036+ commands::Command::goto_line_start.execute(&mut cxt);
1037+ commands::Command::kill_to_line_end.execute(&mut cxt);
1038+ }
1026 }
1039 }
1027 _ => (),
1040 _ => (),
1028 }
1041 }