Make Vim show ALL white spaces as a character
Asked Answered
U

23

899

I can't find a way to make Vim show all white spaces as a character. All I found was about tabs, trailing spaces etc.

Ulcerate answered 4/11, 2009 at 18:17 Comment(4)
I’m also trying to solve exactly this problem. Please, if you come across this, refrain from making yet another response involving :set list. That doesn’t answer our question. (To other comers: mrucci’s response below is helpful, though not quite a real solution.)Shortage
For all of those who say that spaces are visible with list and listchars consider that a space is directly following a tab. It would be nearly invisible in this situation. I agree that you can catch most situations but if would be nice to have proper highlighting of all spaces.Unwise
For new visitors: This is solved in newer versions of vim! See brettanomyces's answer below.Shortage
Related (but difference stack): vi.stackexchange.com/questions/422/…Hoes
L
777

As others have said, you could use

:set list

which will, in combination with

:set listchars=...

display invisible characters.
Now, there isn't an explicit option which you can use to show whitespace, but in listchars, you could set a character to show for everything BUT whitespace. For example, mine looks like this

:set listchars=eol:$,tab:>-,trail:~,extends:>,precedes:<

so, now, after you use

:set list

everything that isn't explicitly shown as something else, is then, really, a plain old whitespace.

As usual, to understand how listchars works, use the help. It provides great information about what chars can be displayed (like trailing space, for instance) and how to do it:

:help listchars

It might be helpful to add a toggle to it so you can see the changes mid editing easily (source: VIM :set list! as a toggle in .vimrc):

noremap <F5> :set list!<CR>
inoremap <F5> <C-o>:set list!<CR>
cnoremap <F5> <C-c>:set list!<CR>
Libenson answered 4/11, 2009 at 18:30 Comment(6)
“everything that isn't explicitly shown as something else”? Try out unicode spaces from range U+2000..U+200A. If fixed-width font supports them they will be shown just as normal 0x20 space.Congenital
@Congenital - I was't taking the whole of Unicode, but the rather common set of characters in use. If you're unsatisfied with the answer, feel free to suggest improvements.Libenson
Great tip! I recommend to put the set listchars line to the .vimrc file, so this pretty way of displaying invisible characters can be easily enabled with :set list in any time (without googling this page again).Gilles
@ckarbass Same way you toggle anything in vim - adding a ! to the end. So it becomes :set list!Lama
Let's look again at the ALL-part. I'm searching for visualization of all spaces while everything mentioned here only works for tabs and trailing spaces. Anyone have any suggestions for showing ALL spaces?Operator
I used middle dot · for white spaces and my VIM now looks awesome! Thanks for the tip~Bakker
E
386

As of patch 7.4.710 you can now set a character to show in place of space using listchars!

:set listchars+=space:␣

So, to show ALL white space characters as a character you can do the following:

:set listchars=eol:¬,tab:>·,trail:~,extends:>,precedes:<,space:␣
:set list

When you are finished, to hide the non-visible chars you would:

:set nolist

Discussion on mailing list: https://groups.google.com/forum/?fromgroups#!topic/vim_dev/pjmW6wOZW_Q

Empyrean answered 22/4, 2015 at 3:46 Comment(12)
This is pretty cool, but I'm wondering why the eol character doesn't get colourised differently, unlike the others.Alarm
I tried this and got an error at first. It turned out that "space" was not a valid option in the slightly older version of gvim I was using. Upgrading my gvim solved my problem. For others that are getting an error, type :help listchars to check whether "space" is a valid option for "listchars". If it is not, upgrade your vim to the patch @brettanomyces specified. Or just leave "space" out of the set command if you don't care to see spaces.Parasynapsis
Works great. My only wish you could set the color to be a bit lighter so the space characters are less distracting.Drawee
I use Unicode's Middle Dot (U+00B7) for space character (space:·), as it looks like MS Word, Notepad++, etc.Ehrman
I keep getting errors with the character chosen here for space; E474: Invalid argument: listchars+=space:�~P�. Looks like something about this character is not working properly when I either write it directly to my .vimrc from my local desktop, or copy/paste it into the terminal as a command within vim. I am using vim 7.4Lubumbashi
@Lubumbashi try <ctrl-v>u2334 to enter the unicode open box character (␣). See sanctum.geek.nz/arabesque/special-characters-in-vim for more detailsEmpyrean
Thanks, looks like I was actually still out of date, on version 7.4.629 (had to start vim with no file and type :version to find out). A combination of installing my own user local vim and adding these items to my .vimrc has fixed it.Lubumbashi
Type <C-K>.M in vim for ·. See :h digraph for details.Calamanco
maybe someone likes my choice of symbols: set listchars=tab:⇤–⇥,space:·,trail:·,precedes:⇠,extends:⇢,nbsp:×Ovation
And if using emacs, all you would do was M-x whitespace-mode. Man, I sometimes miss emacs.Raddy
I like this answer, except I also swapped it out with the dot character for spaces. A little easier to read. :set listchars=eol:¬,tab:>·,trail:~,extends:>,precedes:<,space:⋅Insignificant
It's too bad that RHEL7 runs an older version.Tellurite
P
278

