146

When I work on files in python, I sometimes mistake tabs for spaces and vice versa. Is there a way I can get Vim to display a character for a tab instead of a tab?

  • Just as a side note, you can configure to convert all tabs to spaces with retab every time you save the file. – 0xc0de Mar 15 '19 at 10:12
  • If you have installed vim-faq, you can get an offline answer there: :h vim-faq and search /invisible. The hard to memorize tag is :h faq-19.8. – Hotschke Jul 23 '19 at 7:50
144

Yes, use listchars:

set list
set listchars=tab:>-

If you put these two lines in your .vimrc, tabs will be shown as > for the start position and - through the rest of the tab.

(Sidenote: listchars can also show trailing spaces with trail:x (replace x with the character you want to use for a trailing space), which can be useful as well.)

| improve this answer | |
  • 8
    Note: I like to use set listchars=tab:!·,trail:·, IMHO · is a lot clearer than a - ... You need a fairly recent Vim version for this to work btw (not sure which exactly, I think 7.3.x)... – Martin Tournoij Feb 5 '15 at 15:07
  • 9
    I like using the unicode character as it is slightly smaller than >. Currently I see trailing white space by marking the eol (though I may try the above). My settings are: set listchars=eol:¬,tab:▸\ and – Martin York Feb 6 '15 at 21:43
  • This one works the best for me set listchars=eol:·,tab:⍿·,trail:×· as it is very clean. – 71GA Dec 30 '19 at 4:20
  • Here's what I'm currently using: set listchars=tab:┌┬┐,trail:·. (The non-ASCII characters are: 250c:BOX DRAWINGS LIGHT DOWN AND RIGHT, 252c:BOX DRAWINGS LIGHT DOWN AND HORIZONTAL, 2510:BOX DRAWINGS LIGHT DOWN AND LEFT, b7:MIDDLE DOT.) – Keith Thompson Jun 25 at 0:24
63

The basic answer is :set list, which causes tabs to display as ^I.

However, I recommend going beyond that. Just :set list is problematic in that it fails to preserve visual alignment on screen. For example:

%.o: %.cpp
^Ig++ -c $<

doesn't look good, especially when you expect the g of g++ to appear under the first p of cpp (assuming tabstop=8).

Therefore, I suggest that in your .vimrc you put something like :set listchars=tab:␉· (To be clear, that's Unicode character U+2409 SYMBOL FOR HORIZONTAL TABULATION followed by U+00B7 MIDDLE DOT.)

As explained in :help listchars, a two-character setting for tab:xy causes visual alignment to be preserved:

tab:xy        Two characters to be used to show a tab.  The first
              char is used once.  The second char is repeated to
              fill the space that the tab normally occupies.
              "tab:>-" will show a tab that takes four spaces as
              ">---".  When omitted, a tab is show as ^I.

The example above would appear on screen as:

%.o: %.cpp
␉·······g++ -c $<

Personally, I go all-out with my listchars:

:set listchars=eol:⏎,tab:␉·,trail:␠,nbsp:⎵

These characters are distinctive enough that they rarely appear literally in document text.

To type these special characters into your vimrc, type Ctrl-vu23CE while in Insert Mode, as explained in :help utf-8-typing.

| improve this answer | |
  • 3
    See also set lcs=tab:├─ – sch Feb 5 '15 at 15:33
  • this just gave me a ? at eol – WendyG Oct 7 '19 at 12:45
22

Highlighting tabs

Temporary Tab highlighting

For occasional use, one can simply highlight all tabs in a document using the following search / command:

/\t

To remove the highlighting, simply type :noh which is short for :nohlsearch —no high lighting.

Permanent Tab highlighting

" Highlight tabs as errors.
" https://vi.stackexchange.com/a/9353/3168
match Error /\t/

Tab highlighting in vim

More highlighting

For more of these useful highlighting commands —including combined with trailing whitespace and making this permanent— see the Vim wiki.

| improve this answer | |
  • 4
    You can also use :match Error /\t/ to highlight tabs (or any other pattern for that matter) independently from the search register and hlsearch (type :match to clear it). – Martin Tournoij Aug 25 '16 at 22:56
  • 1
    @Carpetsmoker One can find a whole lot more of these useful highlighting commands (including combined with trailing whitespace!) on the Vim wiki about highlighting unwanted spaces. – Serge Stroobandt Aug 26 '16 at 19:05
10

I personally like the use of the plugin indentLine, which displays a vertical line at indentation levels.

It is of great help especially in python, where the indentation is important.

(Image taken from the link above)

Among other things, it provides a toggle command, that can be mapped to a key combination, so that you can turn it off, when you don't need it.

| improve this answer | |
  • 4
    I believe this plugin is intended for spaces indenting though? – Jake Byman Dec 11 '17 at 18:02
  • Indeed: > This plugin is used for displaying thin vertical lines at each indentation level for code indented with spaces. For code indented with tabs I think there is no need to support it, because you can use :set list lcs=tab:\|\ (here is a space). – thiagowfx Jul 6 at 3:22
  • indent guide supports tabs as well: github.com/nathanaelkane/vim-indent-guides – aderchox Jul 28 at 5:13
5

Easiest method is to do :set list, which will show tabs as ^I and end of line as $.

I like to use a mapping that calls

:set invlist 

to toggle between regular display and list display.

For example:

:nmap <leader>l :set invlist<cr>

This allows me to quickly check if there are tab vs space problems and then go back to a regular display.

| improve this answer | |
5

You may want to show tabs differently in a regular terminal and gvim.

set list!
if has('gui_running')
    set listchars=tab:▶\ ,trail:·,extends:\#,nbsp:.
else
    set listchars=tab:>.,trail:.,extends:\#,nbsp:.
endif

(Adding for completeness, in case others find it useful).

| improve this answer | |
2

I combined @john-om approach with this character Unicode Character 'ZERO WIDTH SPACE' (U+200B) and indentLine plugin. So, if I use spaces, plugin show nice formated indents, if I use tabs, pipes are the only visible mark and that is what I want. I can also toggle tab's marks.

" indicate tabs
:nmap <leader>l :set invlist<cr>
set list listchars=tab:❘⠀,trail:·,extends:»,precedes:«,nbsp:×
| improve this answer | |
1

This can be easily achieved using listchars by specifying the tab as: ,tab:\ \ ┊,

By providing two escaped spaces in front of your tab declaration, vim will repeat the spaces. This is opposed to the default, where vim prefers the second character as the repeating character.

This achieves a similar effect to using a plugin like IndentLine without the overhead. Here's an example of what it might look like using the following complete listchars config:

set listchars=eol:↓,tab:\ \ ┊,trail:●,extends:…,precedes:…,space:·

source code

| improve this answer | |
  • 2
    Welcome to Vi and Vim! Do note that the top 2 answers (and a few of the others as well) already mention this solution. – D. Ben Knoble Jul 14 at 12:52
  • 1
    @D.BenKnoble Thank you for the friendly welcome and feedback! However, I disagree. This is an alternative to @mike's response. While the other responses do reference listchars, none of them explain how to achieve repeating the left character to achieve the same result as a plugin like IndentLine. – Swivel Jul 17 at 6:47
  • 1
    @D.BenKnoble I've reworded my answer to hopefully clarify how my answer differs from the others mentioned. – Swivel Jul 17 at 6:54

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.