How can I use variables to DRY up Vim colorthemes
I would like to tidy up my Vim color scheme file, by replacing #ABCDEF colors with variables. For example, I would like to replace this:
highlight String guifg=#61CE3C
highlight Identifier guifg=#61CE3C
highlight Type guifg=#84A7C1
with something like this (pseudo-code vimscript):
my_string =#61CE3C
my_type =#84A7C1
highlight String guifg=my_string
highlight Identifier guifg=my_string
highlight Type guifg=my_type
I wasn't sure whether vimscript considers the hex color to be a string, or a hexadecimal number. Apparently it's a string, cause this seems t开发者_开发技巧o work:
:highlight Normal guifg='#ffffff'
So I thought I'd try this:
:let my_color='#ffffff'
:highlight Normal guifg=my_color
But this gives the error "E254: Cannot allocate color my_color". Can anyone suggest a way to make this work?
Since :highlight
doesn't accept a variable as an argument, you have to build the command to run as an expression and then evaluate it with the :execute command.
:let my_color='#ffffff'
:exe 'highlight Normal guifg=' . my_color
As jamessan has said, you need to use :exe
to do this. I found the general syntax for the colour scheme files a bit difficult to manage, so I made my own, which you may be interested in. I find it a lot more maintainable, but you may still find it a bit too verbose, in which case see the alternative at the end of this answer.
Rather than writing the long :hi
lines, you create a dictionary along the lines of:
" Unspecified colours default to NONE, EXCEPT cterm(.*) which default to matching gui(.*)
" ctermfg will default to 'Blue' and ctermbg to 'NONE' if gui(.*) are RGB
"
" In most cases, only GUIFG is therefore important unless support for Black and White
" terminals is essential
let ColourAssignment['Normal'] = {"GUIFG": 'White', "GUIBG": 'Black'}
let ColourAssignment['Comment'] = {"GUIFG": '#00ff00'}
As mentioned in the comment, all unspecified parts assume sensible defaults, so you don't have to do the common:
:hi Comment guifg=green ctermfg=green guibg=black ctermfg=black
repetition. You can also (of course) put variables in place of the '#00ff00'
bit if you want.
It's currently designed around dark background colour schemes: for light background colour schemes, it automatically chooses an appropriate colour (it makes bright colours darker basically) unless you override it, but if you prefer light background colour schemes, it wouldn't be too hard to change so that the default is light.
The other advantage of it is that it comes with a syntax highlighting file that automatically highlights the "ColourAssignment" bit in the colour that you've selected.
Anyway, if that's any interest to you, you can get it from here.
An alternative you could use would be to create a command like this:
command! -nargs=+ Hi call CustomHighlighter(<f-args>)
function! CustomHighlighter(name, ...)
let colour_order = ['guifg', 'guibg']
let command = 'hi ' . a:name
if (len(a:000) < 1) || (len(a:000) > (len(colour_order)))
echoerr "No colour or too many colours specified"
else
for i in range(0,len(a:000)-1)
let command .= ' ' . colour_order[i] . '=' . a:000[i]
endfor
exe command
endif
endfunc
You could then use:
Hi Comment #00ff00
Hi String Yellow
Hi Normal White Black
精彩评论