Fred
Fred

Reputation: 4947

Change wrap width in a text file using Vim

I want to format srt subtitle text files to avoid wrapping problems on my media player.

I need to set a line wrap width to a number of characters e.g. 43

I can do this with Editplus, its a built in function and works well. The reason I want to do it in Vim, firstly Editplus is only available on the PC and the secondly Vim is badass.

I have found the following solution on the net..

:set tw=43
gggqG

It does work, but not exactly how I want it.

E.g.

I have this text:

557
00:47:39,487 --> 00:47:42,453
I will have to complete some procedures,
and I asked you to check out what they are for me

after I format it, I get:

557 00:47:39,487 --> 00:47:42,453 I will
have to complete some procedures, and I
asked you to check out what they are for
me

It seems to ignore line breaks/CRs. As you can see the "I will" has been added to the first line.

How do I get it to not ignore line breaks?

EDIT: apoligies about the formatting, first time using stackoverflow!

Upvotes: 3

Views: 4372

Answers (5)

DrAl
DrAl

Reputation: 72606

You could use the whitespace option of formatoptions and make the lines you want to wrap end in whitespace.

:set tw=43
:set fo+=w
:g/^\a/s/$/ /
gggqG

The third line adds a space on the end of any line starting with a letter and fo+=w stops gq from joining lines that don't end in spaces.

See:

:help fo-table
:help 'formatoptions'
:help gq
:help :g

Edit in response to comments

:g/^\a/s/$/ /

This translates to:

:g/   " Search the file
^\a   " For lines starting (^) with an alphabetic character (\a - equivalent to [A-Za-z])
/     " Then on each line that the regexp matches (i.e. each line starting with an alphabetic character)
s/    " Substitute...
$     " The end of line (zero-width match at the end of the line)
/ /   " With a space (slashes are delimiters)

The global (:g) command will only operate on the current file, but the textwidth and formatoptions lines will last for the whole session. If you want those options to only be used on the current buffer, use :setlocal instead:

:setlocal tw=43
:setlocal fo+=w
:help :setlocal

Upvotes: 6

erichui
erichui

Reputation: 2771

While not exactly robust (or elegant), if you can assume that the subtitle lines do not begin with numbers, you can configure Vim to treat them as comments.

:set comments=:0,:1,:2,:3,:4,:5,:6,:7,:8,:9
gggqG

Lines starting with 0-9 will be treated as comments and won't be merged together with the text.

Upvotes: 1

rampion
rampion

Reputation: 89043

If the only lines you want to wrap are the ones that start with text (ignore the ones that start with numbers) you can use the following.

:g/^[a-zA-Z]/normal gqq

This will run p00ya's command on each text line in the file.

Upvotes: 2

p00ya
p00ya

Reputation: 3709

With the following text (i.e. only 3 lines):

557
00:47:39,487 --> 00:47:42,453
I will have to complete some procedures, and I asked you to check out what they are for me

Use gqq (format current line) on the 3rd line after setting tw. Formatting by paragraph will not work since vim will treat all 3 lines as part of the same paragraph (paragraphs only end with a blank line).

Upvotes: 1

Gavin Gilmour
Gavin Gilmour

Reputation: 6963

I can't see exactly what the issue is due to the formatting of your post, but you might want to checkout the 'formatoptions' setting in vim's help, specifically :he fo-table which contains a bunch of customization flags.

This link might be useful.

Upvotes: 0

Related Questions