mirror of
https://github.com/neovim/neovim.git
synced 2025-10-06 01:46:29 +00:00
floats: add borders (MS-DOS MODE)
This commit is contained in:
@@ -1645,6 +1645,20 @@ bool api_object_to_bool(Object obj, const char *what,
|
||||
}
|
||||
}
|
||||
|
||||
int object_to_hl_id(Object obj, const char *what, Error *err)
|
||||
{
|
||||
if (obj.type == kObjectTypeString) {
|
||||
String str = obj.data.string;
|
||||
return str.size ? syn_check_group((char_u *)str.data, (int)str.size) : 0;
|
||||
} else if (obj.type == kObjectTypeInteger) {
|
||||
return (int)obj.data.integer;
|
||||
} else {
|
||||
api_set_error(err, kErrorTypeValidation,
|
||||
"%s is not a valid highlight", what);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
HlMessage parse_hl_msg(Array chunks, Error *err)
|
||||
{
|
||||
HlMessage hl_msg = KV_INITIAL_VALUE;
|
||||
@@ -1768,6 +1782,91 @@ static bool parse_float_bufpos(Array bufpos, lpos_T *out)
|
||||
return true;
|
||||
}
|
||||
|
||||
static void parse_border_style(Object style, FloatConfig *fconfig, Error *err)
|
||||
{
|
||||
struct {
|
||||
const char *name;
|
||||
schar_T chars[8];
|
||||
} defaults[] = {
|
||||
{ "double", { "╔", "═", "╗", "║", "╝", "═", "╚", "║" } },
|
||||
{ "single", { "┌", "─", "┐", "│", "┘", "─", "└", "│" } },
|
||||
{ NULL, { { NUL } } },
|
||||
};
|
||||
|
||||
schar_T *chars = fconfig->border_chars;
|
||||
int *hl_ids = fconfig->border_hl_ids;
|
||||
|
||||
fconfig->border = true;
|
||||
|
||||
if (style.type == kObjectTypeArray) {
|
||||
Array arr = style.data.array;
|
||||
size_t size = arr.size;
|
||||
if (!size || size > 8 || (size & (size-1))) {
|
||||
api_set_error(err, kErrorTypeValidation,
|
||||
"invalid number of border chars");
|
||||
return;
|
||||
}
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
Object iytem = arr.items[i];
|
||||
String string = NULL_STRING;
|
||||
int hl_id = 0;
|
||||
if (iytem.type == kObjectTypeArray) {
|
||||
Array iarr = iytem.data.array;
|
||||
if (!iarr.size || iarr.size > 2) {
|
||||
api_set_error(err, kErrorTypeValidation, "invalid border char");
|
||||
return;
|
||||
}
|
||||
if (iarr.items[0].type != kObjectTypeString) {
|
||||
api_set_error(err, kErrorTypeValidation, "invalid border char");
|
||||
return;
|
||||
}
|
||||
string = iarr.items[0].data.string;
|
||||
if (iarr.size == 2) {
|
||||
hl_id = object_to_hl_id(iarr.items[1], "border char highlight", err);
|
||||
if (ERROR_SET(err)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (iytem.type == kObjectTypeString) {
|
||||
string = iytem.data.string;
|
||||
} else {
|
||||
api_set_error(err, kErrorTypeValidation, "invalid border char");
|
||||
return;
|
||||
}
|
||||
if (!string.size
|
||||
|| mb_string2cells_len((char_u *)string.data, string.size) != 1) {
|
||||
api_set_error(err, kErrorTypeValidation,
|
||||
"border chars must be one cell");
|
||||
}
|
||||
size_t len = MIN(string.size, sizeof(*chars)-1);
|
||||
memcpy(chars[i], string.data, len);
|
||||
chars[i][len] = NUL;
|
||||
hl_ids[i] = hl_id;
|
||||
}
|
||||
while (size < 8) {
|
||||
memcpy(chars+size, chars, sizeof(*chars) * size);
|
||||
memcpy(hl_ids+size, hl_ids, sizeof(*hl_ids) * size);
|
||||
size <<= 1;
|
||||
}
|
||||
} else if (style.type == kObjectTypeString) {
|
||||
String str = style.data.string;
|
||||
if (str.size == 0 || strequal(str.data, "none")) {
|
||||
fconfig->border = false;
|
||||
return;
|
||||
}
|
||||
for (size_t i = 0; defaults[i].name; i++) {
|
||||
if (strequal(str.data, defaults[i].name)) {
|
||||
memcpy(chars, defaults[i].chars, sizeof(defaults[i].chars));
|
||||
memset(hl_ids, 0, 8 * sizeof(*hl_ids));
|
||||
return;
|
||||
}
|
||||
}
|
||||
api_set_error(err, kErrorTypeValidation,
|
||||
"invalid border style \"%s\"", str.data);
|
||||
}
|
||||
}
|
||||
|
||||
bool parse_float_config(Dictionary config, FloatConfig *fconfig, bool reconf,
|
||||
Error *err)
|
||||
{
|
||||
@@ -1890,7 +1989,7 @@ bool parse_float_config(Dictionary config, FloatConfig *fconfig, bool reconf,
|
||||
return false;
|
||||
}
|
||||
} else if (!strcmp(key, "border")) {
|
||||
fconfig->border = api_object_to_bool(val, "border", false, err);
|
||||
parse_border_style(val, fconfig, err);
|
||||
if (ERROR_SET(err)) {
|
||||
return false;
|
||||
}
|
||||
|
@@ -1416,6 +1416,25 @@ void nvim_chan_send(Integer chan, String data, Error *err)
|
||||
/// end-of-buffer region is hidden by setting `eob` flag of
|
||||
/// 'fillchars' to a space char, and clearing the
|
||||
/// |EndOfBuffer| region in 'winhighlight'.
|
||||
/// - `border`: style of (optional) window border. This can either be a string
|
||||
/// or an array. the string values are:
|
||||
/// - "none" No border. This is the default
|
||||
/// - "single" a single line box
|
||||
/// - "double" a double line box
|
||||
/// If it is an array it should be an array of eight items or any divisor of
|
||||
/// eight. The array will specifify the eight chars building up the border
|
||||
/// in a clockwise fashion starting with the top-left corner. As, an
|
||||
/// example, the double box style could be specified as:
|
||||
/// [ "╔", "═" ,"╗", "║", "╝", "═", "╚", "║" ]
|
||||
/// if the number of chars are less than eight, they will be repeated. Thus
|
||||
/// an ASCII border could be specified as:
|
||||
/// [ "/", "-", "\\", "|" ]
|
||||
/// or all chars the same as:
|
||||
/// [ "x" ]
|
||||
/// By default `FloatBorder` highlight is used which links to `VertSplit`
|
||||
/// when not defined. It could also be specified by character:
|
||||
/// [ {"+", "MyCorner"}, {"x", "MyBorder"} ]
|
||||
///
|
||||
/// @param[out] err Error details, if any
|
||||
///
|
||||
/// @return Window handle, or 0 on error
|
||||
|
Reference in New Issue
Block a user