3

I'm a long time vi/vim user from college days in the 90s, but never considered myself a power user. I'd like to improve at it and the other day I was staring at something in an Ansible playbook like this:

- name:  Execute a shell command
  shell:  "do-this && do-that && this-other-thing && echo 'Done'"

Now imagine deciding that we don't want do that or the other thing, so if I go the space before do-that and set a mark, and then use search to quickly move over to echo, how can I either:

  • set another mark and then zap the text between the first and second
  • zap everything between the first mark and where the cursor is now

In other words, quickly remove everything highlighted here:

- name:  Execute a shell command
  shell:  "do-this && do-that && this-other-thing && echo 'Done'"
#                    --------------------------------

Normal (command) mode is preferred as this is an open file, make quick edit, and close exercise.

1 Answer 1

4

Using marks

To do this with marks, do the following:

  1. Set your mark on the first ampersand: ma
  2. Move to the echo command anyway you choose.
  3. Delete from there back to the mark: d`a Make sure to use a backtick, and not an apostrophe here.

I don't like this approach. In my mind, I'm never certain which route it will take to the mark while deleting text. Will it go backwards or wrap around while deleting text? Keep in mind I have nothing to back up this suspicion.

Using the search text-motion

Instead, I suggest you could do it this way far easier. It deletes until the specified text is found.

  1. Navigate to the first ampersand.
  2. Delete everything until the word echo: d/echo<CR>

Using the :substitute Ex command

You could also do this with an Ex command while the cursor is on the desired line, substituting

  • everything between the first and last ampersand with an empty string: :s/&.*& //,
  • or replacing everything from the first ampersand up until echo: :s/&.*\zeecho//

Aside

There are many ways to do just about anything in Vim. I've found that the key to mastering it is to learn the language components and how to combine them. Pairing the right verb with either an object or a motion can do amazing things. Here's a small list.

Verbs

d - delete, c - change, y - yank, > - indent

Objects :h text-objects

iw - inner word, at - a (HTML/XML) tag block, i( - inside parentheses

Motions :h motion.txt

B - to previous Word, } - to next paragraph, tc - to, but not including, the character c

3
  • The first suggestion d`a was flawless, so much in fact I realized my example would have left me with a shell syntax error. Thanks so much!
    – Joe
    Jul 26, 2022 at 22:16
  • In the end, in normal mode, I set the mark a and then used /ec to get me in front of the echo, backed up a space, and d`a. Victory.
    – Joe
    Jul 26, 2022 at 22:18
  • 1
    0f&f d/echo<cr> is probably what I would do, too. The answer would, in my mind, benefit from explaining that (unlike emacs, I think) Vim's delete command does not operate between two marks, but rather from the cursor position through a motion. One such motion is jumping to a mark, and you can set the cursor position with a mark, so `ad`b is valid, but if you just set one of the marks, you don't need to jump to it first. Also, :'a,'b delete deletes the lines bewteen two marks, which is different but no less useful.
    – D. Ben Knoble
    Jul 27, 2022 at 14:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.