:set list to enable.

:set nolist to disable.

Pediment answered 4/11, 2009 at 19:43 Comment(5)
Thank you for showing us how to toggle between modes. You'd think other advanced answers would teach that.Mehalek
yes this is helpful. I wish it was the top answer as I found this answer myself only to find that it was already on the site, just out of view.Moussaka
: set list! is better :)Obel
@Skippr By what measure? It's same number of key presses, except that Shift and ! are both harder to type than no. If you're putting it in your .vimrc, I agree that the exclam form is easier to read.Frederico
@Dan If you are looking to toggle this off and on in a relatively short time, :set list! will do so without you ever needing to enter nolist. The ! simply does the opposite of whatever is currently set. I use this all the time especially when with :set paste!. I hate pressing the arrow key to find :set paste or :set nopaste lolObel
B
220

I think other answers here are more comprehensive, but I thought I'd share a trick I usually use to differentiate tabs and spaces visually:

:syntax on
:set syntax=whitespace

These are syntax highlighting rules for the Whitespace programming language - tabs show in green and spaces in red. :)

Can be combined with :set list as mentioned by many other answers, although the tabs will then show as ^I without a green higlight, but the spaces will show in red.

Beffrey answered 25/9, 2013 at 18:27 Comment(8)
I like this one, it is quite clever, and feels somehow better than most of the other answers. Not really a solution that's usable all the time, though.Cumbrous
I prefer more conventional methods, but I'm +1'ing this for inventiveness.Chara
I knew that language would be useful for something.Frederico
Do you mind linking to the .vim syntax file you're using to highlightCharmian
@SeldomNeedy you shouldn't need to download anything, the whitespace highlighting rules have been shipping with Vim for years. They should essentially be built-in unless you're using a weird or really old version of Vim.Beffrey
I really like this answer. Been looking for something exactly like this for a while.Colorist
To be able to return to the original syntax setting: :syntax on, then :setlocal syntax? (take a note of the result, e. g. "syntax=go"), :set syntax=whitespace, then (when done looking at whitespace;) :set syntax=goTurnstile
mysys - does not include the built in rules atleast my experienceRenoir
Z
105

:set list will show all whitespaces as a character. Everything but a space will look different than its normal state, which means that if you still see a plain old space, it's really a plain old space. :)

Zanazander answered 4/11, 2009 at 18:20 Comment(5)
Turn this back off with :set nolistGambado
What if you want to see the space character, like in Sublime Text 2 with "show whitespace" on? I found it really helpful.Attaway
Not what I came here for but very helpful. Thanks.Coelostat
Also options with no could be toggled with ! at the end: set list!Electropositive
I was looking to set the space character which it seems you do with space:• when setting listchars. Mine looks like this: --- set showbreak=↪\ set listchars=tab:→\ ,eol:↲,nbsp:␣,trail:•,extends:⟩,precedes:⟨,space:•Producer
Q
75

If you set:

:highlight Search cterm=underline gui=underline ctermbg=none guibg=none ctermfg=none guifg=none

and then perform a search for a space, every space character will be shown as an underline character.

You can use this command in a handy function that toggles "underscoring" of spaces.

set hls
let g:HLSpace = 1
let g:HLColorScheme = g:colors_name
function ToggleSpaceUnderscoring()
    if g:HLSpace
        highlight Search cterm=underline gui=underline ctermbg=none guibg=none ctermfg=none guifg=none
        let @/ = " "
    else
        highlight clear
        silent colorscheme "".g:HLColorScheme
        let @/ = ""
    endif
    let g:HLSpace = !g:HLSpace
endfunction

Map the function to a shortcut key with:

nmap <silent> <F3> <Esc>:call ToggleSpaceUnderscoring()<CR>

NB: Define the function in vimrc after the colorscheme has been set.

Quechuan answered 4/11, 2009 at 18:33 Comment(1)
Well, it’s a bit of a hack, but it’s closer than anything else so far. Bounty awarded! :DShortage
L
48

