开发者

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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