mirror of
https://github.com/neovim/neovim
synced 2025-07-15 16:51:49 +00:00
feat(option): custom chars in 'winborder' #33772
Problem: winborder option only supported predefined styles and lacked support for custom border characters. Solution: implement parsing for comma-separated list format that allows specifying 8 individual border characters (topleft, top, topright, right, botright, bottom, botleft, left).
This commit is contained in:
@ -229,7 +229,7 @@ OPTIONS
|
|||||||
• 'diffopt' `inline:` configures diff highlighting for changes within a line.
|
• 'diffopt' `inline:` configures diff highlighting for changes within a line.
|
||||||
• 'grepformat' is now a |global-local| option.
|
• 'grepformat' is now a |global-local| option.
|
||||||
• 'pummaxwidth' sets maximum width for the completion popup menu.
|
• 'pummaxwidth' sets maximum width for the completion popup menu.
|
||||||
• 'winborder' "bold" style.
|
• 'winborder' "bold" style, custom border style.
|
||||||
• |g:clipboard| accepts a string name to force any builtin clipboard tool.
|
• |g:clipboard| accepts a string name to force any builtin clipboard tool.
|
||||||
• 'busy' sets a buffer "busy" status. Indicated in the default statusline.
|
• 'busy' sets a buffer "busy" status. Indicated in the default statusline.
|
||||||
|
|
||||||
|
@ -7410,6 +7410,10 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||||||
- "shadow": Drop shadow effect, by blending with the background.
|
- "shadow": Drop shadow effect, by blending with the background.
|
||||||
- "single": Single-line box.
|
- "single": Single-line box.
|
||||||
- "solid": Adds padding by a single whitespace cell.
|
- "solid": Adds padding by a single whitespace cell.
|
||||||
|
- custom: comma-separated list of exactly 8 characters in clockwise
|
||||||
|
order starting from topleft. Example: >lua
|
||||||
|
vim.o.winborder='+,-,+,|,+,-,+,|'
|
||||||
|
<
|
||||||
|
|
||||||
*'window'* *'wi'*
|
*'window'* *'wi'*
|
||||||
'window' 'wi' number (default screen height - 1)
|
'window' 'wi' number (default screen height - 1)
|
||||||
|
9
runtime/lua/vim/_meta/options.lua
generated
9
runtime/lua/vim/_meta/options.lua
generated
@ -8117,8 +8117,15 @@ vim.wo.winbl = vim.wo.winblend
|
|||||||
--- - "shadow": Drop shadow effect, by blending with the background.
|
--- - "shadow": Drop shadow effect, by blending with the background.
|
||||||
--- - "single": Single-line box.
|
--- - "single": Single-line box.
|
||||||
--- - "solid": Adds padding by a single whitespace cell.
|
--- - "solid": Adds padding by a single whitespace cell.
|
||||||
|
--- - custom: comma-separated list of exactly 8 characters in clockwise
|
||||||
|
--- order starting from topleft. Example:
|
||||||
---
|
---
|
||||||
--- @type ''|'double'|'single'|'shadow'|'rounded'|'solid'|'bold'|'none'
|
--- ```lua
|
||||||
|
--- vim.o.winborder='+,-,+,`,+,-,+,`'
|
||||||
|
--- ```
|
||||||
|
---
|
||||||
|
---
|
||||||
|
--- @type string
|
||||||
vim.o.winborder = ""
|
vim.o.winborder = ""
|
||||||
vim.go.winborder = vim.o.winborder
|
vim.go.winborder = vim.o.winborder
|
||||||
|
|
||||||
|
@ -1064,6 +1064,52 @@ static void generate_api_error(win_T *wp, const char *attribute, Error *err)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Parses a border style name or custom (comma-separated) style.
|
||||||
|
bool parse_winborder(WinConfig *fconfig, Error *err)
|
||||||
|
{
|
||||||
|
if (!fconfig) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Object style = OBJECT_INIT;
|
||||||
|
|
||||||
|
if (strchr(p_winborder, ',')) {
|
||||||
|
Array border_chars = ARRAY_DICT_INIT;
|
||||||
|
char *p = p_winborder;
|
||||||
|
char part[MAX_SCHAR_SIZE] = { 0 };
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
while (*p != NUL) {
|
||||||
|
if (count >= 8) {
|
||||||
|
api_free_array(border_chars);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t part_len = copy_option_part(&p, part, sizeof(part), ",");
|
||||||
|
if (part_len == 0 || part[0] == NUL) {
|
||||||
|
api_free_array(border_chars);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
String str = cstr_to_string(part);
|
||||||
|
ADD(border_chars, STRING_OBJ(str));
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count != 8) {
|
||||||
|
api_free_array(border_chars);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
style = ARRAY_OBJ(border_chars);
|
||||||
|
} else {
|
||||||
|
style = CSTR_TO_OBJ(p_winborder);
|
||||||
|
}
|
||||||
|
|
||||||
|
parse_border_style(style, fconfig, err);
|
||||||
|
api_free_object(style);
|
||||||
|
return !ERROR_SET(err);
|
||||||
|
}
|
||||||
|
|
||||||
static bool parse_win_config(win_T *wp, Dict(win_config) *config, WinConfig *fconfig, bool reconf,
|
static bool parse_win_config(win_T *wp, Dict(win_config) *config, WinConfig *fconfig, bool reconf,
|
||||||
Error *err)
|
Error *err)
|
||||||
{
|
{
|
||||||
@ -1297,14 +1343,15 @@ static bool parse_win_config(win_T *wp, Dict(win_config) *config, WinConfig *fco
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
border_style = config->border;
|
border_style = config->border;
|
||||||
} else if (*p_winborder != NUL && (wp == NULL || !wp->w_floating)) {
|
if (border_style.type != kObjectTypeNil) {
|
||||||
border_style = CSTR_AS_OBJ(p_winborder);
|
parse_border_style(border_style, fconfig, err);
|
||||||
}
|
if (ERROR_SET(err)) {
|
||||||
if (border_style.type != kObjectTypeNil) {
|
goto fail;
|
||||||
parse_border_style(border_style, fconfig, err);
|
}
|
||||||
if (ERROR_SET(err)) {
|
|
||||||
goto fail;
|
|
||||||
}
|
}
|
||||||
|
} else if (*p_winborder != NUL && (wp == NULL || !wp->w_floating)
|
||||||
|
&& !parse_winborder(fconfig, err)) {
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (HAS_KEY_X(config, style)) {
|
if (HAS_KEY_X(config, style)) {
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include "nvim/api/keysets_defs.h" // IWYU pragma: keep
|
#include "nvim/api/keysets_defs.h" // IWYU pragma: keep
|
||||||
#include "nvim/api/private/defs.h" // IWYU pragma: keep
|
#include "nvim/api/private/defs.h" // IWYU pragma: keep
|
||||||
|
#include "nvim/buffer_defs.h" // IWYU pragma: keep
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
# include "api/win_config.h.generated.h"
|
# include "api/win_config.h.generated.h"
|
||||||
|
@ -10431,6 +10431,9 @@ local options = {
|
|||||||
type = 'number',
|
type = 'number',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
full_name = 'winborder',
|
||||||
|
scope = { 'global' },
|
||||||
|
cb = 'did_set_winborder',
|
||||||
defaults = { if_true = '' },
|
defaults = { if_true = '' },
|
||||||
values = { '', 'double', 'single', 'shadow', 'rounded', 'solid', 'bold', 'none' },
|
values = { '', 'double', 'single', 'shadow', 'rounded', 'solid', 'bold', 'none' },
|
||||||
desc = [=[
|
desc = [=[
|
||||||
@ -10443,11 +10446,14 @@ local options = {
|
|||||||
- "shadow": Drop shadow effect, by blending with the background.
|
- "shadow": Drop shadow effect, by blending with the background.
|
||||||
- "single": Single-line box.
|
- "single": Single-line box.
|
||||||
- "solid": Adds padding by a single whitespace cell.
|
- "solid": Adds padding by a single whitespace cell.
|
||||||
|
- custom: comma-separated list of exactly 8 characters in clockwise
|
||||||
|
order starting from topleft. Example: >lua
|
||||||
|
vim.o.winborder='+,-,+,|,+,-,+,|'
|
||||||
|
<
|
||||||
]=],
|
]=],
|
||||||
full_name = 'winborder',
|
|
||||||
scope = { 'global' },
|
|
||||||
short_desc = N_('border of floating window'),
|
short_desc = N_('border of floating window'),
|
||||||
type = 'string',
|
type = 'string',
|
||||||
|
list = 'onecomma',
|
||||||
varname = 'p_winborder',
|
varname = 'p_winborder',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "nvim/api/private/defs.h"
|
#include "nvim/api/private/defs.h"
|
||||||
|
#include "nvim/api/win_config.h"
|
||||||
#include "nvim/ascii_defs.h"
|
#include "nvim/ascii_defs.h"
|
||||||
#include "nvim/autocmd.h"
|
#include "nvim/autocmd.h"
|
||||||
#include "nvim/buffer_defs.h"
|
#include "nvim/buffer_defs.h"
|
||||||
@ -2101,6 +2102,19 @@ const char *did_set_winbar(optset_T *args)
|
|||||||
return did_set_statustabline_rulerformat(args, false, false);
|
return did_set_statustabline_rulerformat(args, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The 'winborder' option is changed.
|
||||||
|
const char *did_set_winborder(optset_T *args)
|
||||||
|
{
|
||||||
|
WinConfig fconfig = WIN_CONFIG_INIT;
|
||||||
|
Error err = ERROR_INIT;
|
||||||
|
if (!parse_winborder(&fconfig, &err)) {
|
||||||
|
api_clear_error(&err);
|
||||||
|
return e_invarg;
|
||||||
|
}
|
||||||
|
api_clear_error(&err);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/// The 'winhighlight' option is changed.
|
/// The 'winhighlight' option is changed.
|
||||||
const char *did_set_winhighlight(optset_T *args)
|
const char *did_set_winhighlight(optset_T *args)
|
||||||
{
|
{
|
||||||
|
@ -10938,7 +10938,16 @@ describe('float window', function()
|
|||||||
winid = api.nvim_open_win(buf, false, config)
|
winid = api.nvim_open_win(buf, false, config)
|
||||||
eq('┏', api.nvim_win_get_config(winid).border[1])
|
eq('┏', api.nvim_win_get_config(winid).border[1])
|
||||||
|
|
||||||
-- it is currently not supported.
|
command([[set winborder=+,-,+,\|,+,-,+,\|]])
|
||||||
|
winid = api.nvim_open_win(buf, false, config)
|
||||||
|
eq('+', api.nvim_win_get_config(winid).border[1])
|
||||||
|
|
||||||
|
command([[set winborder=●,○,●,○,●,○,●,○]])
|
||||||
|
winid = api.nvim_open_win(buf, false, config)
|
||||||
|
eq('●', api.nvim_win_get_config(winid).border[1])
|
||||||
|
|
||||||
|
eq('Vim(set):E474: Invalid argument: winborder=,,', pcall_err(command, 'set winborder=,,'))
|
||||||
|
eq('Vim(set):E474: Invalid argument: winborder=+,-,+,|,+,-,+,', pcall_err(command, [[set winborder=+,-,+,\|,+,-,+,]]))
|
||||||
eq('Vim(set):E474: Invalid argument: winborder=custom', pcall_err(command, 'set winborder=custom'))
|
eq('Vim(set):E474: Invalid argument: winborder=custom', pcall_err(command, 'set winborder=custom'))
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
Reference in New Issue
Block a user