delete.rs

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