35

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?

34

You can use the gq or gw operators combined with a motion command. By default, it uses the fmt program (in Linux) to format the given text. However, to the best of my knowledge, it does not justify the lines so you will get ragged right margins.

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).

  • 1
    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 '15 at 13:04
  • 3
    By default, Vim doesn't use any external program, although you can choose to use one by setting the 'formatprg' option. – jamessan Feb 6 '15 at 14:16
14

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 */
11

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.

  • For a closer look on formatting, see: VIM USER MANUAL - Editing formatted text – Suuuehgi Apr 3 '15 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 '15 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 '16 at 5:06
5

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
    That's good for typing. Can I apply that for pre-existing text? – SF. Feb 6 '15 at 13:03
3

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.

  • sorry about that, fixed now – kaan Dec 6 '15 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 '15 at 22:26
-1

Mark the text using the visual command and then use:

:!par 40j 

where 40 is the column width and j means justify.

  • 2
    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 '18 at 9:57

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.