3

I'd like to use Ex mode :g/pattern/d to delete most (but not all) of the rows containing pattern, but I want to see each one first and confirm before deleting, similar to :s/pattern/foo/gc. Is there a way to do this, in Ex mode or otherwise?

4
  • 1
    Try :help :g.
    – Ralf
    Commented Jun 22, 2020 at 8:37
  • Thanks! That answers the second question Commented Jun 22, 2020 at 8:39
  • @JoshFriedlander please avoid asking multiple questions in one post! I’ve edited the second out for you.
    – D. Ben Knoble
    Commented Jun 22, 2020 at 11:20
  • @D.BenKnoble 👍 Commented Jun 22, 2020 at 12:18

2 Answers 2

6

One way to achieve what you want to do is to use the :s command inside your :g command:

We know that we can delete a line, with a confirmation using the following substitution:

:s/.*\n//c

This will replace all the characters (.*) and the next end of line character (\n) with nothing, effectively deleting the line. The c flag at the end of the substitution prompts for a confirmation.

Now :h :g tells us that the command :g takes a pattern and a command. The pattern is up to you to choose but the command can be the one we used before, making your :g command like this:

:g/pattern/s/.*\n//c

Replace pattern by your own pattern and you are good to go.


EDIT As Luc pointed out in the comments, this solution has some flaws: If you have consecutive lines matching the pattern only the first one will be handled.

A solution could be to use :g/pattern/s/.*\|.*\n//c but this will leave empty lines instead of deleting them completely. These remaining lines could be handled with :g/^$/d but that require to have no other empty lines in the buffer.

If you have empty lines in the buffer, you could replace the lines to be deleted with a marker :g/pattern/s/.*\|.*\n/deleteme/c and then delete the lines containing this marker with :g/^deleteme$/d.

1
  • 2
    The :g/pat/s/.*\n/c solution doesn't work with consecutive lines which shall be removed. :%s/.*|.*\n//c works though. Commented Jun 22, 2020 at 12:51
4

Sometimes ago, on SO, I've posted a solution to have a :global command which asks for confirmation before executing anything (:delete in your case): https://stackoverflow.com/a/46830106/15934

It's a little bit convoluted :D. It's shipped with my library plugin, and it can be used with

:ConfirmGlobal/pattern/d

Note: unlike the :g/pattern/s/.*\n//c solution, the confirmation is global, and it doesn't skip consecutive lines that shall be removed.

In the end, the only vanilla solution that I'm aware of, and that works in all situations (consecutive lines, first line (see Q/A on SO)) is

:%s/.*pattern.*\n//c

It's not :global with confirm, it's :substitute hijacked to remove entire lines, with confirm.

5
  • Brilliant, thanks! I see also now that my question is an exact dupe of that one Commented Jun 22, 2020 at 12:57
  • 1
    It's a dupe indeed... but not on the same site... :D Commented Jun 22, 2020 at 12:57
  • Ah, good point... Commented Jun 22, 2020 at 12:58
  • @JoshFriedlander This answer might deserve to be the accepted one, I completely missed the potential consecutive lines issue :)
    – statox
    Commented Jun 22, 2020 at 16:14
  • 2
    Yeah. @LucHermitte's comment adapting your solution is maybe the best, plus its vanilla Vim. Commented Jun 22, 2020 at 18:22

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.