mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
Merge pull request #9571 from bfredl/pum_transparent
UI: implement 'pumblend' option for semi-transparent popupmenu
This commit is contained in:
commit
fa2580f953
@ -4486,6 +4486,16 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
Insert mode completion. When zero as much space as available is used.
|
||||
|ins-completion-menu|.
|
||||
|
||||
*'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.
|
||||
|
||||
UI-dependent. Supported by TUI with 'termguicolors' enabled.
|
||||
|
||||
*'pyxversion'* *'pyx'*
|
||||
'pyxversion' 'pyx' number (default depends on the build)
|
||||
global
|
||||
|
@ -189,6 +189,7 @@ Options:
|
||||
for |hl-EndOfBuffer| marker
|
||||
'inccommand' shows interactive results for |:substitute|-like commands
|
||||
'listchars' local to window
|
||||
'pumblend' semi-transparent popupmenu
|
||||
'scrollback'
|
||||
'statusline' supports unlimited alignment sections
|
||||
'tabline' %@Func@foo%X can call any function on mouse-click
|
||||
|
@ -357,10 +357,7 @@ static void remote_ui_default_colors_set(UI *ui, Integer rgb_fg,
|
||||
Integer cterm_fg, Integer cterm_bg)
|
||||
{
|
||||
if (!ui->ui_ext[kUITermColors]) {
|
||||
bool dark = (*p_bg == 'd');
|
||||
rgb_fg = rgb_fg != -1 ? rgb_fg : (dark ? 0xFFFFFF : 0x000000);
|
||||
rgb_bg = rgb_bg != -1 ? rgb_bg : (dark ? 0x000000 : 0xFFFFFF);
|
||||
rgb_sp = rgb_sp != -1 ? rgb_sp : 0xFF0000;
|
||||
HL_SET_DEFAULT_COLORS(rgb_fg, rgb_bg, rgb_sp);
|
||||
}
|
||||
Array args = ARRAY_DICT_INIT;
|
||||
ADD(args, INTEGER_OBJ(rgb_fg));
|
||||
|
@ -23,11 +23,15 @@ static kvec_t(HlEntry) attr_entries = KV_INITIAL_VALUE;
|
||||
|
||||
static Map(HlEntry, int) *attr_entry_ids;
|
||||
static Map(int, int) *combine_attr_entries;
|
||||
static Map(int, int) *blend_attr_entries;
|
||||
static Map(int, int) *blendthrough_attr_entries;
|
||||
|
||||
void highlight_init(void)
|
||||
{
|
||||
attr_entry_ids = map_new(HlEntry, int)();
|
||||
combine_attr_entries = map_new(int, int)();
|
||||
blend_attr_entries = map_new(int, int)();
|
||||
blendthrough_attr_entries = map_new(int, int)();
|
||||
|
||||
// index 0 is no attribute, add dummy entry:
|
||||
kv_push(attr_entries, ((HlEntry){ .attr = HLATTRS_INIT, .kind = kHlUnknown,
|
||||
@ -213,6 +217,8 @@ void clear_hl_tables(bool reinit)
|
||||
kv_size(attr_entries) = 1;
|
||||
map_clear(HlEntry, int)(attr_entry_ids);
|
||||
map_clear(int, int)(combine_attr_entries);
|
||||
map_clear(int, int)(blend_attr_entries);
|
||||
map_clear(int, int)(blendthrough_attr_entries);
|
||||
highlight_attr_set_all();
|
||||
highlight_changed();
|
||||
screen_invalidate_highlights();
|
||||
@ -220,15 +226,22 @@ void clear_hl_tables(bool reinit)
|
||||
kv_destroy(attr_entries);
|
||||
map_free(HlEntry, int)(attr_entry_ids);
|
||||
map_free(int, int)(combine_attr_entries);
|
||||
map_free(int, int)(blend_attr_entries);
|
||||
map_free(int, int)(blendthrough_attr_entries);
|
||||
}
|
||||
}
|
||||
|
||||
void hl_invalidate_blends(void)
|
||||
{
|
||||
map_clear(int, int)(blend_attr_entries);
|
||||
map_clear(int, int)(blendthrough_attr_entries);
|
||||
}
|
||||
|
||||
// Combine special attributes (e.g., for spelling) with other attributes
|
||||
// (e.g., for syntax highlighting).
|
||||
// "prim_attr" overrules "char_attr".
|
||||
// This creates a new group when required.
|
||||
// Since we expect there to be few spelling mistakes we don't cache the
|
||||
// result.
|
||||
// Since we expect there to be a lot of spelling mistakes we cache the result.
|
||||
// Return the resulting attributes.
|
||||
int hl_combine_attr(int char_attr, int prim_attr)
|
||||
{
|
||||
@ -283,6 +296,85 @@ int hl_combine_attr(int char_attr, int prim_attr)
|
||||
return id;
|
||||
}
|
||||
|
||||
/// Get the used rgb colors for an attr group.
|
||||
///
|
||||
/// If colors are unset, use builtin default colors. Never returns -1
|
||||
/// Cterm colors are unchanged.
|
||||
static HlAttrs get_colors_force(int attr)
|
||||
{
|
||||
HlAttrs attrs = syn_attr2entry(attr);
|
||||
if (attrs.rgb_bg_color == -1) {
|
||||
attrs.rgb_bg_color = normal_bg;
|
||||
}
|
||||
if (attrs.rgb_fg_color == -1) {
|
||||
attrs.rgb_fg_color = normal_fg;
|
||||
}
|
||||
if (attrs.rgb_sp_color == -1) {
|
||||
attrs.rgb_sp_color = normal_sp;
|
||||
}
|
||||
HL_SET_DEFAULT_COLORS(attrs.rgb_fg_color, attrs.rgb_bg_color,
|
||||
attrs.rgb_sp_color);
|
||||
return attrs;
|
||||
}
|
||||
|
||||
/// 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.
|
||||
/// @return the resulting attributes.
|
||||
int hl_blend_attrs(int back_attr, int front_attr, bool through)
|
||||
{
|
||||
int combine_tag = (back_attr << 16) + front_attr;
|
||||
Map(int, int) *map = through ? blendthrough_attr_entries : blend_attr_entries;
|
||||
int id = map_get(int, int)(map, combine_tag);
|
||||
if (id > 0) {
|
||||
return id;
|
||||
}
|
||||
|
||||
HlAttrs battrs = get_colors_force(back_attr);
|
||||
HlAttrs fattrs = get_colors_force(front_attr);
|
||||
HlAttrs cattrs;
|
||||
if (through) {
|
||||
cattrs = battrs;
|
||||
cattrs.rgb_fg_color = rgb_blend((int)p_pb, battrs.rgb_fg_color,
|
||||
fattrs.rgb_bg_color);
|
||||
cattrs.cterm_bg_color = fattrs.cterm_bg_color;
|
||||
cattrs.cterm_fg_color = fattrs.cterm_bg_color;
|
||||
} else {
|
||||
cattrs = fattrs;
|
||||
if (p_pb >= 50) {
|
||||
cattrs.rgb_ae_attr |= battrs.rgb_ae_attr;
|
||||
}
|
||||
cattrs.rgb_fg_color = rgb_blend((int)p_pb/2, battrs.rgb_fg_color,
|
||||
fattrs.rgb_fg_color);
|
||||
}
|
||||
cattrs.rgb_bg_color = rgb_blend((int)p_pb, battrs.rgb_bg_color,
|
||||
fattrs.rgb_bg_color);
|
||||
|
||||
HlKind kind = through ? kHlBlendThrough : kHlBlend;
|
||||
id = get_attr_entry((HlEntry){ .attr = cattrs, .kind = kind,
|
||||
.id1 = back_attr, .id2 = front_attr });
|
||||
if (id > 0) {
|
||||
map_put(int, int)(map, combine_tag, id);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
static int rgb_blend(int ratio, int rgb1, int rgb2)
|
||||
{
|
||||
int a = ratio, b = 100-ratio;
|
||||
int r1 = (rgb1 & 0xFF0000) >> 16;
|
||||
int g1 = (rgb1 & 0x00FF00) >> 8;
|
||||
int b1 = (rgb1 & 0x0000FF) >> 0;
|
||||
int r2 = (rgb2 & 0xFF0000) >> 16;
|
||||
int g2 = (rgb2 & 0x00FF00) >> 8;
|
||||
int b2 = (rgb2 & 0x0000FF) >> 0;
|
||||
int mr = (a * r1 + b * r2)/100;
|
||||
int mg = (a * g1 + b * g2)/100;
|
||||
int mb = (a * b1 + b * b2)/100;
|
||||
return (mr << 16) + (mg << 8) + mb;
|
||||
}
|
||||
|
||||
/// Get highlight attributes for a attribute code
|
||||
HlAttrs syn_attr2entry(int attr)
|
||||
{
|
||||
@ -406,6 +498,8 @@ static void hl_inspect_impl(Array *arr, int attr)
|
||||
break;
|
||||
|
||||
case kHlCombine:
|
||||
case kHlBlend:
|
||||
case kHlBlendThrough:
|
||||
// attribute combination is associative, so flatten to an array
|
||||
hl_inspect_impl(arr, e.id1);
|
||||
hl_inspect_impl(arr, e.id2);
|
||||
|
@ -10,4 +10,12 @@
|
||||
# include "highlight.h.generated.h"
|
||||
#endif
|
||||
|
||||
# define HL_SET_DEFAULT_COLORS(rgb_fg, rgb_bg, rgb_sp) \
|
||||
do { \
|
||||
bool dark_ = (*p_bg == 'd'); \
|
||||
rgb_fg = rgb_fg != -1 ? rgb_fg : (dark_ ? 0xFFFFFF : 0x000000); \
|
||||
rgb_bg = rgb_bg != -1 ? rgb_bg : (dark_ ? 0x000000 : 0xFFFFFF); \
|
||||
rgb_sp = rgb_sp != -1 ? rgb_sp : 0xFF0000; \
|
||||
} while (0);
|
||||
|
||||
#endif // NVIM_HIGHLIGHT_H
|
||||
|
@ -160,6 +160,8 @@ typedef enum {
|
||||
kHlSyntax,
|
||||
kHlTerminal,
|
||||
kHlCombine,
|
||||
kHlBlend,
|
||||
kHlBlendThrough,
|
||||
} HlKind;
|
||||
|
||||
typedef struct {
|
||||
|
@ -50,6 +50,7 @@
|
||||
#include "nvim/fold.h"
|
||||
#include "nvim/getchar.h"
|
||||
#include "nvim/hardcopy.h"
|
||||
#include "nvim/highlight.h"
|
||||
#include "nvim/indent_c.h"
|
||||
#include "nvim/mbyte.h"
|
||||
#include "nvim/memfile.h"
|
||||
@ -65,6 +66,7 @@
|
||||
#include "nvim/normal.h"
|
||||
#include "nvim/os_unix.h"
|
||||
#include "nvim/path.h"
|
||||
#include "nvim/popupmnu.h"
|
||||
#include "nvim/regexp.h"
|
||||
#include "nvim/screen.h"
|
||||
#include "nvim/spell.h"
|
||||
@ -4338,6 +4340,14 @@ static char *set_num_option(int opt_idx, char_u *varp, long value,
|
||||
if (p_uc && !old_value) {
|
||||
ml_open_files();
|
||||
}
|
||||
} else if (pp == &p_pb) {
|
||||
p_pb = MAX(MIN(p_pb, 100), 0);
|
||||
if (old_value != 0) {
|
||||
hl_invalidate_blends();
|
||||
}
|
||||
if (pum_drawn()) {
|
||||
pum_recompose();
|
||||
}
|
||||
} else if (pp == &p_pyx) {
|
||||
if (p_pyx != 0 && p_pyx != 2 && p_pyx != 3) {
|
||||
errmsg = e_invarg;
|
||||
|
@ -375,6 +375,7 @@ EXTERN int p_confirm; // 'confirm'
|
||||
EXTERN int p_cp; // 'compatible'
|
||||
EXTERN char_u *p_cot; // 'completeopt'
|
||||
EXTERN long p_ph; // 'pumheight'
|
||||
EXTERN long p_pb; // 'pumblend'
|
||||
EXTERN char_u *p_cpo; // 'cpoptions'
|
||||
EXTERN char_u *p_csprg; // 'cscopeprg'
|
||||
EXTERN int p_csre; // 'cscoperelative'
|
||||
|
@ -1805,6 +1805,14 @@ return {
|
||||
varname='p_ph',
|
||||
defaults={if_true={vi=0}}
|
||||
},
|
||||
{
|
||||
full_name='pumblend', abbreviation='pb',
|
||||
type='number', scope={'global'},
|
||||
vi_def=true,
|
||||
redraw={'ui_option'},
|
||||
varname='p_pb',
|
||||
defaults={if_true={vi=0}}
|
||||
},
|
||||
{
|
||||
full_name='pyxversion', abbreviation='pyx',
|
||||
type='number', scope={'global'},
|
||||
|
@ -44,6 +44,7 @@ static int pum_col; // left column of pum
|
||||
static bool pum_is_visible = false;
|
||||
static bool pum_is_drawn = false;
|
||||
static bool pum_external = false;
|
||||
static bool pum_invalid = false; // the screen was just cleared
|
||||
|
||||
static ScreenGrid pum_grid = SCREEN_GRID_INIT;
|
||||
|
||||
@ -360,12 +361,14 @@ void pum_redraw(void)
|
||||
grid_assign_handle(&pum_grid);
|
||||
bool moved = ui_comp_put_grid(&pum_grid, pum_row, pum_col-col_off,
|
||||
pum_height, grid_width);
|
||||
bool invalid_grid = moved || pum_invalid;
|
||||
pum_invalid = false;
|
||||
|
||||
if (!pum_grid.chars
|
||||
|| pum_grid.Rows != pum_height || pum_grid.Columns != grid_width) {
|
||||
grid_alloc(&pum_grid, pum_height, grid_width, !moved, false);
|
||||
grid_alloc(&pum_grid, pum_height, grid_width, !invalid_grid, false);
|
||||
ui_call_grid_resize(pum_grid.handle, pum_grid.Columns, pum_grid.Rows);
|
||||
} else if (moved) {
|
||||
} else if (invalid_grid) {
|
||||
grid_invalidate(&pum_grid);
|
||||
}
|
||||
|
||||
@ -806,6 +809,17 @@ bool pum_drawn(void)
|
||||
return pum_visible() && !pum_external;
|
||||
}
|
||||
|
||||
/// Screen was cleared, need to redraw next time
|
||||
void pum_invalidate(void)
|
||||
{
|
||||
pum_invalid = true;
|
||||
}
|
||||
|
||||
void pum_recompose(void)
|
||||
{
|
||||
ui_comp_compose_grid(&pum_grid);
|
||||
}
|
||||
|
||||
/// Gets the height of the menu.
|
||||
///
|
||||
/// @return the height of the popup menu, the number of entries visible.
|
||||
|
@ -154,7 +154,7 @@ static bool highlights_invalid = false;
|
||||
|
||||
static bool conceal_cursor_used = false;
|
||||
|
||||
static bool floats_invalid = false;
|
||||
static bool redraw_popupmenu = false;
|
||||
|
||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||
# include "screen.c.generated.h"
|
||||
@ -466,13 +466,13 @@ void update_screen(int type)
|
||||
|
||||
end_search_hl();
|
||||
// May need to redraw the popup menu.
|
||||
if (pum_drawn() && floats_invalid) {
|
||||
if (pum_drawn() && redraw_popupmenu) {
|
||||
pum_redraw();
|
||||
}
|
||||
|
||||
send_grid_resize = false;
|
||||
highlights_invalid = false;
|
||||
floats_invalid = false;
|
||||
redraw_popupmenu = false;
|
||||
|
||||
/* Reset b_mod_set flags. Going through all windows is probably faster
|
||||
* than going through all buffers (there could be many buffers). */
|
||||
@ -6185,7 +6185,6 @@ static void screenclear2(void)
|
||||
default_grid.line_wraps[i] = false;
|
||||
}
|
||||
|
||||
floats_invalid = true;
|
||||
ui_call_grid_clear(1); // clear the display
|
||||
clear_cmdline = false;
|
||||
mode_displayed = false;
|
||||
@ -6193,6 +6192,8 @@ static void screenclear2(void)
|
||||
redraw_all_later(NOT_VALID);
|
||||
redraw_cmdline = true;
|
||||
redraw_tabline = true;
|
||||
redraw_popupmenu = true;
|
||||
pum_invalidate();
|
||||
if (must_redraw == CLEAR) {
|
||||
must_redraw = NOT_VALID; // no need to clear again
|
||||
}
|
||||
@ -7196,6 +7197,10 @@ void screen_resize(int width, int height)
|
||||
} else {
|
||||
update_topline();
|
||||
if (pum_drawn()) {
|
||||
// TODO(bfredl): ins_compl_show_pum wants to redraw the screen first.
|
||||
// For now make sure the nested update_screen(0) won't redraw the
|
||||
// pum at the old position. Try to untangle this later.
|
||||
redraw_popupmenu = false;
|
||||
ins_compl_show_pum();
|
||||
}
|
||||
update_screen(NOT_VALID);
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "nvim/ascii.h"
|
||||
#include "nvim/vim.h"
|
||||
#include "nvim/ui.h"
|
||||
#include "nvim/highlight.h"
|
||||
#include "nvim/memory.h"
|
||||
#include "nvim/ui_compositor.h"
|
||||
#include "nvim/ugrid.h"
|
||||
@ -169,11 +170,9 @@ void ui_comp_remove_grid(ScreenGrid *grid)
|
||||
(void)kv_pop(layers);
|
||||
grid->comp_index = 0;
|
||||
|
||||
if (ui_comp_should_draw()) {
|
||||
// inefficent: only draw up to grid->comp_index
|
||||
compose_area(grid->comp_row, grid->comp_row+grid->Rows,
|
||||
grid->comp_col, grid->comp_col+grid->Columns);
|
||||
}
|
||||
// recompose the area under the grid
|
||||
// inefficent when being overlapped: only draw up to grid->comp_index
|
||||
ui_comp_compose_grid(grid);
|
||||
}
|
||||
|
||||
bool ui_comp_set_grid(handle_T handle)
|
||||
@ -229,6 +228,10 @@ static void compose_line(Integer row, Integer startcol, Integer endcol,
|
||||
|
||||
int col = (int)startcol;
|
||||
ScreenGrid *grid = NULL;
|
||||
schar_T *bg_line = &default_grid.chars[default_grid.line_offset[row]
|
||||
+(size_t)startcol];
|
||||
sattr_T *bg_attrs = &default_grid.attrs[default_grid.line_offset[row]
|
||||
+(size_t)startcol];
|
||||
|
||||
while (col < endcol) {
|
||||
int until = 0;
|
||||
@ -256,6 +259,16 @@ 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));
|
||||
|
||||
if (grid != &default_grid && p_pb) {
|
||||
for (int i = col-(int)startcol; i < until-startcol; i++) {
|
||||
bool thru = strequal((char *)linebuf[i], " ");
|
||||
attrbuf[i] = (sattr_T)hl_blend_attrs(bg_attrs[i], attrbuf[i], thru);
|
||||
if (thru) {
|
||||
memcpy(linebuf[i], bg_line[i], sizeof(linebuf[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tricky: if overlap caused a doublewidth char to get cut-off, must
|
||||
// replace the visible half with a space.
|
||||
if (linebuf[col-startcol][0] == NUL) {
|
||||
@ -272,6 +285,7 @@ static void compose_line(Integer row, Integer startcol, Integer endcol,
|
||||
skip = 0;
|
||||
}
|
||||
}
|
||||
|
||||
col = until;
|
||||
}
|
||||
assert(endcol <= chk_width);
|
||||
@ -293,11 +307,25 @@ static void compose_area(Integer startrow, Integer endrow,
|
||||
{
|
||||
endrow = MIN(endrow, default_grid.Rows);
|
||||
endcol = MIN(endcol, default_grid.Columns);
|
||||
if (endcol <= startcol) {
|
||||
return;
|
||||
}
|
||||
for (int r = (int)startrow; r < endrow; r++) {
|
||||
compose_line(r, startcol, endcol, kLineFlagInvalid);
|
||||
}
|
||||
}
|
||||
|
||||
/// compose the area under the grid.
|
||||
///
|
||||
/// This is needed when some option affecting composition is changed,
|
||||
/// such as 'pumblend' for popupmenu grid.
|
||||
void ui_comp_compose_grid(ScreenGrid *grid)
|
||||
{
|
||||
if (ui_comp_should_draw()) {
|
||||
compose_area(grid->comp_row, grid->comp_row+grid->Rows,
|
||||
grid->comp_col, grid->comp_col+grid->Columns);
|
||||
}
|
||||
}
|
||||
|
||||
static void ui_comp_raw_line(UI *ui, Integer grid, Integer row,
|
||||
Integer startcol, Integer endcol,
|
||||
@ -316,8 +344,10 @@ static void ui_comp_raw_line(UI *ui, Integer grid, Integer row,
|
||||
if (curgrid != &default_grid) {
|
||||
flags = flags & ~kLineFlagWrap;
|
||||
}
|
||||
assert(row < default_grid.Rows);
|
||||
assert(clearcol <= default_grid.Columns);
|
||||
if (flags & kLineFlagInvalid || kv_size(layers) > curgrid->comp_index+1) {
|
||||
if (flags & kLineFlagInvalid
|
||||
|| kv_size(layers) > (p_pb ? 1 : curgrid->comp_index+1)) {
|
||||
compose_line(row, startcol, clearcol, flags);
|
||||
} else {
|
||||
ui_composed_call_raw_line(1, row, startcol, endcol, clearcol, clearattr,
|
||||
|
@ -18,6 +18,7 @@ describe('ui receives option updates', function()
|
||||
guifontset='',
|
||||
guifontwide='',
|
||||
linespace=0,
|
||||
pumblend=0,
|
||||
showtabline=1,
|
||||
termguicolors=false,
|
||||
ext_cmdline=false,
|
||||
|
@ -999,9 +999,52 @@ describe('builtin popupmenu', function()
|
||||
{1:~ }|
|
||||
{2:-- INSERT --} |
|
||||
]])
|
||||
|
||||
screen:try_resize(25,10)
|
||||
screen:expect([[
|
||||
some long prefix before |
|
||||
the text^ |
|
||||
{1:~ }{n: word }{1: }|
|
||||
{1:~ }{n: choice }{1: }|
|
||||
{1:~ }{s: text }{1: }|
|
||||
{1:~ }{n: thing }{1: }|
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
{2:-- INSERT --} |
|
||||
]])
|
||||
|
||||
screen:try_resize(12,5)
|
||||
screen:expect([[
|
||||
some long |
|
||||
prefix |
|
||||
bef{n: word } |
|
||||
tex{n: }^ |
|
||||
{2:-- }{s: text } |
|
||||
]])
|
||||
|
||||
-- can't draw the pum, but check we don't crash
|
||||
screen:try_resize(12,2)
|
||||
screen:expect([[
|
||||
text^ |
|
||||
{2:-- INSERT -} |
|
||||
]])
|
||||
|
||||
-- but state is preserved, pum reappears
|
||||
screen:try_resize(20,8)
|
||||
screen:expect([[
|
||||
some long prefix |
|
||||
before the text^ |
|
||||
{1:~ }{n: word }|
|
||||
{1:~ }{n: choice }|
|
||||
{1:~ }{s: text }|
|
||||
{1:~ }{n: thing }|
|
||||
{1:~ }|
|
||||
{2:-- INSERT --} |
|
||||
]])
|
||||
end)
|
||||
|
||||
it('can be moved due to wrap or resize', function()
|
||||
it('works with rightleft window', function()
|
||||
command("set rl")
|
||||
feed('isome rightleft ')
|
||||
screen:expect([[
|
||||
@ -1230,4 +1273,176 @@ describe('builtin popupmenu', function()
|
||||
]])
|
||||
end)
|
||||
|
||||
it('works with pumblend', function()
|
||||
screen:try_resize(60,14)
|
||||
screen:set_default_attr_ids({
|
||||
[1] = {background = Screen.colors.Yellow},
|
||||
[2] = {bold = true, reverse = true},
|
||||
[3] = {bold = true, foreground = Screen.colors.Brown},
|
||||
[4] = {foreground = Screen.colors.Blue1},
|
||||
[5] = {reverse = true},
|
||||
[6] = {background = Screen.colors.Gray55, foreground = Screen.colors.Grey45, special = Screen.colors.Red},
|
||||
[7] = {background = Screen.colors.Gray55, foreground = Screen.colors.Grey0, special = Screen.colors.Red},
|
||||
[8] = {background = tonumber('0x191919'), foreground = Screen.colors.Grey0, special = Screen.colors.Red},
|
||||
[9] = {background = tonumber('0xffc1ff'), foreground = tonumber('0xe5a8e5'), special = Screen.colors.Red},
|
||||
[10] = {background = tonumber('0xffc1ff'), foreground = Screen.colors.Grey0, special = Screen.colors.Red},
|
||||
[11] = {foreground = tonumber('0xe5a8e5'), special = Screen.colors.Red, background = tonumber('0xffc1ff'), reverse = true, bold = true},
|
||||
[12] = {foreground = Screen.colors.Grey45, special = Screen.colors.Red, background = Screen.colors.Gray55, reverse = true, bold = true},
|
||||
[13] = {background = tonumber('0xffc1e5'), foreground = Screen.colors.Grey0, special = Screen.colors.Red},
|
||||
[14] = {background = tonumber('0xffc1e5'), foreground = tonumber('0xe5a8e5'), special = Screen.colors.Red},
|
||||
[15] = {background = tonumber('0xffc1ff'), foreground = tonumber('0x080202'), special = Screen.colors.Red},
|
||||
[16] = {special = Screen.colors.Red, background = tonumber('0xffc1ff'), bold = true, foreground = tonumber('0xf6ace9')},
|
||||
[17] = {background = tonumber('0xffc1ff'), foreground = tonumber('0xe5a8ff'), special = Screen.colors.Red},
|
||||
[18] = {special = Screen.colors.Red, background = tonumber('0xffc1ff'), reverse = true, foreground = tonumber('0xe5a8e5')},
|
||||
[19] = {special = Screen.colors.Red, background = Screen.colors.Gray55, reverse = true, foreground = Screen.colors.Grey45},
|
||||
[20] = {bold = true},
|
||||
[21] = {bold = true, foreground = Screen.colors.SeaGreen4},
|
||||
[22] = {background = Screen.colors.WebGray},
|
||||
[23] = {background = Screen.colors.Grey0},
|
||||
[24] = {background = Screen.colors.LightMagenta},
|
||||
[25] = {background = Screen.colors.Gray75, foreground = Screen.colors.Grey25, special = Screen.colors.Red},
|
||||
[26] = {background = Screen.colors.Gray75, foreground = Screen.colors.Grey0, special = Screen.colors.Red},
|
||||
[27] = {background = Screen.colors.Gray50, foreground = Screen.colors.Grey0, special = Screen.colors.Red},
|
||||
[28] = {background = tonumber('0xffddff'), foreground = tonumber('0x7f5d7f'), special = Screen.colors.Red},
|
||||
[29] = {background = tonumber('0xffddff'), foreground = Screen.colors.Grey0, special = Screen.colors.Red},
|
||||
[30] = {foreground = tonumber('0x7f5d7f'), special = Screen.colors.Red, background = tonumber('0xffddff'), reverse = true, bold = true},
|
||||
[31] = {foreground = Screen.colors.Grey0, special = Screen.colors.Red, background = tonumber('0xffddff'), reverse = true, bold = true},
|
||||
[32] = {foreground = Screen.colors.Grey25, special = Screen.colors.Red, background = Screen.colors.Gray75, reverse = true, bold = true},
|
||||
[33] = {background = tonumber('0xffdd7f'), foreground = Screen.colors.Grey0, special = Screen.colors.Red},
|
||||
[34] = {background = tonumber('0xffdd7f'), foreground = tonumber('0x7f5d7f'), special = Screen.colors.Red},
|
||||
[35] = {special = Screen.colors.Red, background = tonumber('0xffddff'), bold = true, foreground = tonumber('0x290a0a')},
|
||||
[36] = {special = Screen.colors.Red, background = tonumber('0xffddff'), bold = true, foreground = tonumber('0xd27294')},
|
||||
[37] = {background = tonumber('0xffddff'), foreground = tonumber('0x7f5dff'), special = Screen.colors.Red},
|
||||
[38] = {special = Screen.colors.Red, background = tonumber('0xffddff'), reverse = true, foreground = tonumber('0x7f5d7f')},
|
||||
[39] = {special = Screen.colors.Red, background = tonumber('0xffddff'), reverse = true, foreground = Screen.colors.Grey0},
|
||||
[40] = {special = Screen.colors.Red, background = Screen.colors.Gray75, reverse = true, foreground = Screen.colors.Grey25},
|
||||
[41] = {background = tonumber('0xffddff'), foreground = tonumber('0x00003f'), special = Screen.colors.Red},
|
||||
})
|
||||
command('syntax on')
|
||||
command('set mouse=a')
|
||||
command('set 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
|
||||
exercitation ullamco laboris nisi ut aliquip ex
|
||||
ea commodo consequat. Duis aute irure dolor in
|
||||
reprehenderit in voluptate velit esse cillum
|
||||
dolore eu fugiat nulla pariatur. Excepteur sint
|
||||
occaecat cupidatat non proident, sunt in culpa
|
||||
qui officia deserunt mollit anim id est
|
||||
laborum.]])
|
||||
command('match Statement /el/')
|
||||
command('2match Comment /ut/')
|
||||
command('1')
|
||||
command('split')
|
||||
command('/ol')
|
||||
screen:expect([[
|
||||
Lorem ipsum d{1:ol}or sit amet, consectetur |
|
||||
adipisicing elit, sed do eiusmod tempor |
|
||||
^incididunt ut labore et d{1:ol}ore magna aliqua. |
|
||||
Ut enim ad minim veniam, quis nostrud |
|
||||
exercitation ullamco laboris nisi ut aliquip ex |
|
||||
ea commodo consequat. Duis aute irure d{1:ol}or in |
|
||||
{2:[No Name] [+] }|
|
||||
Lorem ipsum d{1:ol}or sit amet, consectetur |
|
||||
adipisicing {3:el}it, sed do eiusmod tempor |
|
||||
incididunt {4:ut} labore et d{1:ol}ore magna aliqua. |
|
||||
Ut enim ad minim veniam, quis nostrud |
|
||||
exercitation ullamco laboris nisi {4:ut} aliquip ex |
|
||||
{5:[No Name] [+] }|
|
||||
|
|
||||
]])
|
||||
|
||||
feed('Obla bla <c-x><c-n>')
|
||||
screen:expect([[
|
||||
Lorem ipsum d{1:ol}or sit amet, consectetur |
|
||||
adipisicing elit, sed do eiusmod tempor |
|
||||
bla bla incididunt^ |
|
||||
incidid{6:u}{7:incididunt}{6:re et}{8: }d{1:ol}ore magna aliqua. |
|
||||
Ut enim{9: }{10:ut}{9: minim veniam}{6:,} quis nostrud |
|
||||
exercit{9:a}{10:labore}{9:llamco la}{6:b}oris nisi ut aliquip ex |
|
||||
{2:[No Nam}{11:e}{10:et}{11:[+] }{12: }{2: }|
|
||||
Lorem i{9:p}{10:dolor}{13:e}{14:l}{9:or sit a}{6:m}et, consectetur |
|
||||
adipisi{9:c}{10:magn}{15:a}{16:l}{9:it, sed d}{6:o} eiusmod tempor |
|
||||
bla bla{9: }{10:aliqua}{9:dunt }{6: } |
|
||||
incidid{9:u}{10:Ut}{9: }{17:ut}{9: labore et}{6: }d{1:ol}ore magna aliqua. |
|
||||
Ut enim{9: }{10:enim}{9:inim veniam}{6:,} quis nostrud |
|
||||
{5:[No Nam}{18:e}{10:ad}{18:[+] }{19: }{5: }|
|
||||
{20:-- Keyword Local completion (^N^P) }{21:match 1 of 65} |
|
||||
]])
|
||||
|
||||
command('set pumblend=0')
|
||||
screen:expect([[
|
||||
Lorem ipsum d{1:ol}or sit amet, consectetur |
|
||||
adipisicing elit, sed do eiusmod tempor |
|
||||
bla bla incididunt^ |
|
||||
incidid{22: incididunt }{23: }d{1:ol}ore magna aliqua. |
|
||||
Ut enim{24: ut }{22: } quis nostrud |
|
||||
exercit{24: labore }{22: }oris nisi ut aliquip ex |
|
||||
{2:[No Nam}{24: et }{22: }{2: }|
|
||||
Lorem i{24: dolore }{22: }et, consectetur |
|
||||
adipisi{24: magna }{22: } eiusmod tempor |
|
||||
bla bla{24: aliqua }{22: } |
|
||||
incidid{24: Ut }{22: }d{1:ol}ore magna aliqua. |
|
||||
Ut enim{24: enim }{22: } quis nostrud |
|
||||
{5:[No Nam}{24: ad }{22: }{5: }|
|
||||
{20:-- Keyword Local completion (^N^P) }{21:match 1 of 65} |
|
||||
]])
|
||||
|
||||
command('set pumblend=50')
|
||||
screen:expect([[
|
||||
Lorem ipsum d{1:ol}or sit amet, consectetur |
|
||||
adipisicing elit, sed do eiusmod tempor |
|
||||
bla bla incididunt^ |
|
||||
incidid{25:u}{26:incididunt}{25:re et}{27: }d{1:ol}ore magna aliqua. |
|
||||
Ut enim{28: }{29:ut}{28: minim veniam}{25:,} quis nostrud |
|
||||
exercit{28:a}{29:labore}{28:llamco la}{25:b}oris nisi ut aliquip ex |
|
||||
{2:[No Nam}{30:e}{31:et}{30:[+] }{32: }{2: }|
|
||||
Lorem i{28:p}{29:dolor}{33:e}{34:l}{28:or sit a}{25:m}et, consectetur |
|
||||
adipisi{28:c}{29:magn}{35:a}{36:l}{28:it, sed d}{25:o} eiusmod tempor |
|
||||
bla bla{28: }{29:aliqua}{28:dunt }{25: } |
|
||||
incidid{28:u}{29:Ut}{28: }{37:ut}{28: labore et}{25: }d{1:ol}ore magna aliqua. |
|
||||
Ut enim{28: }{29:enim}{28:inim veniam}{25:,} quis nostrud |
|
||||
{5:[No Nam}{38:e}{39:ad}{38:[+] }{40: }{5: }|
|
||||
{20:-- Keyword Local completion (^N^P) }{21:match 1 of 65} |
|
||||
]])
|
||||
|
||||
meths.input_mouse('wheel', 'down', '', 0, 9, 40)
|
||||
screen:expect([[
|
||||
Lorem ipsum d{1:ol}or sit amet, consectetur |
|
||||
adipisicing elit, sed do eiusmod tempor |
|
||||
bla bla incididunt^ |
|
||||
incidid{25:u}{26:incididunt}{25:re et}{27: }d{1:ol}ore magna aliqua. |
|
||||
Ut enim{28: }{29:ut}{28: minim veniam}{25:,} quis nostrud |
|
||||
exercit{28:a}{29:labore}{28:llamco la}{25:b}oris nisi ut aliquip ex |
|
||||
{2:[No Nam}{30:e}{31:et}{30:[+] }{32: }{2: }|
|
||||
incidid{28:u}{29:dol}{41:or}{29:e}{28:labore et}{25: }d{1:ol}ore magna aliqua. |
|
||||
Ut enim{28: }{29:magna}{28:nim veniam}{25:,} quis nostrud |
|
||||
exercit{28:a}{29:aliqua}{28:llamco la}{25:b}oris nisi {4:ut} aliquip ex |
|
||||
ea comm{28:o}{29:Ut}{28: consequat. D}{25:u}is a{4:ut}e irure d{1:ol}or in |
|
||||
reprehe{28:n}{29:enim}{28:t in v}{34:ol}{28:upt}{25:a}te v{3:el}it esse cillum |
|
||||
{5:[No Nam}{38:e}{39:ad}{38:[+] }{40: }{5: }|
|
||||
{20:-- Keyword Local completion (^N^P) }{21:match 1 of 65} |
|
||||
]])
|
||||
|
||||
feed('<c-e>')
|
||||
screen:expect([[
|
||||
Lorem ipsum d{1:ol}or sit amet, consectetur |
|
||||
adipisicing elit, sed do eiusmod tempor |
|
||||
bla bla ^ |
|
||||
incididunt ut labore et d{1:ol}ore magna aliqua. |
|
||||
Ut enim ad minim veniam, quis nostrud |
|
||||
exercitation ullamco laboris nisi ut aliquip ex |
|
||||
{2:[No Name] [+] }|
|
||||
incididunt {4:ut} labore et d{1:ol}ore magna aliqua. |
|
||||
Ut enim ad minim veniam, quis nostrud |
|
||||
exercitation ullamco laboris nisi {4:ut} aliquip ex |
|
||||
ea commodo consequat. Duis a{4:ut}e irure d{1:ol}or in |
|
||||
reprehenderit in v{1:ol}uptate v{3:el}it esse cillum |
|
||||
{5:[No Name] [+] }|
|
||||
{20:-- INSERT --} |
|
||||
]])
|
||||
end)
|
||||
end)
|
||||
|
@ -1303,6 +1303,8 @@ function Screen:_pprint_attrs(attrs)
|
||||
if f == "foreground" or f == "background" or f == "special" then
|
||||
if Screen.colornames[v] ~= nil then
|
||||
desc = "Screen.colors."..Screen.colornames[v]
|
||||
else
|
||||
desc = string.format("tonumber('0x%06x')",v)
|
||||
end
|
||||
end
|
||||
table.insert(items, f.." = "..desc)
|
||||
|
Loading…
Reference in New Issue
Block a user