Smart Wrap in Vim

27,267

Solution 1

This feature has been implemented on June 25, 2014 as patch 7.4.338. There followed a few patches refining the feature, last one being 7.4.354, so that's the version you'll want.

:help breakindent
:help breakindentopt

Excerpts from vim help below:

'breakindent'     'bri'   boolean (default off)
                          local to window
                          {not in Vi}
                          {not available when compiled without the |+linebreak|
                          feature}
        Every wrapped line will continue visually indented (same amount of
        space as the beginning of that line), thus preserving horizontal blocks
        of text.

'breakindentopt' 'briopt' string (default empty)
                          local to window
                          {not in Vi}
                          {not available when compiled without the |+linebreak|
                          feature}
        Settings for 'breakindent'. It can consist of the following optional
        items and must be seperated by a comma:
                  min:{n}     Minimum text width that will be kept after
                              applying 'breakindent', even if the resulting
                              text should normally be narrower. This prevents
                              text indented almost to the right window border
                              occupying lot of vertical space when broken.
                  shift:{n}   After applying 'breakindent', wrapped line
                              beginning will be shift by given number of
                              characters. It permits dynamic French paragraph
                              indentation (negative) or emphasizing the line
                              continuation (positive).
                  sbr         Display the 'showbreak' value before applying the 
                              additional indent.
        The default value for min is 20 and shift is 0.

Also relevant to this is the showbreak setting, this will suffix your shift amount with character(s) you specify.

Example configuration

" enable indentation
set breakindent

" ident by an additional 2 characters on wrapped lines, when line >= 40 characters, put 'showbreak' at start of line
set breakindentopt=shift:2,min:40,sbr

" append '>>' to indent
set showbreak=>>   

Note on behaviour

If you don't specify the sbr option, any showbreak any characters put appended to the indentation. Removing sbr from the above example causes an effective indent of 4 characters; with that setting, if you just want to use showbreak without additional indentation, specify shift:0.

You can also give a negative shift, which would have the effect of dragging showbreak characters, and wrapped text, back into any available indent space.

When specifying a min value, the shifted amount will be squashed if you terminal width is narrower, but showbreak characters are always preserved.

Solution 2

There is a patch for this, but it's been lingering for years and last time I checked did not apply cleanly. See the "Correctly indent wrapped lines" entry in http://groups.google.com/group/vim_dev/web/vim-patches -- I really wish this would get in the mainline.

Update: that link seems to have bitrotted. Here is a more up to date version of the patch.

Update 2: it has been merged upstream (as of 7.4.345), so now you only have to :set breakindent.

Solution 3

I don't think it's possible to have exactly the same indentation, but you can still get a better view by setting the 'showbreak' option.

:set showbreak=>>>

Example:

<p>
    <a href="http://www.example.com">
        This is a bogus link, used to demonstrate
>>>an example
    </a>
</p>

The real thing looks better than the example code above, because Vim uses a different colour for '>>>'.

Solution 4

UPDATE: In June 2014, a patch to support a breakindent option was merged into Vim (version 7.4.346 or later for best support).


You might also try :set nowrap which will allow vim to display long lines by scrolling to the right. This may be useful for examining the overall structure of a document, but can be less convenient for actually editing.

Other options close to what you're looking for are linebreak and showbreak. With showbreak, you can modify what is displayed at the left margin of lines that are wrapped, but unfortunately it doesn't allow a variable indent depending on the current context.

Solution 5

The only way I know of that you could do this would be to use a return character (as mentioned by Cfreak) and combine the textwidth option with the various indentation options. If your indent is configured correctly (as it is by default with the html syntax I believe, but otherwise see the autoindent and smartindent options), you can:

:set formatoptions = tcqw
:set textwidth = 50
gggqG

If you have any customisation of the formatoptions setting, it may be better to simply do:

:set fo += w
:set tw = 50
gggqG

What this does:

:set fo+=w  " Add the 'w' flag to the formatoptions so 
            " that reformatting is only done when lines
            " end in spaces or are too long (so your <p>
            " isn't moved onto the same line as your <a...).
:set tw=50  " Set the textwidth up to wrap at column 50
gg          " Go to the start of the file
gq{motion}  " Reformat the lines that {motion} moves over.
G           " Motion that goes to the end of the file.

Note that this is not the same as a soft wrap: it will wrap the lines in the source file as well as on the screen (unless you don't save it of course!). There are other settings that can be added to formatoptions that will auto-format as you type: details in :help fo-table.

For more information, see:

:help 'formatoptions'
:help fo-table
:help 'textwidth'
:help gq
:help gg
:help G
:help 'autoindent'
:help 'smartindent'
Share:
27,267
Sasha
Author by

Sasha

Updated on February 07, 2020

Comments

  • Sasha
    Sasha about 4 years

    I have been wondering if Vim has the capability to smart wrap lines of code, so that it keeps the same indentation as the line that it is indenting. I have noticed it on some other text editor, such as e-text editor, and found that it helped me to comprehend what I'm looking at easier.

    For example rather than

    <p>
        <a href="http://www.example.com">
            This is a bogus link, used to demonstrate
    an example
        </a>
    </p>
    

    it would appear as

    <p>
        <a href="somelink">
            This is a bogus link, used to demonstrate
            an example
        </a>
    </p>
    
  • Jeromy Anglim
    Jeromy Anglim about 13 years
    you can also use :set showbreak=\ \ \ \ \ \ \ \ \ \ \ \ \ \ (the backslash space combination makes the break character space. Thus, you could add enough spaces to be deeper than most of your wrapped code (e.g., 10 spaces would be deeper than 2 four space tabs and 14 would be deeper than 3 four space tabs); a nice feature of the space is that it is less visually distracting (if that's what you want).
  • ZyX
    ZyX about 13 years
    @Jeromy Anglim A minor fix: set showbreak=\ \ \ \ \ \ \ \ \ \ \ \ \ \ is much less readable then let &showbreak=repeat(' ', 14)
  • Jose Elera
    Jose Elera about 13 years
    I'd like that very much, I'll make html markup way more readable
  • puk
    puk about 12 years
    I don't see any patch on that site. Can anyone else confirm?
  • ergosys
    ergosys about 12 years
    Apparently the site was recently rebuilt and those links are broken. There is a recent blog entry with an even newer patch, on that same site.
  • cseelus
    cseelus about 10 years
    This is really missing. I don't get why this isn't in the mainline, esp. since the patch is very well written.
  • ergosys
    ergosys almost 10 years
    Thanks @Vitor Eiji for the update. This is awesome news.
  • james2doyle
    james2doyle over 7 years
    In short, adding set breakindent to your vim config will make the line break and wrap at the indent - instead of breaking and starting on the next line as if it was a new line.
  • fritzo
    fritzo almost 7 years
    And adding set breakindentopt=shift:4 to your vim config will indent an extra 4 spaces.
  • Mnebuerquo
    Mnebuerquo over 5 years
    This answer would be helped by adding more examples for breakindentopt. The syntax isn't obvious from the help doc. Thanks @fritzo for the example in your comment.