Currently, I use this:

map <F7> <Esc>:if has("gui_running")<Bar>hi comment gui=bold<Bar>else<Bar>hi comment cterm=bold<Bar>endif<LF>

It turns comments bold in terminal or in GUI when I press <F7>.

And I would like it also to toggle the bold text. Is there a way to do this?

Something like:

if hi comment gui == bold
    hi comment gui=none
    hi comment gui=bold
  • Note you can just use :hi comment gui=bold cterm=bold, no need for the if statement here. Jun 28 '15 at 0:03

You can get the current settings of a highlight group with the :highlight command. For example:

:highlight Comment
Comment        xxx term=bold ctermfg=4 guifg=Blue

This will just output the text; there is (as far as I know), no VimScript function to get the same text in a string, but not all is lost, since we can use the :redir command to redirect the output of a command to a variable.

We can then match this, and call the appropriate :highlight command.

Putting that all together, we end up with this function:

fun! ToggleHighlight()
    " Redirect output of :highlight to l:current
    redir => l:current
        silent highlight Comment
    redir END

    if l:current =~# '\(cterm\|gui\)=bold'
        highlight Comment gui=none cterm=none
        highlight Comment gui=none cterm=bold

And you can map this function to <F7> with:

noremap <F7> <Esc>:call ToggleComments()<CR>
  • Ah, I figured there would be some way of getting the state of the cterm or gui attributes. Jun 28 '15 at 0:35
  • Nice! Thanks. But I think nomap is wrong. Can you correct it please? I dont know which map command I would want to use here.
    – MichalH
    Jun 28 '15 at 0:37
  • @Mike Oops, sorry, I meant to use noremap, which is the same as map but non-recursive. See Learn VimScript the Hard way chapters 3 through 5 (especially chapter 5) to learn why you should always use noremap and never map. Jun 28 '15 at 0:46
  • You can use :echo synIDattr(synIDtrans(hlID('Comment')), 'bold', 'gui') to check for bold mode for gui. See the help at :h synIDattr for all the arguments. Sep 3 '15 at 9:24

This mapping is probably more suited to a mapping which calls a function, since it contains so many commands. Here is my best shot at this:

" This just uses the call command to run the ToggleBoldComments function
nnoremap <F7> :call ToggleBoldComments()<CR>

function! ToggleBoldComments()
    " Make a variable in the current buffer to keep track of whether the
    " comments are bold or not.
    if !exists("g:comments_bold")
        let g:comments_bold = 0

    " If comments aren't already bold, make it so.
    if g:comments_bold == 0
        let g:comments_bold = 1
        hi comment gui=bold cterm=bold
        return 0
    elseif g:comments_bold == 1
        " Same, except the other way around.
        let g:comments_bold = 0
        hi comment gui=none cterm=none

Here are the relevant help topics (I recommend you read these if you want to know more about how this mapping works):

  • :help :function
  • :help :call
  • :help exists()
  • :help g:
  • :help internal-variables
  • :help :highlight

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.