1

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 Jun 22 '20 at 8:37
  • Thanks! That answers the second question – Josh Friedlander Jun 22 '20 at 8:39
  • @JoshFriedlander please avoid asking multiple questions in one post! I’ve edited the second out for you. – D. Ben Knoble Jun 22 '20 at 11:20
  • @D.BenKnoble 👍 – Josh Friedlander Jun 22 '20 at 12:18
4

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. – Luc Hermitte Jun 22 '20 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 – Josh Friedlander Jun 22 '20 at 12:57
  • 1
    It's a dupe indeed... but not on the same site... :D – Luc Hermitte Jun 22 '20 at 12:57
  • Ah, good point... – Josh Friedlander Jun 22 '20 at 12:58
  • @JoshFriedlander This answer might deserve to be the accepted one, I completely missed the potential consecutive lines issue :) – statox Jun 22 '20 at 16:14
  • 2
    Yeah. @LucHermitte's comment adapting your solution is maybe the best, plus its vanilla Vim. – Josh Friedlander Jun 22 '20 at 18:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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