Save current colors as loadable colorscheme in vim

How can I save the current colors into a file loadable with :colorscheme in vim?

:hi shows me the colors but not in a form that is loadable as color scheme.

Upvotes: 3

Views: 767

Answers (3)

Thanks to the answer from Matt I wrote the following script. Let's call it save_colorscheme.vim.

This script can be used to save the current colors. To use, open a new buffer and :source save_colorscheme.vim.

If g:save_all_highlights is set to 1 before sourcing the script, all highlight colors known by vim are listed, otherwise save the one listed in s:names defined in the script.

Change the line with g:colors_name to give a reasonable name.

" If g:save_all_highlights is 1, save all highlight colors known by vim,
" otherwise save the one listed in s:names below.
if exists('g:save_all_highlights')
  let s:save_all_highlights = g:save_all_highlights
else
  let s:save_all_highlights = 0
endif

" List of hightlights from
" https://github.com/ggalindezb/vim_colorscheme_template/blob/master/template.vim
" plus highlights for diff files
" https://github.com/ggalindezb/vim_colorscheme_template/issues/1.
let s:names = [
      \ 'Normal',
      \ 'Cursor',
      \ 'CursorLine',
      \ 'LineNr',
      \ 'CursorLineNR',
      \ 'CursorColumn',
      \ 'FoldColumn',
      \ 'SignColumn',
      \ 'Folded',
      \ 'VertSplit',
      \ 'ColorColumn',
      \ 'TabLine',
      \ 'TabLineFill',
      \ 'TabLineSel',
      \ 'Directory',
      \ 'Search',
      \ 'IncSearch',
      \ 'StatusLine',
      \ 'StatusLineNC',
      \ 'WildMenu',
      \ 'Question',
      \ 'Title',
      \ 'ModeMsg',
      \ 'MoreMsg',
      \ 'MatchParen',
      \ 'Visual',
      \ 'VisualNOS',
      \ 'NonText',
      \ 'Todo',
      \ 'Underlined',
      \ 'Error',
      \ 'ErrorMsg',
      \ 'WarningMsg',
      \ 'Ignore',
      \ 'SpecialKey',
      \ 'Constant',
      \ 'String',
      \ 'StringDelimiter',
      \ 'Character',
      \ 'Number',
      \ 'Boolean',
      \ 'Float',
      \ 'Identifier',
      \ 'Function',
      \ 'Statement',
      \ 'Conditional',
      \ 'Repeat',
      \ 'Label',
      \ 'Operator',
      \ 'Keyword',
      \ 'Exception',
      \ 'Comment',
      \ 'Special',
      \ 'SpecialChar',
      \ 'Tag',
      \ 'Delimiter',
      \ 'SpecialComment',
      \ 'Debug',
      \ 'PreProc',
      \ 'Include',
      \ 'Define',
      \ 'Macro',
      \ 'PreCondit',
      \ 'Type',
      \ 'StorageClass',
      \ 'Structure',
      \ 'Typedef',
      \ 'DiffAdd',
      \ 'DiffChange',
      \ 'DiffDelete',
      \ 'DiffText',
      \ 'diffAdded',
          \ 'diffChanged',
          \ 'diffRemoved',
          \ 'diffLine',
      \ 'Pmenu',
      \ 'PmenuSel',
      \ 'PmenuSbar',
      \ 'PmenuThumb',
      \ 'SpellBad',
      \ 'SpellCap',
      \ 'SpellLocal',
      \ 'SpellRare',
      \]

" Preamble.
call append('$', printf('" Set ''background'' back to the default.  The value can''t always be estimated'))
call append('$', printf('" and is then guessed.'))
call append('$', printf('hi clear Normal'))
call append('$', printf('set background&'))
call append('$', printf(''))
call append('$', printf('" Remove all existing highlighting and set the defaults.'))
call append('$', printf('hi clear'))
call append('$', printf(''))
call append('$', printf('" Load the syntax highlighting defaults, if it''s enabled.'))
call append('$', printf('if exists("syntax_on")'))
call append('$', printf('  syntax reset'))
call append('$', printf('endif'))
call append('$', printf(''))

