45

The only reason why I'd ever edit a text file in Pico or Nano, and not in Vim was its "Justify" command ^J. It would reformat a paragraph of text, creating line breaks at word breaks so that the text would float on fixed width screen nicely - format the text to fit predefined 80 columns, creating line breaks only between words. As limited the function was, it was very useful, whether to format lengthy comment blocks, documentation files, or just replacing an endless line of parameters with something more readable.

Can I do something like that in Vim?

6 Answers 6

44

You can use the gq or gw operators combined with a motion command. By default, formatting of applicable text is done by Vim and to the best of my knowledge it does not justify the lines (you will get ragged right margins). Alternatively, an external program (e.g. the fmt command on Linux) can be used to do the formatting by specifying it with the formatprg setting.

The way I use it is to gwip (normal mode) with the cursor on a paragraph. This will format the current paragraph keeping the cursor on the same position. I use it this way to make sure that only the current paragraph is formatted. When editing a text file, issuing gwG (normal mode) at the begining of the file will format the whole text. As a good practice, be sure to leave at least one blank line between paragraphs.

There is a lot of configuration that can be done. To begin with, here are some relevant help: :h gq, :h gw, :h fo (format options), :h fp (format program), :h fo-table (an explanation of the possible options).

2
  • 2
    gq/gw is definitely the way to go. to add to this message you can change format program to par to have more options. Checkout vimcasts.org/episodes/formatting-text-with-par
    – Bambu
    Feb 6, 2015 at 13:04
  • 6
    By default, Vim doesn't use any external program, although you can choose to use one by setting the 'formatprg' option.
    – jamessan
    Feb 6, 2015 at 14:16
19

There is a great VimCast on this topic.

http://vimcasts.org/episodes/formatting-text-with-par/

Basically, you need to install par:

$ brew install par
# or
$ sudo apt-get install par

And then, since you want columns to be wrapped in 80 columns:

:set formatprg=par\ -w80

Now you can use the gq operator, like in other answers (e.g. gqip), and it will use Par instead of Vim's built-in formatter.

Par is quite advanced, and it will format comments like this nicely:

/* This is a long */
/* multiline comment */
18

From :help usr_25:

JUSTIFYING TEXT                                                                 

Vim has no built-in way of justifying text.  However, there is a neat macro     
package that does the job.  To use this package, execute the following          
command:                                                                        

        :runtime macros/justify.vim                                             

This Vim script file defines a new visual command "_j".  To justify a block of  
text, highlight the text in Visual mode and then execute "_j".

So, all you have to do is run

:ru macros/justify.vim

and then type

_j

to justify the text in the entire file.

(Of course, you could also add ru macros/justify.vim to your .vimrc so you don't have to type it every time.)

Note: this does not add line breaks for you. You have to add those manually with gq. For this you must also set the textwidth (default is 0) to your desired value via

set textwidth=80

and—if you want—automatic text wrapping by setting the t-flag via

set formatoptions+=t

If you want, you can set a mapping in your .vimrc to do the entire thing for you:

nnoremap <C-j> gggqG_j

This moves to the beginning of the file (gg), wraps all the lines (gq until G), and then _justifies the text.

4
  • For a closer look on formatting, see: VIM USER MANUAL - Editing formatted text
    – Suuuehgi
    Apr 3, 2015 at 19:38
  • I just found the very useful :set fo+=a option for automatic reformatting of the whole paragraph. Have a look at :help fo-table for other options. There also is a nice video tutorial here.
    – Suuuehgi
    Apr 4, 2015 at 8:26
  • +1 for a completely built-in solution. The _j mapping added by the macro seems to justify the entire file for me, or it can be limited with a linewise visual selection.
    – ches
    Apr 10, 2016 at 5:06
  • One minor drawback I found is that _j tries stretching every selected line, including the last line of a paragraph (which normally should not be stretched). I would love that it would observe the convention adopted by :set fo+=w and only stretch lines which end with a space.
    – Maëlan
    Nov 11, 2020 at 12:06
6

While nano's help call the ^J command "Justify" it actually doesn't justify the text, it reformat the text breaking the lines before the right margin of the screen (or at some configurable column, I guess).

You can do the same thing in VIM by setting the variable textwidth, from :help 'textwidth':

Maximum width of text that is being inserted. A longer line will be broken after white space to get this width. A zero value disables this.

That is to say: while you are typing, if a line is longer than textwidth characters, VIM will wrap the line at the first space to keep the line length less or equal to textwidth.

For this to work the option formatoptions must contain the letter t. See :help 'formatoptions' and :help fo-table for the available options, for example you may be interested in the c option to make formatting work with comments.

Edit: you can perform the same operation, without the need to put t in formatoptions, using the command gw{motion}, it formats the text between the current cursor position and the position of the cursor after {motion}. The gw command is available also in visual mode, it format the selected text.

1
  • 1
    That's good for typing. Can I apply that for pre-existing text?
    – SF.
    Feb 6, 2015 at 13:03
4

Here are two easy options:

  1. with a block of text selected, type !fmt
  2. with your cursor at the start of a block, type !}fmt

Both of these send a block of text to unix fmt, see man fmt for options. You can pass option arguments from vim. For example, to format a block a 50 characters wide, type !}fmt -w 50.

4
  • sorry about that, fixed now
    – Kaan
    Dec 6, 2015 at 2:23
  • You can also format your whole file by typing :%!fmt and undo with a single u if you don't like the result.
    – Wildcard
    Dec 21, 2015 at 22:26
  • For me this is the only solution that worked. The above built in and macro solutions mess things up with the indent, and par is no-go if you do not have root access. fmt is typically installed because it comes with coreutils, and worked as intended. Aug 19, 2021 at 11:10
  • Ah nevermind. For anyone reading, gq will also work as expected on a visual selection, as long as you :set autoindent and :set textwidth first. Aug 19, 2021 at 11:26
0

Mark the text using the visual command and then use:

:!par 40j 

where 40 is the column width and j means justify.

1
  • 3
    Welcome to our site! Your question is of low quality currently because it lacks explanations about the tool you are using (par) and why your solution works. You might want to add more details to improve the quality of your answer and make it more useful for future readers.
    – statox
    Mar 29, 2018 at 9:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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