How to unwrap text in Vim?

Since joining paragraph lines using Normal mode commands is already covered by another answer, let us consider solving the same issue by means of line-oriented Ex commands.

Suppose that the cursor is located at the first line of a paragraph. Then, to unwrap it, one can simply join the following lines up until the last line of that paragraph. A convenient way of doing that is to run the :join command designed exactly for the purpose. To define the line range for the command to operate on, besides the obvious starting line which is the current one, it is necessary to specify the ending line. It can be found using the pattern matching the very end of a paragraph, that is, two newline characters in a row or, equivalently, a newline character followed by an empty line. Thus, translating the said definition to Ex-command syntax, we obtain:

:,-/\n$/j

For all paragraphs to be unwrapped, run this command on the first line of every paragraph. A useful tool to jump through them, repeating a given sequence of actions, is the :global command (or :g for short). As :global scans lines from top to bottom, the first line of the next paragraph is just the first non-empty line among those remaining unprocessed. This observation gives us the command

:g/./,-/\n$/j

which is more efficient than its straightforward Normal-mode counterparts.


Go to the beginning of you paragraph and enter:

v i p J

(The J is a capital letter in case that's not clear)

For whole document combine it with norm:

:%norm vipJ

This command will only unwrap paragraphs. I guess this is the behaviour you want.


The problem with :%norm vipJ is that if you have consecutive lines shorter than 80 characters it will also join them, even if they're separated by a blank line. For instance the following example:

# Title 1

## Title 2

Will become:

# Title 1 ## Title 2

With ib's answer, the problem is with lists:

- item1
- item2

Becomes:

- item1 - item2

Thanks to this forum post I discovered another method of achieving this which I wrapped in a function that works much better for me since it doesn't do any of that:

function! SoftWrap()
    let s:old_fo = &formatoptions
    let s:old_tw = &textwidth
    set fo=
    set tw=999999 " works for paragraphs up to 12k lines
    normal gggqG
    let &fo = s:old_fo
    let &tw = s:old_tw
endfunction

Edit: Updated the method because I realized it wasn't working on a Linux setup. Remove the lines containing fo if this newer version doesn't work with MacVim (I have no way to test).

Tags:

Vim