vim: Join all lines in paragraph

I'm trying without success to join all lines in a paragraph (block of text) using a vimscript. I want to do this for every paragraph (block of text) and want to keep the empty lines between them. (I don't want to use macros)

When I use the }w command to go to the first word in the next paragraph I noted that it does not recognize empty lines with spaces or multiple empty lines between paragraphes. Thats not what I want.

so I tried this: do a search: \(^.*\S\+.*\n\)\{2,} do: normal vipgJ do above search again etc.

It works fine when I do it manually but I can't put this in a script.

I tried this script:

function! <SID>JoinParagraphs() let i = 1 normal gg while i <= 200 call search("\\(^.*\\S\\+.*\\n\\)\\{2,})", "") normal vipgJ let i=i+1 endwhile endfunction

Doesn't work... I tried also to change the line "call search..." for let @/ = "\\(^.*\\S\\+.*\\n\\)\\{2,})" but that does a Join of all lines together (doesn't keep the empty lines).

What did I wrong?

Answers


Replace all newlines followed by something other than a newline with the second matched character:

:%s/\(\S\)\n\(\S\)/\1 \2/

Another approach:

:%s/\n\([^\n]\)/\1/

Just found this answer

:set tw=1000000
gggqG

Which is the absolute winner IMHO.

It executes gq on the motion from gg (start) to G (end of document), using a textwidth of 1000000.


Click: Pragmatic approach added

much underrated command mode and :global

Update Fixed after a correct comment. It happened with whitespace-only lines containing Tab-character(s)... sry bout that.

:g#\v[^\s\t]#normal vipJ

How does that work for you? (perhaps replacing vipJ -> vipgJ if you like)

Update Here is one that not uses normal mode (inspired by Peter's comment)

The big benefit is that it reuses the same pattern in negative and positive sense; That way it can be genericized to

:let @/='\v^\s*$'
:v//.,//-1 join

Now the second line shows the simplicity of the this approach (for every nonmatching line, join up until the next matching line). The best thing is that you can use any odd search pattern instead

Of course you could write this particular task as one line, but it wouldn't quite be as elegant:

:v#\v^\s*$#.,//-1 join

Another approach that has been around since Berkeley UNIX, before vim existed... If you're on a linux/unix system, you can invoke the fmt command like so:

:%!fmt -w 9999

That will do it on the whole file, which might screw up stuff like numbered lists. You can do it by paragraph with:

!}fmt -w 9999

or do it from the command line outside of vi:

$ fmt -w 9999 file.txt

I like this approach because I don't have to remember to reset textwidth=80


Need Your Help

How to use Bootstrap 4 flexbox to fill available content?

css twitter-bootstrap angular flexbox bootstrap-4

I have an angular app that uses bootstrap 4. I have a nav bar that sticks to the top, and I want to add content that fills the remaining space in the browser. Aside from the navbar at the top, I have