Word Wrap in Vim (preserving indentation)

VimWord Wrap

Vim Problem Overview


I was just looking at https://stackoverflow.com/questions/744159/word-wrap-in-gvim">this post which describes how to wrap entire words in vim. The accepted solution was this:

:set formatoptions=l
:set lbr

Which takes this text (tabs are shown as \t):

 *Inside of window                        *Outside of window
|---------------------------------------|    
|\t\tthis is a like of text that will wr|ap here                            
|\t\tcan you see the wrap               |
|                                       |
|---------------------------------------|

This accomplishes a behavior like this (tabs are shown as \t):

 *Inside of window                        *Outside of window
|---------------------------------------|    
|\t\tthis is a like of text that will   |
|wrap here                              |
|\t\tcan you see the wrap               |
|                                       |
|---------------------------------------|

I would however like to redefine this function. I would like the wrapped line to have the same number of tabs in front of it that the line above has plus one. Ie:

 *Inside of window                        *Outside of window
|---------------------------------------|    
|\t\tthis is a like of text that will   |
|\t\t\twrap here                        |
|\t\tcan you see the wrap               |
|                                       |
|---------------------------------------|

Any ideas?

Vim Solutions


Solution 1 - Vim

This did not work when the question was originally asked, but as of June 25, 2014, this will work. (Assuming you update your vim to a version newer than that date)

Add to your .vimrc:

" Indents word-wrapped lines as much as the 'parent' line
set breakindent
" Ensures word-wrap does not split words
set formatoptions=l
set lbr

And that's it!

--

Some people (myself included) share a single .vimrc across multiple computers. In that case, it's important to have this line be robust (to avoid annoying error messages). This is a little better:

if has("patch-7.4.354")
	" Indents word-wrapped lines as much as the 'parent' line
    set breakindent
    " Ensures word-wrap does not split words
    set formatoptions=l
    set lbr
endif

This way, if you're on an earlier version of vim, you don't get an error message.

Solution 2 - Vim

The breakindent patch has what you're looking for. I successfully applied it using instructions found in this thread:

https://stackoverflow.com/questions/11323095/patch-vim-on-mac-with-homebrew

Specifically, echristopherson's Homebrew formula.

I know this thread is old but it's popular on google and I came across it multiple times when trying to find a solution.

EDIT: This patch is now included with vim as patch 7.4.338. See: https://retracile.net/blog/2014/07/18/18.00

On Yosemite (Mac OS X), I used snowbound's command with hombrew:

brew install macvim --with-features=huge --override-system-vim --HEAD 

Solution 3 - Vim

The best you're going to get is the showbreak option which will put a fixed string in front of each wrapped line (I use set showbreak=...).

Solution 4 - Vim

I agree with the answer that says 'showbreak' is the best option. Showbreak does not typically allow you to put nonprinting characters (e.g., spaces or tabs) into the showbreak string, so as typically used it will just give you an indicator along left margin, i.e., no real indent. This isn't great, since main goal of OP, I think, is to give wrapped lines an indent keep them from cluttering left margin area and looking like lines of their own.

So one way to add an (ugly) indent using showbreak is to just use a lot of characters, .e.g, ":set showbreak=>--------------->". This results in something that looks like this:

 *Inside of window                        *Outside of window
|---------------------------------------|    
|\t\tthis is a like of text that will   |
|>--------------->wrap here             |
|\t\tcan you see the wrap               |
|                                       |
|---------------------------------------|

A better alternative might be to make use of nonbreaking space characters (assuming your instance of Vim is unicode enabled), each of which can be entered into the showbreak string using the key sequence of ctrl-v,160. That way you can enter a showbreak string that is blank at the left side and appear to be a true indent. E.g., ":set showbreak=. . . . . . . . . . >>" where each '.' in the command is actually a nonbreaking space character entered by pressing ctrl-V,160. That way you end up with a wrap that is nicely indented, like this:

 *Inside of window                        *Outside of window
|---------------------------------------|    
|\t\tthis is a like of text that will   |
|            >>wrap here                |
|\t\tcan you see the wrap               |
|                                       |
|---------------------------------------|

You still don't have any ability to vary the level of indent according to indent of previous line, but at least you get clean indent of wrapped lines without lots of visual clutter along left margin of window. There could still be confusion if indent of a wrapped line is less than that of the beginning of an actual line, but this could perhaps be avoided by making the showbreak "indent" quite large (i.e., greater than any indent commonly found in your code) but still small enough that it provides enough space for legible wrapping of the text. For many uses I think a showbreak indent of 40 or 50 spaces would do this pretty well.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionsixtyfootersdudeView Question on Stackoverflow
Solution 1 - VimJoshuaDView Answer on Stackoverflow
Solution 2 - VimExit42View Answer on Stackoverflow
Solution 3 - Vimtoo much phpView Answer on Stackoverflow
Solution 4 - VimHerbert SitzView Answer on Stackoverflow