Is it possible to interactively delete matching search pattern in Vim?
Asked Answered
P

5

82

There is a phrase that I want to look for in Vim. When found, I want to delete that occurrence of the phrase. What is the easiest way to cycle through all the occurrences (via n), and delete a match one by one (I do not want to delete all of them at once).

Note: I know I can delete a certain number of characters or a number of words, but I want to specifically remove the match of my search. Is this possible?

Panhellenic answered 20/10, 2011 at 21:14 Comment(0)
F
119

http://vim.wikia.com/wiki/Search_and_replace

Try this search and replace:

:%s/foo/bar/gc

Change each 'foo' to 'bar', but ask for confirmation first.

Press y or n to change or keep your text.

Flotage answered 20/10, 2011 at 21:18 Comment(3)
how can I replace ./ with nothing ? I want to convert ./labeled-data/moth/frame051.png to labeled-data/moth/frame051.pngEndora
@MonaJalal Give this is a shot, it worked for me: :%s/\.\///g Period and slash require a backslash in front of them in order to treat them as literal characters.Flotage
wow.. this is super useful.Dreiser
H
47

There are 3 ways I can think of:

The way that is easiest to explain is

:%s/phrase to delete//gc

but you can also (personally I use this second one more often) do a regular search for the phrase to delete

/phrase to delete

Vim will take you to the beginning of the next occurrence of the phrase.

Go into insert mode (hit i) and use the Delete key to remove the phrase.

Hit escape when you have deleted all of the phrase.

Now that you have done this one time, you can hit n to go to the next occurrence of the phrase and then hit the dot/period "." key to perform the delete action you just performed

Continue hitting n and dot until you are done.

Lastly you can do a search for the phrase to delete (like in second method) but this time, instead of going into insert mode, you

Count the number of characters you want to delete

Type that number in (with number keys)

Hit the x key - characters should get deleted

Continue through with n and dot like in the second method.

PS - And if you didn't know already you can do a capital n to move backwards through the search matches.

Haag answered 20/10, 2011 at 21:26 Comment(5)
Instead of going to insert mode, then hitting delete, then escape, you can save about 4 total keystrokes by not going into insert mode and just using x to delete the character under the cursor.Testimonial
@Testimonial yes but using x counts as a single command so if you want to delete an entire phrase by just hitting the dot, then you have to go into insert mode and delete the amount of characters. BUT you could count the number of characters to delete, type that number and then x - I will add that to my answer, thanks for the inspiration, if not suggestion.Haag
Why not use the d (delete) key for deletion? Since the phrase is the same all the time figure out how to delete using a motion key following d (dw for delete word, dt' for delete everything to the next occurence of ') it will still count as one command and work with .Pithos
@Pithos +1 That is definitely a good set of commands to mention.Haag
%s/word deletes the word. omit % if the word is in the current line. % means (search whole) file, as default (scope) is line.Rayner
E
16

1. In my opinion, the most convenient way is to search for one occurrence first, and then invoke the following :substitute command:

:%s///gc

Since the pattern is empty, this :substitute command will look for the occurrences of the last-used search pattern, and will then replace them with the empty string, each time asking for user confirmation, realizing exactly the desired behavior.

2. If it is a common pattern in one’s editing habits, one can further define a couple of text-object selection mappings to operate specifically on the match of the last search pattern under the cursor. The following two mappings can be used in both Visual and Operator-pending modes to select the text of the preceding match of the last search pattern.

vnoremap <silent> i/ :<c-u>call SelectMatch()<cr>
onoremap <silent> i/ :call SelectMatch()<cr>
function! SelectMatch()
    if search(@/, 'bcW')
        norm! v
        call search(@/, 'ceW')
    else
        norm! gv
    endif
endfunction

Using these mappings one can delete the match under the cursor with di/, or apply any other operator or visually select it with vi/.

Extrauterine answered 21/10, 2011 at 9:43 Comment(0)
C
12

The best way is probably to use:

:%s/phrase//gc

c asks for confirmation before each deletion. g allows multiple replacements to occur on the same line.

You can also just search using /phrase, select the next match with gn, and delete it with d.

Curtate answered 5/11, 2015 at 14:3 Comment(0)
L
0

Let's say you've performed a search with / and so have the string you want to delete in your search register, then either:

  • Enter gn to select the next search match in VISUAL mode
  • Enter d to delete that visual selection
  • Enter n to move to the next match
  • Enter . to repeat the deletion on that match

Or

  • Enter dgn to immediately delete the next match
  • Enter . to repeat, immediately deleting the subsequent match

The first approach is nice as (like you asked) you can use n to cycle through your matches skipping over those you want to keep. Then hit . to swat matches now immediately under your cursor. This also gives you a chance to visually check the difference before/after you hit ., which I often find to be quite helpful.

Or use dgn, that's slightly less keystrokes. It's worth pointing out that with this you can still use n to skip matches and . to delete the match under your cursor (which still counts as deleting the next match), so in some sense this is universally better.

What you're missing is probably just gn or dgn. Of course, you can prefix gn with other commands like cgn so it's quite a composable approach. For simple actions I often prefer this over :s as it's more interactive, more selective and it's still fast.

Lenorelenox answered 16/3 at 20:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.