[vim] Vim 80 column layout concerns

The way I do 80-column indication in Vim seems incorrect:set columns=80. At times I also set textwidth, but I want to be able to see and anticipate line overflow with the set columns alternative.

This has some unfortunate side effects:

  1. I can't set number for fear of splitting between files that have different orders of line numbers; i.e. < 100 line files and >= 100 line files will require two different set columns values because of the extra column used for the additional digit display.
  2. I also start new (g)Vim sessions instead of splitting windows vertically. This is because vsplit forces me to set columns every time I open or close a pane, so starting a new session is less hassle.

How do you handle the 80-character indication when you want to set numbers, vertically split, etc.?

This question is related to vim coding-style

The answer is


You also can draw line to see 80 limit:

let &colorcolumn=join(range(81,999),",")
let &colorcolumn="80,".join(range(400,999),",")

Result:

enter image description here


Shorter way:

match ErrorMsg '\%>80v.\+'

Simon Howard's answer is great. But /\%81v.\+/ fails to highlight tabs that exceed column 81 . So I did a little tweak, based on the stuff I found on VIM wiki and HS's choice of colors above:

highlight OverLength ctermbg=darkred ctermfg=white guibg=#FFD9D9
match OverLength /\%>80v.\+/

And now VIM will highlight anything that exceeds column 80.


You can try this:

au BufWinEnter * if &textwidth > 8
\ | let w:m1=matchadd('MatchParen', printf('\%%<%dv.\%%>%dv', &textwidth+1, &textwidth-8), -1)
\ | let w:m2=matchadd('ErrorMsg', printf('\%%>%dv.\+', &textwidth), -1)
\ | endif

That will set up two highlights in every buffer, one for characters in the 8 columns prior to whatever your &textwidth is set to, and one for characters beyond that column. That way you have some extent of anticipation. Of course you can tweak it to use a different width if you want more or less anticipation (which you pay for in the form of loss of syntax highlighting in those columns).


Well, looking at the :help columns, it's not really being made to mess with.

In console, it's usually determined by console setting (i.e. it's detected automatically) ; in GUI, it determines (and is determined by) the width of the gvim windows.

So normally you just let consoles and window managers doing their jobs by commented out the set columns

I am not sure what you mean by "see and anticipate line overflow". If you want EOL to be inserted roughly column 80, use either set textwidth or set wrapmargin; if you just want soft wrap (i.e. line is wrapped, but no actual EOL), then play with set linebreak and set showbreak.


I'm afraid that you've put constraints on the set of solutions that, well, leave you with the null set.

Using :set textwidth=80 will fix all of the problems you mentioned except that you can't easily see the line limit coming up. If you :set ruler, you'll enable the x,y position display on the status bar, which you can use to see which column you're in.

Aside from that, I'm not sure what to tell you. It's a shame to lose the number column, fold column and splits just because you have to :set columns=80.


A nice way of marking just the first character going out of the specified bounds:

highlight ColorColumn ctermbg=magenta "set to whatever you like
call matchadd('ColorColumn', '\%81v', 100) "set column nr

From Damian Conway's talk.


A nice way of marking just the first character going out of the specified bounds:

highlight ColorColumn ctermbg=magenta "set to whatever you like
call matchadd('ColorColumn', '\%81v', 100) "set column nr

From Damian Conway's talk.


I'm afraid that you've put constraints on the set of solutions that, well, leave you with the null set.

Using :set textwidth=80 will fix all of the problems you mentioned except that you can't easily see the line limit coming up. If you :set ruler, you'll enable the x,y position display on the status bar, which you can use to see which column you're in.

Aside from that, I'm not sure what to tell you. It's a shame to lose the number column, fold column and splits just because you have to :set columns=80.


Newer versions of vim allow a :set numberwidth=x value, which sets the width of the line number display. I don't really use folding etc, so I wouldn't know about that though. Drawing a thin vertical line is beyond the abilities of a console application though. GVim may allow this (I don't use it, so can't comment there).


