6

I sometimes type (by accident) shift-space, inserting unbreakable space into code. With c++, I get this:

error: stray ‘\302’ in program
error: stray ‘\240’ in program

while in other formats (like RestructuredText), I am hunting mysterious errors of syntax without any visible cause.

Is there a way to

  • always highlight unbreakable spaces (and perhaps other type of "illegal" whitespace, i.e. any whitespace besides space and tab)
  • map shift-space to space, so that these characters are not inserted in the first place?

Thanks!

4 Answers 4

10

List & Listchars

'list' is a boolean option that, when set, instructs vim to display whitespace characters. And it is completely customizable using 'listchars'.

For example, to show non-breaking spaces as ! (you can use whatever character you like, especially with digraphs and unicode support):

set list listchars=nbsp:!

I use 'listchars' extensively, since it supports tabs, trailing whitespace, and more. It helps provide little background indicators that things aren't really what they seem.

My current settings, for example, are

set list listchars=tab:»\ ,trail:·,nbsp:⎵,precedes:<,extends:>

Meaning:

  • tabs show as » followed by spaces ;
  • trailing white spaces show up as dots ;
  • non-breaking spaces show up as that weird unicode space character ;
  • if the line wraps to the left or the right, I get angle-bracket notifiers

Further Reading:

  • :h 'list'
  • :h 'listchars'
1
  • 1
    This is also useful in languages like Python or GNU Make where whitespace is significant and the difference between four spaces and a tab can make a big difference.
    – bta
    Oct 23, 2018 at 15:08
3

You can use

:syntax match ErrorMsg " "

while inserting an unbreakable space between the "'s.

To automatically load the rule, you can simply add

au VimEnter,BufWinEnter * syn match ErrorMsg " "

to your .vimrc.

If you want to customize the highlighting, create a custom rule before the syn match, i.e.

highlight UnbreakableSpace ctermbg=red guibg=red
au VimEnter,BufWinEnter * syn match UnbreakableSpace " "
2

I do have this in my custom vimrc file, which highlights git conflict markers as well as special whitespace characters.

" highlight VCS conflict markers
" highlight strange Whitespace
aug CustomHighlighting
  au!
  au WinEnter * if !exists("w:custom_hi1") | let w:custom_hi1 = matchadd('ErrorMsg', '^\(<\|=\|>\)\{7\}\([^=].\+\)\?$') | endif
  au WinEnter * if !exists("w:custom_hi2") | let w:custom_hi2 = matchadd('ErrorMsg', '[\x0b\x0c\u00a0\u1680\u180e\u2000-\u200a\u2028\u202f\u205f\u3000\ufeff]') |  endif
aug END

kudos to Benjamin Haskell via the vim_use mailinglist

2

I don't think you can use the <S-Space> notation in a mapping* but I think you should be able to map it by pressing Shift+Space when typing in the mapping where I've written [lhs] below:

:inoremap [lhs] <Space>

Of course, when reading your .vimrc, this will be a bit confusing, so you might be better off using an :execute command and Vim's notation for adding Unicode characters to a string:

execute "inoremap \u00A0 <Space>"

(N.B. I'm not entirely sure which character you are inserting when you press Shift+Space: you may need to adjust the Unicode value accordingly.)

* I think that the keystrokes are probably converted in your terminal and never make it to Vim. So Vim only sees the unbreakable space: it doesn't know you pressed Shift+Space.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.