Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Render space if it have multi space in Vim

Tags:

vim

vim-plugin

I used:

set listchars=tab:→\ ,trail:·,precedes:←,extends:→,nbsp:·,space:·

to render space and tab character.

But I want to show only >=2 space, I don't want to display if It has one space between other characters.

(It is the same of "editor.renderWhitespace": "boundary" in vscode) enter image description here

Can I do it in Vim? (config or plugin)

Thank you.

Edit: I use:

if exists('space_match')
  call matchdelete(space_match)
endif
let space_match = matchadd('Conceal', '\v( @<= )|(  @=)', -1, -1, {'conceal': '·'})
  • I use priority -1 to compatible with indentLine
  • ( @<= ) to match a space after another space
  • ( @=) to match a space before another space

and remove space in listchars:

set listchars=tab:→\ ,trail:·,precedes:←,extends:→,nbsp:·

Thank Ben Knoble so much to help me find that!!!

like image 798
hong4rc Avatar asked Mar 04 '23 09:03

hong4rc


1 Answers

Using conceal, there are a couple of ways this can go, depending on what you want to achieve. Since we are using conceal, you'll want to remove space from 'listchars'.

I'll be using matchadd() below, but you can theoretically do something similar with syn-conceal. The difference is that a match is local to a window. Syntax is available where defined—you could use any filetype or other mechanism to set this via syntax.

I assume that the regex \s (match whitespace) matches what you need. If you need only spaces, change \s to (a single space character) in the regexp.

I assume you can read vim regexp. The help pages are extensive, but do note below that I use \v to explicitly set the magic type (matchadd is sensitive to regex-influencing options like 'magic') and I use \zs where appropriate to start the match.

I'll be using the test text below.

Test file

word word  word   word
word word  word   word

set conceallevel=1

At level 1, we're allowed to use replacement characters in our matches.

So, we could replace all the extra spaces with, e.g., a . to make them standout:

let space_match = matchadd('Conceal', '\s\@<=\s+', 10, -1, {'conceal': '.'})

(10 is the default priority, and -1 requests a new ID for the match.)

Cleaning up

To get rid of the match/conceal, you can simply

call matchdelete(space_match)

The OP has stated that the following worked best for the question:

let space_match = matchadd('Conceal', '\v( @<= )|(  @=)', -1, -1, {'conceal': '·'})
  • priority -1 to compatible with indentLine
  • ( @<= ) to match a space after another space
  • ( @=) to match a space before another space
like image 142
D. Ben Knoble Avatar answered Mar 08 '23 11:03

D. Ben Knoble