Disable autoindent in visual block insert mode

Conrad Irwin created

Change summary

crates/editor/src/editor.rs              | 17 ++++++++++++++---
crates/editor/src/multi_buffer.rs        |  1 +
crates/vim/src/state.rs                  |  4 ++++
crates/vim/src/test/neovim_connection.rs |  3 +--
crates/vim/src/vim.rs                    |  2 ++
crates/vim/src/visual.rs                 |  4 ++--
6 files changed, 24 insertions(+), 7 deletions(-)

Detailed changes

crates/editor/src/editor.rs 🔗

@@ -575,6 +575,7 @@ pub struct Editor {
     searchable: bool,
     cursor_shape: CursorShape,
     collapse_matches: bool,
+    autoindent_mode: Option<AutoindentMode>,
     workspace: Option<(WeakViewHandle<Workspace>, i64)>,
     keymap_context_layers: BTreeMap<TypeId, KeymapContext>,
     input_enabled: bool,
@@ -1409,6 +1410,7 @@ impl Editor {
             searchable: true,
             override_text_style: None,
             cursor_shape: Default::default(),
+            autoindent_mode: Some(AutoindentMode::EachLine),
             collapse_matches: false,
             workspace: None,
             keymap_context_layers: Default::default(),
@@ -1587,6 +1589,14 @@ impl Editor {
         self.input_enabled = input_enabled;
     }
 
+    pub fn set_autoindent(&mut self, autoindent: bool) {
+        if autoindent {
+            self.autoindent_mode = Some(AutoindentMode::EachLine);
+        } else {
+            self.autoindent_mode = None;
+        }
+    }
+
     pub fn set_read_only(&mut self, read_only: bool) {
         self.read_only = read_only;
     }
@@ -1719,7 +1729,7 @@ impl Editor {
         }
 
         self.buffer.update(cx, |buffer, cx| {
-            buffer.edit(edits, Some(AutoindentMode::EachLine), cx)
+            buffer.edit(edits, self.autoindent_mode.clone(), cx)
         });
     }
 
@@ -2194,7 +2204,7 @@ impl Editor {
         drop(snapshot);
         self.transact(cx, |this, cx| {
             this.buffer.update(cx, |buffer, cx| {
-                buffer.edit(edits, Some(AutoindentMode::EachLine), cx);
+                buffer.edit(edits, this.autoindent_mode.clone(), cx);
             });
 
             let new_anchor_selections = new_selections.iter().map(|e| &e.0);
@@ -2504,6 +2514,7 @@ impl Editor {
     }
 
     pub fn insert(&mut self, text: &str, cx: &mut ViewContext<Self>) {
+        dbg!("insert!");
         self.insert_with_autoindent_mode(
             text,
             Some(AutoindentMode::Block {
@@ -3003,7 +3014,7 @@ impl Editor {
                 this.buffer.update(cx, |buffer, cx| {
                     buffer.edit(
                         ranges.iter().map(|range| (range.clone(), text)),
-                        Some(AutoindentMode::EachLine),
+                        this.autoindent_mode.clone(),
                         cx,
                     );
                 });

crates/editor/src/multi_buffer.rs 🔗

@@ -364,6 +364,7 @@ impl MultiBuffer {
         S: ToOffset,
         T: Into<Arc<str>>,
     {
+        dbg!("edit", &autoindent_mode);
         if self.buffers.borrow().is_empty() {
             return;
         }

crates/vim/src/state.rs 🔗

@@ -90,6 +90,10 @@ impl VimState {
             )
     }
 
+    pub fn should_autoindent(&self) -> bool {
+        !(self.mode == Mode::Insert && self.last_mode == Mode::VisualBlock)
+    }
+
     pub fn clip_at_line_ends(&self) -> bool {
         match self.mode {
             Mode::Insert | Mode::Visual | Mode::VisualLine | Mode::VisualBlock => false,

crates/vim/src/test/neovim_connection.rs 🔗

@@ -520,6 +520,5 @@ fn encode_ranges(text: &str, point_ranges: &Vec<Range<Point>>) -> String {
             byte_range
         })
         .collect::<Vec<_>>();
-    let ret = util::test::generate_marked_text(text, &byte_ranges[..], true);
-    ret
+    util::test::generate_marked_text(text, &byte_ranges[..], true);
 }

crates/vim/src/vim.rs 🔗

@@ -339,6 +339,7 @@ impl Vim {
                 editor.set_clip_at_line_ends(state.clip_at_line_ends(), cx);
                 editor.set_collapse_matches(true);
                 editor.set_input_enabled(!state.vim_controlled());
+                editor.set_autoindent(state.should_autoindent());
                 editor.selections.line_mode = matches!(state.mode, Mode::VisualLine);
                 let context_layer = state.keymap_context_layer();
                 editor.set_keymap_context_layer::<Self>(context_layer, cx);
@@ -355,6 +356,7 @@ impl Vim {
         editor.set_cursor_shape(CursorShape::Bar, cx);
         editor.set_clip_at_line_ends(false, cx);
         editor.set_input_enabled(true);
+        editor.set_autoindent(true);
         editor.selections.line_mode = false;
 
         // we set the VimEnabled context on all editors so that we

crates/vim/src/visual.rs 🔗

@@ -192,7 +192,7 @@ pub fn visual_block_motion(
             let start = map.clip_point(DisplayPoint::new(row, columns.start), Bias::Left);
             let end = map.clip_point(DisplayPoint::new(row, columns.end), Bias::Left);
             if columns.start <= map.line_len(row) {
-                let mut selection = Selection {
+                let selection = Selection {
                     id: s.new_selection_id(),
                     start: start.to_point(map),
                     end: end.to_point(map),
@@ -392,7 +392,7 @@ pub fn paste(_: &mut Workspace, _: &VisualPaste, cx: &mut ViewContext<Workspace>
                                     linewise = all_selections_were_entire_line;
                                 }
 
-                                let selection = selection.clone();
+                                let mut selection = selection.clone();
                                 if !selection.reversed {
                                     let adjusted = selection.end;
                                     // If the selection is empty, move both the start and end forward one