1

I wrote a function to show some special characters with red color:

function! ShowChar()
    set list
    set listchars=tab:→\ ,space:·,nbsp:␣,eol:¶
    highlight SpecialKey ctermfg=blue ctermbg=red guifg=blue guibg=red
endfunction
map <f5> :call ShowChar()<CR>

When to press f5, the characters -- tab, space, nbsp, eol will be shown with red color, now I want to design a new function key f6, when to press f6 after pressing f5, all the special characters will be shown as previous status, not with red color. Should I write a new function which called by f6?

4
  • Can you create two highlighting groups SpecialKeyWarning and SpecialKeyNormal and use :h :highlight-link? In your vimrc you link SpecialKey to SpecialKeyNormal, in ShowChar() you link it to SpecialKeyWarning and when you're done you link again to SpecialKeyNormal?
    – statox
    Jul 20 '20 at 12:49
  • What statox is driving at is there isn’t really a good way to “save” the old highlight value... it’s whatever is defined by the colorscheme. You could try just doing execute 'colorscheme' g:colors_name
    – D. Ben Knoble
    Jul 20 '20 at 13:23
  • Yup definitely not a good way to save the value set from the colorscheme indeed, it was just a way to avoid playing with highlighting commands output. But reloading the whole colorscheme as Ben suggests might be a better idea.
    – statox
    Jul 20 '20 at 13:28
  • one can use redir with output to variable, parse, save and then restore it
    – Maxim Kim
    Jul 20 '20 at 15:55
1

I assume you use termguicolors:

if has("termguicolors")
  set termguicolors
endif

You can use this to store the colors of the SpecialKey group each time your colorscheme changes:

augroup SaveSpecialKeyColors
  au!
  au ColorScheme,VimEnter *
        \ let g:specialkey_fg = synIDattr(hlID('SpecialKey'), "fg#") |
        \ let g:specialkey_bg = synIDattr(hlID('SpecialKey'), "bg#")
augroup end

And a function to toggle:

set listchars=tab:→\ ,space:·,nbsp:␣,eol:¶

function! SpecialKeyToggle()
  if &list == ""
    set list
    highlight SpecialKey guifg=blue guibg=red
  else
    exe "highlight SpecialKey guifg= " g:specialkey_bg "guibg= " g:specialkey_bg
  endif
endfunction

nnoremap <f6> :call SpecialKeyToggle()<CR>

You could have a mapping to toggle list (stole this one from tpope's unimpaired):

nnoremap yol setlocal list!

nnoremap is good practice: you only need this function in normal mode (n), and don't want it to be recursive (nore).

0
function! SpecialKeyWarning()
    set list
    set listchars=tab:→\ ,space:·,nbsp:␣,eol:¶
    highlight SpecialKey ctermfg=blue ctermbg=red guifg=blue guibg=red
endfunction
map <f5> :call SpecialKeyWarning()<CR>

function! SpecialKeyNormal()
    set  nolist 
endfunction
map <f6> :call SpecialKeyNormal()<CR>
1
  • That's not really what you asked in your question. But if it works for you, you can simplify everything: leave set listchar... and highlight SpecialKey... in your vimrc out of a function and simple use nnoremap <f5> :set list!<CR> to toggle the list option with only one key. (Also you should always use mode specific map commands like nmap or imap and unless you know what you are doing you should always use the non recursive version of map commands i.e. nnoremap and inoremap)
    – statox
    Jul 20 '20 at 15:20
0
set listchars=tab:→\ ,space:·,nbsp:␣,eol:¶
highlight SpecialKey ctermfg=blue ctermbg=red guifg=blue guibg=red
nnoremap <f5> :set list!<CR>
1
  • 5
    It would be great if you'd provide a bit of explanation as for why this solution works (even if this is quite obvious).
    – Biggybi
    Jul 21 '20 at 2:19

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.