12

I have a quite big text file formed of blocks like

Short line.
Really long line.
Short line.

separated by empty lines, and I would like to use vim (on Linux) to break down the long lines and obtain blocks like

Short line.
This was
part of
a long line.
Short line.

My problem with gq (and gw) is that it reflows each block as an entire paragraph, i.e. it doesn't preserve the two line breaks within each block, and according to :help fo-table none of gq's format options would allow me to do what I want. I also thought that I could achieve my goal if I could define new-line characters to be paragraph delimiters, but according to :help paragraph those are hard-coded.

Edit: I know that I could use gq or gw to format each long line one by one, but since my file runs over a few thousand lines I am looking for a way to achieve this automatically.

  • By the way: I looked for solutions to my problem in vim's documentation, here on SU, and on the web, coming up empty. I will gladly delete this question if I overlooked something obvious. – A.P. Mar 30 '15 at 13:10
  • There is Can I justify text in Vim? at vi.sx. – Martin Schröder Apr 3 '15 at 12:26
  • @MartinSchröder: Glad to know there's a vi SE! Those answers don't address my issue, though, since I already knew about gq and gw. I'm also glad I didn't stop there, otherwise I wouldn't have learned about the :g command. :) – A.P. Apr 3 '15 at 12:33
16
:%norm! gww

This applies the normal command gww (which formats the current line as with gw) on the entire buffer, without taking customized mappings into account (to avoid problems if e.g. gw has been mapped to something else).

See

  • :help :%
  • :help :norm
  • :help gww

This alternative is as per Ben's suggestion in the comments, and is more straightforward than the original solution, which is saved below since it might fit better in other similar circumstances due to the regular expression matching ability. In the "match all lines" case, it is unnecessarily brute, though.


Applying gww on every individual line in the buffer programmatically:

:g/^/norm gww

See :help :g and :help norm. ^ matches the beginning of a line, which in practice makes this match every line.

One can also opt to select only lines longer than e.g. 60 characters with

:g/\%>60v/norm gww

(see :help \%<) but in practice gww will only reformat lines longer than textwidth anyway, so it might not matter much in neither speed nor result.

(I am using v for "virtual column" instead of c for "column", since the latter really calculates a certain number of bytes into the line. This can lead to unexpected results when using multibyte encodings, which is often a reason to be wary. In practice it is not a real issue for the same reason as above, regarding that gww will not reformat lines shorter than textwidth anyway.)

  • Apparently :g fails without a pattern, so :g//norm gww doesn't work but :g/.*/norm gww does. – A.P. Mar 30 '15 at 17:01
  • @A.P.: Huh, works for me. I am using Vim 7.4.488-6 from Debian Unstable. – Daniel Andersson Mar 30 '15 at 18:32
  • 4
    :g// reuses the last search pattern; if there's none, it fails. Use :g/^/ to apply to all lines. – Ingo Karkat Mar 30 '15 at 18:35
  • @IngoKarkat: Ah, makes sense, since my last pattern during the tests was the line length aware one I demonstrated later. I will update the answer. Do you know where in the help this "empty pattern" behavior is mentioned? I can not trivially find it. – Daniel Andersson Mar 30 '15 at 18:39
  • Looking through the manual, it is probably implied that the information given in :help last-pattern for normal searching applies to the :global command as well. – Daniel Andersson Mar 30 '15 at 18:55
4

Since you’ve already read the manual for the gq and gw commands, I figure you probably want something more convenient than manually moving to the long lines and then using gw0, gw$ or another gw command to only format the current line.

I don’t know an easy way of breaking long lines in Vim over a block of text. However, since you’ve mentioned that your using Vim on a GNU/Linux system, I’d suggest filtering your text through the GNU fmt command.

For the whole file:

:%!fmt --width=75 --split-only

For the current paragraph (using short options):

:'{,'}!fmt -75 -s

Explanation of the relevant fmt options are:

  • -w, --width=WIDTH – maximum line width (default of 75 columns). The option -WIDTH is an abbreviated form of --width=DIGITS (if using this abbreviated version, it must be the first option).

  • -s, --split-only – split long lines, but do not refill; this is the option that preserves your pre-existing hard line breaks.

  • Thanks for mentioning fmt. I preferred to accept the other answer, though, because it requires only vim. – A.P. Mar 30 '15 at 17:03
  • @A.P. No worries. It's a great answer and I'd have accepted it, myself. Both it and your question merit upvotes. – Anthony Geoghegan Mar 30 '15 at 22:39
1

From:

Short line.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Short line.

Putting the marker on the "lorem ipsum" line and pressing gww yields (with textwidth=40 for clarity):

Short line.
Lorem ipsum dolor sit amet, consectetur
adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna
aliqua. Ut enim ad minim veniam, quis
nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat.
Short line.

which to me seems like what you are asking for. If not, please feel free to clarify.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.