Join lines inside paragraphs in vim

6,383

Solution 1

I think this does what you want: make sure there is an empty line at the end of the file, then join every paragraph (terminated by an empty line).

G:a

.
:g/^./ .,/^$/-1 join

Explanation: first go to the end of the file and append an extra empty line with :a (maybe there's a more elegant way to do that; interactively, you can replace the first three lines with o<ESC>). Then, for every non-blank line that hasn't been considered yet (:g/^./), apply the join command to the range starting at the selected line (.) and ending one line before the next empty line (/^$/-1).

Optionally, :g/^$/d if you don't want any blank line to remain (then you can take off the -1).

Solution 2

This should do it:

:set tw=99999
gggqG

tw is set to some value at least as large as the number of characters in the longest paragraph. gg moves the cursor to the first line; gq is the command to reformat; G moves the cursor to the last line, telling gq to reformat from the current cursor location to the last line.

Solution 3

  1. Set the cursor inside the desired paragraph

  2. Type: vipJ

(vip highlights the current paragraph, J joins all lines)

Solution 4

Might not be the cleanest way to do it, but here's what I would use:

ggqav}bgJ}wq999@a   # go to the top of the file (gg)
                    # start recording macro "a" (qa)
                    # select the entire paragraph (v})
                    # go back one word so as not to join the blank line (b)
                    # join the selected lines without spaces (gJ)
                    # go to first word of the next paragraph (}w)
                    # finish recording the macro (q)
                    # 999 times (arbitrary number of paragraphs to join)
                    # run macro "a" (@a)

(Works in VIM 7.2.)

Depending on exactly how the paragraphs were split when they were originally formatted, you may want to replace the gJ command (join without spaces) with the J command (join with spaces).

The arbitrary 999 count only needs to be at least the number of paragraphs in the file -- you can select a larger number if you want and lose nothing but processor cycles. Assuming one and only one blank line between paragraphs, you can get a more accurate paragraph count using:

:%s/^$//gn     # returns "999 matches on 999 lines"
Share:
6,383

Related videos on Youtube

dggoldst
Author by

dggoldst

I like progging.

Updated on September 17, 2022

Comments

  • dggoldst
    dggoldst over 1 year

    Suppose you've typed a long document in vim with automatic line breaking on, so all the lines have been broken at, say, 79 characters. You may have even applied formatting to the whole document to break all the lines at that length.

    Paragraphs are demarcated in your document by blank lines.

    Now you decide you don't want line breaks within paragraphs at all.

    How can you remove all the line breaks within paragraphs without eliminating the paragraph boundaries altogether?

    I have made this quick and idiotic hack, but am looking for the proper way.

    :%s/^\s*$/@@@@@ - replace blank lines with @@@@@
    ggVGgJ           - join all lines in the file
    :%s/@@@@@/\r\r/g   - replace @@@@@ with line breaks
    
  • dggoldst
    dggoldst over 13 years
    Thanks. This is getting very close for me, however, it's deleting the blank lines between paragraphs. (I tried fileformat unix and dos to see if it was a Windows thing). Also, could you translate the commands a bit? G goes to the last line. :a according to help is "append" but I'm not sure what that does. Also the g/pattern/cmd you have there has lost me. What's the command?
  • dggoldst
    dggoldst over 13 years
    This works for me. Would be good to add a "gg" at the beginning to put the cursor at the top of the file. Also, using J instead of gJ doesn't cause separate words to mash together into one. This might only be the case for my values of "formatoptions", which are currently puzzling me.
  • Gilles 'SO- stop being evil'
    Gilles 'SO- stop being evil' over 13 years
    @dggoldst: I've changed the command to retain empty lines. The first three lines are just to add an empty line at the end of the file (otherwise the last paragraph won't be matched). The last command is :g, which applies a command to all matching lines; see :help :g and perhaps this thread on how :g behaves when you delete line breaks.
  • SergioAraujo
    SergioAraujo over 5 years
    :$pu _ at the end put black hole register, which results in a blank line at the end.
  • G-Man Says 'Reinstate Monica'
    G-Man Says 'Reinstate Monica' almost 4 years
    … and just repeat the above 817 times.    ?    :-(   ⁠
  • sepideha
    sepideha almost 4 years
    sorry why 817 times? I did n't get your point
  • G-Man Says 'Reinstate Monica'
    G-Man Says 'Reinstate Monica' almost 4 years
    The point is that the question doesn’t ask “How can I merge a bunch of lines (e.g., representing a paragraph) into a single line?”  It asks “How can I take a loooong document, with many paragraphs demarcated by blank lines, and remove all the line breaks within paragraphs?”  goldPseudo’s answer notionally suggested that the document might contain as many as 999 paragraphs and provided a solution that would automatically process that many paragraphs all in one shot. … (Cont’d)
  • G-Man Says 'Reinstate Monica'
    G-Man Says 'Reinstate Monica' almost 4 years
    (Cont’d) …  On the other hand, your answer requires the user to manually mark the beginning and end of one paragraph (rather than automatically taking everything from one blank line to the next), and then remove the line breaks in that paragraph.  You provide no method to process all the paragraphs in the document automatically, suggesting that the user must execute your manual procedure many many times.   (I just randomly picked a large number less than 999.)
  • sepideha
    sepideha almost 4 years
    Thank a lot for clarification.
  • D. Ben Knoble
    D. Ben Knoble over 3 years
    Another alternative would be :$put =''