4

I'm familiar with vertical blocks, and I often ctrl+v down down down shift+I foobar esc to write foobar in various locations at once. This is useful if I want to replace <td> to <th> in a chain, for instance.

Since not all the text blocks are of equal size, I don't know how to do the same for </td> to </th>. I can think of selecting multiple lines as I did earlier, move to the end of the line with shift+a, maybe, move one to the left, delete a character with x, and type my h, but I don't know how to move my position(s) when I am in visual block mode.

Is there a way to select a position as active, and move as I usually would with my marker, choosing where to write?

In SublimeText3 I would do something like ctrl+d to select the cases I'm looking for (skipping with ctrl+k+d if necessary), moving to the end-of-line with end (home for the beginning of the line), and then moving with the arrow keys (alternatively with ctrl+arrow keys).

An example scenario:

<tr> <th>Language</th> <th>Oral</th> <th>Written</th> <th>Diplomas</th> <th>Notes</th> </tr> 

which I want to be

<tr> <td>Language</td> <td>Oral</td> <td>Written</td> <td>Diplomas</td> <td>Notes</td> </tr> 
5
  • I gues you want github.com/terryma/vim-multiple-cursors Commented Apr 16, 2019 at 13:37
  • Interesting plugin. I might take a look at it on my home machine. Is there a native way to do the same, or similar? Commented Apr 16, 2019 at 13:40
  • There is. But you need to provide a text sample. It's hard to understand what you really want. Commented Apr 16, 2019 at 13:43
  • I've added my scenario. Commented Apr 16, 2019 at 14:01
  • A few years ago we had a question about multiple cursors and I think it is pretty related to this one. Commented Apr 16, 2019 at 14:02

5 Answers 5

3

Aside from the suggested plugin vim-multiple-cursors, you have different options:

For example you can go on the parent tag (tr I guess?) and visual select in the tag:

vit 

Then do a substitution in the tr tag only:

:'<,'>s/td/th/g 

If you want to do a more complex change than a substitution, you can search for a pattern matching all the places you want to apply a change, go to the first one, do your change, and for all the other, if the change is atomic, use . to repeat it:

/td> ceth<esc> n.n.n. 

The first command searches for a td> tag, the second cut until the end (ce) and types th, then leaves the insert mode. The third line goes to the next td (n), execute the second command (.) and this 3 times (do it as many times as you need of course, it is just an example).

If the change is more complex, you can also create a macro.

There is an interesting article about multiple cursor (or rather lack of) in Vim: https://medium.com/@schtoeffel/you-don-t-need-more-than-one-cursor-in-vim-2c44117d51db

6
  • I neither know how to do a substitution in a selected mode (vit is great to select my tags to apply it too, though!), nor how to use move my cursor after having found my matches with n Can you explain this? Commented Apr 16, 2019 at 13:59
  • For the first one, do a visual selection, then press : to enter in command mode, it will show: :\<,\> which means "type a command that I will run in a range (\< being the beginning of the selection and \> being the end. Your command would look like: :\<,\>s/td/th/g. Commented Apr 16, 2019 at 14:01
  • When you do a search in Vim, you can then go from result to result of your search with the n key. I am updating my answer with an example. Commented Apr 16, 2019 at 14:04
  • Interesting. Knowing RegEx, I find the substitution method really nice. What effect does the last /g mean? I assume global. Commented Apr 16, 2019 at 14:15
  • yes, global, especially in his case where he wants to replace both start and end td tags of the lines Commented Apr 16, 2019 at 14:16
2

I know there has already answers. But i couldn't help to try something i just learned from @padawin's link.

  1. /th> search th>
  2. cgntd> change th> to td>
  3. ......... repeat 9 times with 9 dots. You can just press the button, don't lift it.

check :h gn

update

If your text doesn't contain th, place your cursor under th, you can replace word under cursor like this:

  1. *#cgntd
    • * set @/ to \v<th>, search forward
    • # search backward, restore cursor, you can also use N if you want.
    • cgntd replace next match (or the one under cursor) to td
  2. .........
    • repeat, You can hold . , don't release
1
  • Indeed, I just played a bit with it too, it is definitely promising! I'll try to keep it in mind. Commented Apr 16, 2019 at 14:45
1

Building on padawin’s answer, I would go to the <tr> tag, vit, and then

:s-<\(/\)?th>-<\1td>-g 

To do the replacement. If your text doesn’t contain th, then :s/th/td/g is simpler.

Alternately, with tpope’s surround plugin, on each th, do cst<td>. Combined with tpope’s repeat, you can do this for one line and repeat on each with the . command, or even :g/<th>/normal f>lcst<td>

1

I use surround.vim which makes changing tags easier, e.g. cst<td>. Combine this with :normal and a visual mode makes this pretty easy. Just visually select the lines with V then run:

:norm cst<td> 

For more help see:

:h :range :h :norm :h V 
1
  • Nice to see a similar idea ;) Commented Apr 17, 2019 at 2:42
0

Note: Not an answer anymore after your last update to the question, but perhaps still useful to know.


Try it like this:

  1. Goto end of first line.
  2. Hit <Ctrl-V>$
  3. Move down
  4. Hit Afoobar<esc>

With the $ you hit in step 2, the visual block selection is always till end-of-line. Even if one of the following lines is shorter.

2
  • This works if I delete all the end-of-line > tags in the html, and add them in the foobar. I tried tricking it with I, but that worked out wrong. Can I somehow tell it to move one position to the left? Commented Apr 16, 2019 at 13:52
  • @mazunki I don't think this is possible. I would do it with search/replace. See the answer from D. Ben Knoble. Commented Apr 16, 2019 at 14:25

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.