Skip to content

Instantly share code, notes, and snippets.

@numEricL
Last active February 25, 2026 18:47
Show Gist options
  • Select an option

  • Save numEricL/16e98a106392b0aabdd75213dd618211 to your computer and use it in GitHub Desktop.

Select an option

Save numEricL/16e98a106392b0aabdd75213dd618211 to your computer and use it in GitHub Desktop.
vim/nvim colorscheme
" this file: colors/feywild.vim
highlight clear
if exists('syntax_on') | syntax reset | endif
let g:colors_name = 'feywild'
if !exists('g:use_term_bg') | let g:use_term_bg = 0 | endif
if !exists('g:use_term_fg') | let g:use_term_fg = 0 | endif
call feywild_colorscheme#Set()
" this file: autoload/feywild_colorscheme.vim
let s:colordict_dark256 = { 'NONE': 'NONE' , 'bw_shade_0': 16 , 'bw_shade_1': 234 , 'bw_shade_2': 236 , 'bw_shade_3': 240 , 'bw_shade_4': 244 , 'bw_shade_5': 254 , 'black': 16 , 'blue': 27 , 'blue_2': 69 , 'blue_bg': 17 , 'cyan': 81 , 'cyan_2': 31 , 'cyan_3': 33 , 'cyan_bg': 24 , 'green': 79 , 'green_2': 30 , 'green_bg': 22 , 'purple': 129 , 'purple_2': 212 , 'purple_bg': 54 , 'red': 162 , 'red_2': 163 , 'red_bg': 52 , 'yellow': 222 , 'yellow_2': 173 , 'yellow_bg': 94 , 'yellow_hl': 186 }
let s:colordict_light256 = { 'NONE': 'NONE' , 'bw_shade_0': 254 , 'bw_shade_1': 253 , 'bw_shade_2': 251 , 'bw_shade_3': 247 , 'bw_shade_4': 241 , 'bw_shade_5': 236 , 'black': 16 , 'blue': 21 , 'blue_2': 63 , 'blue_bg': 189 , 'cyan': 33 , 'cyan_2': 31 , 'cyan_3':81 , 'cyan_bg': 159 , 'green': 29 , 'green_2': 34 , 'green_bg': 158 , 'purple': 92 , 'purple_2': 164 , 'purple_bg': 183 , 'red': 163 , 'red_2': 124 , 'red_bg': 224 , 'yellow': 172 , 'yellow_2': 100 , 'yellow_bg': 223 , 'yellow_hl': 228 }
let s:colordict_16 = { 'NONE': 'NONE' , 'bw_shade_0': 0 , 'bw_shade_1': 8 , 'bw_shade_2': 8 , 'bw_shade_3': 7 , 'bw_shade_4': 7 , 'bw_shade_5': 15 , 'black': 0 , 'blue': 12 , 'blue_2': 12 , 'blue_bg': 4 , 'cyan': 14 , 'cyan_2': 14 , 'cyan_3': 14 , 'cyan_bg': 6 , 'green': 10 , 'green_2': 10 , 'green_bg': 2 , 'purple': 13 , 'purple_2': 13 , 'purple_bg': 5 , 'red': 9 , 'red_2': 9 , 'red_bg': 1 , 'yellow': 11 , 'yellow_2': 11 , 'yellow_bg': 3 , 'yellow_hl': 11 }
function! feywild_colorscheme#Set() abort
" Decide if emulator's defaults should be used (e.g. acrylic backgrounds)
let normal_fg = g:use_term_fg ? 'NONE' : 'bw_shade_5'
let normal_bg = g:use_term_bg ? 'NONE' : 'bw_shade_0'
call s:SetHighlight('Normal' , { 'fg': normal_fg , 'bg': normal_bg } )
call s:SetHighlight('Comment' , { 'fg': 'bw_shade_4' , 'term': 'italic' } )
call s:SetHighlight('Special' , { 'fg': 'red' } )
call s:SetHighlight('Type' , { 'fg': 'green' } )
call s:SetHighlight('Identifier' , { 'fg': 'yellow' } )
call s:SetHighlight('PreProc' , { 'fg': 'blue' } )
call s:SetHighlight('Statement' , { 'fg': 'purple' } )
call s:SetHighlight('Constant' , { 'fg': 'cyan' } )
call s:SetHighlight('String' , { 'fg': 'cyan' } )
call s:SetHighlight('Function' , { 'fg': 'yellow' } )
call s:SetHighlight('Special_2' , { 'fg': 'red_2' } )
call s:SetHighlight('Type_2' , { 'fg': 'green_2' } )
call s:SetHighlight('Identifier_2' , { 'fg': 'yellow_2' } )
call s:SetHighlight('PreProc_2' , { 'fg': 'blue_2' } )
call s:SetHighlight('Statement_2' , { 'fg': 'purple_2' } )
call s:SetHighlight('Constant_2' , { 'fg': 'cyan_2' } )
call s:SetHighlight('Error' , { 'fg': 'bw_shade_5' , 'bg': 'red_bg' } )
call s:SetHighlight('WarningMsg' , { 'fg': 'bw_shade_5' , 'bg': 'yellow_bg' } )
call s:SetHighlight('DiffAdd' , { 'bg': 'red_bg' } )
call s:SetHighlight('DiffChange' , { 'bg': 'blue_bg' } )
call s:SetHighlight('DiffDelete' , { 'fg': 'red' } )
call s:SetHighlight('DiffText' , { 'fg': 'black' , 'bg': 'yellow_hl' } )
call s:SetHighlight('SpellBad' , { 'bg': 'red_bg' } )
call s:SetHighlight('SpellCap' , { 'bg': 'blue_bg' } )
call s:SetHighlight('SpellLocal' , { 'bg': 'green_bg' } )
call s:SetHighlight('SpellRare' , { 'bg': 'purple_bg' } )
call s:SetHighlight('ColorColumn' , { 'bg': 'bw_shade_2' } )
call s:SetHighlight('Cursor' , { 'bg': 'cyan_3' } )
call s:SetHighlight('CursorLine' , { 'bg': 'bw_shade_1' } )
call s:SetHighlight('CursorLineNr' , { 'fg': 'green' , 'bg': normal_bg } )
call s:SetHighlight('EndOfBuffer' , { 'fg': 'bw_shade_0' } )
call s:SetHighlight('LineNr' , { 'fg': 'bw_shade_3' } )
call s:SetHighlight('NonText' , { 'fg': 'bw_shade_2' , 'bg': normal_bg } ) "showbreak extends precedes
call s:SetHighlight('SpecialKey' , { 'fg': 'bw_shade_3' } ) "list listchars
call s:SetHighlight('StatusLine' , { 'fg': 'green' , 'term': 'underline' } )
call s:SetHighlight('StatusLineNC' , { 'fg': 'bw_shade_3' , 'term': 'underline' } )
call s:SetHighlight('TabLine' , { 'fg': 'bw_shade_4' } )
call s:SetHighlight('TabLineFill' , { } )
call s:SetHighlight('TabLineSel' , { 'fg': 'bw_shade_5' , 'bg': 'blue_bg' } )
call s:SetHighlight('Todo' , { 'fg': 'yellow_hl' , 'bg': 'black' , 'term': 'reverse' } )
call s:SetHighlight('VertSplit' , { 'fg': 'bw_shade_5' } )
call s:SetHighlight('Directory' , { 'fg': 'blue' } )
call s:SetHighlight('IncSearch' , { 'fg': 'black' , 'bg': 'yellow_hl' } )
call s:SetHighlight('MatchParen' , { 'fg': 'bw_shade_5' , 'bg': 'bw_shade_3' } )
call s:SetHighlight('Pmenu' , { 'fg': 'bw_shade_4' , 'bg': normal_bg } )
call s:SetHighlight('PmenuSel' , { 'fg': 'bw_shade_4' , 'bg': 'blue_bg' } )
call s:SetHighlight('PmenuThumb' , { 'bg': 'cyan_bg' } )
call s:SetHighlight('PmenuSbar' , { 'bg': normal_bg } )
call s:SetHighlight('QuickFixLine' , { 'bg': 'blue_bg' } )
call s:SetHighlight('Search' , { 'term': 'reverse' } )
call s:SetHighlight('Visual' , { 'bg': 'bw_shade_2' } )
call s:SetHighlight('WildMenu' , { 'fg': 'green' , 'bg': 'green_bg' } )
" Vim Terminal should use dark theme or Terminal default.
let term_fg = g:use_term_fg ? 'NONE': normal_fg
let term_bg = g:use_term_bg ? 'NONE': 'bw_shade_1'
call s:SetHighlight('Terminal', { 'use_dark_theme':1, 'fg': term_fg, 'bg': term_bg } )
highlight! link Conceal Comment
highlight! link CursorColumn CursorLine
highlight! link ErrorMsg Error
highlight! link FoldColumn LineNr
highlight! link Folded Comment
highlight! link ModeMsg Normal
highlight! link MoreMsg Type
highlight! link Question Type
highlight! link SignColumn Type
highlight! link StatusLineTerm StatusLine
highlight! link StatusLineTermNC StatusLineNC
highlight! link Title Type
endfunction
let s:ft_loaded = {}
function! feywild_colorscheme#InitFiletype(ft) abort
if has_key(s:ft_loaded, a:ft)
return
endif
let s:ft_loaded[a:ft] = 1
call s:SetFiletype(a:ft)
augroup feywild_colorscheme
"use execute so autocmds can be distinguished in :autocmd feywild_colorscheme
execute 'autocmd ColorScheme feywild call s:SetFiletype(' .. string(a:ft) .. ')'
augroup END
endfunction
function! s:SetFiletype(ft) abort
if a:ft == 'markdown'
call s:SetMarkdown()
elseif a:ft == 'tex'
call s:SetLatex()
elseif a:ft == 'vim'
call s:SetVim()
else
echohl WarningMsg | echomsg 'feywild_colorscheme: No highlight links defined for filetype: ' . a:ft | echohl None
endif
endfunction
function! s:SetMarkdown() abort
call s:SetHighlight('markdownH1', { 'fg': 'green', 'term':'underline' } )
call s:SetHighlight('markdownH2', { 'fg': 'green' } )
call s:SetHighlight('markdownH3', { 'fg': 'green_2' } )
call s:SetHighlight('markdownH4', { 'fg': 'green_2' } )
call s:SetHighlight('markdownH5', { 'fg': 'green_2' } )
call s:SetHighlight('markdownH6', { 'fg': 'green_2' } )
call s:SetHighlight('markdownCode', { 'fg': 'bw_shade_4' } )
call s:SetHighlight('markdownItalic', { 'term': 'italic' } )
endfunction
function! s:SetLatex() abort
highlight link texMathZone Normal
highlight link texMathSymbol Normal
highlight link texRefArg Type
endfunction
function! s:SetVim() abort
highlight link vimVar Normal
endfunction
function! s:SetHighlight(group, prop) abort
let theme = &background
let theme = get(a:prop, 'use_light_theme', 0) ? 'light' : theme
let theme = get(a:prop, 'use_dark_theme', 0) ? 'dark' : theme
let color_to_cterm = s:GetColorDict(theme)
let fg = color_to_cterm[ get(a:prop, 'fg', 'NONE') ]
let bg = color_to_cterm[ get(a:prop, 'bg', 'NONE') ]
let guifg = s:CTermToHex(fg)
let guibg = s:CTermToHex(bg)
let term = ''
if has_key(a:prop, 'term')
if a:prop['term'] =~? 'bold' | let term.='bold,' | endif
if a:prop['term'] =~? 'underline' | let term.='underline,' | endif
if a:prop['term'] =~? 'undercurl' | let term.='undercurl,' | endif
if a:prop['term'] =~? 'reverse' | let term.='reverse,' | endif
if a:prop['term'] =~? 'inverse' | let term.='inverse,' | endif
if a:prop['term'] =~? 'italic' | let term.=(v:version >= 800)? 'italic,': '' | endif
if a:prop['term'] =~? 'standout' | let term.='standout,' | endif
if a:prop['term'] =~? 'NONE' | let term='NONE,' | endif
endif
let term = empty(term)? 'NONE' : term
" workaround for bug in old vim builds
if v:version < 800 && a:group == 'Normal' | let bg_opt = &background | endif
execute 'highlight '.a:group.' cterm='.term.' ctermfg='.fg.' ctermbg='.bg.' gui='.term.' guifg='.guifg.' guibg='.guibg
" workaround for bug in old vim builds
if v:version < 800 && a:group == 'Normal' | let &background = bg_opt | endif
endfunction
function! s:GetColorDict(background) abort
if &t_Co >= 256 || has('gui_running')
if a:background == 'dark'
return s:colordict_dark256
else
return s:colordict_light256
endif
else
return s:colordict_16
endif
endfunction
function! s:CTermToHex(nr) abort
if a:nr == 'NONE'
return 'NONE'
endif
let nr = (a:nr >= 0 && a:nr < 16) ? s:AsciiTo256(a:nr) : a:nr
if nr >= 16 && nr < 232
let idx = nr -16
let r = s:_6ToRGBChannel( (idx) /36 %6 )
let g = s:_6ToRGBChannel( (idx) /6 %6 )
let b = s:_6ToRGBChannel( (idx) %6 )
let hex = printf('#%02x%02x%02x', r, g, b)
return hex
elseif nr >= 232 && nr < 256
let gray = (nr - 232) * 10 + 8
let hex = printf('#%02x%02x%02x', gray, gray, gray)
return hex
end
throw 'Unsupported cterm number: ' .. a:nr
endfunction
function! s:_6ToRGBChannel(nr) abort
return (a:nr == 0)? 0 : 95 + 40 * (a:nr- 1)
endfunction
function! s:AsciiTo256(nr) abort
let color_names = [
\ 'black', 'red_bg', 'green_bg', 'yellow_bg', 'blue_bg', 'purple_bg', 'cyan_bg', 'bw_shade_3',
\ 'bw_shade_1', 'red', 'green', 'yellow', 'blue', 'purple', 'cyan', 'bw_shade_5'
\ ]
if a:nr < 0 || a:nr > 15
throw 'AsciiToHex: Unsupported ascii number: ' .. a:nr
endif
let colordict = (&background == 'dark') ? s:colordict_dark256 : s:colordict_light256
return colordict[color_names[a:nr]]
endfunction
" this file: after/syntax/markdown.vim
let s:ft = expand('<sfile>:t:r')
" nvim loads colorscheme before filetype, vim loads after
if exists('g:colors_name') && g:colors_name == 'feywild'
call feywild_colorscheme#InitFiletype(s:ft)
else
augroup feywild_colorscheme
autocmd ColorScheme feywild ++once call feywild_colorscheme#InitFiletype(s:ft)
augroup END
endif
" this file: after/syntax/tex.vim
let s:ft = expand('<sfile>:t:r')
" nvim loads colorscheme before filetype, vim loads after
if exists('g:colors_name') && g:colors_name == 'feywild'
call feywild_colorscheme#InitFiletype(s:ft)
else
augroup feywild_colorscheme
autocmd ColorScheme feywild ++once call feywild_colorscheme#InitFiletype(s:ft)
augroup END
endif
" this file: after/syntax/vim.vim
let s:ft = expand('<sfile>:t:r')
" nvim loads colorscheme before filetype, vim loads after
if exists('g:colors_name') && g:colors_name == 'feywild'
call feywild_colorscheme#InitFiletype(s:ft)
else
augroup feywild_colorscheme
autocmd ColorScheme feywild ++once call feywild_colorscheme#InitFiletype(s:ft)
augroup END
endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment