Heading image for post: Vim can have better tab characters for Golang


Vim can have better tab characters for Golang

Profile picture of Chris Erin

A short tutorial showing how to display beautiful tabs for a beautiful language: Golang.

Tabs characters can be distracting in vim

I have a problem. That problem is: Whenever I open a file in vim for a language that uses tabs rather than spaces to indent I see the > char followed by 8 spaces. And the > is blue. To me, this is ugly.

Ugly tab characters

I see this in both Php and Go. For PHP I don't care. For Golang however, I do. Go is a beautiful language and it deserves to look good in my editor. I want something clean looking that doesn't detract from the code but still conveys the sense of whitespace.

The characters

The first step is replacing the > character with something more pleasing to my eye, like a pipe (|). listchars is the option that governs what characters you see and my default setting (which you can check with :set listchars) is:

listchars=tab:> ,trail:-,extends:>,precedes:<,nbsp:+

The value we want for tab is instead \|\. We need to escape the pipe because that is a special command mode operator in vim. When editing listchars you can type :set listchars= and hit the tab key to place the current value into the command and then edit that current value. The final command I want to run is:

:set listchars=tab:\|\  ,trail:-,extends:>,precedes:<,nbsp:+

There are better characters, but they are non-ascii

The pipe doesn't fill the entire line height as I was hoping. There are longer pipes in unicode, but they are a bit trick to access.

Vim has a concept of digraphs to make it easier to remember special characters. A digraph is short two ascii character keys that map to a unicode character. Digraphs are easier to remember than unicode digital values. To see all the digraphs mapped in vim type: :digraphs or just :dig.

I've spotted a longer pipe () that has the digraph of vv and also a centered pipe that has the digraph of VV. To use a digraph type CTRL-K and the two character key (vv or VV) in this case. With that knowledge I can now edit the listchars with this command:

:set listchars=tab:\│\ ,trail:-,extends:>,precedes:<,nbsp:+

Note the longer pipe. A bit better, yes?

Tab width

As a matter of personal preference I prefer shorter tabs. In this case I'm going to shorten the tab width with :set tabstop=4 or set ts=4.


The character is still light blue. I would like a neutral gray and a dark grey background to differentiate the whitespace determined by the tab character from the space character.

Vim's highlighting system is fairly sophisticated, in this case I can change the colors of this particular syntactic element with:

:highlight SpecialKey ctermfg=grey ctermbg=black

Which I like, but I want something more precise. We're using the cterm{fg,bg} but values those values can represent 256 colors. Too limited.

There is a way to use rgb hex colors instead of the 256 colors, but I need macvim in iTerm2 rather than vim. I use to have vim symlink to macvim but when I upgraded to vim 8.0 I accidentally overwrote that symlink.

I am using macOS and brew so the commands I used to fix this were:

brew upgrade macvim --with-override-system-vim
brew link --overwrite macvim

Now I'm using macvim but how do I access a larger pallete of colors? By using the gui{fg,bg} values rather than the cterm{fg,bg} values. Let me try to set some ridiculous colors just to see if that works.

:highlight SpecialKey guifg=red guibg=purple

No, still grey. What I am missing is an option introduced in 7.4 that allows a vim instance running in a terminal to have access to the enabled gui{fg,bg} values. This option is:

:set termguicolors

I now see the ridiculous colors shining through. Let me try the more neutral greys that I would rather have.

:highlight SpecialKey guifg=#333333 guibg=#111111

Better looking tab characters

Go now has the tab character display that I like. I hope you can use these tips to customize tab characters to your own preference.

More posts about Vim