if (s:save_all_highlights == 1)
  let s:names = getcompletion('', 'highlight')
endif

for s:name in s:names
  let s:id = hlID(s:name)
  let s:tid = synIDtrans(s:id)

  if (s:id != s:tid)
    call append('$', printf('hi link %s %s', s:name, synIDattr(s:tid, 'name')))
  else
    let s:cterm = 'none'
    if (synIDattr(s:id, 'bold', 'cterm') == '1')
      let s:cterm = 'bold'
    elseif (synIDattr(s:id, 'italic', 'cterm') == '1')
      let s:cterm = 'italic'
    elseif (synIDattr(s:id, 'reverse', 'cterm') == '1')
      let s:cterm = 'reverse'
    elseif (synIDattr(s:id, 'inverse', 'cterm') == '1')
      let s:cterm = 'reverse'
    elseif (synIDattr(s:id, 'standout', 'cterm') == '1')
      let s:cterm = 'standout'
    elseif (synIDattr(s:id, 'underline', 'cterm') == '1')
      let s:cterm = 'underline'
    elseif (synIDattr(s:id, 'undercurl', 'cterm') == '1')
      let s:cterm = 'undercurl'
    elseif (synIDattr(s:id, 'strikethrough', 'cterm') == '1')
      let s:cterm = 'strikethrough'
    endif
    if (synIDattr(s:id, 'fg', 'cterm') != '')
      let s:ctermfg = synIDattr(s:id, 'fg', 'cterm')
    else
      let s:ctermfg = 'none'
    endif
    if (synIDattr(s:id, 'bg', 'cterm') != '')
      let s:ctermbg = synIDattr(s:id, 'bg', 'cterm')
    else
      let s:ctermbg = 'none'
    endif
    call append('$', printf('hi %s cterm=%s ctermfg=%s ctermbg=%s', s:name, s:cterm, s:ctermfg, s:ctermbg))
  endif
endfor

call append('$', printf(''))
call append('$', 'let g:colors_name = ''autosaved''')

Upvotes: 1

Matt
Matt

Reputation: 15206

The ingredients you'll need: :h getcompletion() :h hlID() :h synIDattr() and :h synIDtrans()

Start with getting all highlight groups names: let names = getcompletion('', 'highlight').

To get numeric IDs: let id = hlID(name) and let tid = synIDtrans(id)

If id != tid then it's a "linked" group, so the command is printf('hi link %s %s', name, synIDattr(tid, 'name'))

Otherwise, you have to query all possible combinations of synIDattr(id, what, mode) and then compose a command hi <name> <non-empty-attrs>. As it looks like a particularly tedious task, it's "left as an excercise to a reader" ;-)

Putting script output into a buffer in Vim is trivial: new then call append('$', printf(...)) and so on. Be careful though not to forget to add on top of your "colorscheme script" a "standard preamble" (hi clear and stuff), otherwise the colors will get messed up with existing ones.

Upvotes: 2

Cyans
Cyans

Reputation: 34

If you want to create a color theme, you should look at the included color files.

For example this file, vim installation path "...\Vim\vim81\colors\pablo.vim", this is a text file, It can be opened with vim.

The content format looks like this:

"......
"These are instructions
"......

hi clear
set background = dark
if exists ("syntax_on")
   syntax reset
endif
let g: colors_name = "pablo" "this is point, :colorscheme command needs this name to define.

"Here is the color definition code
hi color_group_name guifg=color_code guibg=color_code gui=none or bold
hi ...more color definition code

You can create your own color.vim file in this format, save it to '...\Vim\vim81\colors\colorname.vim' folder, and then you can use it.

:colorscheme your_colorname

Upvotes: 0

Related Questions