You can try this:

au BufWinEnter * if &textwidth > 8
\ | let w:m1=matchadd('MatchParen', printf('\%%<%dv.\%%>%dv', &textwidth+1, &textwidth-8), -1)
\ | let w:m2=matchadd('ErrorMsg', printf('\%%>%dv.\+', &textwidth), -1)
\ | endif

That will set up two highlights in every buffer, one for characters in the 8 columns prior to whatever your &textwidth is set to, and one for characters beyond that column. That way you have some extent of anticipation. Of course you can tweak it to use a different width if you want more or less anticipation (which you pay for in the form of loss of syntax highlighting in those columns).


As of vim 7.3, you can use set colorcolumn=80 (set cc=80 for short).

Since earlier versions do not support this, my .vimrc uses instead:

if exists('+colorcolumn')
  set colorcolumn=80
else
  au BufWinEnter * let w:m2=matchadd('ErrorMsg', '\%>80v.\+', -1)
endif

See also the online documentation on the colorcolumn option.


enter image description here

Minimalistic, not-over-the-top approach. Only the 79th character of lines that are too long gets highlighted. It overcomes a few common problems: works on new windows, overflowing words are highlighted properly.

augroup collumnLimit
  autocmd!
  autocmd BufEnter,WinEnter,FileType scala,java
        \ highlight CollumnLimit ctermbg=DarkGrey guibg=DarkGrey
  let collumnLimit = 79 " feel free to customize
  let pattern =
        \ '\%<' . (collumnLimit+1) . 'v.\%>' . collumnLimit . 'v'
  autocmd BufEnter,WinEnter,FileType scala,java
        \ let w:m1=matchadd('CollumnLimit', pattern, -1)
augroup END

Note: notice the FileType scala,java this limits this to Scala and Java source files. You'll probably want to customize this. If you were to omit it, it would work on all file types.


You can try this:

au BufWinEnter * if &textwidth > 8
\ | let w:m1=matchadd('MatchParen', printf('\%%<%dv.\%%>%dv', &textwidth+1, &textwidth-8), -1)
\ | let w:m2=matchadd('ErrorMsg', printf('\%%>%dv.\+', &textwidth), -1)
\ | endif

That will set up two highlights in every buffer, one for characters in the 8 columns prior to whatever your &textwidth is set to, and one for characters beyond that column. That way you have some extent of anticipation. Of course you can tweak it to use a different width if you want more or less anticipation (which you pay for in the form of loss of syntax highlighting in those columns).


Newer versions of vim allow a :set numberwidth=x value, which sets the width of the line number display. I don't really use folding etc, so I wouldn't know about that though. Drawing a thin vertical line is beyond the abilities of a console application though. GVim may allow this (I don't use it, so can't comment there).


You can try this to set the window size to allow 80 characters of actual text. This still doesn't work with vertical splits though.

let &co=80 + &foldcolumn + (&number || &relativenumber ? &numberwidth : 0)

This requires vim 7+, 7.3 for relativenumber.


I prefer:

highlight ColorColumn ctermbg=gray
set colorcolumn=80

I'm afraid that you've put constraints on the set of solutions that, well, leave you with the null set.

Using :set textwidth=80 will fix all of the problems you mentioned except that you can't easily see the line limit coming up. If you :set ruler, you'll enable the x,y position display on the status bar, which you can use to see which column you're in.

Aside from that, I'm not sure what to tell you. It's a shame to lose the number column, fold column and splits just because you have to :set columns=80.


Newer versions of vim allow a :set numberwidth=x value, which sets the width of the line number display. I don't really use folding etc, so I wouldn't know about that though. Drawing a thin vertical line is beyond the abilities of a console application though. GVim may allow this (I don't use it, so can't comment there).


You can try this:

au BufWinEnter * if &textwidth > 8
\ | let w:m1=matchadd('MatchParen', printf('\%%<%dv.\%%>%dv', &textwidth+1, &textwidth-8), -1)
\ | let w:m2=matchadd('ErrorMsg', printf('\%%>%dv.\+', &textwidth), -1)
\ | endif

That will set up two highlights in every buffer, one for characters in the 8 columns prior to whatever your &textwidth is set to, and one for characters beyond that column. That way you have some extent of anticipation. Of course you can tweak it to use a different width if you want more or less anticipation (which you pay for in the form of loss of syntax highlighting in those columns).


You can try this to set the window size to allow 80 characters of actual text. This still doesn't work with vertical splits though.

let &co=80 + &foldcolumn + (&number || &relativenumber ? &numberwidth : 0)

This requires vim 7+, 7.3 for relativenumber.


Newer versions of vim allow a :set numberwidth=x value, which sets the width of the line number display. I don't really use folding etc, so I wouldn't know about that though. Drawing a thin vertical line is beyond the abilities of a console application though. GVim may allow this (I don't use it, so can't comment there).


Well, looking at the :help columns, it's not really being made to mess with.

In console, it's usually determined by console setting (i.e. it's detected automatically) ; in GUI, it determines (and is determined by) the width of the gvim windows.

So normally you just let consoles and window managers doing their jobs by commented out the set columns

I am not sure what you mean by "see and anticipate line overflow". If you want EOL to be inserted roughly column 80, use either set textwidth or set wrapmargin; if you just want soft wrap (i.e. line is wrapped, but no actual EOL), then play with set linebreak and set showbreak.


Simon Howard's answer is great. But /\%81v.\+/ fails to highlight tabs that exceed column 81 . So I did a little tweak, based on the stuff I found on VIM wiki and HS's choice of colors above:

highlight OverLength ctermbg=darkred ctermfg=white guibg=#FFD9D9
match OverLength /\%>80v.\+/

And now VIM will highlight anything that exceeds column 80.


I prefer:

highlight ColorColumn ctermbg=gray
set colorcolumn=80

As of vim 7.3, you can use set colorcolumn=80 (set cc=80 for short).

Since earlier versions do not support this, my .vimrc uses instead:

if exists('+colorcolumn')
  set colorcolumn=80
else
  au BufWinEnter * let w:m2=matchadd('ErrorMsg', '\%>80v.\+', -1)
endif

See also the online documentation on the colorcolumn option.


this one is out of left field but its a nice little map for resizing your current split to 80 characters if you've got the line numbers on:

" make window 80 + some for numbers wide  
noremap <Leader>w :let @w=float2nr(log10(line("$")))+82\|:vertical resize <c-r>w<cr> 

Shorter way:

match ErrorMsg '\%>80v.\+'

You also can draw line to see 80 limit:

let &colorcolumn=join(range(81,999),",")
let &colorcolumn="80,".join(range(400,999),",")

Result:

enter image description here


enter image description here

Minimalistic, not-over-the-top approach. Only the 79th character of lines that are too long gets highlighted. It overcomes a few common problems: works on new windows, overflowing words are highlighted properly.

augroup collumnLimit
  autocmd!
  autocmd BufEnter,WinEnter,FileType scala,java
        \ highlight CollumnLimit ctermbg=DarkGrey guibg=DarkGrey
  let collumnLimit = 79 " feel free to customize
  let pattern =
        \ '\%<' . (collumnLimit+1) . 'v.\%>' . collumnLimit . 'v'
  autocmd BufEnter,WinEnter,FileType scala,java
        \ let w:m1=matchadd('CollumnLimit', pattern, -1)
augroup END

Note: notice the FileType scala,java this limits this to Scala and Java source files. You'll probably want to customize this. If you were to omit it, it would work on all file types.


this one is out of left field but its a nice little map for resizing your current split to 80 characters if you've got the line numbers on:

" make window 80 + some for numbers wide  
noremap <Leader>w :let @w=float2nr(log10(line("$")))+82\|:vertical resize <c-r>w<cr>