├── .gitignore
├── .gitmodules
├── Makefile
├── README.md
├── autoload
├── hexokinase.vim
└── hexokinase
│ ├── checker.vim
│ ├── highlighters
│ ├── background.vim
│ ├── backgroundfull.vim
│ ├── foreground.vim
│ ├── foregroundfull.vim
│ ├── sign_column.vim
│ └── virtual.vim
│ ├── patterns
│ ├── colour_names.vim
│ ├── full_hex.vim
│ ├── rgb.vim
│ ├── rgba.vim
│ └── triple_hex.vim
│ ├── utils.vim
│ ├── v1.vim
│ ├── v2.vim
│ └── v2
│ └── scraper.vim
├── doc
└── hexokinase.txt
├── lua
└── hexokinase.lua
├── plugin
└── hexokinase.vim
├── screenshot_colours.txt
└── test_colours.txt
/.gitignore:
--------------------------------------------------------------------------------
1 | sample_colours*
2 | gif_colours.txt
3 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "hexokinase"]
2 | path = hexokinase
3 | url = https://github.com/RRethy/hexokinase.git
4 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | .PHONY: hexokinase
2 | hexokinase:
3 | git submodule init && git submodule update && cd hexokinase/ && go build
4 |
5 | .PHONY: clean
6 | clean:
7 | rm -rf hexokinase/
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # vim-hexokinase
2 |
3 | The fastest (Neo)Vim plugin for asynchronously displaying the colours in the file (#rrggbb, #rgb, rgb(a)? functions, hsl(a)? functions, web colours, custom patterns)
4 |
5 | > let g:Hexokinase_highlighters = ['virtual']
6 |
7 | 
8 |
9 | > let g:Hexokinase_highlighters = ['sign_column']
10 |
11 | 
12 |
13 | > set signcolumn=yes:9 " Neovim only
14 |
15 |
16 |
17 | > let g:Hexokinase_highlighters = ['foreground']
18 |
19 |
20 |
21 | > let g:Hexokinase_highlighters = ['foregroundfull']
22 |
23 |
24 |
25 | > let g:Hexokinase_highlighters = ['background']
26 |
27 |
28 |
29 | > let g:Hexokinase_highlighters = ['backgroundfull']
30 |
31 |
32 |
33 | ## Rationale
34 |
35 | **Problem:** [Colorizer](https://github.com/chrisbra/Colorizer) and [Colorizer](https://github.com/lilydjwg/colorizer) are plugins which also display the colour of text. However, they do so by changing the background of the text which is not pleasing to look at. On top of that, they all scrape the file synchronously.
36 |
37 | **Solution:** Have 6 different options for displaying colour, including as virtual text or in the sign column. As well, do all scraping asynchronously.
38 |
39 | ## About
40 |
41 | This plugin can display the colour of 6 digit hex codes, 3 digit hex codes, rgb functions, rgba functions, hsl functions, hsla functions, and custom patterns.
42 |
43 | Colour can be displayed in each of the 6 six ways shown above, or can be customized to display colour any way the user chooses.
44 |
45 | **Note:** By default all filetypes are scraped and highlighted on `['TextChanged', 'InsertLeave', 'BufRead']`, see `:h g:Hexokinase_refreshEvents` for more info.
46 |
47 | ## Requirements
48 |
49 | - `:h 'termguicolors'` must be turned on and your terminal must support it
50 | - **Golang must be installed, for more information visit https://golang.org/doc/install.**
51 | - For *virtual text*: Neovim 0.3.2
52 | - For *sign_column*: Vim compiled with `+signs` or any Neovim version
53 | - Currently, untested on Windows, help is welcomed.
54 |
55 | ## Installation
56 |
57 | 1. Install Golang https://golang.org/doc/install
58 | 2. Install the plugin with the plugin manager of choice and ensure `make hexokinase` is executed in the project root:
59 |
60 | ```vim
61 | " vim-plug
62 | Plug 'rrethy/vim-hexokinase', { 'do': 'make hexokinase' }
63 |
64 | " minpac
65 | call minpac#add('rrethy/vim-hexokinase', { 'do': 'make hexokinase' })
66 |
67 | " dein
68 | call dein#add('rrethy/vim-hexokinase', { 'build': 'make hexokinase' })
69 |
70 | " etc.
71 | ```
72 |
73 | 3. `:set termguicolors`
74 |
75 | ## Quick Start
76 |
77 | Choose your method of highlighting:
78 |
79 | ```vim
80 | " Neovim default
81 | let g:Hexokinase_highlighters = [ 'virtual' ]
82 |
83 | " Vim default
84 | let g:Hexokinase_highlighters = [ 'sign_column' ]
85 |
86 | " All possible highlighters
87 | let g:Hexokinase_highlighters = [
88 | \ 'virtual',
89 | \ 'sign_column',
90 | \ 'background',
91 | \ 'backgroundfull',
92 | \ 'foreground',
93 | \ 'foregroundfull'
94 | \ ]
95 | ```
96 |
97 | Choose which patterns are matched:
98 |
99 | ```vim
100 | " Patterns to match for all filetypes
101 | " Can be a comma separated string or a list of strings
102 | " Default value:
103 | let g:Hexokinase_optInPatterns = 'full_hex,rgb,rgba,hsl,hsla,colour_names'
104 |
105 | " All possible values
106 | let g:Hexokinase_optInPatterns = [
107 | \ 'full_hex',
108 | \ 'triple_hex',
109 | \ 'rgb',
110 | \ 'rgba',
111 | \ 'hsl',
112 | \ 'hsla',
113 | \ 'colour_names'
114 | \ ]
115 |
116 | " Filetype specific patterns to match
117 | " entry value must be comma seperated list
118 | let g:Hexokinase_ftOptInPatterns = {
119 | \ 'css': 'full_hex,rgb,rgba,hsl,hsla,colour_names',
120 | \ 'html': 'full_hex,rgb,rgba,hsl,hsla,colour_names'
121 | \ }
122 | ```
123 |
124 | Choose which filetypes to scrape automatically (by default ALL filetypes are scraped):
125 |
126 | ```vim
127 | " Sample value, to keep default behaviour don't define this variable
128 | let g:Hexokinase_ftEnabled = ['css', 'html', 'javascript']
129 | ```
130 |
131 | ## Commands
132 |
133 | | Command | Description |
134 | |---|---|
135 | | **HexokinaseToggle** | Toggle the colouring |
136 | | **HexokinaseTurnOn** | Turn on colouring (refresh if already turned on) |
137 | | **HexokinaseTurnOff** | Turn off colouring |
138 |
139 | ## Full Configuration
140 |
141 | See `:help hexokinase.txt`
142 |
143 | ## Custom Patterns
144 |
145 | See `:help g:Hexokinase_palettes`.
146 |
147 | This can be used to colour specific variables.
148 |
149 | ## FAQ
150 |
151 | > I'm seeing grey colours when I toggle vim-hexokinase
152 |
153 | You need `termguicolors` to be turned on. Verify `:set termguicolors?` outputs `termguicolors`. For more info, see https://github.com/RRethy/vim-hexokinase/issues/10.
154 |
--------------------------------------------------------------------------------
/autoload/hexokinase.vim:
--------------------------------------------------------------------------------
1 | " This file is for v1, v2 is all in the subdirectories
2 |
3 | fun! hexokinase#toggle_scraping() abort
4 | let b:hexokinase_scraper_on = !get(b:, 'hexokinase_scraper_on', 0)
5 | let g:Hexokinase_silent = get(g:, 'Hexokinase_silent', 0)
6 | if b:hexokinase_scraper_on
7 | call hexokinase#scrape_colours()
8 | if !g:Hexokinase_silent
9 | echo 'Turned on highlighting'
10 | endif
11 | else
12 | call hexokinase#tear_down()
13 | if !g:Hexokinase_silent
14 | echo 'Turned off highlighting'
15 | endif
16 | endif
17 | endf
18 |
19 | fun! hexokinase#on_autoload_ft_set() abort
20 | let b:hexokinase_scraper_on = !get(b:, 'hexokinase_scraper_on', 0)
21 | if b:hexokinase_scraper_on
22 | call hexokinase#scrape_colours()
23 | endif
24 | endf
25 |
26 | fun! hexokinase#scrape_colours() abort
27 | let lnum = 1
28 | " Builds a map of patterns to processors
29 | let pattern_processor_map = hexokinase#utils#get_pat_proc_map()
30 | " Builds a regex that handles all colour patterns
31 | let pattern = hexokinase#utils#get_colour_pattern(keys(pattern_processor_map))
32 |
33 | for lnum in range(1, line('$'))
34 |
35 | let line_text = getline(lnum)
36 | let n = 1
37 | let colorsInfo = []
38 |
39 | let [colourMatch,start,end] = matchstrpos(line_text, pattern, 0, n)
40 | " Try to process the colour to a six digit hex code
41 | while colourMatch !=# ''
42 | let processed = 0
43 | for pattern_regex in keys(pattern_processor_map)
44 | if colourMatch =~# '^' . pattern_regex . '$'
45 | " Call the appropriate pocessor to get a six digit hex or empty str
46 | let colourMatch = pattern_processor_map[pattern_regex](colourMatch)
47 | if !empty(colourMatch)
48 | let processed = 1
49 | break
50 | endif
51 | endif
52 | endfor
53 |
54 | if processed
55 | call add(colorsInfo, [colourMatch, start, end])
56 | endif
57 | let n += 1
58 | let [colourMatch,start,end] = matchstrpos(line_text, pattern, 0, n)
59 | endwhile
60 |
61 | " Reverse such that the last highlighting is the first color and thus
62 | " can overwrite other highlighting (sign_column, virtual)
63 | " https://github.com/RRethy/vim-hexokinase/issues/12
64 | call reverse(colorsInfo)
65 |
66 | for [colourMatch,start,end] in colorsInfo
67 | " Create the highlight group
68 | let hl_name = 'hexokinaseHighlight'.strpart(colourMatch, 1)
69 | exe 'hi '.hl_name.' guifg='.colourMatch
70 | for F in g:Hexokinase_highlightCallbacks
71 | call F(lnum, colourMatch, hl_name, start + 1, end)
72 | endfor
73 | endfor
74 | endfor
75 | endf
76 |
77 | fun! hexokinase#tear_down() abort
78 | for F in g:Hexokinase_tearDownCallbacks
79 | call F()
80 | endfor
81 | endf
82 |
--------------------------------------------------------------------------------
/autoload/hexokinase/checker.vim:
--------------------------------------------------------------------------------
1 | " Experimental and unused currently
2 | finish
3 |
4 | fun! hexokinase#checker#check() abort
5 | call s:cancel_cur_job()
6 |
7 | let tmpname = hexokinase#utils#tmpname()
8 | let fail = writefile(getbufline(bufnr('%'), 1, '$'), tmpname)
9 | if !fail
10 | let opts = {
11 | \ 'tmpname': tmpname,
12 | \ 'on_exit': function('s:on_exit'),
13 | \ 'bufnr': bufnr('%'),
14 | \ }
15 | let cmd = printf('%s -check=%s ', g:Hexokinase_executable_path, tmpname)
16 | let cmd .= hexokinase#utils#getPatModifications()
17 | if !empty(g:Hexokinase_palettes)
18 | let cmd .= ' -palettes='.join(g:Hexokinase_palettes, ',')
19 | endif
20 | let b:hexokinase_job_id = jobstart(cmd, opts)
21 | endif
22 | endf
23 |
24 | fun! s:on_exit(id, status, event) abort dict
25 | call delete(self.tmpname)
26 | if !a:status
27 | if bufnr('%') == self.bufnr
28 | call hexokinase#v2#scraper#on()
29 | endif
30 | endif
31 | endf
32 |
33 | fun! s:cancel_cur_job() abort
34 | let b:hexokinase_checker_job_id = get(b:, 'hexokinase_checker_job_id', -1)
35 | try
36 | call chanclose(b:hexokinase_checker_job_id)
37 | catch /E900/
38 | endtry
39 | endf
40 |
--------------------------------------------------------------------------------
/autoload/hexokinase/highlighters/background.vim:
--------------------------------------------------------------------------------
1 | let s:isNvim040 = exists('*nvim_buf_add_highlight')
2 | if s:isNvim040
3 | let s:namespace = nvim_create_namespace('')
4 | endif
5 |
6 | if !s:isNvim040
7 | augroup hexokinase_background_autocmds
8 | autocmd!
9 | " TODO figure out how many of these can be cut down on
10 | autocmd BufEnter,BufWinEnter,WinNew,TabNew,BufNew,BufAdd * call s:showhl()
11 | augroup END
12 |
13 | fun! s:showhl() abort
14 | call s:hidehl()
15 | for it in get(b:, 'hexokinase_colours', [])
16 | if has_key(it, 'bg_check')
17 | let id = matchaddpos(it.hlname, it.positions)
18 | call add(w:hexokinase_bg_match_ids, id)
19 | endif
20 | endfor
21 | endf
22 |
23 | fun! s:hidehl() abort
24 | for it in get(w:, 'hexokinase_bg_match_ids', [])
25 | try
26 | call matchdelete(it)
27 | catch /\v(E803|E802)/
28 | endtry
29 | endfor
30 | let w:hexokinase_bg_match_ids = []
31 | endf
32 | end
33 |
34 | fun! hexokinase#highlighters#background#highlightv2(bufnr) abort
35 | for it in getbufvar(a:bufnr, 'hexokinase_colours', [])
36 | let it['hlname'] = hexokinase#utils#create_bg_hl(it.hex)
37 | let buflines = getbufline(a:bufnr, it.lnum)
38 | if len(buflines) == 0
39 | continue
40 | endif
41 | let line = buflines[0]
42 |
43 | if s:isNvim040
44 | let positions = []
45 |
46 | if line[it.end - 1] ==# ')'
47 | let [_, _, first_char] = matchstrpos(line, '(', it.start)
48 | let positions = [
49 | \ {
50 | \ 'col_start': str2nr(first_char)-1,
51 | \ 'col_end': str2nr(first_char)
52 | \ },
53 | \ {
54 | \ 'col_start': str2nr(it.end)-1,
55 | \ 'col_end': str2nr(it.end)
56 | \ }
57 | \ ]
58 | elseif line[it.start - 1] ==# '#'
59 | let positions = [
60 | \ {
61 | \ 'col_start': str2nr(it.start)-1,
62 | \ 'col_end': str2nr(it.start)
63 | \ }
64 | \ ]
65 | else
66 | let positions = [
67 | \ {
68 | \ 'col_start': str2nr(it.start)-1,
69 | \ 'col_end': str2nr(it.end)
70 | \ }
71 | \ ]
72 | endif
73 |
74 | for pos in positions
75 | call nvim_buf_add_highlight(
76 | \ a:bufnr,
77 | \ s:namespace,
78 | \ it.hlname,
79 | \ str2nr(it.lnum)-1,
80 | \ pos.col_start,
81 | \ pos.col_end,
82 | \ )
83 | endfor
84 | else
85 | if line[it.end - 1] ==# ')'
86 | let [_, _, first_char] = matchstrpos(line, '(', it.start)
87 | let it['positions'] = [[it.lnum, first_char, 1], [it.lnum, it.end, 1]]
88 | elseif line[it.start - 1] ==# '#'
89 | let it['positions'] = [[it.lnum, it.start, 1]]
90 | else
91 | let it['positions'] = [[it.lnum, it.start, it.end - it.start + 1]]
92 | endif
93 |
94 | let it['bg_check'] = 1
95 | endif
96 | endfor
97 |
98 | if a:bufnr == bufnr('%') && !s:isNvim040
99 | call s:showhl()
100 | endif
101 | endf
102 |
103 | fun! hexokinase#highlighters#background#tearDownv2(bufnr) abort
104 | if s:isNvim040
105 | if !bufexists(a:bufnr)
106 | return
107 | endif
108 |
109 | if exists('*nvim_buf_clear_namespace')
110 | call nvim_buf_clear_namespace(a:bufnr, s:namespace, 0, -1)
111 | endif
112 | else
113 | let b:hexokinase_colours = []
114 | if a:bufnr == bufnr('%')
115 | call s:hidehl()
116 | endif
117 | endif
118 | endf
119 |
120 | fun! hexokinase#highlighters#background#highlight(lnum, hex, hl_name, start, end) abort
121 | let b:bg_match_ids = get(b:, 'bg_match_ids', [])
122 | if getline(a:lnum)[a:end - 1] ==# ')'
123 | let [_, _, first_char] = matchstrpos(getline(a:lnum), '(', a:start)
124 | call add(b:bg_match_ids, matchaddpos(a:hl_name, [[a:lnum, first_char, 1], [a:lnum, a:end, 1]]))
125 | else
126 | call add(b:bg_match_ids, matchaddpos(a:hl_name, [[a:lnum, a:start, 1]]))
127 | endif
128 | endf
129 |
130 | fun! hexokinase#highlighters#background#tearDown() abort
131 | let b:bg_match_ids = get(b:, 'bg_match_ids', [])
132 | for id in b:bg_match_ids
133 | try
134 | call matchdelete(id)
135 | catch /\v(E803|E802)/
136 | endtry
137 | endfor
138 | let b:bbgmatch_ids = []
139 | endf
140 |
--------------------------------------------------------------------------------
/autoload/hexokinase/highlighters/backgroundfull.vim:
--------------------------------------------------------------------------------
1 | let s:isNvim040 = exists('*nvim_buf_add_highlight')
2 | if s:isNvim040
3 | let s:namespace = nvim_create_namespace('')
4 | endif
5 |
6 | if !s:isNvim040
7 | augroup hexokinase_backgroundfull_autocmds
8 | autocmd!
9 | " TODO figure out how many of these can be cut down on
10 | autocmd BufEnter,BufWinEnter,WinNew,TabNew,BufNew,BufAdd * call s:showhl()
11 | augroup END
12 |
13 | fun! s:showhl() abort
14 | call s:hidehl()
15 | for it in get(b:, 'hexokinase_colours', [])
16 | if has_key(it, 'bgfull_check')
17 | let id = matchaddpos(it.hlname, it.positions)
18 | call add(w:hexokinase_bgfull_match_ids, id)
19 | endif
20 | endfor
21 | endf
22 |
23 | fun! s:hidehl() abort
24 | for it in get(w:, 'hexokinase_bgfull_match_ids', [])
25 | try
26 | call matchdelete(it)
27 | catch /\v(E803|E802)/
28 | endtry
29 | endfor
30 | let w:hexokinase_bgfull_match_ids = []
31 | endf
32 | end
33 |
34 | fun! hexokinase#highlighters#backgroundfull#highlightv2(bufnr) abort
35 | for it in getbufvar(a:bufnr, 'hexokinase_colours', [])
36 | let it['hlname'] = hexokinase#utils#create_bg_hl(it.hex)
37 | if s:isNvim040
38 | call nvim_buf_add_highlight(
39 | \ a:bufnr,
40 | \ s:namespace,
41 | \ it.hlname,
42 | \ str2nr(it.lnum)-1,
43 | \ str2nr(it.start)-1,
44 | \ str2nr(it.end)
45 | \ )
46 | else
47 | let it['positions'] = [[it.lnum, it.start, it.end - it.start + 1]]
48 | let it['bgfull_check'] = 1
49 | endif
50 | endfor
51 |
52 | if a:bufnr == bufnr('%') && !s:isNvim040
53 | call s:showhl()
54 | endif
55 | endf
56 |
57 | fun! hexokinase#highlighters#backgroundfull#tearDownv2(bufnr) abort
58 | if s:isNvim040
59 | if !bufexists(a:bufnr)
60 | return
61 | endif
62 |
63 | if exists('*nvim_buf_clear_namespace')
64 | call nvim_buf_clear_namespace(a:bufnr, s:namespace, 0, -1)
65 | endif
66 | else
67 | let b:hexokinase_colours = []
68 | if a:bufnr == bufnr('%')
69 | call s:hidehl()
70 | endif
71 | endif
72 | endf
73 |
74 | fun! hexokinase#highlighters#backgroundfull#highlight(lnum, hex, hl_name, start, end) abort
75 | let b:bgfull_match_ids = get(b:, 'bgfull_match_ids', [])
76 | call add(b:bgfull_match_ids, matchaddpos(a:hl_name, [[a:lnum, a:start, a:end - a:start + 1]]))
77 | endf
78 |
79 | fun! hexokinase#highlighters#backgroundfull#tearDown() abort
80 | let b:bgfull_match_ids = get(b:, 'bgfull_match_ids', [])
81 | for id in b:bgfull_match_ids
82 | try
83 | call matchdelete(id)
84 | catch /\v(E803|E802)/
85 | endtry
86 | endfor
87 | let b:bgfull_match_ids = []
88 | endf
89 |
--------------------------------------------------------------------------------
/autoload/hexokinase/highlighters/foreground.vim:
--------------------------------------------------------------------------------
1 | let s:isNvim040 = exists('*nvim_buf_add_highlight')
2 | if s:isNvim040
3 | let s:namespace = nvim_create_namespace('')
4 | endif
5 |
6 | if !s:isNvim040
7 | augroup hexokinase_foreground_autocmds
8 | autocmd!
9 | " TODO figure out how many of these can be cut down on
10 | autocmd BufEnter,BufWinEnter,WinNew,TabNew,BufNew,BufAdd * call s:showhl()
11 | augroup END
12 |
13 | fun! s:showhl() abort
14 | call s:hidehl()
15 | for it in get(b:, 'hexokinase_colours', [])
16 | if has_key(it, 'fg_check')
17 | let id = matchaddpos(it.hlname, it.positions)
18 | call add(w:hexokinase_fg_match_ids, id)
19 | endif
20 | endfor
21 | endf
22 |
23 | fun! s:hidehl() abort
24 | for it in get(w:, 'hexokinase_fg_match_ids', [])
25 | try
26 | call matchdelete(it)
27 | catch /\v(E803|E802)/
28 | endtry
29 | endfor
30 | let w:hexokinase_fg_match_ids = []
31 | endf
32 | end
33 |
34 | fun! hexokinase#highlighters#foreground#highlightv2(bufnr) abort
35 | for it in getbufvar(a:bufnr, 'hexokinase_colours', [])
36 | let it['hlname'] = hexokinase#utils#create_fg_hl(it.hex)
37 | let buflines = getbufline(a:bufnr, it.lnum)
38 | if len(buflines) == 0
39 | continue
40 | endif
41 | let line = buflines[0]
42 |
43 | if s:isNvim040
44 | let positions = []
45 |
46 | if line[it.end - 1] ==# ')'
47 | let [_, _, first_char] = matchstrpos(line, '(', it.start)
48 | let positions = [
49 | \ {
50 | \ 'col_start': str2nr(first_char)-1,
51 | \ 'col_end': str2nr(first_char)
52 | \ },
53 | \ {
54 | \ 'col_start': str2nr(it.end)-1,
55 | \ 'col_end': str2nr(it.end)
56 | \ }
57 | \ ]
58 | elseif line[it.start - 1] ==# '#'
59 | let positions = [
60 | \ {
61 | \ 'col_start': str2nr(it.start)-1,
62 | \ 'col_end': str2nr(it.start)
63 | \ }
64 | \ ]
65 | else
66 | let positions = [
67 | \ {
68 | \ 'col_start': str2nr(it.start)-1,
69 | \ 'col_end': str2nr(it.end)
70 | \ }
71 | \ ]
72 | endif
73 |
74 | for pos in positions
75 | call nvim_buf_add_highlight(
76 | \ a:bufnr,
77 | \ s:namespace,
78 | \ it.hlname,
79 | \ str2nr(it.lnum)-1,
80 | \ pos.col_start,
81 | \ pos.col_end,
82 | \ )
83 | endfor
84 | else
85 | if line[it.end - 1] ==# ')'
86 | let [_, _, first_char] = matchstrpos(line, '(', it.start)
87 | let it['positions'] = [[it.lnum, first_char, 1], [it.lnum, it.end, 1]]
88 | elseif line[it.start - 1] ==# '#'
89 | let it['positions'] = [[it.lnum, it.start, 1]]
90 | else
91 | let it['positions'] = [[it.lnum, it.start, it.end - it.start + 1]]
92 | endif
93 |
94 | let it['fg_check'] = 1
95 | endif
96 | endfor
97 |
98 | if a:bufnr == bufnr('%') && !s:isNvim040
99 | call s:showhl()
100 | endif
101 | endf
102 |
103 | fun! hexokinase#highlighters#foreground#tearDownv2(bufnr) abort
104 | if s:isNvim040
105 | if !bufexists(a:bufnr)
106 | return
107 | endif
108 |
109 | if exists('*nvim_buf_clear_namespace')
110 | call nvim_buf_clear_namespace(a:bufnr, s:namespace, 0, -1)
111 | endif
112 | else
113 | let b:hexokinase_colours = []
114 | if a:bufnr == bufnr('%')
115 | call s:hidehl()
116 | endif
117 | endif
118 | endf
119 |
120 | fun! hexokinase#highlighters#foreground#highlight(lnum, hex, hl_name, start, end) abort
121 | let b:fg_match_ids = get(b:, 'fg_match_ids', [])
122 | if getline(a:lnum)[a:end - 1] ==# ')'
123 | let [_, _, first_char] = matchstrpos(getline(a:lnum), '(', a:start)
124 | call add(b:fg_match_ids, matchaddpos(a:hl_name, [[a:lnum, first_char, 1], [a:lnum, a:end, 1]]))
125 | else
126 | call add(b:fg_match_ids, matchaddpos(a:hl_name, [[a:lnum, a:start, 1]]))
127 | endif
128 | endf
129 |
130 | fun! hexokinase#highlighters#foreground#tearDown() abort
131 | let b:fg_match_ids = get(b:, 'fg_match_ids', [])
132 | for id in b:fg_match_ids
133 | try
134 | call matchdelete(id)
135 | catch /\v(E803|E802)/
136 | endtry
137 | endfor
138 | let b:fg_match_ids = []
139 | endf
140 |
--------------------------------------------------------------------------------
/autoload/hexokinase/highlighters/foregroundfull.vim:
--------------------------------------------------------------------------------
1 | let s:isNvim040 = exists('*nvim_buf_add_highlight')
2 | if s:isNvim040
3 | let s:namespace = nvim_create_namespace('')
4 | endif
5 |
6 | if !s:isNvim040
7 | augroup hexokinase_foregroundfull_autocmds
8 | autocmd!
9 | " TODO figure out how many of these can be cut down on
10 | autocmd BufEnter,BufWinEnter,WinNew,TabNew,BufNew,BufAdd * call s:showhl()
11 | augroup END
12 |
13 | fun! s:showhl() abort
14 | call s:hidehl()
15 | for it in get(b:, 'hexokinase_colours', [])
16 | if has_key(it, 'fgfull_check')
17 | let id = matchaddpos(it.hlname, it.positions)
18 | call add(w:hexokinase_fgfull_match_ids, id)
19 | endif
20 | endfor
21 | endf
22 |
23 | fun! s:hidehl() abort
24 | for it in get(w:, 'hexokinase_fgfull_match_ids', [])
25 | try
26 | call matchdelete(it)
27 | catch /\v(E803|E802)/
28 | endtry
29 | endfor
30 | let w:hexokinase_fgfull_match_ids = []
31 | endf
32 | end
33 |
34 | fun! hexokinase#highlighters#foregroundfull#highlightv2(bufnr) abort
35 | for it in getbufvar(a:bufnr, 'hexokinase_colours', [])
36 | let it['hlname'] = hexokinase#utils#create_fg_hl(it.hex)
37 | if s:isNvim040
38 | call nvim_buf_add_highlight(
39 | \ a:bufnr,
40 | \ s:namespace,
41 | \ it.hlname,
42 | \ str2nr(it.lnum)-1,
43 | \ str2nr(it.start)-1,
44 | \ str2nr(it.end)
45 | \ )
46 | else
47 | let it['positions'] = [[it.lnum, it.start, it.end - it.start + 1]]
48 | let it['fgfull_check'] = 1
49 | endif
50 | endfor
51 |
52 | if a:bufnr == bufnr('%') && !s:isNvim040
53 | call s:showhl()
54 | endif
55 | endf
56 |
57 | fun! hexokinase#highlighters#foregroundfull#tearDownv2(bufnr) abort
58 | if s:isNvim040
59 | if !bufexists(a:bufnr)
60 | return
61 | endif
62 |
63 | if exists('*nvim_buf_clear_namespace')
64 | call nvim_buf_clear_namespace(a:bufnr, s:namespace, 0, -1)
65 | endif
66 | else
67 | let b:hexokinase_colours = []
68 | if a:bufnr == bufnr('%')
69 | call s:hidehl()
70 | endif
71 | endif
72 | endf
73 |
74 | fun! hexokinase#highlighters#foregroundfull#highlight(lnum, hex, hl_name, start, end) abort
75 | let b:fgfull_match_ids = get(b:, 'fgfull_match_ids', [])
76 | call add(b:fgfull_match_ids, matchaddpos(a:hl_name, [[a:lnum, a:start, a:end - a:start + 1]]))
77 | endf
78 |
79 | fun! hexokinase#highlighters#foregroundfull#tearDown() abort
80 | let b:fgfull_match_ids = get(b:, 'fgfull_match_ids', [])
81 | for id in b:fgfull_match_ids
82 | try
83 | call matchdelete(id)
84 | catch /\v(E803|E802)/
85 | endtry
86 | endfor
87 | let b:fgfull_match_ids = []
88 | endf
89 |
--------------------------------------------------------------------------------
/autoload/hexokinase/highlighters/sign_column.vim:
--------------------------------------------------------------------------------
1 | let s:group_prefix = 'hexokinase-sign_column'
2 |
3 | fun! s:signs_api_hl(bufnr) abort
4 | let n = 0
5 | for it in getbufvar(a:bufnr, 'hexokinase_colours', [])
6 | let it['hlname'] = hexokinase#utils#create_fg_hl(it.hex)
7 |
8 | let sign_name = it.hlname . 'sign'
9 | let sign_id = 4000 + n
10 | let n += 1
11 | call sign_define(sign_name,
12 | \ {
13 | \ 'text': g:Hexokinase_signIcon,
14 | \ 'texthl': it.hlname,
15 | \ }
16 | \ )
17 | call sign_place(
18 | \ sign_id,
19 | \ s:group_prefix.string(a:bufnr),
20 | \ sign_name,
21 | \ a:bufnr,
22 | \ { 'lnum': it.lnum }
23 | \ )
24 | endfor
25 | endf
26 |
27 | fun! s:signs_api_tear_down(bufnr) abort
28 | if !bufexists(a:bufnr)
29 | return
30 | endif
31 |
32 | call sign_unplace(s:group_prefix.string(a:bufnr))
33 | endf
34 |
35 | fun! s:signs_command_hl(bufnr) abort
36 | let sign_ids = []
37 | for it in getbufvar(a:bufnr, 'hexokinase_colours', [])
38 | let it['hlname'] = hexokinase#utils#create_fg_hl(it.hex)
39 |
40 | let sign_name = it.hlname . 'sign'
41 | let sign_id = 4000 + it.lnum
42 | exe 'sign define ' . sign_name . ' text=' . g:Hexokinase_signIcon . ' texthl=' . it.hlname
43 | exe 'sign place ' . sign_id . ' line=' . it.lnum . ' name=' . sign_name . ' buffer=' . a:bufnr
44 |
45 | call add(sign_ids, sign_id)
46 | endfor
47 | call setbufvar(a:bufnr, 'sign_ids', sign_ids)
48 | endf
49 |
50 | fun! s:signs_command_tear_down(bufnr) abort
51 | if !bufexists(a:bufnr)
52 | return
53 | endif
54 |
55 | let sign_ids = getbufvar(a:bufnr, 'sign_ids', [])
56 | for sign_id in sign_ids
57 | exe 'sign unplace ' . sign_id . ' buffer=' . a:bufnr
58 | endfor
59 |
60 | call setbufvar(a:bufnr, 'sign_ids', [])
61 | endf
62 |
63 | fun! hexokinase#highlighters#sign_column#highlightv2(bufnr) abort
64 | if exists('*sign_place')
65 | call s:signs_api_hl(a:bufnr)
66 | else
67 | call s:signs_command_hl(a:bufnr)
68 | endif
69 | endf
70 |
71 | fun! hexokinase#highlighters#sign_column#tearDownv2(bufnr) abort
72 | if exists('*sign_place')
73 | call s:signs_api_tear_down(a:bufnr)
74 | else
75 | call s:signs_command_tear_down(a:bufnr)
76 | endif
77 | endf
78 |
79 | fun! hexokinase#highlighters#sign_column#highlight(lnum, hex, hl_name, start, end) abort
80 | let b:sign_ids = get(b:, 'sign_ids', [])
81 |
82 | let sign_name = a:hl_name . 'sign'
83 | let sign_id = 4000 + a:lnum
84 | exe 'sign define ' . sign_name . ' text=' . g:Hexokinase_signIcon . ' texthl=' . a:hl_name
85 | exe 'sign place ' . sign_id . ' line=' . a:lnum . ' name=' . sign_name . ' buffer=' . bufnr('%')
86 |
87 | call add(b:sign_ids, sign_id)
88 | endf
89 |
90 | fun! hexokinase#highlighters#sign_column#tearDown() abort
91 | call hexokinase#highlighters#sign_column#tearDownv2(bufnr('%'))
92 | endf
93 |
--------------------------------------------------------------------------------
/autoload/hexokinase/highlighters/virtual.vim:
--------------------------------------------------------------------------------
1 | if exists('*nvim_create_namespace')
2 | let s:namespace = nvim_create_namespace('')
3 | else
4 | echoerr 'virtual highlighting only works with Neovim v0.3.2 - please upgrade'
5 | finish
6 | endif
7 |
8 | fun! hexokinase#highlighters#virtual#highlightv2(bufnr) abort
9 | for it in getbufvar(a:bufnr, 'hexokinase_colours', [])
10 | let it['hlname'] = hexokinase#utils#create_fg_hl(it.hex)
11 |
12 | let chunks = [[g:Hexokinase_virtualText, it.hlname]]
13 | if exists('*nvim_buf_get_virtual_text')
14 | let chunks += nvim_buf_get_virtual_text(a:bufnr, it.lnum - 1)
15 | elseif exists('*nvim_buf_get_extmarks')
16 | let set_chunks = nvim_buf_get_extmarks(
17 | \ a:bufnr,
18 | \ s:namespace,
19 | \ [it.lnum - 1, 0],
20 | \ [it.lnum - 1, 0],
21 | \ {'details': v:true}
22 | \ )
23 | if !empty(set_chunks)
24 | let chunks += set_chunks[0][3].virt_text
25 | endif
26 | endif
27 | call nvim_buf_set_virtual_text(
28 | \ a:bufnr,
29 | \ s:namespace,
30 | \ it.lnum - 1,
31 | \ chunks,
32 | \ {}
33 | \ )
34 | endfor
35 | endf
36 |
37 | fun! hexokinase#highlighters#virtual#tearDownv2(bufnr) abort
38 | if !bufexists(a:bufnr)
39 | return
40 | endif
41 |
42 | if exists('*nvim_buf_clear_namespace')
43 | call nvim_buf_clear_namespace(a:bufnr, s:namespace, 0, -1)
44 | endif
45 | endf
46 |
47 | fun! hexokinase#highlighters#virtual#highlight(lnum, hex, hl_name, start, end) abort
48 | if exists('*nvim_buf_set_virtual_text')
49 | let chunks = [[g:Hexokinase_virtualText, a:hl_name]]
50 | if exists('*nvim_buf_get_virtual_text')
51 | let chunks += nvim_buf_get_virtual_text(bufnr('%'), a:lnum - 1)
52 | endif
53 | call nvim_buf_set_virtual_text(
54 | \ bufnr('%'),
55 | \ s:namespace,
56 | \ a:lnum - 1,
57 | \ chunks,
58 | \ {}
59 | \ )
60 | endif
61 | endf
62 |
63 | fun! hexokinase#highlighters#virtual#tearDown() abort
64 | call hexokinase#highlighters#virtual#tearDownv2(bufnr('%'))
65 | endf
66 |
--------------------------------------------------------------------------------
/autoload/hexokinase/patterns/colour_names.vim:
--------------------------------------------------------------------------------
1 | " see: https://www.w3schools.com/colors/colors_names.asp // 2019-04-11
2 | let s:colours = {
3 | \ 'aliceblue': '#f0f8ff',
4 | \ 'antiquewhite': '#faebd7',
5 | \ 'aqua': '#00ffff',
6 | \ 'aquamarine': '#7fffd4',
7 | \ 'azure': '#f0ffff',
8 | \ 'beige': '#f5f5dc',
9 | \ 'bisque': '#ffe4c4',
10 | \ 'black': '#000000',
11 | \ 'blanchedalmond': '#ffebcd',
12 | \ 'blue': '#0000ff',
13 | \ 'blueviolet': '#8a2be2',
14 | \ 'brown': '#a52a2a',
15 | \ 'burlywood': '#deb887',
16 | \ 'cadetblue': '#5f9ea0',
17 | \ 'chartreuse': '#7fff00',
18 | \ 'chocolate': '#d2691e',
19 | \ 'coral': '#ff7f50',
20 | \ 'cornflowerblue': '#6495ed',
21 | \ 'cornsilk': '#fff8dc',
22 | \ 'crimson': '#dc143c',
23 | \ 'cyan': '#00ffff',
24 | \ 'darkblue': '#00008b',
25 | \ 'darkcyan': '#008b8b',
26 | \ 'darkgoldenrod': '#b8860b',
27 | \ 'darkgray': '#a9a9a9',
28 | \ 'darkgrey': '#a9a9a9',
29 | \ 'darkgreen': '#006400',
30 | \ 'darkkhaki': '#bdb76b',
31 | \ 'darkmagenta': '#8b008b',
32 | \ 'darkolivegreen': '#556b2f',
33 | \ 'darkorange': '#ff8c00',
34 | \ 'darkorchid': '#9932cc',
35 | \ 'darkred': '#8b0000',
36 | \ 'darksalmon': '#e9967a',
37 | \ 'darkseagreen': '#8fbc8f',
38 | \ 'darkslateblue': '#483d8b',
39 | \ 'darkslategray': '#2f4f4f',
40 | \ 'darkslategrey': '#2f4f4f',
41 | \ 'darkturquoise': '#00ced1',
42 | \ 'darkviolet': '#9400d3',
43 | \ 'deeppink': '#ff1493',
44 | \ 'deepskyblue': '#00bfff',
45 | \ 'dimgray': '#696969',
46 | \ 'dimgrey': '#696969',
47 | \ 'dodgerblue': '#1e90ff',
48 | \ 'firebrick': '#b22222',
49 | \ 'floralwhite': '#fffaf0',
50 | \ 'forestgreen': '#228b22',
51 | \ 'fuchsia': '#ff00ff',
52 | \ 'gainsboro': '#dcdcdc',
53 | \ 'ghostwhite': '#f8f8ff',
54 | \ 'gold': '#ffd700',
55 | \ 'goldenrod': '#daa520',
56 | \ 'gray': '#808080',
57 | \ 'grey': '#808080',
58 | \ 'green': '#008000',
59 | \ 'greenyellow': '#adff2f',
60 | \ 'honeydew': '#f0fff0',
61 | \ 'hotpink': '#ff69b4',
62 | \ 'indianred': '#cd5c5c',
63 | \ 'indigo': '#4b0082',
64 | \ 'ivory': '#fffff0',
65 | \ 'khaki': '#f0e68c',
66 | \ 'lavender': '#e6e6fa',
67 | \ 'lavenderblush': '#fff0f5',
68 | \ 'lawngreen': '#7cfc00',
69 | \ 'lemonchiffon': '#fffacd',
70 | \ 'lightblue': '#add8e6',
71 | \ 'lightcoral': '#f08080',
72 | \ 'lightcyan': '#e0ffff',
73 | \ 'lightgoldenrodyellow': '#fafad2',
74 | \ 'lightgray': '#d3d3d3',
75 | \ 'lightgrey': '#d3d3d3',
76 | \ 'lightgreen': '#90ee90',
77 | \ 'lightpink': '#ffb6c1',
78 | \ 'lightsalmon': '#ffa07a',
79 | \ 'lightseagreen': '#20b2aa',
80 | \ 'lightskyblue': '#87cefa',
81 | \ 'lightslategray': '#778899',
82 | \ 'lightslategrey': '#778899',
83 | \ 'lightsteelblue': '#b0c4de',
84 | \ 'lightyellow': '#ffffe0',
85 | \ 'lime': '#00ff00',
86 | \ 'limegreen': '#32cd32',
87 | \ 'linen': '#faf0e6',
88 | \ 'magenta': '#ff00ff',
89 | \ 'maroon': '#800000',
90 | \ 'mediumaquamarine': '#66cdaa',
91 | \ 'mediumblue': '#0000cd',
92 | \ 'mediumorchid': '#ba55d3',
93 | \ 'mediumpurple': '#9370db',
94 | \ 'mediumseagreen': '#3cb371',
95 | \ 'mediumslateblue': '#7b68ee',
96 | \ 'mediumspringgreen': '#00fa9a',
97 | \ 'mediumturquoise': '#48d1cc',
98 | \ 'mediumvioletred': '#c71585',
99 | \ 'midnightblue': '#191970',
100 | \ 'mintcream': '#f5fffa',
101 | \ 'mistyrose': '#ffe4e1',
102 | \ 'moccasin': '#ffe4b5',
103 | \ 'navajowhite': '#ffdead',
104 | \ 'navy': '#000080',
105 | \ 'oldlace': '#fdf5e6',
106 | \ 'olive': '#808000',
107 | \ 'olivedrab': '#6b8e23',
108 | \ 'orange': '#ffa500',
109 | \ 'orangered': '#ff4500',
110 | \ 'orchid': '#da70d6',
111 | \ 'palegoldenrod': '#eee8aa',
112 | \ 'palegreen': '#98fb98',
113 | \ 'paleturquoise': '#afeeee',
114 | \ 'palevioletred': '#db7093',
115 | \ 'papayawhip': '#ffefd5',
116 | \ 'peachpuff': '#ffdab9',
117 | \ 'peru': '#cd853f',
118 | \ 'pink': '#ffc0cb',
119 | \ 'plum': '#dda0dd',
120 | \ 'powderblue': '#b0e0e6',
121 | \ 'purple': '#800080',
122 | \ 'rebeccapurple': '#663399',
123 | \ 'red': '#ff0000',
124 | \ 'rosybrown': '#bc8f8f',
125 | \ 'royalblue': '#4169e1',
126 | \ 'saddlebrown': '#8b4513',
127 | \ 'salmon': '#fa8072',
128 | \ 'sandybrown': '#f4a460',
129 | \ 'seagreen': '#2e8b57',
130 | \ 'seashell': '#fff5ee',
131 | \ 'sienna': '#a0522d',
132 | \ 'silver': '#c0c0c0',
133 | \ 'skyblue': '#87ceeb',
134 | \ 'slateblue': '#6a5acd',
135 | \ 'slategray': '#708090',
136 | \ 'slategrey': '#708090',
137 | \ 'snow': '#fffafa',
138 | \ 'springgreen': '#00ff7f',
139 | \ 'steelblue': '#4682b4',
140 | \ 'tan': '#d2b48c',
141 | \ 'teal': '#008080',
142 | \ 'thistle': '#d8bfd8',
143 | \ 'tomato': '#ff6347',
144 | \ 'turquoise': '#40e0d0',
145 | \ 'violet': '#ee82ee',
146 | \ 'wheat': '#f5deb3',
147 | \ 'white': '#ffffff',
148 | \ 'whitesmoke': '#f5f5f5',
149 | \ 'yellow': '#ffff00',
150 | \ 'yellowgreen': '#9acd32'
151 | \ }
152 |
153 | function! hexokinase#patterns#colour_names#get_pattern() abort
154 | return '\c\<\(' . join(keys(s:colours), '\|') . '\)\>'
155 | endfunction
156 |
157 | function! hexokinase#patterns#colour_names#process(str) abort
158 | let str_lcase = tolower(a:str)
159 | if has_key(s:colours, str_lcase)
160 | return s:colours[str_lcase]
161 | else
162 | return ''
163 | endif
164 | endfunction
165 |
--------------------------------------------------------------------------------
/autoload/hexokinase/patterns/full_hex.vim:
--------------------------------------------------------------------------------
1 | fun! hexokinase#patterns#full_hex#get_pattern() abort
2 | return '#\x\{6}'
3 | endf
4 |
5 | fun! hexokinase#patterns#full_hex#process(str) abort
6 | return a:str
7 | endf
8 |
--------------------------------------------------------------------------------
/autoload/hexokinase/patterns/rgb.vim:
--------------------------------------------------------------------------------
1 | let s:REGEX_NUM = '\d\{1,3}'
2 | let s:REGEX_PERCENTAGE = s:REGEX_NUM.'%'
3 |
4 | fun! hexokinase#patterns#rgb#get_pattern() abort
5 | let val = '\('.s:REGEX_NUM.'\|'.s:REGEX_PERCENTAGE.'\)'
6 | let _ = '\s*'
7 | return 'rgb('._.val._.','._.val._.','._.val._.')'
8 | endf
9 |
10 | fun! hexokinase#patterns#rgb#process(str) abort
11 | let [r, g, b] = hexokinase#patterns#rgb#rgb_str_to_nums(a:str)
12 | if !hexokinase#utils#valid_rgb([r, g, b])
13 | return ''
14 | endif
15 | return hexokinase#utils#rgb_to_hex([r, g, b])
16 | endf
17 |
18 | fun! hexokinase#patterns#rgb#rgb_str_to_nums(rgb_str) abort
19 | let r = s:get_formatted_value('(', ',', a:rgb_str)
20 | let g = s:get_formatted_value(',', ',', a:rgb_str)
21 | let b = s:get_formatted_value(',', ')', a:rgb_str)
22 | return [r, g, b]
23 | endf
24 |
25 | fun! s:get_formatted_value(prefix, postfix, str) abort
26 | let _ = '\s*'
27 | if match(a:str, a:prefix._.s:REGEX_NUM._.a:postfix) != -1
28 | return str2nr(matchstr(a:str, a:prefix._.'\zs'.s:REGEX_NUM.'\ze'._.a:postfix))
29 | else
30 | return str2nr(matchstr(a:str, a:prefix._.'\zs'.s:REGEX_NUM.'\ze'.'%'._.a:postfix)) * 255 / 100
31 | endif
32 | endf
33 |
--------------------------------------------------------------------------------
/autoload/hexokinase/patterns/rgba.vim:
--------------------------------------------------------------------------------
1 | let s:REGEX_NUM = '\d\{1,3}'
2 | let s:REGEX_PERCENTAGE = s:REGEX_NUM.'%'
3 |
4 | fun! hexokinase#patterns#rgba#get_pattern() abort
5 | let val = '\('.s:REGEX_NUM.'\|'.s:REGEX_PERCENTAGE.'\)'
6 | let regex_alpha = '\([01]\|[01]\.\d\)'
7 | let _ = '\s*'
8 | return 'rgba('._.val._.','._.val._.','._.val._.','._.regex_alpha._.')'
9 | endf
10 |
11 | fun! hexokinase#patterns#rgba#process(str) abort
12 | let val = '\('.s:REGEX_NUM.'\|'.s:REGEX_PERCENTAGE.'\)'
13 | let _ = '\s*'
14 | let [old_r, old_g, old_b] = hexokinase#patterns#rgb#rgb_str_to_nums(
15 | \ matchstr(a:str, '('._.val._.','._.val._.','._.val._) . ')'
16 | \ )
17 | let alpha = str2float(matchstr(a:str, ',\s*\zs\([01]\|[01]\.\d\)\ze\s*)'))
18 | let alpha = alpha > 1.0 ? 1.0 : alpha
19 | if !hexokinase#utils#valid_rgb([old_r, old_g, old_b]) || alpha == 0.0
20 | return ''
21 | endif
22 |
23 | return hexokinase#utils#rgb_to_hex(
24 | \ hexokinase#utils#apply_alpha_to_rgb(
25 | \ [old_r, old_g, old_b], alpha
26 | \ )
27 | \)
28 | endf
29 |
--------------------------------------------------------------------------------
/autoload/hexokinase/patterns/triple_hex.vim:
--------------------------------------------------------------------------------
1 | fun! hexokinase#patterns#triple_hex#get_pattern() abort
2 | return '\<#\x\{3}\>'
3 | endf
4 |
5 | fun! hexokinase#patterns#triple_hex#process(str) abort
6 | return '#' . a:str[1] . a:str[1] . a:str[2] . a:str[2] . a:str[3] . a:str[3]
7 | endf
8 |
--------------------------------------------------------------------------------
/autoload/hexokinase/utils.vim:
--------------------------------------------------------------------------------
1 | let s:hexadecimals = ['0', '1', '2', '3',
2 | \ '4', '5', '6', '7',
3 | \ '8', '9', 'A', 'B',
4 | \ 'C', 'D', 'E', 'F']
5 |
6 | fun! hexokinase#utils#get_colour_pattern(patterns_list) abort
7 | return '\%\(' . join(a:patterns_list, '\|') . '\)'
8 | endf
9 |
10 | " Combine the filetype specific pattern/processor map with the global one
11 | fun! hexokinase#utils#get_pat_proc_map() abort
12 | let pattern_processor_map = {}
13 | if has_key(g:Hexokinase_ft_patterns, &filetype)
14 | call extend(pattern_processor_map, g:Hexokinase_ft_patterns[&filetype])
15 | endif
16 | call extend(pattern_processor_map, g:Hexokinase_patterns)
17 | return pattern_processor_map
18 | endf
19 |
20 | " rgbList should be a list of numbers
21 | fun! hexokinase#utils#rgb_to_hex(rgbList) abort
22 | let r = a:rgbList[0]
23 | let g = a:rgbList[1]
24 | let b = a:rgbList[2]
25 | let hex = '#'
26 | let hex .= s:hexadecimals[r / 16]
27 | let hex .= s:hexadecimals[r % 16]
28 | let hex .= s:hexadecimals[g / 16]
29 | let hex .= s:hexadecimals[g % 16]
30 | let hex .= s:hexadecimals[b / 16]
31 | let hex .= s:hexadecimals[b % 16]
32 | return hex
33 | endf
34 |
35 | " returns a list of numbers
36 | fun! hexokinase#utils#hex_to_rgb(hex) abort
37 | let raw_hex = [0, 0, 0, 0, 0, 0]
38 | for i in range(1, 6)
39 | let raw_hex[i - 1] = index(s:hexadecimals, toupper(a:hex[i]))
40 | endfor
41 | let r = (raw_hex[0] * 16) + raw_hex[1]
42 | let g = (raw_hex[2] * 16) + raw_hex[3]
43 | let b = (raw_hex[4] * 16) + raw_hex[5]
44 | return [r, g, b]
45 | endf
46 |
47 | fun! hexokinase#utils#get_background_rgb() abort
48 | return hexokinase#utils#hex_to_rgb(hexokinase#utils#get_background_hex())
49 | endf
50 |
51 | fun! hexokinase#utils#get_background_hex() abort
52 | if !empty(get(g:, 'Hexokinase_alpha_bg', ''))
53 | return g:Hexokinase_alpha_bg
54 | elseif len(g:Hexokinase_highlighters) == 1 && g:Hexokinase_highlighters[0] ==# 'sign_column'
55 | return synIDattr(hlID('SignColumn'), 'bg')
56 | else
57 | return synIDattr(hlID('Normal'), 'bg')
58 | endif
59 | endf
60 |
61 | fun! hexokinase#utils#valid_rgb(rgbList) abort
62 | let [r, g, b] = a:rgbList
63 | if r > 255 || r < 0 || g > 255 || g < 0 || b > 255 || b < 0
64 | return 0
65 | else
66 | return 1
67 | endif
68 | endf
69 |
70 | fun! hexokinase#utils#apply_alpha_to_rgb(primary_rgb, alpha) abort
71 | let [bg_r, bg_g, bg_b] = hexokinase#utils#get_background_rgb()
72 | let [old_r, old_g, old_b] = a:primary_rgb
73 |
74 | let new_r = float2nr(bg_r + ((old_r - bg_r) * a:alpha))
75 | let new_g = float2nr(bg_g + ((old_g - bg_g) * a:alpha))
76 | let new_b = float2nr(bg_b + ((old_b - bg_b) * a:alpha))
77 | return [new_r, new_g, new_b]
78 | endf
79 |
80 | fun! hexokinase#utils#tmpname() abort
81 | let l:clear_tempdir = 0
82 |
83 | if exists('$TMPDIR') && empty($TMPDIR)
84 | let l:clear_tempdir = 1
85 | let $TMPDIR = '/tmp'
86 | endif
87 |
88 | try
89 | let l:name = tempname()
90 | finally
91 | if l:clear_tempdir
92 | let $TMPDIR = ''
93 | endif
94 | endtry
95 |
96 | return l:name
97 | endf
98 |
99 | fun! hexokinase#utils#getPatModifications() abort
100 | if has_key(g:Hexokinase_ftOptOutPatterns, &filetype)
101 | let dp = g:Hexokinase_ftOptOutPatterns[&filetype]
102 | if type(dp) == 1
103 | return ['-dp', substitute(dp, '\s', '', 'g')]
104 | elseif type(dp) == 3
105 | return ['-dp', join(dp, ',')]
106 | else
107 | echohl Error | echom printf('ERROR: g:Hexokinase_ftOptOutPatterns[%s] must be a string or a list', &filetype) | echohl None
108 | endif
109 | elseif has_key(g:Hexokinase_ftOptInPatterns, &filetype)
110 | let ep = g:Hexokinase_ftOptInPatterns[&filetype]
111 | if type(ep) == 1
112 | return ['-ep', substitute(ep, '\s', '', 'g')]
113 | elseif type(ep) == 3
114 | return ['-ep', join(ep, ',')]
115 | else
116 | echohl Error | echom printf('ERROR: g:Hexokinase_ftOptInPatterns[%s] must be a string or a list', &filetype) | echohl None
117 | endif
118 | elseif !empty(g:Hexokinase_optOutPatterns)
119 | if type(g:Hexokinase_optOutPatterns) == 1
120 | return ['-dp', substitute(g:Hexokinase_optOutPatterns, '\s', '', 'g')]
121 | elseif type(g:Hexokinase_optOutPatterns) == 3
122 | return ['-dp', join(g:Hexokinase_optOutPatterns, ',')]
123 | else
124 | echohl Error | echom 'ERROR: g:Hexokinase_optOutPatterns must be a string or a list' | echohl None
125 | endif
126 | elseif !empty(g:Hexokinase_optInPatterns)
127 | if type(g:Hexokinase_optInPatterns) == 1
128 | return ['-ep', substitute(g:Hexokinase_optInPatterns, '\s', '', 'g')]
129 | elseif type(g:Hexokinase_optInPatterns) == 3
130 | return ['-ep', join(g:Hexokinase_optInPatterns, ',')]
131 | else
132 | echohl Error | echom 'ERROR: g:Hexokinase_optInPatterns must be a string or a list' | echohl None
133 | endif
134 | endif
135 | return []
136 | endf
137 |
138 | fun! hexokinase#utils#create_fg_hl(hex) abort
139 | let hlname = 'v2hexokinaseHighlight'.strpart(a:hex, 1)
140 | exe 'hi '.hlname.' guifg='.a:hex
141 | return hlname
142 | endf
143 |
144 | fun! hexokinase#utils#create_bg_hl(hex) abort
145 | let hlname = 'v2hexokinaseHighlight_withfg'.strpart(a:hex, 1)
146 | let [r, g, b] = hexokinase#utils#hex_to_rgb(a:hex)
147 | " This calculation is from the following:
148 | " https://www.w3.org/TR/WCAG20/#relativeluminancedef
149 | if 0.2126 * r + 0.7152 * g + 0.0722 * b > 179
150 | let fg = '#000000'
151 | else
152 | let fg = '#ffffff'
153 | endif
154 | exe 'hi '.hlname.' guibg='.a:hex.' guifg='.fg
155 | return hlname
156 | endf
157 |
--------------------------------------------------------------------------------
/autoload/hexokinase/v1.vim:
--------------------------------------------------------------------------------
1 | scriptencoding utf-8
2 |
3 | fun! hexokinase#v1#setup() abort
4 | if has('nvim')
5 | let g:Hexokinase_highlighters = get(g:, 'Hexokinase_highlighters', ['virtual'])
6 | else
7 | let g:Hexokinase_highlighters = get(g:, 'Hexokinase_highlighters', ['sign_column'])
8 | endif
9 |
10 | let g:Hexokinase_virtualText = get(g:, 'Hexokinase_virtualText', '■')
11 | let g:Hexokinase_signIcon = get(g:, 'Hexokinase_signIcon', '■')
12 |
13 | " initialize various patterns that are supported by default
14 | let g:Hexokinase_optInPatterns = get(g:, 'Hexokinase_optInPatterns', ['full_hex', 'triple_hex', 'rgb', 'rgba'])
15 | let g:Hexokinase_patterns = get(g:, 'Hexokinase_patterns', {})
16 | for pat in g:Hexokinase_optInPatterns
17 | if pat ==# 'full_hex'
18 | let g:Hexokinase_patterns[hexokinase#patterns#full_hex#get_pattern()] = function('hexokinase#patterns#full_hex#process')
19 | elseif pat ==# 'triple_hex'
20 | let g:Hexokinase_patterns[hexokinase#patterns#triple_hex#get_pattern()] = function('hexokinase#patterns#triple_hex#process')
21 | elseif pat ==# 'rgb'
22 | let g:Hexokinase_patterns[hexokinase#patterns#rgb#get_pattern()] = function('hexokinase#patterns#rgb#process')
23 | elseif pat ==# 'rgba'
24 | let g:Hexokinase_patterns[hexokinase#patterns#rgba#get_pattern()] = function('hexokinase#patterns#rgba#process')
25 | elseif pat =~# 'colou\?r_names'
26 | let g:Hexokinase_patterns[hexokinase#patterns#colour_names#get_pattern()] = function('hexokinase#patterns#colour_names#process')
27 | endif
28 | endfor
29 |
30 | let g:Hexokinase_ft_patterns = get(g:, 'Hexokinase_ft_patterns', {})
31 |
32 | let g:Hexokinase_builtinHighlighters = get(g:, 'Hexokinase_builtinHighlighters', ['virtual', 'sign_column', 'background', 'foreground', 'foregroundfull'])
33 |
34 | " initialize various highlighters
35 | let g:Hexokinase_highlightCallbacks = get(g:, 'Hexokinase_highlightCallbacks', [])
36 | let g:Hexokinase_tearDownCallbacks = get(g:, 'Hexokinase_tearDownCallbacks', [])
37 | for mode in g:Hexokinase_highlighters
38 | if index(g:Hexokinase_builtinHighlighters, mode) >= 0
39 | call add(g:Hexokinase_highlightCallbacks, function('hexokinase#highlighters#' . mode . '#highlight'))
40 | call add(g:Hexokinase_tearDownCallbacks, function('hexokinase#highlighters#' . mode . '#tearDown'))
41 | endif
42 | endfor
43 |
44 | command! HexokinaseToggle call hexokinase#toggle_scraping()
45 | command! HexokinaseRefresh call hexokinase#tear_down() | call hexokinase#scrape_colours()
46 |
47 | let g:Hexokinase_refreshEvents = get(g:, 'Hexokinase_refreshEvents', ['BufWritePost'])
48 | let g:Hexokinase_ftAutoload = get(g:, 'Hexokinase_ftAutoload', [])
49 |
50 | if has('autocmd')
51 | augroup hexokinase_autocmds
52 | autocmd!
53 | for event in g:Hexokinase_refreshEvents
54 | exe 'autocmd '.event.' * call s:on_refresh_event()'
55 | endfor
56 | if !empty(g:Hexokinase_ftAutoload)
57 | exe 'autocmd FileType '.join(g:Hexokinase_ftAutoload, ',').' call hexokinase#on_autoload_ft_set()'
58 | endif
59 | augroup END
60 | endif
61 |
62 | fun! s:on_refresh_event() abort
63 | if exists('b:hexokinase_scraper_on') && b:hexokinase_scraper_on
64 | HexokinaseRefresh
65 | endif
66 | endf
67 |
68 | fun! s:toggle() abort
69 | HexokinaseToggle
70 | endf
71 | endf
72 |
--------------------------------------------------------------------------------
/autoload/hexokinase/v2.vim:
--------------------------------------------------------------------------------
1 | scriptencoding utf-8
2 |
3 | fun! hexokinase#v2#setup() abort
4 | if has('nvim')
5 | let g:Hexokinase_highlighters = get(g:, 'Hexokinase_highlighters', ['virtual'])
6 | else
7 | let g:Hexokinase_highlighters = get(g:, 'Hexokinase_highlighters', ['sign_column'])
8 | endif
9 | if len(g:Hexokinase_highlighters) == 1 && g:Hexokinase_highlighters[0] == 'sign_column' && &signcolumn == 'no'
10 | echom "[vim-hexokinase] You seem to be using sign_column for highlighting but 'signcolumn' is set to 'no', try enabling it to see colours."
11 | endif
12 |
13 | let g:Hexokinase_virtualText = get(g:, 'Hexokinase_virtualText', '■')
14 | let g:Hexokinase_signIcon = get(g:, 'Hexokinase_signIcon', '■')
15 |
16 | let g:Hexokinase_optOutPatterns = get(g:, 'Hexokinase_optOutPatterns', '')
17 | let g:Hexokinase_optInPatterns = get(g:, 'Hexokinase_optInPatterns', 'full_hex,rgb,rgba,hsl,hsla,colour_names')
18 | let g:Hexokinase_ftOptOutPatterns = get(g:, 'Hexokinase_ftOptOutPatterns', {})
19 | let g:Hexokinase_ftOptInPatterns = get(g:, 'Hexokinase_ftOptInPatterns', {})
20 | let g:Hexokinase_palettes = get(g:, 'Hexokinase_palettes', [])
21 |
22 | let g:Hexokinase_builtinHighlighters = get(g:, 'Hexokinase_builtinHighlighters', [
23 | \ 'virtual',
24 | \ 'sign_column',
25 | \ 'background',
26 | \ 'backgroundfull',
27 | \ 'foreground',
28 | \ 'foregroundfull'
29 | \ ])
30 | let g:Hexokinase_highlightCallbacks = get(g:, 'Hexokinase_highlightCallbacks', [])
31 | let g:Hexokinase_tearDownCallbacks = get(g:, 'Hexokinase_tearDownCallbacks', [])
32 | for highlighter in g:Hexokinase_highlighters
33 | if index(g:Hexokinase_builtinHighlighters, highlighter) >= 0
34 | call add(g:Hexokinase_highlightCallbacks, function('hexokinase#highlighters#' . highlighter . '#highlightv2'))
35 | call add(g:Hexokinase_tearDownCallbacks, function('hexokinase#highlighters#' . highlighter . '#tearDownv2'))
36 | endif
37 | endfor
38 |
39 | command! HexokinaseToggle call hexokinase#v2#scraper#toggle()
40 | command! HexokinaseTurnOn call hexokinase#v2#scraper#on()
41 | command! HexokinaseTurnOff call hexokinase#v2#scraper#off()
42 |
43 | let g:Hexokinase_refreshEvents = get(g:, 'Hexokinase_refreshEvents', ['TextChanged', 'InsertLeave', 'BufRead'])
44 | let g:Hexokinase_ftDisabled = get(g:, 'Hexokinase_ftDisabled', [])
45 | let g:Hexokinase_termDisabled = get(g:, 'Hexokinase_termDisabled', 0)
46 |
47 | augroup hexokinase_autocmds
48 | autocmd!
49 | exe 'autocmd '.join(g:Hexokinase_refreshEvents, ',').' * call s:on_refresh_event()'
50 | autocmd ColorScheme * call s:on_refresh_event()
51 | augroup END
52 | endf
53 |
54 | fun! s:on_refresh_event() abort
55 | let b:hexokinase_is_on = get(b:, 'hexokinase_is_on', 0)
56 | let b:hexokinase_is_disabled = get(b:, 'hexokinase_is_disabled', 0)
57 | if b:hexokinase_is_on
58 | call hexokinase#v2#scraper#on()
59 | return
60 | endif
61 |
62 | if b:hexokinase_is_disabled
63 | return
64 | endif
65 |
66 | if g:Hexokinase_termDisabled && &buftype ==# 'terminal'
67 | return
68 | endif
69 |
70 | if !empty(g:Hexokinase_ftDisabled)
71 | if index(g:Hexokinase_ftDisabled, &filetype) > -1
72 | return
73 | endif
74 | elseif has_key(g:, 'Hexokinase_ftEnabled')
75 | if index(g:Hexokinase_ftEnabled, &filetype) == -1
76 | return
77 | endif
78 | endif
79 |
80 | call hexokinase#v2#scraper#on()
81 | endf
82 |
--------------------------------------------------------------------------------
/autoload/hexokinase/v2/scraper.vim:
--------------------------------------------------------------------------------
1 | " Used for Vim because it has a shit api
2 | let s:chan_infos = {}
3 |
4 | fun! hexokinase#v2#scraper#toggle() abort
5 | let b:hexokinase_is_on = get(b:, 'hexokinase_is_on', 0)
6 | if b:hexokinase_is_on
7 | call hexokinase#v2#scraper#off()
8 | else
9 | call hexokinase#v2#scraper#on()
10 | endif
11 | endf
12 |
13 | fun! hexokinase#v2#scraper#on() abort
14 | call s:cancel_cur_job()
15 |
16 | let b:hexokinase_is_on = 1
17 | let b:hexokinase_is_disabled = 0
18 | let tmpname = hexokinase#utils#tmpname()
19 | let fail = writefile(getbufline(bufnr('%'), 1, '$'), tmpname)
20 | if fail
21 | let b:hexokinase_is_on = 0
22 | else
23 | if has('nvim')
24 | let opts = {
25 | \ 'tmpname': tmpname,
26 | \ 'on_stdout': function('s:on_stdout'),
27 | \ 'on_stderr': function('s:on_stderr'),
28 | \ 'on_exit': function('s:on_exit'),
29 | \ 'bufnr': bufnr('%'),
30 | \ 'colours': []
31 | \ }
32 | else
33 | let opts = {
34 | \ 'out_cb': function('s:on_stdout_vim'),
35 | \ 'close_cb': function('s:on_exit_vim'),
36 | \ }
37 | endif
38 | let cmd = [g:Hexokinase_executable_path, '-simplified', '-files', tmpname]
39 | " Neovim has multiple sign columns, in which case we don't want a
40 | " reversed output.
41 | if get(g:, 'Hexokinase_prioritizeHead', 1)
42 | \ && get(b:, 'Hexokinase_prioritizeHead', 1)
43 | \ && (index(g:Hexokinase_highlighters, 'sign_column') == -1 || &signcolumn !~# '\v(auto|yes):[2-9]')
44 | call add(cmd, '-r')
45 | endif
46 | call extend(cmd, hexokinase#utils#getPatModifications())
47 | call add(cmd, '-bg')
48 | call add(cmd, hexokinase#utils#get_background_hex())
49 | if !empty(g:Hexokinase_palettes)
50 | call add(cmd, '-palettes')
51 | call add(cmd, join(g:Hexokinase_palettes, ','))
52 | endif
53 | if get(g:, 'Hexokinase_checkBoundary', 1)
54 | call add(cmd, '-boundary')
55 | endif
56 |
57 | if has('nvim')
58 | let b:hexokinase_job_id = jobstart(cmd, opts)
59 | else
60 | let b:hexokinase_job = job_start(cmd, opts)
61 | let s:chan_infos[ch_info(job_getchannel(b:hexokinase_job)).id] = {
62 | \ 'tmpname': tmpname,
63 | \ 'colours': [],
64 | \ 'bufnr': bufnr('%')
65 | \ }
66 | endif
67 | endif
68 | endf
69 |
70 | fun! hexokinase#v2#scraper#off() abort
71 | let b:hexokinase_is_on = 0
72 | let b:hexokinase_is_disabled = 1
73 | call s:cancel_cur_job()
74 | call s:clear_hl(bufnr('%'))
75 | endf
76 |
77 | fun! s:clear_hl(bufnr) abort
78 | for F in g:Hexokinase_tearDownCallbacks
79 | call F(a:bufnr)
80 | endfor
81 | endf
82 |
83 | fun! s:cancel_cur_job() abort
84 | try
85 | if has('nvim')
86 | let b:hexokinase_job_id = get(b:, 'hexokinase_job_id', -1)
87 | call chanclose(b:hexokinase_job_id)
88 | else
89 | if has_key(b:, 'hexokinase_job')
90 | call ch_close(b:hexokinase_job)
91 | endif
92 | endif
93 | catch /E90[06]/
94 | endtry
95 | endf
96 |
97 | fun! s:on_stdout_vim(chan, line) abort
98 | let colour = s:parse_colour(a:line)
99 | if !empty(colour)
100 | call add(s:chan_infos[ch_info(a:chan).id].colours, colour)
101 | endif
102 | endf
103 |
104 | fun! s:on_exit_vim(chan) abort
105 | let info = s:chan_infos[ch_info(a:chan).id]
106 | call delete(info.tmpname)
107 | call s:clear_hl(info.bufnr)
108 | call setbufvar(info.bufnr, 'hexokinase_colours', info.colours)
109 | for F in g:Hexokinase_highlightCallbacks
110 | call F(info.bufnr)
111 | endfor
112 | endf
113 |
114 | fun! s:on_stdout(id, data, event) abort dict
115 | for line in a:data
116 | let colour = s:parse_colour(line)
117 | if !empty(colour)
118 | call add(self.colours, colour)
119 | endif
120 | endfor
121 | endf
122 |
123 | fun! s:on_stderr(id, data, event) abort dict
124 | if get(g:, 'Hexokinase_logging', 0)
125 | echohl Error | echom string(a:data) | echohl None
126 | endif
127 | endf
128 |
129 | fun! s:on_exit(id, status, event) abort dict
130 | call delete(self.tmpname)
131 | call s:clear_hl(self.bufnr)
132 | if a:status
133 | return
134 | endif
135 | call setbufvar(self.bufnr, 'hexokinase_colours', self.colours)
136 | for F in g:Hexokinase_highlightCallbacks
137 | call F(self.bufnr)
138 | endfor
139 | endf
140 |
141 | fun! s:parse_colour(line) abort
142 | let parts = split(a:line, ':')
143 | if len(parts) < 4
144 | return ''
145 | endif
146 | " If a system allows `:` inside the filename, then we join together all
147 | " parts before the final 3 (which are guaranteed to be the form
148 | " lnum:col:hex). This allows the filename to remain intact. For example,
149 | " Windows can prefix the filename with the drive (e.g. C:/foo/bar.txt)
150 | let parts = insert(parts[-3:], join(parts[:-4], ':'))
151 |
152 | return { 'lnum': parts[1],
153 | \ 'start': split(parts[2], '-')[0],
154 | \ 'end': split(parts[2], '-')[1],
155 | \ 'hex': parts[3]
156 | \ }
157 | endf
158 |
--------------------------------------------------------------------------------
/doc/hexokinase.txt:
--------------------------------------------------------------------------------
1 | *hexokinase.txt* (Neo)Vim plugin for asynchronously displaying the colour of
2 | hex codes, rgb(a)? functions, hsl(a)? functions, web
3 | colours, and custom patterns
4 |
5 | Author: Adam P. Regasz-Rethy (RRethy)
6 | License: Same terms as Vim itself (see |license|)
7 |
8 | CONTENTS *hexokinase-contents*
9 | ===========================================================================
10 |
11 | Introduction.................................|hexokinase-introduction|
12 | Quick Start..................................|hexokinase-quick-start|
13 | Installation.................................|hexokinase-installation|
14 | Commands.....................................|hexokinase-commands|
15 | Configuration................................|hexokinase-configuration|
16 | Highlighters.............................|g:Hexokinase_highlighters|
17 | Custom Patterns via Palettes ............|g:Hexokinase_palettes|
18 | Patterns To Find ........................|g:Hexokinase_optInPatterns|
19 | Patterns To Ignore ......................|g:Hexokinase_optOutPatterns|
20 | FileType Specific Patterns to Find ......|g:Hexokinase_ftOptInPatterns|
21 | FileType Specific Patterns to Ignore.....|g:Hexokinase_ftOptOutPatterns|
22 | Virtual Text.............................|g:Hexokinase_virtualText|
23 | Sign Column Icon.........................|g:Hexokinase_signIcon|
24 | Refresh Events...........................|g:Hexokinase_refreshEvents|
25 | Disabled TerminalBuffers.................|g:Hexokinase_termDisabled|
26 | Disabled FileTypes.......................|g:Hexokinase_ftDisabled|
27 | Enabled FileTypes........................|g:Hexokinase_ftEnabled|
28 | Background Colour for Alpha Calculations.|g:Hexokinase_alpha_bg|
29 | Use word Boundary........................|g:Hexokinase_checkBoundary|
30 | Create Custom Highlighters...................|hexokinase-custom-highlighters|
31 | Highlight Callback.......................|hexokinase-highlight_callback|
32 | Teardown Callback........................|hexokinase-teardown_callback|
33 | FAQ..........................................|hexokinase-faq|
34 |
35 | INTRODUCTION *hexokinase-introduction*
36 | ===========================================================================
37 |
38 | This plugin will display the colour which corresponds to text on the screen.
39 |
40 | All scraping is done asynchronously via a Golang scraper.
41 |
42 | It can show the colour of 6 digit hex codes, 3 digit hex codes, rgb functions,
43 | rgba functions, hsl functions, hsla functions, web colours
44 | (https://www.w3schools.com/colors/colors_names.asp), and even custom patterns.
45 | See |g:Hexokinase_palettes| for more info on advanced pattern customization.
46 |
47 | This means the following will display a beautiful rainbow (assuming all
48 | patterns enabled):
49 | >
50 | deeppink
51 | #f00
52 | oRaNgE
53 | rgb(255, 255, 0)
54 | rgba(0, 128, 0, 1)
55 | hsl(174,72.1%,56.5%)
56 | hsla(274.6,100%,25.5%, 1)
57 | #ee82ee
58 |
59 | It can display the colour in many different ways, and can be customized to
60 | display it any way you choose. Out of the box, colours can be displayed in the
61 | sign column, as virtual text (only for Neovim), as the foreground colour for
62 | the text (there are two different types of foreground colouring), or as the
63 | background colour of the text (there are also two different types of
64 | background colouring). See |g:Hexokinase_highlighters| for more information.
65 |
66 | Note: |'termguicolors'| must be turned on and your terminal must support it.
67 |
68 | QUICK START *hexokinase-quick-start*
69 | ===========================================================================
70 |
71 | These are the three most basic parts of the plugin to get up and running. #1
72 | is a must, while #2 and #3 already have strong defaults. For more complete
73 | description of the plugin, although verbose, this help file documents
74 | everything.
75 |
76 | 1. Follow |hexokinase-installation|.
77 | 2. Choose your highlighting method, or stick with the default,
78 | |g:Hexokinase_highlighters|.
79 | 3. Choose which patterns are matched, or stick with the default,
80 | |g:Hexokinase_optInPatterns| and |g:Hexokinase_ftOptInPatterns|.
81 |
82 | INSTALLATION *hexokinase-installation*
83 | ===========================================================================
84 |
85 | Golang must be installed, for more information visit
86 | https://golang.org/doc/install.
87 |
88 | Simply run the following in the project root each time the plugin is updated: >
89 | make hexokinase
90 | <
91 | Or alternatively, leverage your plugin manager to run `make hexokinase` on update: >
92 | " vim-plug
93 | Plug 'rrethy/vim-hexokinase', { 'do': 'make hexokinase' }
94 |
95 | " minpac
96 | call minpac#add('rrethy/vim-hexokinase', { 'do': 'make hexokinase' })
97 |
98 | " dein
99 | call dein#add('rrethy/vim-hexokinase', { 'build': 'make hexokinase' })
100 |
101 | " etc.
102 | <
103 | |'termguicolors'| must be turned on and your terminal must support it.
104 |
105 | Note: This has been tested on MacOS. Linux should work as well. Windows is
106 | untested, if you find an issue with Windows, open an issue at
107 | https://github.com/rrethy/vim-hexokinase/issues.
108 |
109 | COMMANDS *hexokinase-commands*
110 | ===========================================================================
111 |
112 | ----------------------+-------------------------------------------------
113 | Command | Description ~
114 | ----------------------+-------------------------------------------------
115 | `HexokinaseToggle` | Toggle the colouring
116 | `HexokinaseTurnOn` | Turn on colouring (refresh if already turned on)
117 | `HexokinaseTurnOff` | Turn off colouring
118 | ----------------------+-------------------------------------------------
119 |
120 | CONFIGURATION *hexokinase-configuration*
121 | ===========================================================================
122 |
123 | Highlighters *g:Hexokinase_highlighters*
124 |
125 | Type: |List| of |String|s
126 | How to display the colour.
127 | Checkout |hexokinase-custom-highlighters| to create your own
128 | highlighter.
129 |
130 | Default value: >
131 | " Neovim default
132 | let g:Hexokinase_highlighters = [ 'virtual' ]
133 |
134 | " Vim default
135 | let g:Hexokinase_highlighters = [ 'sign_column' ]
136 | <
137 | Possible values: >
138 | let g:Hexokinase_highlighters = [
139 | \ 'virtual',
140 | \ 'sign_column',
141 | \ 'background',
142 | \ 'backgroundfull',
143 | \ 'foreground',
144 | \ 'foregroundfull'
145 | \ ]
146 | <
147 | Any combination of them can be used, on top of custom
148 | highlighters.
149 |
150 | "virtual" will use Neovim's virtual text feature
151 | (|nvim_buf_set_virtual_text()|) to display
152 | the colour.
153 |
154 | "sign_column" will use the |'sign_column'| to display the
155 | colour. In Vim, only one colour per line can be displayed.
156 | If you are using Neovim 0.4 or newer that supports multiple
157 | sign columns, the number of colors will respect your
158 | |'sign_column'| settings.
159 |
160 | "background" will highlight the background of certain
161 | characters, such as the parenthesis of various functions or
162 | the hash symbol for hex codes. For web colours it'll just
163 | highlight the whole background.
164 |
165 | "backgroundfull" will highlight the whole background of the
166 | appropriate text.
167 |
168 | "foreground" will act the same as "background", but as the
169 | name suggest, it'll highlight the foreground of the
170 | characters.
171 |
172 | "foregroundfull" will highlight the whole foreground of the
173 | appropriate text.
174 |
175 | Custom Patterns via Palettes *g:Hexokinase_palettes*
176 |
177 | Type: |List| of |String|s
178 | Each string is a path to a file that can be used as a
179 | palette.
180 |
181 | Sample value: >
182 | " must be absolute path
183 | let g:Hexokinase_palettes = [expand($HOME).'/path/to/file']
184 | <
185 | A palette is a json file that looks like the following:
186 | >
187 | {
188 | "regex_pattern": "foo[0-9]bar[0-9]baz[0-9]",
189 | "colour_table": {
190 | "foo1bar1baz1": "#eb00ff",
191 | "foo2bar2baz2": "#ffeb00",
192 | "foo3bar3baz3": "#00ffeb"
193 | }
194 | }
195 | <
196 | If the key "regex_pattern" exists in the top-level, then
197 | hexokinase will look for the regex pattern in the file. Upon
198 | finding a match, it will use the "colour_table" to translate
199 | the match into a hex code. False positives are ignored.
200 |
201 | If the key "regex_pattern" does not exist in the top-level.
202 | Each key in "colour_table" will be looked for. Omitting an
203 | overly complex "regex_pattern" will improve performance, but
204 | it's unlikely to produce a noticeable difference.
205 |
206 | By using a palette, you can highlight variables which refer to
207 | colours in your code.
208 |
209 | Note: "regex_pattern" follows the regex syntax accepted by
210 | RE2, except for \C. For more information see
211 | https://github.com/google/re2/wiki/Syntax. This syntax is
212 | similar to Golang, Perl, Python, etc.. It is NOT Vimscript
213 | style regex.
214 |
215 | Patterns To Find *g:Hexokinase_optInPatterns*
216 |
217 | Type: |List| of |String|s
218 | OR
219 | Comma separated |String| with no spaces
220 | Which patterns to look for.
221 |
222 | Default value: >
223 | let g:Hexokinase_optInPatterns = 'full_hex,rgb,rgba,hsl,hsla,colour_names'
224 | <
225 |
226 | Possible values: >
227 | let g:Hexokinase_optInPatterns = [
228 | \ 'full_hex',
229 | \ 'triple_hex',
230 | \ 'rgb',
231 | \ 'rgba',
232 | \ 'hsl',
233 | \ 'hsla',
234 | \ 'colour_names'
235 | \ ]
236 | <
237 | This option can be overridden by other configuration, this is
238 | the relevant precedence order:
239 | 1. |g:Hexokinase_ftOptOutPatterns|
240 | 2. |g:Hexokinase_ftOptInPatterns|
241 | 3. |g:Hexokinase_optOutPatterns|
242 | 4. |g:Hexokinase_optInPatterns|
243 |
244 | Patterns To Ignore *g:Hexokinase_optOutPatterns*
245 |
246 | Type: |List| of |String|s
247 | OR
248 | Comma separated |String| with no spaces
249 | Which patterns to ignore.
250 |
251 | Default value: >
252 | let g:Hexokinase_optInPatterns = ''
253 | <
254 |
255 | Possible values: >
256 | let g:Hexokinase_optOutPatterns = [
257 | \ 'full_hex',
258 | \ 'triple_hex',
259 | \ 'rgb',
260 | \ 'rgba',
261 | \ 'hsl',
262 | \ 'hsla',
263 | \ 'colour_names'
264 | \ ]
265 | <
266 | This option can be overridden by other configuration, this is
267 | the relevant precedence order:
268 | 1. |g:Hexokinase_ftOptOutPatterns|
269 | 2. |g:Hexokinase_ftOptInPatterns|
270 | 3. |g:Hexokinase_optOutPatterns|
271 | 4. |g:Hexokinase_optInPatterns|
272 |
273 | FileType Specific Patterns to Find *g:Hexokinase_ftOptInPatterns*
274 |
275 | Type: |Dict| of |String| to |List| of |String|s
276 | Which patterns to look for for specific filetypes.
277 |
278 | Default value: >
279 | let g:Hexokinase_ftOptInPatterns = {}
280 | <
281 | This option can be overridden by other configuration, this is
282 | the relevant precedence order:
283 | 1. |g:Hexokinase_ftOptOutPatterns|
284 | 2. |g:Hexokinase_ftOptInPatterns|
285 | 3. |g:Hexokinase_optOutPatterns|
286 | 4. |g:Hexokinase_optInPatterns|
287 |
288 | FileType Specific Patterns to Ignore *g:Hexokinase_ftOptOutPatterns*
289 |
290 | Type: |Dict| of |String| to |List| of |String|s
291 | Which patterns to ignore for specific filetypes.
292 |
293 | Default value: >
294 | let g:Hexokinase_ftOptOutPatterns = {}
295 | <
296 | This option can override other configuration, this is the
297 | relevant precedence order:
298 | 1. |g:Hexokinase_ftOptOutPatterns|
299 | 2. |g:Hexokinase_ftOptInPatterns|
300 | 3. |g:Hexokinase_optOutPatterns|
301 | 4. |g:Hexokinase_optInPatterns|
302 |
303 | Virtual Text *g:Hexokinase_virtualText*
304 |
305 | Type: |String|
306 | The text to display when using virtual text for the
307 | highlighting.
308 |
309 | Default value: >
310 | let g:Hexokinase_virtualText = '■'
311 | <
312 | Note: Highlighting is done on the foreground of what is
313 | passed, so spaces will not work, instead use "█".
314 |
315 | Sign Column Icon *g:Hexokinase_signIcon*
316 |
317 | Type: |String|
318 | The text to display when using the |sign_column|.
319 |
320 | Default value: >
321 | let g:Hexokinase_signIcon = '■'
322 | <
323 | Note: Can only be one or two characters long.
324 |
325 | Note: Highlighting is done on the foreground of what is
326 | passed, so spaces will not work, instead use "█".
327 |
328 | Refresh Events *g:Hexokinase_refreshEvents*
329 |
330 | Type: |List| of |String|s
331 | Which |autocmd-events| trigger a refresh of highlighting.
332 |
333 | Default value: >
334 | let g:Hexokinase_refreshEvents = ['TextChanged', 'InsertLeave', 'BufRead']
335 | <
336 | Disabled TerminalBuffers *g:Hexokinase_termDisabled*
337 |
338 | Type: |Integer|
339 | Do not scraped any terminal buffers.
340 |
341 | Default value: >
342 | let g:Hexokinase_termDisabled = 0
343 | <
344 | By Default, all terminal buffers are scraped.
345 |
346 |
347 | Disabled FileTypes *g:Hexokinase_ftDisabled*
348 |
349 | Type: |List| of |String|s
350 | Which FileTypes not to scrape.
351 |
352 | Default value: >
353 | let g:Hexokinase_ftDisabled = []
354 | <
355 | By Default, all filetypes are scraped.
356 |
357 | Regex patterns are not supported.
358 |
359 | This will override |g:Hexokinase_ftEnabled|.
360 | This will be overridden by any use of |HexokinaseTurnOn|.
361 |
362 | Enabled FileTypes *g:Hexokinase_ftEnabled*
363 |
364 | Type: |List| of |String|s
365 | Which FileTypes to scrape automatically.
366 |
367 | Sample value: >
368 | let g:Hexokinase_ftEnabled = ['css', 'html', 'javascript']
369 | <
370 | By Default, all filetypes are scraped.
371 |
372 | Regex patterns are not supported.
373 |
374 | An empty list means not filetypes are scraped automatically.
375 | To scrape all filetypes automatically, simply don't define
376 | this variable (also leave |g:Hexokinase_ftDisabled| empty).
377 |
378 | This will be overriden by |g:Hexokinase_ftDisabled|.
379 |
380 | Background Colour for Alpha Calculations *g:Hexokinase_alpha_bg*
381 |
382 | Type: |String|
383 | Hex code to use when calculating alpha for `rgba` and `hsla`
384 | functions.
385 |
386 | Default value: >
387 | g:Hexokinase_alpha_bg = ''
388 | <
389 | By default calculations are done using the background of
390 | |hl-Normal| or |hl-SignColumn|. This will override that.
391 |
392 | Note: This MUST be a valid 6 digit hex. Such as `#ffffff`.
393 |
394 | Use word Boundary *g:Hexokinase_checkBoundary*
395 |
396 | Type: 1 or 0
397 | Whether or not to discard matches which are not words. If you
398 | want absolutely everything to be highlighted regardless of
399 | context, then turn this off. This will reduce false positives.
400 |
401 | Default value: >
402 | let g:Hexokinase_checkBoundary = 1
403 | <
404 | Currently only applies to hex codes and web colours. Setting
405 | this to 1 will cause the following: >
406 | " not a match for any colour
407 | not#a#match#ffffff
408 |
409 | " not a match
410 | #fffffffail
411 |
412 | " will match only #aaaaaa
413 | #aaaaaa#ffffff#000000
414 |
415 | " will match pink but not blue or red
416 | redblue pink
417 |
418 | Executable path *g:Hexokinase_executable_path*
419 |
420 | Type: |String|
421 | Path to the `hexokinase` executable.
422 |
423 | Default value: >
424 | " relative to the plugin root
425 | g:Hexokinase_executable_path = 'hexokinase/hexokinase'
426 | <
427 |
428 | CREATE CUSTOM HIGHLIGHTERS *hexokinase-custom-highlighters*
429 | ===========================================================================
430 |
431 | To create a custom highlighter you need to create two functions with the
432 | following signatures (the name doesn't matter since it gets passed as a
433 | function reference below):
434 |
435 | Note: Check out ./autoload/hexokinase/highlighters/*.vim for examples of
436 | highlighters. Look at the functions ending in v2.
437 |
438 | highlight_callback({bufnr})
439 | *hexokinase-highlight_callback*
440 |
441 | {bufnr} is the buffer number of the buffer that was scraped.
442 | The currently active buffer may be different since scraping is
443 | done asynchronously.
444 |
445 | `b:hexokinase_colours` will be set to a list of dictionaries
446 | with the following entries:
447 |
448 | lnum line number for the match
449 | start start column of the match (indexed from 1)
450 | end end column of the match (indexed from 1)
451 | hex six digit hex code of the colour
452 |
453 | Sample value: >
454 | echo b:hexokinase_colours
455 | => [{'lnum': '407', 'start': '1', 'end': '7', 'hex':
456 | '#ffffff'}, {'lnum': '381', 'start': '66', 'end': '72 ',
457 | 'hex': '#00ffaa'}]
458 | <
459 | Register this callback as follows: >
460 | let g:Hexokinase_highlightCallbacks = [
461 | \ function('highlight_callback')
462 | \ ]
463 |
464 | teardown_callback({bufnr})
465 | *hexokinase-teardown_callback*
466 |
467 | {bufnr} is the buffer number of the buffer that was scraped.
468 | The currently active buffer may be different than {bufnr} so
469 | don't rely on "bufnr('%')".
470 |
471 | This will get triggered when the highlighting is turned off by
472 | the user or when it is refreshed for a buffer. This would be
473 | the time to revert any UI changes that were made in
474 | |hexokinase-highlight_callback|. When being refreshed, the
475 | entire buffer is scraped before the callback is triggered.
476 |
477 | Register this callback as follows: >
478 | let g:Hexokinase_tearDownCallbacks = [
479 | \ function('teardown_callback')
480 | \ ]
481 |
482 | FAQ *hexokinase-faq*
483 | ===========================================================================
484 |
485 | Q: I'm seeing grey colours when I toggle vim-hexokinase
486 |
487 | A: You need `termguicolors` to be turned on. Verify `:set termguicolors?`
488 | outputs `termguicolors`.
489 |
490 | vim:tw=78:ts=8:ft=help:norl:
491 |
--------------------------------------------------------------------------------
/lua/hexokinase.lua:
--------------------------------------------------------------------------------
1 | local M = {}
2 | return M
3 |
--------------------------------------------------------------------------------
/plugin/hexokinase.vim:
--------------------------------------------------------------------------------
1 | " hexokinase.(n)vim - (Neo)Vim plugin for colouring hex codes
2 | " Maintainer: Adam P. Regasz-Rethy (RRethy)
3 | " Vertion 2.0
4 |
5 | if exists('g:loaded_hexokinase')
6 | finish
7 | endif
8 |
9 | let g:loaded_hexokinase = 1
10 |
11 | let g:Hexokinase_executable_path = get(g:, 'Hexokinase_executable_path',
12 | \ executable(expand(':h:h').'/hexokinase/hexokinase')
13 | \ ? expand(':h:h').'/hexokinase/hexokinase'
14 | \ : expand($GOPATH).'/bin/hexokinase')
15 | let g:Hexokinase_v2 = get(g:, 'Hexokinase_v2', 1)
16 |
17 | if g:Hexokinase_v2
18 | if executable(g:Hexokinase_executable_path)
19 | call hexokinase#v2#setup()
20 | else
21 | echohl Error | echom 'vim-hexokinase needs updating. Run `make hexokinase` in project root. See `:h hexokinase-installation` for more info.' | echohl None
22 | endif
23 | else
24 | call hexokinase#v1#setup()
25 | endif
26 |
--------------------------------------------------------------------------------
/screenshot_colours.txt:
--------------------------------------------------------------------------------
1 | blue red pink orange yellow
2 |
3 | #00f #08f #0ff #0f8 #0f0
4 |
5 | #8f0 #ff0 #f80 #f00 #f08
6 |
7 | #ffffff #00f900 #08f900
8 | #0f8900 #0f0900
9 | #8f0900 #ff0900 #8f0900
10 |
11 | rgba(100%,0%,0%,1.0) rgba(255,0,0,0.5)
12 | rgba(100%,0%,0%,0.5) rgba(255,0,0,0.3)
13 |
14 | hsl(195.5, 100%, 50%) hsl(195.53, 100%, 50%)
15 | hsl(0, 0%, 100%) hsl(0, 0%, 0%)
16 |
17 | hsla(195.5, 100%, 50%, .5) hsla(195.53, 100%, 50%, .5)
18 | hsla(0, 0%, 100%, .5) hsla(0, 0%, 0%, .5)
19 |
20 | rgb(255,0,0) rgb(128,0,0) rgb(64,0,0)
21 | rgb(0,255,0) rgb(0,128,0) rgb(0,64,0)
22 | rgb(0,0,255) rgb(0,0,128) rgb(0,0,64)
23 |
--------------------------------------------------------------------------------
/test_colours.txt:
--------------------------------------------------------------------------------
1 | This file lists various colors, for testing the supported color syntax
2 |
3 | green red blue
4 |
5 | #ffffffFF
6 |
7 | #AAbB11aa
8 |
9 | #fffffff
10 |
11 | #fff
12 | #000000 #333333 #666666
13 | #ffffff
14 | #999999 #cccccc #ffffff
15 | #000000ff #333333ff #666666ff
16 | #999999ff #ccccccff #ffffffff
17 | #00000088 #33333388 #66666688
18 | #99999988 #cccccc88 #ffffff88
19 |
20 | foo3bar3baz3
21 |
22 | #fff #333 #666
23 | #999 #ccc #fff
24 | #000 #333f #666f
25 | #999f #cccf #ffff
26 | #000c #333c #666c
27 | #999c #cccc #fffc
28 | #0009 #3339 #6669
29 | #9999 #ccc9 #fff9
30 | #0006 #3336 #6666
31 | #9996 #ccc6 #fff6
32 | #0003 #3333 #6663
33 | #9993 #ccc3 #fff3
34 | #0000 #3330 #6660
35 | #9990 #ccc0 #fff0
36 |
37 | #00f#08f#0ff#0f8#0f0#8f0#ff0#f80#f00#f08#f0f#80f
38 |
39 | #f00f #f00c #f009 #f006 #f003 #f000
40 |
41 | rgba(0,0,0,1.0)
42 | rgba(100%,0%,0%,1.0) #f00f #0f0f #00ff #ff00 #f0f0 #f00f
43 | rgba(255,0,0,0.5)
44 | rgba(100%,0%,0%,0.5) #f008 #0f08 #00f8 #8f00 #80f0 #800f
45 | rgba(255,0,0,0.3)
46 | rgba(100%,0%,0%,0.3) #f004 #0f04 #00f4 #4f00 #40f0 #400f
47 |
48 |
49 | rgb(255,0,0) rgb(128,0,0) rgb(64,0,0)
50 | rgb(0,255,0) rgb(0,128,0) rgb(0,64,0)
51 | rgb(0,0,255) rgb(0,0,128) rgb(0,0,64)
52 |
53 | #00f #08f #0ff #0f8 #0f0 #8f0 #ff0 #f80 #f00 #f08 #f0f #80f
54 |
55 | #00ff00
56 | #08ff00
57 | #0fff00
58 | #0f8f00
59 | #0f0f00
60 | #8f0f00
61 | #ff0f00
62 | #f80f00
63 | #f00f00
64 | #f08f00
65 | #f0ff00
66 | #80ff00
67 | #00fc00
68 | #08fc00
69 | #0ffc00
70 | #0f8c00
71 | #0f0c00
72 | #8f0c00
73 | #ff0c00
74 | #f80c00
75 | #f00c00
76 | #f08c00
77 | #f0fc00
78 | #80fc00
79 | #00f900
80 | #08f900
81 | #0ff900
82 | #0f8900
83 | #0f0900
84 | #8f0900
85 | #ff0900
86 | #f80900
87 | #f00900
88 | #f08900
89 | #f0f900
90 | #80f900
91 | #00f600
92 | #08f600
93 | #0ff600
94 | #0f8600
95 | #0f0600
96 | #8f0600
97 | #ff0600
98 | #f80600
99 | #f00600
100 | #f08600
101 | #f0f600
102 | #80f600
103 | #00f300
104 | #08f300
105 | #0ff300
106 | #0f8300
107 | #0f0300
108 | #8f0300
109 | #ff0300
110 | #f80300
111 | #f00300
112 | #f08300
113 | #f0f300
114 | #80f300
115 | #00f000
116 | #08f000
117 | #0ff000
118 | #0f8000
119 | #0f0000
120 | #8f0000
121 | #ff0000
122 | #f80000
123 | #f00000
124 | #f08000
125 | #f0f000
126 | #80f000
127 |
--------------------------------------------------------------------------------