user3208243
user3208243

Reputation: 1

In Vim, creating a key map to toggle the color of GUI foreground?

I'm using gVim as a word processor, and find that it helps to switch foreground colors, one color for writing and another for proofreading.

I'm trying to map a key to a function that will toggle between the two colors, rather than laboriously type out "hi normal guifg=[writing color]" and "hi normal guifg=[proofreading color]" over and over.

I know there is a way to toggle between entire colorschemes, but then I would have to write up two separate colorschemes, one for writing and another for proofreading, which only differed by their foreground color. Instead, I want to keep the same colorscheme and toggle only between two different foreground colors that are written in hex form.

Here is my attempt to do this (forgive me, I just started using Vim this week). The writing color that is usually on is #e67300, while the proofreading color is #29cccc.

nnoremap <C-P> :call ToggleColor()<CR>
function! ToggleColor()
if (guifg=#e67300)
    exec 'hi normal guifg=#29cccc'
else
    exec 'hi normal guifg=#e67300'
endif
endfunction

Pressing the mapped key, Ctrl+P, gives this error message:

E121: Undefined variable: guifg

What I mean is, "If the foreground color variable takes on the value #e67300 (the writing color), then execute this step that will change the value to #29cccc (the proofreading color)." The "else" condition switches the color back.

I've tried other ways of referring to the foreground color as a variable -- foreground, fg, g:foreground, etc. -- putting spaces around the equals sign, using a double equals sign... but they all give the same error. I've tried a few "let" statements to define the variable, but they failed too.

This must be a basic noob error in the syntax of defining and referring to variables and their values, but I've done :h for the relevant terms and pieces of syntax, to no avail. Any help would be greatly appreciated.

Upvotes: 0

Views: 313

Answers (1)

benjifisher
benjifisher

Reputation: 5122

Not bad for your first week. Spend some time browsing the extensive help. For example,

:help function-list

and scroll to the section on syntax and highlighting (or get there directly with :help syntax-functions) and read up on synIDattr(). After reading the docs and a little experimentation, I came up with this:

nnoremap <C-P> :call ToggleColor()<CR>
function! ToggleColor()
  let normalID = hlID('Normal')
  let guifg = synIDattr(normalID, 'fg#')
  if guifg == '#e67300'
    hi normal guifg=#29cccc
  else
    hi normal guifg=#e67300
  endif
endfunction

If you like using :execute, then do it this way:

nnoremap <C-P> :call ToggleColor()<CR>
function! ToggleColor()
  let normalID = hlID('Normal')
  let guifg = synIDattr(normalID, 'fg#')
  exec 'hi normal guifg=' . (guifg == '#e67300' ? '#29cccc' : '#e67300')
endfunction

P.S. Not everything (such as highlighting attributes) can be referenced as a variable, but environment variables, options, and registers can. See :help 41.3 in the users' manual, although you will have to read the reference manual for all the juicy detail.

Upvotes: 3

Related Questions