aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin M. Keyes <justinkz@gmail.com>2019-02-12 20:22:28 +0100
committerGitHub <noreply@github.com>2019-02-12 20:22:28 +0100
commit73dffc5053c06a81373c1f0f9344bfd76352b345 (patch)
tree84424f03bc722d2ce3b695132dc5a4b8a1d3b02d
parent9b4383261a3de874969b7df89d32eaeb92ab8abf (diff)
parente50d0b6fc19fe7555651166b73aff9c3703ef11a (diff)
downloadrneovim-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.txt9
-rw-r--r--runtime/doc/ui.txt1
-rw-r--r--runtime/doc/vim_diff.txt2
-rw-r--r--src/nvim/highlight.c86
-rw-r--r--src/nvim/ui_compositor.c3
-rw-r--r--test/functional/ui/popupmenu_spec.lua39
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)