Skip to content

Commit

Permalink
Added support for custom colour definitions (fixes #581). Added suppo…
Browse files Browse the repository at this point in the history
…rt for linking highlight groups together (fixes #579). Added support for multiple highlight groups on the left of the ':' (fixes #580).
  • Loading branch information
abudden committed Feb 24, 2012
1 parent d27e47d commit ce34882
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 29 deletions.
69 changes: 60 additions & 9 deletions autoload/EasyColour/ColourScheme.vim
Expand Up @@ -21,11 +21,16 @@ endtry
let g:loaded_EasyColourColourScheme = 1

let s:need_to_write_cache = 0

if ! exists('g:EasyColourDebug')
let g:EasyColourDebug = 0
endif

function! EasyColour#ColourScheme#LoadColourScheme(name)
let command_list = EasyColour#ColourScheme#GetColourSchemeLoadCommands(a:name)
for command in command_list
if g:EasyColourDebug == 1
echomsg command
endif
exe command
endfor
if s:need_to_write_cache == 1
Expand All @@ -39,6 +44,13 @@ function! EasyColour#ColourScheme#GetColourSchemeLoadCommands(name)
let ColourScheme = EasyColour#LoadDataFile#LoadColourSpecification(a:name)
let command_list = []

if ! has_key(ColourScheme, 'Colours')
let ColourScheme['Colours'] = {}
endif

" Used by the colour scheme file highlighter
let g:EasyColourCustomColours = ColourScheme['Colours']

if has_key(ColourScheme, 'Background')
let &background = tolower(ColourScheme['Background'])
endif
Expand Down Expand Up @@ -92,7 +104,7 @@ function! EasyColour#ColourScheme#GetColourSchemeLoadCommands(name)
let ColourScheme[details]['Normal'] = ["Black","White"]
endif
endif
let command_list += s:StandardHandler(ColourScheme[details])
let command_list += s:StandardHandler(ColourScheme, details)
elseif handler == 'Auto'
let command_list += s:AutoHandler(ColourScheme, basis, details)
endif
Expand Down Expand Up @@ -140,6 +152,12 @@ function! s:GenerateColourMap(Colours)
let group_colours = [a:Colours[hlgroup]]
endif

" Links
if len(group_colours) == 1 && group_colours[0][0] == '@'
let field_colour_map[hlgroup] = {'Link': group_colours[0][1:]}
continue
endif

let highlight_map = {}
let index = 0
let handled = []
Expand Down Expand Up @@ -181,14 +199,24 @@ function! s:GenerateColourMap(Colours)
return field_colour_map
endfunction

function! s:StandardHandler(Colours)
let field_colour_map = s:GenerateColourMap(a:Colours)
function! s:StandardHandler(ColourScheme, details)
let Colours = a:ColourScheme[a:details]
let field_colour_map = s:GenerateColourMap(Colours)
let colour_map = s:GetColourMap()

let modified_colours = {}
for hlgroup in keys(field_colour_map)
let modified_colours[hlgroup] = {}
if has_key(field_colour_map[hlgroup], 'Link')
" This is a link entry: just copy across
let modified_colours[hlgroup] = field_colour_map[hlgroup]
continue
endif
for field in keys(field_colour_map[hlgroup])
if s:all_fields[field] != 'Style' && has_key(a:ColourScheme['Colours'], field_colour_map[hlgroup][field])
let field_colour_map[hlgroup][field] = a:ColourScheme['Colours'][field_colour_map[hlgroup][field]]
endif

if colour_map == 'None' || s:all_fields[field] == 'Style'
let modified_colours[hlgroup][field] = field_colour_map[hlgroup][field]
elseif field_colour_map[hlgroup][field] == 'NONE'
Expand Down Expand Up @@ -217,11 +245,15 @@ function! s:RunHighlighter(map)
endif
endif

let command = 'hi ' . hlgroup
for field in keys(a:map[hlgroup])
let command .= ' ' . field . '=' . a:map[hlgroup][field]
endfor
let command_list += [command]
if has_key(a:map[hlgroup], 'Link')
let command = 'hi link ' . hlgroup . ' ' . a:map[hlgroup]['Link']
else
let command = 'hi ' . hlgroup
for field in keys(a:map[hlgroup])
let command .= ' ' . field . '=' . a:map[hlgroup][field]
endfor
endif
let command_list += ['hi clear ' . hlgroup, command]
endfor
return command_list
endfunction
Expand All @@ -243,6 +275,13 @@ function! s:AutoHandler(ColourScheme, basis, details)
let modified_colours = {}
for hlgroup in keys(standard_field_colour_map)
let modified_colours[hlgroup] = {}

if has_key(standard_field_colour_map[hlgroup], 'Link')
" This is a link entry: just copy across
let modified_colours[hlgroup] = standard_field_colour_map[hlgroup]
continue
endif

for field in keys(standard_field_colour_map[hlgroup])
if s:all_fields[field] == 'Style'
" Don't modify style hints
Expand All @@ -253,10 +292,18 @@ function! s:AutoHandler(ColourScheme, basis, details)
let modified_colours[hlgroup][field] = 'NONE'
continue
elseif hlgroup == 'Normal'
" Handle customised colours
if s:all_fields[field] != 'Style' && has_key(a:ColourScheme['Colours'], standard_field_colour_map[hlgroup][field])
let standard_field_colour_map[hlgroup][field] = a:ColourScheme['Colours']
endif
" Do a complete colour invert on normal
let std_colour = EasyColour#Translate#GetHexColour(standard_field_colour_map[hlgroup][field])
let modified_colours[hlgroup][field] = EasyColour#Shade#Invert(std_colour)
else
" Handle customised colours
if s:all_fields[field] != 'Style' && has_key(a:ColourScheme['Colours'], standard_field_colour_map[hlgroup][field])
let standard_field_colour_map[hlgroup][field] = a:ColourScheme['Colours']
endif
let std_colour = EasyColour#Translate#GetHexColour(standard_field_colour_map[hlgroup][field])
" Modify the colour if it's too dark or too light
if a:details == 'Dark'
Expand All @@ -271,6 +318,10 @@ function! s:AutoHandler(ColourScheme, basis, details)
let override_key = a:details . 'Override'
if has_key(override_map, hlgroup) && has_key(override_map[hlgroup], field)
let modified_colour = override_map[hlgroup][field]
" Handle customised colours
if s:all_fields[field] != 'Style' && has_key(a:ColourScheme['Colours'], modified_colour)
let modified_colour = a:ColourScheme['Colours']
endif
endif

if colour_map == 'None' || s:all_fields[field] == 'Style'
Expand Down
25 changes: 15 additions & 10 deletions autoload/EasyColour/LoadDataFile.vim
Expand Up @@ -46,9 +46,7 @@ function! s:LoadFile(filename)
" Comment: ignore
elseif entry[0] =~ '\k'
" Keyword character first, so not sub entry or top-levelcomment
if entry[1] == '#'
" Comment: ignore
elseif entry[len(entry)-1:] == ":"
if entry[len(entry)-1:] == ":"
" Beginning of a field, but we don't know whether
" it's a list of a dict yet
let top_key = entry[:len(entry)-2]
Expand All @@ -73,7 +71,9 @@ function! s:LoadFile(filename)
elseif top_key != '' && entry =~ '^\s\+'
" This is a continuation of a top level key
let details = substitute(entry, '^\s\+', '', '')
if stridx(details, ':') != -1
if details[0] == '#'
" Comment: ignore
elseif stridx(details, ':') != -1
" The key is a dictionary:
if ! has_key(result, top_key)
let result[top_key] = {}
Expand All @@ -87,12 +87,17 @@ function! s:LoadFile(filename)
if len(parts) > 2
let parts[1] = join(parts[1:], ':')
endif
if stridx(parts[1], ',') != -1
" This entry is a list
let result[top_key][parts[0]] = split(parts[1], ',')
else
let result[top_key][parts[0]] = parts[1]
endif
" If there are multiple keys, apply the
" right-hand side to all keys
let keys = split(parts[0],',')
for key in keys
if stridx(parts[1], ',') != -1
" This entry is a list
let result[top_key][key] = split(parts[1], ',')
else
let result[top_key][key] = parts[1]
endif
endfor
else
echoerr "Type mismatch on line '".entry."': expected key:value"
endif
Expand Down
21 changes: 12 additions & 9 deletions colors/bandit.txt
@@ -1,5 +1,9 @@
# Saving this file will update the current colour scheme.
Basis:None
Colours:
Violet:#EE82EE
CoralRed:#FF4040
DavysGrey:#555555
Dark:
Normal:White,Black
Comment:Green
Expand All @@ -13,11 +17,10 @@ Dark:
String:LightYellow
Character:DarkYellow
PreProc:Blue,Style=Bold
Include:Blue,Style=Bold
Define:#5555FF,Style=Bold
Macro:#5555FF,Style=Bold
Include:@PreProc
Define,Macro:#5555FF,Style=Bold
PreCondit:#8888FF,Style=Bold
Statement:Blue,Style=Bold
Statement:@PreProc
Conditional:#5555FF
Repeat:#8888FF
Label:#2222FF
Expand All @@ -27,7 +30,7 @@ Dark:
Function:#007777
Method:#009966
Class:Purple
DefinedName:#EE82EE
DefinedName:Violet
EnumerationValue:#C000C0
EnumerationName:#FF22FF
Member:DarkGrey
Expand All @@ -36,12 +39,12 @@ Dark:
LocalVariable:#AAA14C
GlobalConstant:#BBBB00
Type:#FF8000
StorageClass:#FF4040
StorageClass:CoralRed
Structure:#FF8080
Special:Red
SpecialChar:#AA0000
SpecialKey:#555555
NonText:#555555
SpecialKey:DavysGrey
NonText:DavysGrey
MatchParen:Yellow,Style=Underline
Error:White,Red
NonIndentTabError:SP=#FFAA00,Style=Undercurl
Expand All @@ -62,7 +65,7 @@ Dark:
htmlH5:#8888AA
htmlH6:#888888
Delimiter:DarkCyan
hlLevel0:DarkCyan
hlLevel0:@Delimiter
hlLevel1:#bfbf00
hlLevel2:#990033
hlLevel3:#334488
Expand Down
52 changes: 52 additions & 0 deletions doc/EasyColour.txt
Expand Up @@ -287,6 +287,33 @@ Copyright: (c) 2011-2012 by A. S. Budden *EasyColour-copyright

2.4.4 Sections *EasyColour-sections* {{{3

Colours *EasyColour-Colours*

This section allows you to define custom named colours that can then
be used elsewhere in the colour scheme. It is not required for a
colour scheme. If you'd rather just use standard named colours (such
as 'Blue' or RGB colours such as '#0F4F6A') then you can do that
without a 'Colours' section. The 'Colours' section simply allows you
to give more convenient names to non-standard RGB colours. For
example, if you really like Burnt Sienna and Ochre want to use them
for several highlight groups, you can do something like this:
>
Colours:
--->BurntSienna:#E97451
--->Ochre:#CC7722
<
(where ---> indicates a hard tab character).

The new colour names can then be used anywhere in the colour
specification (see |EasyColour-colour-spec|). Colour names should
consist of ASCII letters, digits and the underscore. They should
start with an ASCII letter.

If you use the Colours section to define a colour that is already
specified by Vim, your custom definition will take precedence (so if,
for some reason you define Blue to be #FF0000 then anything specified
as Blue will be shown in Red). This is probably a bad idea.

Light *EasyColour-Light*

This section is used to define the colours to be used when the
Expand Down Expand Up @@ -384,6 +411,25 @@ Copyright: (c) 2011-2012 by A. S. Budden *EasyColour-copyright
---># with the default (white in this case) text.
--->SignColumn:BG=#222222
<
2.4.6 Linking Highlight Groups *EasyColour-links* {{{3

If you wish to highlight (e.g.) the Statement highlight group in the same
way as the Keyword highlight group, you can define the Statement colour
specification like this:
>
--->Statement:@Keyword
<
Hopefully the syntax is obvious, but it simply consists of the '@' symbol
followed by the name of the other highlight group to copy.

Another way to link highlight groups is to specify multiple groups on the
left-hand side of a colour specification, something like this:
>
--->Statement,Keyword:Blue,Green,Red,Undercurl
<
To highlight BOTH the Statement and Keyword groups as blue text on a green
background with a red undercurl.

------------------------------------------------------------------------------

2.5 Highlight Group Reference *EasyColour-highlight* {{{2
Expand All @@ -397,6 +443,12 @@ Copyright: (c) 2011-2012 by A. S. Budden *EasyColour-copyright
==============================================================================
3. EasyColour History *EasyColour-history* {{{1

x.x.x: xxxx xxxxxxxx 2012 : Added support for custom colour definitions
(the 'Colours' section). Added support for
linking highlight groups together (with the @
Now allow multiple highlight groups on the
left of the ':'.

1.0.0: 23rd February 2012 : First public release.

==============================================================================
Expand Down
11 changes: 10 additions & 1 deletion syntax/EasyColour.vim
Expand Up @@ -31,11 +31,20 @@ endtry

syn match Keyword /^\k\+:/me=e-1
syn match Comment /^\s*#.*/
syn region EasyColourBlock start=/^\(Dark\|Light\)\(Override\)\?:/ end=/^\k/me=s-1 contains=Keyword,Comment
syn region EasyColourDefs start=/^Colours:/ end=/^\k/me=s-1 contains=Keyword,Comment
syn region EasyColourSpecification start=/^\(\t\| \+\)#\@!/ end=/:/ containedin=EasyColourBlock contained
syn region EasyColourCustomColour start=/^\(\t\| \+\)#\@!/ end=/:/ containedin=EasyColourDefs contained
syn region EasyColourLink start=/@/ end=/$/
for keyword in keywords
if keyword =~ '^\k*$'
execute 'syn match '.keyword.' /^\(\t\| \+\)\zs'.keyword.":/ms=s,me=e-1"
execute 'syn keyword '.keyword.' '.keyword.' containedin=EasyColourSpecification,EasyColourLink contained'
endif
endfor

for custom_colour in keys(g:EasyColourCustomColours)
execute 'syn keyword EasyColourCustom'.custom_colour.' '.custom_colour.' containedin=EasyColourCustomColour contained'
execute 'hi EasyColourCustom'.custom_colour.' guifg='.g:EasyColourCustomColours[custom_colour].' guibg=NONE gui=NONE'
endfor

let b:current_syntax = "EasyColour"

0 comments on commit ce34882

Please sign in to comment.