Depending on your syntax rules for the current buffer, something like this could work:

:syn match WhiteSpace / / containedin=ALL conceal cchar=Æ
:setl conceallevel=2 concealcursor=nv

This needs a vim 7.3 with +conceal feature

Update 10/24/2014 To expand a little bit on that. It is of course possible to define some highlighting for the conealed characters.

  • You can configure, how the concealed chars look. For highlighting, you would have to at least once configure the 'Conceal' highlighting group (See the help at :h hl-Conceal This can be done in your colorscheme and then you do not need to reconfigure it again. But this affects all concealed chars (e.g. if your syntax script conceals some more items, they will be displayed as your white space chars). That could look like this:

    :hi Conceal ctermfg=7 ctermbg=NONE guifg=LightGrey guibg=NONE

  • There seems to be a particularity that Vim will not highlight spaces, if the syntax script uses the skipwhite keyword. There will be no way around (perhaps this will be fixed, I posted a patch)

  • There seems to be a patch floating around, that will allow to customize how spaces will look in list mode. The latest one at the time of writing seems to be this one. (This means, you need to built your own Vim to use this).
  • The conceallevel and concealcursor are window local options. That means they can be different in different windows (and will possibly be also set by filetype plugins or other plugin scripts).
  • The syntax highlighting groups need to be executed whenever a syntax definition file is reloaded. This could be done using a BufWinEnteror possibly also a Syntax or even FileType autocommand. (I have not tested which one actually works).

The last two items means, you would have to setup some autocommands that reset the syntax rules and the correesponding options. For the first one, one might want to setup the highlighting using a ColorScheme autocommand (so that the concealed chars always look the same, independent of what a color scheme actually sets up). For a complete solution, look into romainl answer, that should give you a start. If you setup a function, you can easily setup a toggle command to switch displaying special Highlighting on or off.

Update 10/26/2014 I made a plugin out of this question.

Update 04/22/2015 A patch has been included in Vim that makes this possible using the list option. Simply set set list listchars+=space:␣ This works as of Vim 7.4.711

Liquidation answered 8/6, 2011 at 13:18 Comment(5)
This works great! How can this be added to .vimrc?Hedve
Since this works on the current buffer, you probably need to wrap this into an autocommand. BufEnter or even Syntax autocommand might work for you:Liquidation
Æ is a strange choice of character for this, why not ·?Grimy
This is actually the correct answer. Any ideas on how to add proper syntax highlighting to this character? I would prefer it if it were a very faded ·Hundredweight
@ChristianBrabandt, you have a bunch of trailing nrrwrgn-related files polluting your repo.Penetrate
L
31

I use this

/\s
:set hlsearch

to highlight white spaces. It searches for all white spaces, and then enables the highlight to make them pop out. However, it does not print a special character.

Lao answered 26/11, 2011 at 17:18 Comment(1)
Simplest solution imho. Great paired with a command to clear search (I use nnoremap <leader><space> :noh<cr>)Quanta
E
25

If by whitespaces you mean the ' ' character, my suggestion would just be a search/replace. As the others have hinted, set list changes non printing characters to a visible character that's configured in listchars.

To explicitly show spaces as some other character, something similar to the below should do the trick:

:%s/ /█/g

Then just undo the change to go back again.

(to get the █ I pressed this exact key sequence: :%s/ /CTRL-KFB/g)

Eerie answered 4/11, 2009 at 20:50 Comment(3)
I like this better than other answers, this looks like inverse of :set list to me, changing visible character ('space') to a _non priting_(??) one. I wonder if one can use this inside match e.g. :match MyBlackBlockChar "appropriate_regex that should do the trick, shouldn't it?Breezeway
The other answers are useful, but this is the first one that actually answers OP's question +1During
Or :%s/\s/█/g for all whitespace. Also, :set hlsearch plus :&s/\s//gn might be useful.Thanet
A
16

To highlight spaces, just search for it:

/<space>

Notes:

  • <space> means just type the space character.
  • Enable highlighting of search results with :set hlsearch

    To highlight spaces & tabs:

    /[<space><tab>]

    A quick way to remove the highlights is to search for anything else: /asdf

    (just type any short list of random characters)

  • Abamp answered 15/7, 2012 at 11:12 Comment(2)
    This is the same as the answer posted 3 years earlier. Also, :noh is quicker than /asdf for unhighlighting text. Or you could even set f1 to :noh given that you'll probably be using it often.Lama
    @DrEval Assuming you're referring to Benedikt Köppel's answer it's actually subtly different /<space> vs /\s. I think it's non-obvious and faster to use the suggestion here.Myna
    P
    16

    The code below is based on Christian Brabandt's answer and seems to do what the OP wants:

    function! Whitespace()
        if !exists('b:ws')
            highlight Conceal ctermbg=NONE ctermfg=240 cterm=NONE guibg=NONE guifg=#585858 gui=NONE
            highlight link Whitespace Conceal
            let b:ws = 1
        endif
    
        syntax clear Whitespace
        syntax match Whitespace / / containedin=ALL conceal cchar=·
        setlocal conceallevel=2 concealcursor=c
    endfunction
    
    augroup Whitespace
        autocmd!
        autocmd BufEnter,WinEnter * call Whitespace()
    augroup END
    

    Append those lines to your ~/.vimrc and start a new Vim session to see the still imperfect magic happen.

    Feel free to edit the default colors and conceal character.


    Caveat: something in the *FuncBody syntax group in several languages prevents the middle dot from showing. I don't know (yet?) how to make that solution more reliable.

    Penetrate answered 23/10, 2014 at 13:9 Comment(5)
    That's what I meant with "depending on the syntax group" I suspect this is a problem with syn keywords in combination with the skipwhite flag.Liquidation
    @ChristianBrabandt, yeah, I couldn't go beyond what you already did beside making it "automatic".Penetrate
    Yes, it's the skipwhite argument in the syntax rules, that prevents the syntax group to match (although it should be allowed to be contained in all groups).Liquidation
    Is there any way to make this work nicely with Indent Guides, which adds background to indentation? I suspect it's a matter of getting this to no override the background color, but this seems to be non-trivial.Clintclintock
    How to disable the same when highlighting of white space are not required? Looking for kind of short toggle command.Cards
    G
    12

    I didn't find exactly what I wanted from the existing answers. The code below will highlight all trailing spaces bright red. Simply add the following to your .vimrc

    highlight ExtraWhitespace ctermbg=red guibg=red
    match ExtraWhitespace /\s\+$/
    autocmd BufWinEnter * match ExtraWhitespace /\s\+$/
    autocmd InsertEnter * match ExtraWhitespace /\s\+\%#\@<!$/
    autocmd InsertLeave * match ExtraWhitespace /\s\+$/
    autocmd BufWinLeave * call clearmatches()
    
    Generative answered 21/11, 2016 at 20:37 Comment(0)
    P
    11

    I was frustrated with all of the other answers to this question, because none of them highlight the space character in a useful way. Showing spaces as characters would particularly help for whitespace-formatted languages, where mixing tabs and spaces is harmful.

    My solution is to show tabs and underline multiple spaces. It borrows from mrucci's answer and this tutorial. Because it uses syntax highlighting, it's persistent:

    set list listchars=tab:\|\ 
    highlight Whitespace cterm=underline gui=underline ctermbg=NONE guibg=NONE ctermfg=yellow guifg=yellow
    autocmd ColorScheme * highlight Whitespace gui=underline ctermbg=NONE guibg=NONE ctermfg=yellow guifg=yellow
    match Whitespace /  \+/
    

    Using this, tabs are displayed as | and spaces as _, which makes it very easy to tell when I'm mixing code styles.

    The only downside I've found is that this snippet doesn't adjust background color to match the context (like in a comment).

    Pilaf answered 26/6, 2012 at 7:23 Comment(0)
    T
    11

    To cover Unicode whitespace characters:

    set list
    set listchars=tab:│\ ,nbsp:·
    highlight StrangeWhitespace guibg=Red ctermbg=Red
    " The list is from https://stackoverflow.com/a/37903645 (with `\t`, `\n`, ` `, `\xa0` removed):
    call matchadd('StrangeWhitespace', '[\x0b\x0c\r\x1c\x1d\x1e\x1f\x85\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u2028\u2029\u202f\u205f\u3000]')
    

    The result:

    • Only the ordinal space (U+0020) looks like an ordinal space (" ").
    • The tab (U+0009) looks like "│ " (two characters: a long pipe and then an ordinal space; they are gray in colorscheme murphy).
    • The non-breaking space (U+00A0) looks like "·" (one character; it's gray in colorscheme murphy).
    • Any other whitespace character looks like a red space (" ").
    Tenancy answered 5/7, 2018 at 16:18 Comment(4)
    Edited to add "ctermbg=Red" to make my terminal to work for the coloring. Personally I used set listchars=tab:»\ ,space:· for your reference.Consubstantiate
    @JohnnyWong Thanks for the update. It was initially rejected by reviewers, but I've checked the code, and it (unsurprisingly) works both for gvim and vim.Tenancy
    Brilliant answer, this is exactly what I needed to capture narrow non-break spaces (Hex 202f) that don't get rendered in Safari and Firefox.Acrefoot
    Perfect solution. I however replaced Red with Brown, as red is already used a lot in many places (and I already use it to show trailing whitespace).Sams
    F
    9

    all of the answers above try to make spaces visible from within vim. If you really insist on having visible spaces as dots, there's another approach...

    If it cannot be done in vim, change your font entirely. I copied the Ubuntu One Mono font and edited it using FontForge. Remember to change the font's fullname, family, preferred family, compatible full (in FontFoge it's under TTF Names in the font info), in order to have it as a separate font. Simply edit the space character to have a dot in the middle and save the font to ~/.fonts Now you can use it for your gvim or the entire terminal... I copied the "!" character, removed the line and moved the dot to the middle. It took a little more than 5 minutes...

    Note: changing the space character (0x20) results in the inconvenience of having dots on the entire vim screen... (but it will separate the spaces from tabs...)

    Facesaving answered 30/1, 2014 at 10:36 Comment(2)
    This sounded like a really good approach until I read the note about filling the entire screen with dots. :/Berl
    Points for creativity! :-)Bab
    V
    5

    You could use

    :set list
    

    to really see the structure of a line. You will see tabs and newlines explicitly. When you see a blank, it's really a blank.

    Vikkivikky answered 4/11, 2009 at 18:21 Comment(0)
    O
    5
    :match CursorLine /\s\+/
    

    avoids the "you have to search for spaces to get them to show up" bit but afaict can't be configured to do non-hilighting things to the spaces. CursorLine can be any hilighting group and in the default theme it's a plain underline.

    Oakie answered 6/6, 2011 at 7:53 Comment(1)
    I can't tell the difference between tabs and spaces using this method, which is too bad, but I love that it's a one liner.Unbreathed
    S
    5

    I like using special characters to show whitespace, is more clear. Even a map to toggle is a key feature, for a quick check.

    You can find this features in an old vim script not updated since 2004:

    vim-scripts/[email protected]

    Thanks to project vim-scripts and vundle you can come back to life this plugin

    vim-scripts/cream-showinvisibles@github

    Even better, my two cents on this is to add a configurable shortcut (instead of predefined F4)

    so add this to ~/.vimrc

    Plugin 'albfan/cream-invisibles'
    
    let g:creamInvisibleShortCut = "<F5>" "for my F4 goto next error
    

    install plugin on vim

    :PluginInstall
    

    and there you go

    Sidneysidoma answered 10/10, 2014 at 18:9 Comment(0)
    R
    5

    Keep those hacks in the .vimrc as comments, so in the shell, simply :

    echo '
      " how-to see the non-visible while spaces
      " :set listchars=eol:¬,tab:>·,trail:~,extends:>,precedes:<,space:␣
      " set listchars=eol:$,tab:>-,trail:~,extends:>,precedes:<
      " :set list
      " but hei how-to unset the visible tabs ?!
      " :set nolist
      ' >> ~/.vimrc
    
    Reyesreykjavik answered 5/9, 2018 at 12:22 Comment(0)
    A
    4

    highlight search

    :set hlsearch 
    

    in .vimrc that is

    and search for space tabs and carriage returns

    / \|\t\|\r
    

    or search for all whitespace characters

    /\s
    

    of search for all non white space characters (the whitespace characters are not shown, so you see the whitespace characters between words, but not the trailing whitespace characters)

    /\S
    

    to show all trailing white space characters - at the end of the line

    /\s$
    
    Archipenko answered 29/10, 2014 at 20:40 Comment(0)
    J
    1
    :se list
    :se nolist
    

    :se is enough, :set isn't needed.

    Jerkwater answered 28/6, 2013 at 10:38 Comment(0)
    E
    1

    you can also highlight the spaces (replacing the spaces with a block):

    :%s/ /█/g
    

    (before writing undo it)

    Endurable answered 24/7, 2013 at 18:0 Comment(0)
    C
    1

    Adding this to my .vimrc works for me. Just make sure you don't have anything else conflicting..

    autocmd VimEnter * :syn match space /\s/
    autocmd VimEnter * :hi space ctermbg=lightgray ctermfg=black guibg=lightgray guifg=black
    
    Cholent answered 29/10, 2014 at 19:36 Comment(0)

    © 2022 - 2024 — McMap. All rights reserved.