views:

118

answers:

1

Howdy,

Is there a way in vim to restore the terminal's original foreground color after changing it with the ':highlight Normal' command?

For example, I'm using vim.exe 7.2 in a Windows Command Prompt. My Command Prompt has green text. When I start vim.exe, I can run the following command to change the text to red:

:highlight Normal ctermfg=red

I cannot, however, figure out how to turn the foreground color back to the original color.

Of course, in this simple example, I know the original color was green, so I could just set it back to green explicitly. In real life, though, I'm writing a vim script and need a generic solution for reverting to the original color.

I've been plowing through the vim docs for the last few hours, and have tried things like ':syntax off', ':highlight normal clear', and 'syntax reset', to no avail. There was some interesting information in the termcap section about the 't_op' variable, but I can't figure out how to use it. The only success I've had so far is quitting out of vim and allowing the Command Prompt to revert to its original color; I'd really like to be able to do this from within the same vim session.

Thanks, in advance, for any suggestions you may have.

-----[20100723 13:30]-----

Sorry for my mess of comments in response to rq. I'll try posting relevant follow-up information to the original question, instead.

On my machine (vim 7.2, Windows 7, Command Prompt) synIDattr() function returns the same value for every Normal foreground color. Consider the following: I start a new vim session in my Command Prompt, with syntax highlighting disabled, and run the following script to report the foreground color of the first character of the first line:

let numID = synID(1, 1, 1)
let numIDtrans = synIDtrans(numID)
let numFG = synIDattr(numIDtrans, "fg")
echo "synID: *" . numID . "*"
echo "synIDtrans: *" . numIDtrans . "*"
echo "synIDattr(fg): *" . numFG . "*"

in response, I get:

synID: *0*
synIDtrans: *0*
synIDattr(fg): **

Observe that there is no value returned by synIDattr(), just the literal asterisk delimiters I added.

Next, I change the Normal group foreground color:

highlight Normal ctermfg=red

When I run the same script, I get the same response - no value from synIDattr(). Note that the script does return useful information when I have syntax highlighting enabled (but at that point it's too late).

-----[20100728 16:11]-----

The 'highlight Normal ctermfg=NONE' solution worked. I'll provide a bit more context, for future reference.

My goal was to write a function and hotkey for quickly switching syntax highlighting on and off. To allow the foreground color to return to the original color after disabling syntax highlighting, I had to remove the 'highlight Normal...' command from the colorscheme file, and add two corresponding commands to the function, itself:

function! fSwitchSyntax()

        if exists("g:syntax_on")

                syntax off    
                highlight normal ctermfg=NONE  <--- New command

        else

                syntax on    
                highlight normal ctermfg=white <--- New command

        endif

endfunction
A: 

In Vim script you can get the foreground color of the piece of text under the cursor with the following snippet:

let oldcolor = synIDattr(synIDtrans(synID(line("."), col("."), 1)), "fg")

You'd have to keep track of the syntax item that you have changed in order to turn it back to the original color. The following snippet will print out how to set the ctermfg color under the cursor:

let synhere = synID(line("."), col("."), 1)
let oldcolor = synIDattr(synIDtrans(synhere), "fg")
let what = synIDattr(synhere, "name")
echo ":highlight " . what . " ctermfg=" . oldcolor

You may have to keep track of bold, underline, and bg color too. :help synIDattr() has the details.

EDIT: I didn't see your update, maybe you should have added a comment.

If you have syntax off, I guess the syn* functions don't do anything. Having re-read the question, I think the easiest way to get back to your original state is with :highlight Normal ctermfg=NONE.

rq
The "ctermfg=NONE" syntax worked; thank you for the answer!I'll make an edit to the original post with some more information.(I haven't quite figured out the workflow/etiquette for posting responses on stackoverflow yet. I added some comments to your reply the other day, then realized that 1. space is limited, and 2. I couldn't format code. After consulting the FAQ and a friend, I decided to remove the comments and modify the original post. I guess I should have left the comments; sorry for the confusion.)
manniongeo
@mannion: No problem! I think the usual way people do that is to edit the question and then post a "hey, I edited the question" comment.
rq