Created
September 22, 2018 17:59
-
-
Save tyru/cf1236e90c403d17399dd576d7496237 to your computer and use it in GitHub Desktop.
DOES NOT WORK! use http://tyru.hatenablog.com/entry/2018/09/23/021423
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
scriptencoding utf-8 | |
let s:save_cpo = &cpo | |
set cpo&vim | |
" index = xterm number | |
" cf. | |
" * :help cterm-colors | |
" * https://jonasjacek.github.io/colors/ | |
let s:color_table = [ | |
\ {'name': 'Black', 'code': 0x000000}, | |
\ {'name': 'DarkRed', 'code': 0x800000}, | |
\ {'name': 'DarkGreen', 'code': 0x008000}, | |
\ {'name': 'Brown', 'code': 0x808000}, | |
\ {'name': 'DarkBlue', 'code': 0x000080}, | |
\ {'name': 'DarkMagenta', 'code': 0x800080}, | |
\ {'name': 'DarkCyan', 'code': 0x008080}, | |
\ {'name': 'Grey', 'code': 0xc0c0c0}, | |
\ {'name': 'DarkGrey', 'code': 0x808080}, | |
\ {'name': 'Red', 'code': 0xff0000}, | |
\ {'name': 'Green', 'code': 0x00ff00}, | |
\ {'name': 'Yellow', 'code': 0xffff00}, | |
\ {'name': 'Blue', 'code': 0x0000ff}, | |
\ {'name': 'Magenta', 'code': 0xff00ff}, | |
\ {'name': 'Cyan', 'code': 0x00ffff}, | |
\ {'name': 'White', 'code': 0xffffff}, | |
\ | |
\ {'name': 'Grey0', 'code': 0x000000}, | |
\ {'name': 'NavyBlue', 'code': 0x00005f}, | |
\ {'name': 'DarkBlue', 'code': 0x000087}, | |
\ {'name': 'Blue3', 'code': 0x0000af}, | |
\ {'name': 'Blue3', 'code': 0x0000d7}, | |
\ {'name': 'Blue1', 'code': 0x0000ff}, | |
\ {'name': 'DarkGreen', 'code': 0x005f00}, | |
\ {'name': 'DeepSkyBlue4', 'code': 0x005f5f}, | |
\ {'name': 'DeepSkyBlue4', 'code': 0x005f87}, | |
\ {'name': 'DeepSkyBlue4', 'code': 0x005faf}, | |
\ {'name': 'DodgerBlue3', 'code': 0x005fd7}, | |
\ {'name': 'DodgerBlue2', 'code': 0x005fff}, | |
\ {'name': 'Green4', 'code': 0x008700}, | |
\ {'name': 'SpringGreen4', 'code': 0x00875f}, | |
\ {'name': 'Turquoise4', 'code': 0x008787}, | |
\ {'name': 'DeepSkyBlue3', 'code': 0x0087af}, | |
\ {'name': 'DeepSkyBlue3', 'code': 0x0087d7}, | |
\ {'name': 'DodgerBlue1', 'code': 0x0087ff}, | |
\ {'name': 'Green3', 'code': 0x00af00}, | |
\ {'name': 'SpringGreen3', 'code': 0x00af5f}, | |
\ {'name': 'DarkCyan', 'code': 0x00af87}, | |
\ {'name': 'LightSeaGreen', 'code': 0x00afaf}, | |
\ {'name': 'DeepSkyBlue2', 'code': 0x00afd7}, | |
\ {'name': 'DeepSkyBlue1', 'code': 0x00afff}, | |
\ {'name': 'Green3', 'code': 0x00d700}, | |
\ {'name': 'SpringGreen3', 'code': 0x00d75f}, | |
\ {'name': 'SpringGreen2', 'code': 0x00d787}, | |
\ {'name': 'Cyan3', 'code': 0x00d7af}, | |
\ {'name': 'DarkTurquoise', 'code': 0x00d7d7}, | |
\ {'name': 'Turquoise2', 'code': 0x00d7ff}, | |
\ {'name': 'Green1', 'code': 0x00ff00}, | |
\ {'name': 'SpringGreen2', 'code': 0x00ff5f}, | |
\ {'name': 'SpringGreen1', 'code': 0x00ff87}, | |
\ {'name': 'MediumSpringGreen', 'code': 0x00ffaf}, | |
\ {'name': 'Cyan2', 'code': 0x00ffd7}, | |
\ {'name': 'Cyan1', 'code': 0x00ffff}, | |
\ {'name': 'DarkRed', 'code': 0x5f0000}, | |
\ {'name': 'DeepPink4', 'code': 0x5f005f}, | |
\ {'name': 'Purple4', 'code': 0x5f0087}, | |
\ {'name': 'Purple4', 'code': 0x5f00af}, | |
\ {'name': 'Purple3', 'code': 0x5f00d7}, | |
\ {'name': 'BlueViolet', 'code': 0x5f00ff}, | |
\ {'name': 'Orange4', 'code': 0x5f5f00}, | |
\ {'name': 'Grey37', 'code': 0x5f5f5f}, | |
\ {'name': 'MediumPurple4', 'code': 0x5f5f87}, | |
\ {'name': 'SlateBlue3', 'code': 0x5f5faf}, | |
\ {'name': 'SlateBlue3', 'code': 0x5f5fd7}, | |
\ {'name': 'RoyalBlue1', 'code': 0x5f5fff}, | |
\ {'name': 'Chartreuse4', 'code': 0x5f8700}, | |
\ {'name': 'DarkSeaGreen4', 'code': 0x5f875f}, | |
\ {'name': 'PaleTurquoise4', 'code': 0x5f8787}, | |
\ {'name': 'SteelBlue', 'code': 0x5f87af}, | |
\ {'name': 'SteelBlue3', 'code': 0x5f87d7}, | |
\ {'name': 'CornflowerBlue', 'code': 0x5f87ff}, | |
\ {'name': 'Chartreuse3', 'code': 0x5faf00}, | |
\ {'name': 'DarkSeaGreen4', 'code': 0x5faf5f}, | |
\ {'name': 'CadetBlue', 'code': 0x5faf87}, | |
\ {'name': 'CadetBlue', 'code': 0x5fafaf}, | |
\ {'name': 'SkyBlue3', 'code': 0x5fafd7}, | |
\ {'name': 'SteelBlue1', 'code': 0x5fafff}, | |
\ {'name': 'Chartreuse3', 'code': 0x5fd700}, | |
\ {'name': 'PaleGreen3', 'code': 0x5fd75f}, | |
\ {'name': 'SeaGreen3', 'code': 0x5fd787}, | |
\ {'name': 'Aquamarine3', 'code': 0x5fd7af}, | |
\ {'name': 'MediumTurquoise', 'code': 0x5fd7d7}, | |
\ {'name': 'SteelBlue1', 'code': 0x5fd7ff}, | |
\ {'name': 'Chartreuse2', 'code': 0x5fff00}, | |
\ {'name': 'SeaGreen2', 'code': 0x5fff5f}, | |
\ {'name': 'SeaGreen1', 'code': 0x5fff87}, | |
\ {'name': 'SeaGreen1', 'code': 0x5fffaf}, | |
\ {'name': 'Aquamarine1', 'code': 0x5fffd7}, | |
\ {'name': 'DarkSlateGray2', 'code': 0x5fffff}, | |
\ {'name': 'DarkRed', 'code': 0x870000}, | |
\ {'name': 'DeepPink4', 'code': 0x87005f}, | |
\ {'name': 'DarkMagenta', 'code': 0x870087}, | |
\ {'name': 'DarkMagenta', 'code': 0x8700af}, | |
\ {'name': 'DarkViolet', 'code': 0x8700d7}, | |
\ {'name': 'Purple', 'code': 0x8700ff}, | |
\ {'name': 'Orange4', 'code': 0x875f00}, | |
\ {'name': 'LightPink4', 'code': 0x875f5f}, | |
\ {'name': 'Plum4', 'code': 0x875f87}, | |
\ {'name': 'MediumPurple3', 'code': 0x875faf}, | |
\ {'name': 'MediumPurple3', 'code': 0x875fd7}, | |
\ {'name': 'SlateBlue1', 'code': 0x875fff}, | |
\ {'name': 'Yellow4', 'code': 0x878700}, | |
\ {'name': 'Wheat4', 'code': 0x87875f}, | |
\ {'name': 'Grey53', 'code': 0x878787}, | |
\ {'name': 'LightSlateGrey', 'code': 0x8787af}, | |
\ {'name': 'MediumPurple', 'code': 0x8787d7}, | |
\ {'name': 'LightSlateBlue', 'code': 0x8787ff}, | |
\ {'name': 'Yellow4', 'code': 0x87af00}, | |
\ {'name': 'DarkOliveGreen3', 'code': 0x87af5f}, | |
\ {'name': 'DarkSeaGreen', 'code': 0x87af87}, | |
\ {'name': 'LightSkyBlue3', 'code': 0x87afaf}, | |
\ {'name': 'LightSkyBlue3', 'code': 0x87afd7}, | |
\ {'name': 'SkyBlue2', 'code': 0x87afff}, | |
\ {'name': 'Chartreuse2', 'code': 0x87d700}, | |
\ {'name': 'DarkOliveGreen3', 'code': 0x87d75f}, | |
\ {'name': 'PaleGreen3', 'code': 0x87d787}, | |
\ {'name': 'DarkSeaGreen3', 'code': 0x87d7af}, | |
\ {'name': 'DarkSlateGray3', 'code': 0x87d7d7}, | |
\ {'name': 'SkyBlue1', 'code': 0x87d7ff}, | |
\ {'name': 'Chartreuse1', 'code': 0x87ff00}, | |
\ {'name': 'LightGreen', 'code': 0x87ff5f}, | |
\ {'name': 'LightGreen', 'code': 0x87ff87}, | |
\ {'name': 'PaleGreen1', 'code': 0x87ffaf}, | |
\ {'name': 'Aquamarine1', 'code': 0x87ffd7}, | |
\ {'name': 'DarkSlateGray1', 'code': 0x87ffff}, | |
\ {'name': 'Red3', 'code': 0xaf0000}, | |
\ {'name': 'DeepPink4', 'code': 0xaf005f}, | |
\ {'name': 'MediumVioletRed', 'code': 0xaf0087}, | |
\ {'name': 'Magenta3', 'code': 0xaf00af}, | |
\ {'name': 'DarkViolet', 'code': 0xaf00d7}, | |
\ {'name': 'Purple', 'code': 0xaf00ff}, | |
\ {'name': 'DarkOrange3', 'code': 0xaf5f00}, | |
\ {'name': 'IndianRed', 'code': 0xaf5f5f}, | |
\ {'name': 'HotPink3', 'code': 0xaf5f87}, | |
\ {'name': 'MediumOrchid3', 'code': 0xaf5faf}, | |
\ {'name': 'MediumOrchid', 'code': 0xaf5fd7}, | |
\ {'name': 'MediumPurple2', 'code': 0xaf5fff}, | |
\ {'name': 'DarkGoldenrod', 'code': 0xaf8700}, | |
\ {'name': 'LightSalmon3', 'code': 0xaf875f}, | |
\ {'name': 'RosyBrown', 'code': 0xaf8787}, | |
\ {'name': 'Grey63', 'code': 0xaf87af}, | |
\ {'name': 'MediumPurple2', 'code': 0xaf87d7}, | |
\ {'name': 'MediumPurple1', 'code': 0xaf87ff}, | |
\ {'name': 'Gold3', 'code': 0xafaf00}, | |
\ {'name': 'DarkKhaki', 'code': 0xafaf5f}, | |
\ {'name': 'NavajoWhite3', 'code': 0xafaf87}, | |
\ {'name': 'Grey69', 'code': 0xafafaf}, | |
\ {'name': 'LightSteelBlue3', 'code': 0xafafd7}, | |
\ {'name': 'LightSteelBlue', 'code': 0xafafff}, | |
\ {'name': 'Yellow3', 'code': 0xafd700}, | |
\ {'name': 'DarkOliveGreen3', 'code': 0xafd75f}, | |
\ {'name': 'DarkSeaGreen3', 'code': 0xafd787}, | |
\ {'name': 'DarkSeaGreen2', 'code': 0xafd7af}, | |
\ {'name': 'LightCyan3', 'code': 0xafd7d7}, | |
\ {'name': 'LightSkyBlue1', 'code': 0xafd7ff}, | |
\ {'name': 'GreenYellow', 'code': 0xafff00}, | |
\ {'name': 'DarkOliveGreen2', 'code': 0xafff5f}, | |
\ {'name': 'PaleGreen1', 'code': 0xafff87}, | |
\ {'name': 'DarkSeaGreen2', 'code': 0xafffaf}, | |
\ {'name': 'DarkSeaGreen1', 'code': 0xafffd7}, | |
\ {'name': 'PaleTurquoise1', 'code': 0xafffff}, | |
\ {'name': 'Red3', 'code': 0xd70000}, | |
\ {'name': 'DeepPink3', 'code': 0xd7005f}, | |
\ {'name': 'DeepPink3', 'code': 0xd70087}, | |
\ {'name': 'Magenta3', 'code': 0xd700af}, | |
\ {'name': 'Magenta3', 'code': 0xd700d7}, | |
\ {'name': 'Magenta2', 'code': 0xd700ff}, | |
\ {'name': 'DarkOrange3', 'code': 0xd75f00}, | |
\ {'name': 'IndianRed', 'code': 0xd75f5f}, | |
\ {'name': 'HotPink3', 'code': 0xd75f87}, | |
\ {'name': 'HotPink2', 'code': 0xd75faf}, | |
\ {'name': 'Orchid', 'code': 0xd75fd7}, | |
\ {'name': 'MediumOrchid1', 'code': 0xd75fff}, | |
\ {'name': 'Orange3', 'code': 0xd78700}, | |
\ {'name': 'LightSalmon3', 'code': 0xd7875f}, | |
\ {'name': 'LightPink3', 'code': 0xd78787}, | |
\ {'name': 'Pink3', 'code': 0xd787af}, | |
\ {'name': 'Plum3', 'code': 0xd787d7}, | |
\ {'name': 'Violet', 'code': 0xd787ff}, | |
\ {'name': 'Gold3', 'code': 0xd7af00}, | |
\ {'name': 'LightGoldenrod3', 'code': 0xd7af5f}, | |
\ {'name': 'Tan', 'code': 0xd7af87}, | |
\ {'name': 'MistyRose3', 'code': 0xd7afaf}, | |
\ {'name': 'Thistle3', 'code': 0xd7afd7}, | |
\ {'name': 'Plum2', 'code': 0xd7afff}, | |
\ {'name': 'Yellow3', 'code': 0xd7d700}, | |
\ {'name': 'Khaki3', 'code': 0xd7d75f}, | |
\ {'name': 'LightGoldenrod2', 'code': 0xd7d787}, | |
\ {'name': 'LightYellow3', 'code': 0xd7d7af}, | |
\ {'name': 'Grey84', 'code': 0xd7d7d7}, | |
\ {'name': 'LightSteelBlue1', 'code': 0xd7d7ff}, | |
\ {'name': 'Yellow2', 'code': 0xd7ff00}, | |
\ {'name': 'DarkOliveGreen1', 'code': 0xd7ff5f}, | |
\ {'name': 'DarkOliveGreen1', 'code': 0xd7ff87}, | |
\ {'name': 'DarkSeaGreen1', 'code': 0xd7ffaf}, | |
\ {'name': 'Honeydew2', 'code': 0xd7ffd7}, | |
\ {'name': 'LightCyan1', 'code': 0xd7ffff}, | |
\ {'name': 'Red1', 'code': 0xff0000}, | |
\ {'name': 'DeepPink2', 'code': 0xff005f}, | |
\ {'name': 'DeepPink1', 'code': 0xff0087}, | |
\ {'name': 'DeepPink1', 'code': 0xff00af}, | |
\ {'name': 'Magenta2', 'code': 0xff00d7}, | |
\ {'name': 'Magenta1', 'code': 0xff00ff}, | |
\ {'name': 'OrangeRed1', 'code': 0xff5f00}, | |
\ {'name': 'IndianRed1', 'code': 0xff5f5f}, | |
\ {'name': 'IndianRed1', 'code': 0xff5f87}, | |
\ {'name': 'HotPink', 'code': 0xff5faf}, | |
\ {'name': 'HotPink', 'code': 0xff5fd7}, | |
\ {'name': 'MediumOrchid1', 'code': 0xff5fff}, | |
\ {'name': 'DarkOrange', 'code': 0xff8700}, | |
\ {'name': 'Salmon1', 'code': 0xff875f}, | |
\ {'name': 'LightCoral', 'code': 0xff8787}, | |
\ {'name': 'PaleVioletRed1', 'code': 0xff87af}, | |
\ {'name': 'Orchid2', 'code': 0xff87d7}, | |
\ {'name': 'Orchid1', 'code': 0xff87ff}, | |
\ {'name': 'Orange1', 'code': 0xffaf00}, | |
\ {'name': 'SandyBrown', 'code': 0xffaf5f}, | |
\ {'name': 'LightSalmon1', 'code': 0xffaf87}, | |
\ {'name': 'LightPink1', 'code': 0xffafaf}, | |
\ {'name': 'Pink1', 'code': 0xffafd7}, | |
\ {'name': 'Plum1', 'code': 0xffafff}, | |
\ {'name': 'Gold1', 'code': 0xffd700}, | |
\ {'name': 'LightGoldenrod2', 'code': 0xffd75f}, | |
\ {'name': 'LightGoldenrod2', 'code': 0xffd787}, | |
\ {'name': 'NavajoWhite1', 'code': 0xffd7af}, | |
\ {'name': 'MistyRose1', 'code': 0xffd7d7}, | |
\ {'name': 'Thistle1', 'code': 0xffd7ff}, | |
\ {'name': 'Yellow1', 'code': 0xffff00}, | |
\ {'name': 'LightGoldenrod1', 'code': 0xffff5f}, | |
\ {'name': 'Khaki1', 'code': 0xffff87}, | |
\ {'name': 'Wheat1', 'code': 0xffffaf}, | |
\ {'name': 'Cornsilk1', 'code': 0xffffd7}, | |
\ {'name': 'Grey100', 'code': 0xffffff}, | |
\ {'name': 'Grey3', 'code': 0x080808}, | |
\ {'name': 'Grey7', 'code': 0x121212}, | |
\ {'name': 'Grey11', 'code': 0x1c1c1c}, | |
\ {'name': 'Grey15', 'code': 0x262626}, | |
\ {'name': 'Grey19', 'code': 0x303030}, | |
\ {'name': 'Grey23', 'code': 0x3a3a3a}, | |
\ {'name': 'Grey27', 'code': 0x444444}, | |
\ {'name': 'Grey30', 'code': 0x4e4e4e}, | |
\ {'name': 'Grey35', 'code': 0x585858}, | |
\ {'name': 'Grey39', 'code': 0x626262}, | |
\ {'name': 'Grey42', 'code': 0x6c6c6c}, | |
\ {'name': 'Grey46', 'code': 0x767676}, | |
\ {'name': 'Grey50', 'code': 0x808080}, | |
\ {'name': 'Grey54', 'code': 0x8a8a8a}, | |
\ {'name': 'Grey58', 'code': 0x949494}, | |
\ {'name': 'Grey62', 'code': 0x9e9e9e}, | |
\ {'name': 'Grey66', 'code': 0xa8a8a8}, | |
\ {'name': 'Grey70', 'code': 0xb2b2b2}, | |
\ {'name': 'Grey74', 'code': 0xbcbcbc}, | |
\ {'name': 'Grey78', 'code': 0xc6c6c6}, | |
\ {'name': 'Grey82', 'code': 0xd0d0d0}, | |
\ {'name': 'Grey85', 'code': 0xdadada}, | |
\ {'name': 'Grey89', 'code': 0xe4e4e4}, | |
\ {'name': 'Grey93', 'code': 0xeeeeee}, | |
\] | |
" Sort by color code, and add 'xtermnr' property to each element. | |
function! s:new_table(ansi_colors) abort | |
" TODO ansi color palette | |
let table = deepcopy(s:color_table) | |
" call map(copy(a:ansi_colors), {i,c -> | |
"\ extend(table[i], {'code': s:parse_color(c)}) | |
"\}) | |
let zipped = map(table, {i,v -> [i, v]}) | |
let sorted = sort(zipped, {a,b -> | |
\ a[1].code ># b[1].code ? 1 : a[1].code is# b[1].code ? 0 : -1 | |
\}) | |
let mapped = map(sorted, {_,tuple -> { | |
\ 'xtermnr' : tuple[0], | |
\ 'name' : tuple[1].name, | |
\ 'code' : tuple[1].code | |
\}}) | |
return filter(mapped, {_,v -> v.xtermnr >= 16}) | |
endfunction | |
let s:group_prefix = 'dupTermBuf' | |
function! duptermbuf#open() abort | |
let lines = getline(1, '$') | |
let maxrow = term_getsize('')[0] | |
let chunk_list = s:flatmap(range(1, maxrow), {row -> | |
\ s:scrape(term_scrape('', row), row) | |
\}) | |
new | |
call s:add_colors(chunk_list) | |
call setline('.', lines) | |
call s:set_buffer_options() | |
endfunction | |
function! s:flatmap(list, f) abort | |
let result = [] | |
return map(copy(a:list), {_,v -> extend(result, a:f(v))})[-1] | |
endfunction | |
" Convert term_scrape() return value into the regexp patterns of the row. | |
function! s:scrape(list, row) abort | |
if empty(a:list) | |
return [] | |
endif | |
let [first; rest] = a:list | |
let prev_key = [first.fg, first.bg, first.attr] | |
let prev_scr = first | |
let buf = [first.chars] | |
let chunks = [] | |
let start = 1 | |
let end = start + first.width | |
for scr in rest | |
let key = [scr.fg, scr.bg, scr.attr] | |
if key ==# prev_key | |
let buf += [scr.chars] | |
let end += scr.width | |
continue | |
endif | |
let chunks += [{ | |
\ 'col': start, | |
\ 'row': a:row, | |
\ 'scr': prev_scr, | |
\ 'str': join(buf, '') | |
\}] | |
let start = end | |
let prev_key = key | |
let prev_scr = scr | |
let buf = [scr.chars] | |
endfor | |
let chunks += [{ | |
\ 'col': start, | |
\ 'row': a:row, | |
\ 'scr': prev_scr, | |
\ 'str': join(buf, '') | |
\}] | |
return chunks | |
endfunction | |
function! s:add_colors(chunk_list) abort | |
call writefile(split(PP(a:chunk_list), '\n'), 'dump.txt') | |
let colors = s:generate_colors(a:chunk_list) | |
let highlights = s:generate_highlights(a:chunk_list) | |
for h in highlights | |
execute 'hi' h.group join(h.args, ' ') | |
endfor | |
for c in colors | |
call matchadd(c.group, c.pattern, c.priority, c.id, c.dict) | |
endfor | |
endfunction | |
function! s:generate_colors(chunk_list) abort | |
return map(copy(a:chunk_list), {i,c -> | |
\ { | |
\ 'group': s:group_prefix . 'Row' . c.row . 'Chunk' . i, | |
\ 'pattern': '\m' . '\%' . c.row . 'l\%' . c.col . 'c\V' . c.str, | |
\ 'priority': 10, | |
\ 'id': -1, | |
\ 'dict': {}, | |
\ } | |
\}) | |
endfunction | |
function! s:generate_highlights(chunk_list) abort | |
" XXX skip 0 - 15 system palette | |
let table = s:new_table(term_getansicolors('')) | |
return map(copy(a:chunk_list), {i,c -> | |
\ { | |
\ 'group': s:group_prefix . 'Row' . c.row . 'Chunk' . i, | |
\ 'args': s:to_hicmd_args(c.scr, table) | |
\ } | |
\}) | |
endfunction | |
" This returns {args} of ':hi {group} {args}' | |
function! s:to_hicmd_args(scr, table) abort | |
let fg = s:pick_near_term_color(a:scr.fg, a:table) | |
let bg = s:pick_near_term_color(a:scr.bg, a:table) | |
let args = [] | |
if !empty(fg) | |
let args += ['ctermfg=' . fg.xtermnr] | |
endif | |
if !empty(bg) | |
let args += ['ctermbg=' . bg.xtermnr] | |
endif | |
let args += [ | |
\ 'guifg=' . a:scr.fg, | |
\ 'guibg=' . a:scr.bg, | |
\] | |
let args += s:to_attr_list(a:scr.attr) | |
return args | |
endfunction | |
" :h cterm-colors | |
" Convert color to cterm-colors. | |
function! s:pick_near_term_color(color, table) abort | |
let code = s:parse_color(a:color) | |
if code < 0 | |
return {} | |
endif | |
" XXX table may contain duplicate codes... but is it problem? | |
let [index, exact] = s:bsearch_code(a:table, code) | |
if exact | |
return a:table[index] | |
endif | |
if index <= 0 | |
return a:table[0] | |
endif | |
if index >= len(a:table) - 1 | |
return a:table[-1] | |
endif | |
let ldiff = abs(code - a:table[index].code) | |
let rdiff = abs(code - a:table[index + 1].code) | |
return a:table[ldiff < rdiff ? index : index + 1] | |
endfunction | |
" TODO support color name (:h gui-colors) | |
function! s:parse_color(color) abort | |
let m = matchlist(a:color, '^#\(\x\x\)\(\x\x\)\(\x\x\)$') | |
if empty(m) | |
return -1 | |
endif | |
return s:hex3_to_code(m[1], m[2], m[3]) | |
endfunction | |
function! s:bsearch_code(list, code) abort | |
let [min, max] = [0, len(a:list)] | |
while min <=# max | |
let mid = min + (max - min) / 2 | |
if a:list[mid].code <# a:code | |
let min = mid + 1 | |
elseif a:list[mid].code ># a:code | |
let max = mid - 1 | |
else | |
return [mid, v:true] | |
endif | |
endwhile | |
return [mid, v:false] | |
endfunction | |
" r = '12', g = '34', b = '56' -> 0x123456 | |
function! s:hex3_to_code(r, g, b) abort | |
return +printf('%d', +printf('0x%02s%02s%02s', a:r, a:g, a:b)) | |
endfunction | |
" 0x123456 -> '1234ff' | |
function! s:code_to_hex(code) abort | |
return printf('%06x', a:code) | |
endfunction | |
" [{what}, {attr}] | |
" {what} = see :help term_getattr() | |
" {attr} = see :help attr-list | |
let s:term_attr_list = [ | |
\ ['bold', 'bold'], | |
\ ['italic', 'italic'], | |
\ ['underline', 'underline'], | |
\ ['strike', 'strikethrough'], | |
\ ['reverse', 'reverse'], | |
\] | |
" :help attr-list | |
function! s:to_attr_list(attr) abort | |
let list = map(copy(s:term_attr_list), {_,a -> | |
\ term_getattr(a:attr, a[0]) ? a[1] : '' | |
\}) | |
call filter(list, {_,v -> !empty(v)}) | |
if empty(list) | |
return [] | |
endif | |
let csv = join(list, ',') | |
return ['term=' . csv, 'gui=' . csv] | |
endfunction | |
function! s:set_buffer_options() abort | |
setlocal readonly buftype=nofile nolist | |
augroup dup-termbuf | |
autocmd! | |
autocmd FileChangedRO <buffer> call clearmatches() | |
augroup END | |
endfunction | |
function! s:test() abort | |
let table = s:new_table(term_getansicolors('')) | |
let [index, exact] = s:bsearch_code(table, 0x40ff40) | |
let picked = s:pick_near_term_color('#40ff40', table) | |
PP [index, exact, table[index], picked] | |
endfunction | |
call s:test() | |
let &cpo = s:save_cpo | |
unlet s:save_cpo |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment