delete.rs

  1use crate::{motion::Motion, Vim};
  2use collections::HashMap;
  3use editor::Bias;
  4use gpui::MutableAppContext;
  5
  6pub fn delete_over(vim: &mut Vim, motion: Motion, cx: &mut MutableAppContext) {
  7    vim.update_active_editor(cx, |editor, cx| {
  8        editor.transact(cx, |editor, cx| {
  9            editor.set_clip_at_line_ends(false, cx);
 10            let mut original_columns: HashMap<_, _> = Default::default();
 11            editor.move_selections(cx, |map, selection| {
 12                let original_head = selection.head();
 13                motion.expand_selection(map, selection, true);
 14                original_columns.insert(selection.id, original_head.column());
 15            });
 16            editor.insert(&"", cx);
 17
 18            // Fixup cursor position after the deletion
 19            editor.set_clip_at_line_ends(true, cx);
 20            editor.move_selections(cx, |map, selection| {
 21                let mut cursor = selection.head();
 22                if motion.linewise() {
 23                    if let Some(column) = original_columns.get(&selection.id) {
 24                        *cursor.column_mut() = *column
 25                    }
 26                }
 27                cursor = map.clip_point(cursor, Bias::Left);
 28                selection.collapse_to(cursor, selection.goal)
 29            });
 30        });
 31    });
 32}
 33
 34#[cfg(test)]
 35mod test {
 36    use indoc::indoc;
 37
 38    use crate::vim_test_context::VimTestContext;
 39
 40    #[gpui::test]
 41    async fn test_delete_h(cx: &mut gpui::TestAppContext) {
 42        let cx = VimTestContext::new(cx, true).await;
 43        let mut cx = cx.binding(["d", "h"]);
 44        cx.assert("Te|st", "T|st");
 45        cx.assert("T|est", "|est");
 46        cx.assert("|Test", "|Test");
 47        cx.assert(
 48            indoc! {"
 49                Test
 50                |test"},
 51            indoc! {"
 52                Test
 53                |test"},
 54        );
 55    }
 56
 57    #[gpui::test]
 58    async fn test_delete_l(cx: &mut gpui::TestAppContext) {
 59        let cx = VimTestContext::new(cx, true).await;
 60        let mut cx = cx.binding(["d", "l"]);
 61        cx.assert("|Test", "|est");
 62        cx.assert("Te|st", "Te|t");
 63        cx.assert("Tes|t", "Te|s");
 64        cx.assert(
 65            indoc! {"
 66                Tes|t
 67                test"},
 68            indoc! {"
 69                Te|s
 70                test"},
 71        );
 72    }
 73
 74    #[gpui::test]
 75    async fn test_delete_w(cx: &mut gpui::TestAppContext) {
 76        let cx = VimTestContext::new(cx, true).await;
 77        let mut cx = cx.binding(["d", "w"]);
 78        cx.assert("Te|st", "T|e");
 79        cx.assert("T|est test", "T|test");
 80        cx.assert(
 81            indoc! {"
 82                Test te|st
 83                test"},
 84            indoc! {"
 85                Test t|e
 86                test"},
 87        );
 88        cx.assert(
 89            indoc! {"
 90                Test tes|t
 91                test"},
 92            indoc! {"
 93                Test te|s
 94                test"},
 95        );
 96        cx.assert(
 97            indoc! {"
 98                Test test
 99                |
100                test"},
101            indoc! {"
102                Test test
103                |
104                test"},
105        );
106
107        let mut cx = cx.binding(["d", "shift-W"]);
108        cx.assert("Test te|st-test test", "Test te|test");
109    }
110
111    #[gpui::test]
112    async fn test_delete_e(cx: &mut gpui::TestAppContext) {
113        let cx = VimTestContext::new(cx, true).await;
114        let mut cx = cx.binding(["d", "e"]);
115        cx.assert("Te|st Test", "Te| Test");
116        cx.assert("T|est test", "T| test");
117        cx.assert(
118            indoc! {"
119                Test te|st
120                test"},
121            indoc! {"
122                Test t|e
123                test"},
124        );
125        cx.assert(
126            indoc! {"
127                Test tes|t
128                test"},
129            "Test te|s",
130        );
131        cx.assert(
132            indoc! {"
133                Test test
134                |
135                test"},
136            indoc! {"
137                Test test
138                |
139                test"},
140        );
141
142        let mut cx = cx.binding(["d", "shift-E"]);
143        cx.assert("Test te|st-test test", "Test te| test");
144    }
145
146    #[gpui::test]
147    async fn test_delete_b(cx: &mut gpui::TestAppContext) {
148        let cx = VimTestContext::new(cx, true).await;
149        let mut cx = cx.binding(["d", "b"]);
150        cx.assert("Te|st Test", "|st Test");
151        cx.assert("Test |test", "|test");
152        cx.assert("Test1 test2 |test3", "Test1 |test3");
153        cx.assert(
154            indoc! {"
155                Test test
156                |test"},
157            // Trailing whitespace after cursor
158            indoc! {"
159                Test| 
160                test"},
161        );
162        cx.assert(
163            indoc! {"
164                Test test
165                |
166                test"},
167            // Trailing whitespace after cursor
168            indoc! {"
169                Test| 
170                
171                test"},
172        );
173
174        let mut cx = cx.binding(["d", "shift-B"]);
175        cx.assert("Test test-test |test", "Test |test");
176    }
177
178    #[gpui::test]
179    async fn test_delete_end_of_line(cx: &mut gpui::TestAppContext) {
180        let cx = VimTestContext::new(cx, true).await;
181        let mut cx = cx.binding(["d", "shift-$"]);
182        cx.assert(
183            indoc! {"
184                The q|uick
185                brown fox"},
186            indoc! {"
187                The |q
188                brown fox"},
189        );
190        cx.assert(
191            indoc! {"
192                The quick
193                |
194                brown fox"},
195            indoc! {"
196                The quick
197                |
198                brown fox"},
199        );
200    }
201
202    #[gpui::test]
203    async fn test_delete_0(cx: &mut gpui::TestAppContext) {
204        let cx = VimTestContext::new(cx, true).await;
205        let mut cx = cx.binding(["d", "0"]);
206        cx.assert(
207            indoc! {"
208                The q|uick
209                brown fox"},
210            indoc! {"
211                |uick
212                brown fox"},
213        );
214        cx.assert(
215            indoc! {"
216                The quick
217                |
218                brown fox"},
219            indoc! {"
220                The quick
221                |
222                brown fox"},
223        );
224    }
225
226    #[gpui::test]
227    async fn test_delete_k(cx: &mut gpui::TestAppContext) {
228        let cx = VimTestContext::new(cx, true).await;
229        let mut cx = cx.binding(["d", "k"]);
230        cx.assert(
231            indoc! {"
232                The quick
233                brown |fox
234                jumps over"},
235            "jumps |over",
236        );
237        cx.assert(
238            indoc! {"
239                The quick
240                brown fox
241                jumps |over"},
242            "The qu|ick",
243        );
244        cx.assert(
245            indoc! {"
246                The q|uick
247                brown fox
248                jumps over"},
249            indoc! {"
250                brown| fox
251                jumps over"},
252        );
253        cx.assert(
254            indoc! {"
255                |brown fox
256                jumps over"},
257            "|jumps over",
258        );
259    }
260
261    #[gpui::test]
262    async fn test_delete_j(cx: &mut gpui::TestAppContext) {
263        let cx = VimTestContext::new(cx, true).await;
264        let mut cx = cx.binding(["d", "j"]);
265        cx.assert(
266            indoc! {"
267                The quick
268                brown |fox
269                jumps over"},
270            "The qu|ick",
271        );
272        cx.assert(
273            indoc! {"
274                The quick
275                brown fox
276                jumps |over"},
277            indoc! {"
278                The quick
279                brown |fox"},
280        );
281        cx.assert(
282            indoc! {"
283                The q|uick
284                brown fox
285                jumps over"},
286            "jumps| over",
287        );
288        cx.assert(
289            indoc! {"
290                The quick
291                brown fox
292                |"},
293            indoc! {"
294                The quick
295                |brown fox"},
296        );
297    }
298
299    #[gpui::test]
300    async fn test_delete_end_of_document(cx: &mut gpui::TestAppContext) {
301        let cx = VimTestContext::new(cx, true).await;
302        let mut cx = cx.binding(["d", "shift-G"]);
303        cx.assert(
304            indoc! {"
305                The quick
306                brown| fox
307                jumps over
308                the lazy"},
309            "The q|uick",
310        );
311        cx.assert(
312            indoc! {"
313                The quick
314                brown| fox
315                jumps over
316                the lazy"},
317            "The q|uick",
318        );
319        cx.assert(
320            indoc! {"
321                The quick
322                brown fox
323                jumps over
324                the l|azy"},
325            indoc! {"
326                The quick
327                brown fox
328                jumps| over"},
329        );
330        cx.assert(
331            indoc! {"
332                The quick
333                brown fox
334                jumps over
335                |"},
336            indoc! {"
337                The quick
338                brown fox
339                |jumps over"},
340        );
341    }
342
343    #[gpui::test]
344    async fn test_delete_gg(cx: &mut gpui::TestAppContext) {
345        let cx = VimTestContext::new(cx, true).await;
346        let mut cx = cx.binding(["d", "g", "g"]);
347        cx.assert(
348            indoc! {"
349                The quick
350                brown| fox
351                jumps over
352                the lazy"},
353            indoc! {"
354                jumps| over
355                the lazy"},
356        );
357        cx.assert(
358            indoc! {"
359                The quick
360                brown fox
361                jumps over
362                the l|azy"},
363            "|",
364        );
365        cx.assert(
366            indoc! {"
367                The q|uick
368                brown fox
369                jumps over
370                the lazy"},
371            indoc! {"
372                brown| fox
373                jumps over
374                the lazy"},
375        );
376        cx.assert(
377            indoc! {"
378                |
379                brown fox
380                jumps over
381                the lazy"},
382            indoc! {"
383                |brown fox
384                jumps over
385                the lazy"},
386        );
387    }
388}