diff options
author | Justin M. Keyes <justinkz@gmail.com> | 2019-02-12 20:22:28 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-02-12 20:22:28 +0100 |
commit | 73dffc5053c06a81373c1f0f9344bfd76352b345 (patch) | |
tree | 84424f03bc722d2ce3b695132dc5a4b8a1d3b02d | |
parent | 9b4383261a3de874969b7df89d32eaeb92ab8abf (diff) | |
parent | e50d0b6fc19fe7555651166b73aff9c3703ef11a (diff) | |
download | rneovim-73dffc5053c06a81373c1f0f9344bfd76352b345.tar.gz rneovim-73dffc5053c06a81373c1f0f9344bfd76352b345.tar.bz2 rneovim-73dffc5053c06a81373c1f0f9344bfd76352b345.zip |
Merge #9589 from justinmk/cterm-pumblend
UI: 'pumblend' for cterm (256-color TUI)
-rw-r--r-- | runtime/doc/options.txt | 9 | ||||
-rw-r--r-- | runtime/doc/ui.txt | 1 | ||||
-rw-r--r-- | runtime/doc/vim_diff.txt | 2 | ||||
-rw-r--r-- | src/nvim/highlight.c | 86 | ||||
-rw-r--r-- | src/nvim/ui_compositor.c | 3 | ||||
-rw-r--r-- | test/functional/ui/popupmenu_spec.lua | 39 |
6 files changed, 130 insertions, 10 deletions
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index f07de55524..4177268780 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -4489,12 +4489,11 @@ A jump table for the options with a short description can be found at |Q_op|. *'pumblend'* *'pb'* 'pumblend' 'pb' number (default 0) global - Enables semi-transparency for the completion popupmenu. Valid values - are in the range from 0 for fully opaque popupmenu (disabled) to 100 - for fully transparent background. Lower values 0-30 are typically most - useful. + Enables pseudo-transparency for the |popup-menu|. Valid values are in + the range of 0 for fully opaque popupmenu (disabled) to 100 for fully + transparent background. Values between 0-30 are typically most useful. - UI-dependent. Supported by TUI with 'termguicolors' enabled. + UI-dependent. Works best with RGB colors. 'termguicolors' *'pyxversion'* *'pyx'* 'pyxversion' 'pyx' number (default depends on the build) diff --git a/runtime/doc/ui.txt b/runtime/doc/ui.txt index 84a24ef2a1..77a829b150 100644 --- a/runtime/doc/ui.txt +++ b/runtime/doc/ui.txt @@ -160,6 +160,7 @@ the editor. 'guifontset' 'guifontwide' 'linespace' + 'pumblend' 'showtabline' 'termguicolors' "ext_*" (all |ui-ext-options|) diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt index ae0bd2fdb2..25517e506b 100644 --- a/runtime/doc/vim_diff.txt +++ b/runtime/doc/vim_diff.txt @@ -189,7 +189,7 @@ Options: for |hl-EndOfBuffer| marker 'inccommand' shows interactive results for |:substitute|-like commands 'listchars' local to window - 'pumblend' semi-transparent popupmenu + 'pumblend' pseudo-transparent popupmenu 'scrollback' 'statusline' supports unlimited alignment sections 'tabline' %@Func@foo%X can call any function on mouse-click diff --git a/src/nvim/highlight.c b/src/nvim/highlight.c index ec07f09481..4c5fca6d39 100644 --- a/src/nvim/highlight.c +++ b/src/nvim/highlight.c @@ -328,7 +328,8 @@ static HlAttrs get_colors_force(int attr) /// Blend overlay attributes (for popupmenu) with other attributes /// /// This creates a new group when required. -/// This will be called on a per-cell basis when in use, so cache the result. +/// This is called per-cell, so cache the result. +/// /// @return the resulting attributes. int hl_blend_attrs(int back_attr, int front_attr, bool through) { @@ -354,7 +355,8 @@ int hl_blend_attrs(int back_attr, int front_attr, bool through) } cattrs.cterm_bg_color = fattrs.cterm_bg_color; - cattrs.cterm_fg_color = fattrs.cterm_bg_color; + cattrs.cterm_fg_color = cterm_blend((int)p_pb, battrs.cterm_fg_color, + fattrs.cterm_bg_color); } else { cattrs = fattrs; if (p_pb >= 50) { @@ -396,6 +398,86 @@ static int rgb_blend(int ratio, int rgb1, int rgb2) return (mr << 16) + (mg << 8) + mb; } +static int cterm_blend(int ratio, int c1, int c2) +{ + // 1. Convert cterm color numbers to RGB. + // 2. Blend the RGB colors. + // 3. Convert the RGB result to a cterm color. + int rgb1 = hl_cterm2rgb_color(c1); + int rgb2 = hl_cterm2rgb_color(c2); + int rgb_blended = rgb_blend(ratio, rgb1, rgb2); + return hl_rgb2cterm_color(rgb_blended); +} + +/// Converts RGB color to 8-bit color (0-255). +static int hl_rgb2cterm_color(int rgb) +{ + int r = (rgb & 0xFF0000) >> 16; + int g = (rgb & 0x00FF00) >> 8; + int b = (rgb & 0x0000FF) >> 0; + + return (r * 6 / 256) * 36 + (g * 6 / 256) * 6 + (b * 6 / 256); +} + +/// Converts 8-bit color (0-255) to RGB color. +/// This is compatible with xterm. +static int hl_cterm2rgb_color(int nr) +{ + static int cube_value[] = { + 0x00, 0x5F, 0x87, 0xAF, 0xD7, 0xFF + }; + static int grey_ramp[] = { + 0x08, 0x12, 0x1C, 0x26, 0x30, 0x3A, 0x44, 0x4E, 0x58, 0x62, 0x6C, 0x76, + 0x80, 0x8A, 0x94, 0x9E, 0xA8, 0xB2, 0xBC, 0xC6, 0xD0, 0xDA, 0xE4, 0xEE + }; + static char_u ansi_table[16][4] = { + // R G B idx + { 0, 0, 0, 1 } , // black + { 224, 0, 0, 2 } , // dark red + { 0, 224, 0, 3 } , // dark green + { 224, 224, 0, 4 } , // dark yellow / brown + { 0, 0, 224, 5 } , // dark blue + { 224, 0, 224, 6 } , // dark magenta + { 0, 224, 224, 7 } , // dark cyan + { 224, 224, 224, 8 } , // light grey + + { 128, 128, 128, 9 } , // dark grey + { 255, 64, 64, 10 } , // light red + { 64, 255, 64, 11 } , // light green + { 255, 255, 64, 12 } , // yellow + { 64, 64, 255, 13 } , // light blue + { 255, 64, 255, 14 } , // light magenta + { 64, 255, 255, 15 } , // light cyan + { 255, 255, 255, 16 } , // white + }; + + int r = 0; + int g = 0; + int b = 0; + int idx; + // *ansi_idx = 0; + + if (nr < 16) { + r = ansi_table[nr][0]; + g = ansi_table[nr][1]; + b = ansi_table[nr][2]; + // *ansi_idx = ansi_table[nr][3]; + } else if (nr < 232) { // 216 color-cube + idx = nr - 16; + r = cube_value[idx / 36 % 6]; + g = cube_value[idx / 6 % 6]; + b = cube_value[idx % 6]; + // *ansi_idx = -1; + } else if (nr < 256) { // 24 greyscale ramp + idx = nr - 232; + r = grey_ramp[idx]; + g = grey_ramp[idx]; + b = grey_ramp[idx]; + // *ansi_idx = -1; + } + return (r << 16) + (g << 8) + b; +} + /// Get highlight attributes for a attribute code HlAttrs syn_attr2entry(int attr) { diff --git a/src/nvim/ui_compositor.c b/src/nvim/ui_compositor.c index 59ae9c34ec..c7ba0306e4 100644 --- a/src/nvim/ui_compositor.c +++ b/src/nvim/ui_compositor.c @@ -259,9 +259,10 @@ static void compose_line(Integer row, Integer startcol, Integer endcol, memcpy(linebuf+(col-startcol), grid->chars+off, n * sizeof(*linebuf)); memcpy(attrbuf+(col-startcol), grid->attrs+off, n * sizeof(*attrbuf)); + // 'pumblend' if (grid != &default_grid && p_pb) { for (int i = col-(int)startcol; i < until-startcol; i++) { - bool thru = strequal((char *)linebuf[i], " "); + bool thru = strequal((char *)linebuf[i], " "); // negative space attrbuf[i] = (sattr_T)hl_blend_attrs(bg_attrs[i], attrbuf[i], thru); if (thru) { memcpy(linebuf[i], bg_line[i], sizeof(linebuf[i])); diff --git a/test/functional/ui/popupmenu_spec.lua b/test/functional/ui/popupmenu_spec.lua index 62428c9657..9a8c5a5789 100644 --- a/test/functional/ui/popupmenu_spec.lua +++ b/test/functional/ui/popupmenu_spec.lua @@ -1273,7 +1273,7 @@ describe('builtin popupmenu', function() ]]) end) - it('works with pumblend', function() + it("'pumblend' RGB-color", function() screen:try_resize(60,14) screen:set_default_attr_ids({ [1] = {background = Screen.colors.Yellow}, @@ -1448,4 +1448,41 @@ describe('builtin popupmenu', function() {20:-- INSERT --} | ]]) end) + + it("'pumblend' 256-color (non-RGB)", function() + screen:detach() + screen = Screen.new(60, 8) + screen:attach({rgb=false, ext_popupmenu=false}) + screen:set_default_attr_ids({ + [1] = {foreground = Screen.colors.Grey0, background = tonumber('0x000007')}, + [2] = {foreground = tonumber('0x000055'), background = tonumber('0x000007')}, + [3] = {foreground = tonumber('0x00008f'), background = Screen.colors.Grey0}, + [4] = {foreground = Screen.colors.Grey0, background = tonumber('0x0000e1')}, + [5] = {foreground = tonumber('0x0000d1'), background = tonumber('0x0000e1')}, + [6] = {foreground = Screen.colors.NavyBlue, background = tonumber('0x0000f8')}, + [7] = {foreground = tonumber('0x0000a5'), background = tonumber('0x0000f8')}, + [8] = {foreground = tonumber('0x00000c')}, + [9] = {bold = true}, + [10] = {foreground = tonumber('0x000002')}, + }) + command('set notermguicolors pumblend=10') + insert([[ + Lorem ipsum dolor sit amet, consectetur + adipisicing elit, sed do eiusmod tempor + incididunt ut labore et dolore magna aliqua. + Ut enim ad minim veniam, quis nostrud + laborum.]]) + + feed('ggOdo<c-x><c-n>') + screen:expect([[ + dolor^ | + {1:dolor}{2: ipsum dol}or sit amet, consectetur | + {4:do}{5:ipisicing eli}t, sed do eiusmod tempor | + {4:dolore}{5:dunt ut l}abore et dolore magna aliqua. | + Ut enim ad minim veniam, quis nostrud | + laborum. | + {8:~ }| + {9:-- Keyword Local completion (^N^P) }{10:match 1 of 3} | + ]]) + end) end) |