mirror of
https://github.com/neovim/neovim.git
synced 2024-12-29 14:41:06 -07:00
feat(ui): add support to display a title in the border of a float (#20184)
add "title" and "title_pos" keys to win config dict.
This commit is contained in:
parent
a79d28e4d7
commit
1af4bd04f9
@ -3068,6 +3068,11 @@ nvim_open_win({buffer}, {enter}, {*config}) *nvim_open_win()*
|
||||
specified by character: [ {"+", "MyCorner"}, {"x",
|
||||
"MyBorder"} ].
|
||||
|
||||
• title: Title (optional) in window border, String or list.
|
||||
List is [text, highlight] tuples. if is string the default
|
||||
highlight group is `FloatBorderTitle`.
|
||||
• title_pos: Title position must set with title option.
|
||||
value can be of `left` `center` `right` default is left.
|
||||
• noautocmd: If true then no buffer-related autocommand
|
||||
events such as |BufEnter|, |BufLeave| or |BufWinEnter| may
|
||||
fire from calling this function.
|
||||
|
@ -81,6 +81,8 @@ return {
|
||||
"focusable";
|
||||
"zindex";
|
||||
"border";
|
||||
"title";
|
||||
"title_pos";
|
||||
"style";
|
||||
"noautocmd";
|
||||
};
|
||||
|
@ -2,14 +2,17 @@
|
||||
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
||||
|
||||
#include <assert.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "nvim/api/extmark.h"
|
||||
#include "nvim/api/private/defs.h"
|
||||
#include "nvim/api/private/helpers.h"
|
||||
#include "nvim/api/win_config.h"
|
||||
#include "nvim/ascii.h"
|
||||
#include "nvim/buffer_defs.h"
|
||||
#include "nvim/drawscreen.h"
|
||||
#include "nvim/highlight_group.h"
|
||||
#include "nvim/option.h"
|
||||
@ -134,6 +137,11 @@
|
||||
/// By default, `FloatBorder` highlight is used, which links to `WinSeparator`
|
||||
/// when not defined. It could also be specified by character:
|
||||
/// [ {"+", "MyCorner"}, {"x", "MyBorder"} ].
|
||||
/// - title: Title (optional) in window border, String or list.
|
||||
/// List is [text, highlight] tuples. if is string the default
|
||||
/// highlight group is `FloatBorderTitle`.
|
||||
/// - title_pos: Title position must set with title option.
|
||||
/// value can be of `left` `center` `right` default is left.
|
||||
/// - noautocmd: If true then no buffer-related autocommand events such as
|
||||
/// |BufEnter|, |BufLeave| or |BufWinEnter| may fire from
|
||||
/// calling this function.
|
||||
@ -273,6 +281,21 @@ Dictionary nvim_win_get_config(Window window, Error *err)
|
||||
}
|
||||
}
|
||||
PUT(rv, "border", ARRAY_OBJ(border));
|
||||
if (config->title) {
|
||||
Array titles = ARRAY_DICT_INIT;
|
||||
VirtText title_datas = config->title_chunks;
|
||||
for (size_t i = 0; i < title_datas.size; i++) {
|
||||
Array tuple = ARRAY_DICT_INIT;
|
||||
ADD(tuple, CSTR_TO_OBJ((const char *)title_datas.items[i].text));
|
||||
if (title_datas.items[i].hl_id > 0) {
|
||||
ADD(tuple,
|
||||
STRING_OBJ(cstr_to_string((const char *)syn_id2name(title_datas.items[i].hl_id))));
|
||||
}
|
||||
ADD(titles, ARRAY_OBJ(tuple));
|
||||
}
|
||||
PUT(rv, "title", ARRAY_OBJ(titles));
|
||||
PUT(rv, "title_pos", INTEGER_OBJ(config->title_pos));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -330,7 +353,75 @@ static bool parse_float_bufpos(Array bufpos, lpos_T *out)
|
||||
return true;
|
||||
}
|
||||
|
||||
static void parse_border_style(Object style, FloatConfig *fconfig, Error *err)
|
||||
static void parse_border_title(Object title, Object title_pos, FloatConfig *fconfig, Error *err)
|
||||
{
|
||||
if (!parse_title_pos(title_pos, fconfig, err)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (title.type == kObjectTypeString) {
|
||||
if (title.data.string.size == 0) {
|
||||
fconfig->title = false;
|
||||
return;
|
||||
}
|
||||
int hl_id = syn_check_group(S_LEN("FloatBorderTitle"));
|
||||
kv_push(fconfig->title_chunks, ((VirtTextChunk){ .text = xstrdup(title.data.string.data),
|
||||
.hl_id = hl_id }));
|
||||
fconfig->title_width = (int)mb_string2cells(title.data.string.data);
|
||||
fconfig->title = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (title.type != kObjectTypeArray) {
|
||||
api_set_error(err, kErrorTypeValidation, "title must be string or array");
|
||||
return;
|
||||
}
|
||||
|
||||
if (title.type == kObjectTypeArray && title.data.array.size == 0) {
|
||||
api_set_error(err, kErrorTypeValidation, "title cannot be an empty array");
|
||||
return;
|
||||
}
|
||||
|
||||
fconfig->title_width = 0;
|
||||
fconfig->title_chunks = parse_virt_text(title.data.array, err, &fconfig->title_width);
|
||||
|
||||
fconfig->title = true;
|
||||
return;
|
||||
}
|
||||
|
||||
static bool parse_title_pos(Object title_pos, FloatConfig *fconfig, Error *err)
|
||||
{
|
||||
if (!HAS_KEY(title_pos)) {
|
||||
fconfig->title_pos = kAlignLeft;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (title_pos.type != kObjectTypeString) {
|
||||
api_set_error(err, kErrorTypeValidation, "title_pos must be string");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (title_pos.data.string.size == 0) {
|
||||
fconfig->title_pos = kAlignLeft;
|
||||
return true;
|
||||
}
|
||||
|
||||
char *pos = title_pos.data.string.data;
|
||||
|
||||
if (strequal(pos, "left")) {
|
||||
fconfig->title_pos = kAlignLeft;
|
||||
} else if (strequal(pos, "center")) {
|
||||
fconfig->title_pos = kAlignCenter;
|
||||
} else if (strequal(pos, "right")) {
|
||||
fconfig->title_pos = kAlignRight;
|
||||
} else {
|
||||
api_set_error(err, kErrorTypeValidation, "invalid title_pos value");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void parse_border_style(Object style, FloatConfig *fconfig, Error *err)
|
||||
{
|
||||
struct {
|
||||
const char *name;
|
||||
@ -414,6 +505,8 @@ static void parse_border_style(Object style, FloatConfig *fconfig, Error *err)
|
||||
String str = style.data.string;
|
||||
if (str.size == 0 || strequal(str.data, "none")) {
|
||||
fconfig->border = false;
|
||||
// title does not work with border equal none
|
||||
fconfig->title = false;
|
||||
return;
|
||||
}
|
||||
for (size_t i = 0; defaults[i].name; i++) {
|
||||
@ -603,6 +696,29 @@ static bool parse_float_config(Dict(float_config) *config, FloatConfig *fconfig,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (HAS_KEY(config->title_pos)) {
|
||||
if (!HAS_KEY(config->title)) {
|
||||
api_set_error(err, kErrorTypeException, "title_pos requires title to be set");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (HAS_KEY(config->title)) {
|
||||
// title only work with border
|
||||
if (!HAS_KEY(config->border) && !fconfig->border) {
|
||||
api_set_error(err, kErrorTypeException, "title requires border to be set");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fconfig->title) {
|
||||
clear_virttext(&fconfig->title_chunks);
|
||||
}
|
||||
parse_border_title(config->title, config->title_pos, fconfig, err);
|
||||
if (ERROR_SET(err)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (HAS_KEY(config->border)) {
|
||||
parse_border_style(config->border, fconfig, err);
|
||||
if (ERROR_SET(err)) {
|
||||
|
@ -44,6 +44,8 @@ typedef struct {
|
||||
#include "klib/kvec.h"
|
||||
// for marktree
|
||||
#include "nvim/marktree.h"
|
||||
// for float window title
|
||||
#include "nvim/extmark_defs.h"
|
||||
|
||||
#define GETFILE_SUCCESS(x) ((x) <= 0)
|
||||
#define MODIFIABLE(buf) (buf->b_p_ma)
|
||||
@ -1048,6 +1050,12 @@ typedef enum {
|
||||
kWinStyleMinimal, /// Minimal UI: no number column, eob markers, etc
|
||||
} WinStyle;
|
||||
|
||||
typedef enum {
|
||||
kAlignLeft = 0,
|
||||
kAlignCenter = 1,
|
||||
kAlignRight = 2,
|
||||
} AlignTextPos;
|
||||
|
||||
typedef struct {
|
||||
Window window;
|
||||
lpos_T bufpos;
|
||||
@ -1060,10 +1068,14 @@ typedef struct {
|
||||
int zindex;
|
||||
WinStyle style;
|
||||
bool border;
|
||||
bool title;
|
||||
bool shadow;
|
||||
schar_T border_chars[8];
|
||||
int border_hl_ids[8];
|
||||
int border_attr[8];
|
||||
AlignTextPos title_pos;
|
||||
VirtText title_chunks;
|
||||
int title_width;
|
||||
bool noautocmd;
|
||||
} FloatConfig;
|
||||
|
||||
|
@ -28,7 +28,6 @@ typedef enum {
|
||||
|
||||
EXTERN const char *const hl_mode_str[] INIT(= { "", "replace", "combine", "blend" });
|
||||
|
||||
typedef kvec_t(VirtTextChunk) VirtText;
|
||||
#define VIRTTEXT_EMPTY ((VirtText)KV_INITIAL_VALUE)
|
||||
|
||||
typedef kvec_t(struct virt_line { VirtText line; bool left_col; }) VirtLines;
|
||||
|
@ -60,11 +60,13 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "nvim/buffer.h"
|
||||
#include "nvim/buffer_defs.h"
|
||||
#include "nvim/charset.h"
|
||||
#include "nvim/cmdexpand.h"
|
||||
#include "nvim/diff.h"
|
||||
#include "nvim/drawscreen.h"
|
||||
#include "nvim/ex_getln.h"
|
||||
#include "nvim/extmark_defs.h"
|
||||
#include "nvim/grid.h"
|
||||
#include "nvim/highlight.h"
|
||||
#include "nvim/highlight_group.h"
|
||||
@ -614,6 +616,20 @@ int update_screen(void)
|
||||
return OK;
|
||||
}
|
||||
|
||||
static void win_border_redr_title(win_T *wp, ScreenGrid *grid, int col)
|
||||
{
|
||||
VirtText title_chunks = wp->w_float_config.title_chunks;
|
||||
|
||||
for (size_t i = 0; i < title_chunks.size; i++) {
|
||||
char *text = title_chunks.items[i].text;
|
||||
int cell = (int)mb_string2cells(text);
|
||||
int hl_id = title_chunks.items[i].hl_id;
|
||||
int attr = hl_id ? syn_id2attr(hl_id) : 0;
|
||||
grid_puts(grid, text, 0, col, attr);
|
||||
col += cell;
|
||||
}
|
||||
}
|
||||
|
||||
static void win_redr_border(win_T *wp)
|
||||
{
|
||||
wp->w_redr_border = false;
|
||||
@ -634,9 +650,24 @@ static void win_redr_border(win_T *wp)
|
||||
if (adj[3]) {
|
||||
grid_put_schar(grid, 0, 0, chars[0], attrs[0]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < icol; i++) {
|
||||
grid_put_schar(grid, 0, i + adj[3], chars[1], attrs[1]);
|
||||
}
|
||||
|
||||
if (wp->w_float_config.title) {
|
||||
int title_col = 0;
|
||||
int title_width = wp->w_float_config.title_width;
|
||||
AlignTextPos title_pos = wp->w_float_config.title_pos;
|
||||
|
||||
if (title_pos == kAlignCenter) {
|
||||
title_col = (icol - title_width) / 2 + 1;
|
||||
} else {
|
||||
title_col = title_pos == kAlignLeft ? 1 : icol - title_width + 1;
|
||||
}
|
||||
|
||||
win_border_redr_title(wp, grid, title_col);
|
||||
}
|
||||
if (adj[1]) {
|
||||
grid_put_schar(grid, 0, icol + adj[3], chars[2], attrs[2]);
|
||||
}
|
||||
|
@ -9,6 +9,8 @@ typedef struct {
|
||||
int hl_id;
|
||||
} VirtTextChunk;
|
||||
|
||||
typedef kvec_t(VirtTextChunk) VirtText;
|
||||
|
||||
typedef struct undo_object ExtmarkUndoObject;
|
||||
typedef kvec_t(ExtmarkUndoObject) extmark_undo_vec_t;
|
||||
|
||||
|
@ -114,6 +114,7 @@ typedef enum {
|
||||
HLF_WBR, // Window bars
|
||||
HLF_WBRNC, // Window bars of not-current windows
|
||||
HLF_CU, // Cursor
|
||||
HLF_BTITLE, // Float Border Title
|
||||
HLF_COUNT, // MUST be the last one
|
||||
} hlf_T;
|
||||
|
||||
@ -178,6 +179,7 @@ EXTERN const char *hlf_names[] INIT(= {
|
||||
[HLF_WBR] = "WinBar",
|
||||
[HLF_WBRNC] = "WinBarNC",
|
||||
[HLF_CU] = "Cursor",
|
||||
[HLF_BTITLE] = "FloatBorderTitle",
|
||||
});
|
||||
|
||||
EXTERN int highlight_attr[HLF_COUNT + 1]; // Highl. attr for each context.
|
||||
|
@ -131,6 +131,7 @@ static const char *highlight_init_both[] = {
|
||||
"default link MsgSeparator StatusLine",
|
||||
"default link NormalFloat Pmenu",
|
||||
"default link FloatBorder WinSeparator",
|
||||
"default link FloatBorderTitle Title",
|
||||
"default FloatShadow blend=80 guibg=Black",
|
||||
"default FloatShadowThrough blend=100 guibg=Black",
|
||||
"RedrawDebugNormal cterm=reverse gui=reverse",
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <assert.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "nvim/api/private/helpers.h"
|
||||
#include "nvim/api/vim.h"
|
||||
@ -5066,6 +5067,9 @@ static void win_free(win_T *wp, tabpage_T *tp)
|
||||
}
|
||||
}
|
||||
|
||||
// free the border title text
|
||||
clear_virttext(&wp->w_float_config.title_chunks);
|
||||
|
||||
clear_matches(wp);
|
||||
|
||||
free_jumplist(wp);
|
||||
|
@ -215,7 +215,7 @@ describe('ui/cursor', function()
|
||||
m.hl_id = 60
|
||||
m.attr = {background = Screen.colors.DarkGray}
|
||||
end
|
||||
if m.id_lm then m.id_lm = 61 end
|
||||
if m.id_lm then m.id_lm = 62 end
|
||||
end
|
||||
|
||||
-- Assert the new expectation.
|
||||
|
@ -1716,6 +1716,200 @@ describe('float window', function()
|
||||
end
|
||||
end)
|
||||
|
||||
it('validates title title_pos', function()
|
||||
local buf = meths.create_buf(false,false)
|
||||
eq("title requires border to be set",
|
||||
pcall_err(meths.open_win,buf, false, {
|
||||
relative='editor', width=9, height=2, row=2, col=5, title='Title',
|
||||
}))
|
||||
eq("title_pos requires title to be set",
|
||||
pcall_err(meths.open_win,buf, false, {
|
||||
relative='editor', width=9, height=2, row=2, col=5,
|
||||
border='single', title_pos='left',
|
||||
}))
|
||||
end)
|
||||
|
||||
it('border with title', function()
|
||||
local buf = meths.create_buf(false, false)
|
||||
meths.buf_set_lines(buf, 0, -1, true, {' halloj! ',
|
||||
' BORDAA '})
|
||||
local win = meths.open_win(buf, false, {
|
||||
relative='editor', width=9, height=2, row=2, col=5, border="double",
|
||||
title = "Left",title_pos = "left",
|
||||
})
|
||||
|
||||
if multigrid then
|
||||
screen:expect{grid=[[
|
||||
## grid 1
|
||||
[2:----------------------------------------]|
|
||||
[2:----------------------------------------]|
|
||||
[2:----------------------------------------]|
|
||||
[2:----------------------------------------]|
|
||||
[2:----------------------------------------]|
|
||||
[2:----------------------------------------]|
|
||||
[3:----------------------------------------]|
|
||||
## grid 2
|
||||
^ |
|
||||
{0:~ }|
|
||||
{0:~ }|
|
||||
{0:~ }|
|
||||
{0:~ }|
|
||||
{0:~ }|
|
||||
## grid 3
|
||||
|
|
||||
## grid 5
|
||||
{5:╔}{11:Left}{5:═════╗}|
|
||||
{5:║}{1: halloj! }{5:║}|
|
||||
{5:║}{1: BORDAA }{5:║}|
|
||||
{5:╚═════════╝}|
|
||||
]], float_pos={
|
||||
[5] = { { id = 1002 }, "NW", 1, 2, 5, true }
|
||||
}, win_viewport={
|
||||
[2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1};
|
||||
[5] = {win = {id = 1002}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2};
|
||||
}}
|
||||
else
|
||||
screen:expect{grid=[[
|
||||
^ |
|
||||
{0:~ }|
|
||||
{0:~ }{5:╔}{11:Left}{5:═════╗}{0: }|
|
||||
{0:~ }{5:║}{1: halloj! }{5:║}{0: }|
|
||||
{0:~ }{5:║}{1: BORDAA }{5:║}{0: }|
|
||||
{0:~ }{5:╚═════════╝}{0: }|
|
||||
|
|
||||
]]}
|
||||
end
|
||||
|
||||
meths.win_set_config(win, {title= "Center",title_pos="center"})
|
||||
if multigrid then
|
||||
screen:expect{grid=[[
|
||||
## grid 1
|
||||
[2:----------------------------------------]|
|
||||
[2:----------------------------------------]|
|
||||
[2:----------------------------------------]|
|
||||
[2:----------------------------------------]|
|
||||
[2:----------------------------------------]|
|
||||
[2:----------------------------------------]|
|
||||
[3:----------------------------------------]|
|
||||
## grid 2
|
||||
^ |
|
||||
{0:~ }|
|
||||
{0:~ }|
|
||||
{0:~ }|
|
||||
{0:~ }|
|
||||
{0:~ }|
|
||||
## grid 3
|
||||
|
|
||||
## grid 5
|
||||
{5:╔═}{11:Center}{5:══╗}|
|
||||
{5:║}{1: halloj! }{5:║}|
|
||||
{5:║}{1: BORDAA }{5:║}|
|
||||
{5:╚═════════╝}|
|
||||
]], float_pos={
|
||||
[5] = { { id = 1002 }, "NW", 1, 2, 5, true }
|
||||
}, win_viewport={
|
||||
[2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1};
|
||||
[5] = {win = {id = 1002}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2};
|
||||
}}
|
||||
else
|
||||
screen:expect{grid=[[
|
||||
^ |
|
||||
{0:~ }|
|
||||
{0:~ }{5:╔═}{11:Center}{5:══╗}{0: }|
|
||||
{0:~ }{5:║}{1: halloj! }{5:║}{0: }|
|
||||
{0:~ }{5:║}{1: BORDAA }{5:║}{0: }|
|
||||
{0:~ }{5:╚═════════╝}{0: }|
|
||||
|
|
||||
]]}
|
||||
end
|
||||
|
||||
meths.win_set_config(win, {title= "Right",title_pos="right"})
|
||||
if multigrid then
|
||||
screen:expect{grid=[[
|
||||
## grid 1
|
||||
[2:----------------------------------------]|
|
||||
[2:----------------------------------------]|
|
||||
[2:----------------------------------------]|
|
||||
[2:----------------------------------------]|
|
||||
[2:----------------------------------------]|
|
||||
[2:----------------------------------------]|
|
||||
[3:----------------------------------------]|
|
||||
## grid 2
|
||||
^ |
|
||||
{0:~ }|
|
||||
{0:~ }|
|
||||
{0:~ }|
|
||||
{0:~ }|
|
||||
{0:~ }|
|
||||
## grid 3
|
||||
|
|
||||
## grid 5
|
||||
{5:╔════}{11:Right}{5:╗}|
|
||||
{5:║}{1: halloj! }{5:║}|
|
||||
{5:║}{1: BORDAA }{5:║}|
|
||||
{5:╚═════════╝}|
|
||||
]], float_pos={
|
||||
[5] = { { id = 1002 }, "NW", 1, 2, 5, true }
|
||||
}, win_viewport={
|
||||
[2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1};
|
||||
[5] = {win = {id = 1002}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2};
|
||||
}}
|
||||
else
|
||||
screen:expect{grid=[[
|
||||
^ |
|
||||
{0:~ }|
|
||||
{0:~ }{5:╔════}{11:Right}{5:╗}{0: }|
|
||||
{0:~ }{5:║}{1: halloj! }{5:║}{0: }|
|
||||
{0:~ }{5:║}{1: BORDAA }{5:║}{0: }|
|
||||
{0:~ }{5:╚═════════╝}{0: }|
|
||||
|
|
||||
]]}
|
||||
end
|
||||
|
||||
meths.win_set_config(win, {title= { {"🦄"},{"BB"}},title_pos="right"})
|
||||
if multigrid then
|
||||
screen:expect{grid=[[
|
||||
## grid 1
|
||||
[2:----------------------------------------]|
|
||||
[2:----------------------------------------]|
|
||||
[2:----------------------------------------]|
|
||||
[2:----------------------------------------]|
|
||||
[2:----------------------------------------]|
|
||||
[2:----------------------------------------]|
|
||||
[3:----------------------------------------]|
|
||||
## grid 2
|
||||
^ |
|
||||
{0:~ }|
|
||||
{0:~ }|
|
||||
{0:~ }|
|
||||
{0:~ }|
|
||||
{0:~ }|
|
||||
## grid 3
|
||||
|
|
||||
## grid 5
|
||||
{5:╔═════}🦄BB{5:╗}|
|
||||
{5:║}{1: halloj! }{5:║}|
|
||||
{5:║}{1: BORDAA }{5:║}|
|
||||
{5:╚═════════╝}|
|
||||
]], float_pos={
|
||||
[5] = { { id = 1002 }, "NW", 1, 2, 5, true }
|
||||
}, win_viewport={
|
||||
[2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1};
|
||||
[5] = {win = {id = 1002}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2};
|
||||
}}
|
||||
else
|
||||
screen:expect{grid=[[
|
||||
^ |
|
||||
{0:~ }|
|
||||
{0:~ }{5:╔═════}🦄BB{5:╗}{0: }|
|
||||
{0:~ }{5:║}{1: halloj! }{5:║}{0: }|
|
||||
{0:~ }{5:║}{1: BORDAA }{5:║}{0: }|
|
||||
{0:~ }{5:╚═════════╝}{0: }|
|
||||
|
|
||||
]]}
|
||||
end
|
||||
end)
|
||||
|
||||
it('terminates border on edge of viewport when window extends past viewport', function()
|
||||
local buf = meths.create_buf(false, false)
|
||||
meths.open_win(buf, false, {relative='editor', width=40, height=7, row=0, col=0, border="single"})
|
||||
|
Loading…
Reference in New Issue
Block a user