Insert Vim after a certain number of delimiters

I want to make the code more readable by taking something like this:

0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 .... 

and adding new lines to create increments of 8:

 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 .... 

Does anyone know any vim magic that will allow me to do this with specially allocated lines?

+6
source share
5 answers

This is not a pleasant solution, and I am sure that it can be removed / simplified. First select the text and enter the following command:

 :'<,'>s/\(\S\+,\s*\)\{8}/&\r/g 

This outputs something like this:

 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, ... 
+5
source

One way to cheat:

  • set textwidth=48
  • highlight (in visual mode) the lines you want to wrap
  • gq

This will work very well if the text width roughly matches where you want to wrap. If all items in the list have the same width, this method should be flawless.

Another, slightly more reliable way would be to define a macro.

  • move the cursor to the beginning of the line
  • qw to start writing a macro to the w register (you can use any register)
  • 8f,a press enter, leave the insert mode and press q again
  • @w to play the macro as many times as you need. I'm sure there is a smart way to automate how many times a macro plays, but I'm not sure how to do it. You can also press @@ to run the last running macro.

The regex also works as sent by @zanegray.

+1
source

This will not win a single vim golf competition, but I like to think about such problems with a simple step.

  • Put each item on its line.
  • Combine 8 lines at a time
  • Do everything you need to clean by hand.

To do this, do the following:

 :s/, /,\r/g :'[,']g/./j 8 

Explanation:

  • :s/, /,\r/g replace all spaces after decimal point with return ( \r )
  • '[,'] is the range of recently changed text.
  • g/./{cmd} will execute the command {cmd} on the entire line corresponding to . (any non-empty string)
  • j 8 not suitable for join 8 , which means joining 8 lines

Now a warning word: it concatenates with 8 lines even after it exceeds the end of the replaced text '] . This could be overcome with a more complex command like:: :'[,']g/./.,+6/,$/j 8 , but this is not easy enough for my tastes. If this problem is a real problem, I would move the source text to a new buffer (via :new ) or at least to the bottom of the current buffer. After the conversion is complete, move it into place.

For more information

 :h range :h :j :h :s :h :g :h '[ 
+1
source

You can do this with a multi-part command, which might be easier to wrap around you ...

Create a macro that adds a semicolon after the 8th comma.

 qq8f,lr;qu 

Select the text, and then run this macro 1000 times (or more if there are more than 8000 per line)

 :'<,'>norm 1000@q 

Select an area with gv and replace all half-columns with line breaks.

 gv :'<,'>s/;/\r/g 

After the 8th comma, a semicolon will be added, and then it will fall under the comma with a line break.

0
source

So, this solution is based on Zanegray solution and a little tweak from my side:

 :s/\(\w\+,\s\)\{8}/&\r/g 

A Zanegray solution would also work like this:

 :s/\(\S\+\s\)/&\r/g 

since negating spaces \S would include,.

0
source

Source: https://habr.com/ru/post/921338/


All Articles