mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
refactor(float): extract "title" and "title_pos" handling
This commit is contained in:
parent
afd0c648a8
commit
617fd5bdc6
@ -240,6 +240,48 @@ void nvim_win_set_config(Window window, Dict(float_config) *config, Error *err)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Dictionary config_put_bordertext(Dictionary config, FloatConfig *fconfig,
|
||||||
|
BorderTextType bordertext_type)
|
||||||
|
{
|
||||||
|
VirtText chunks;
|
||||||
|
AlignTextPos align;
|
||||||
|
char *field_name;
|
||||||
|
char *field_pos_name;
|
||||||
|
if (bordertext_type == kBorderTextTitle) {
|
||||||
|
chunks = fconfig->title_chunks;
|
||||||
|
align = fconfig->title_pos;
|
||||||
|
field_name = "title";
|
||||||
|
field_pos_name = "title_pos";
|
||||||
|
}
|
||||||
|
|
||||||
|
Array bordertext = ARRAY_DICT_INIT;
|
||||||
|
for (size_t i = 0; i < chunks.size; i++) {
|
||||||
|
Array tuple = ARRAY_DICT_INIT;
|
||||||
|
ADD(tuple, CSTR_TO_OBJ(chunks.items[i].text));
|
||||||
|
if (chunks.items[i].hl_id > 0) {
|
||||||
|
ADD(tuple, CSTR_TO_OBJ(syn_id2name(chunks.items[i].hl_id)));
|
||||||
|
}
|
||||||
|
ADD(bordertext, ARRAY_OBJ(tuple));
|
||||||
|
}
|
||||||
|
PUT(config, field_name, ARRAY_OBJ(bordertext));
|
||||||
|
|
||||||
|
char *pos;
|
||||||
|
switch (align) {
|
||||||
|
case kAlignLeft:
|
||||||
|
pos = "left";
|
||||||
|
break;
|
||||||
|
case kAlignCenter:
|
||||||
|
pos = "center";
|
||||||
|
break;
|
||||||
|
case kAlignRight:
|
||||||
|
pos = "right";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
PUT(config, field_pos_name, CSTR_TO_OBJ(pos));
|
||||||
|
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
/// Gets window configuration.
|
/// Gets window configuration.
|
||||||
///
|
///
|
||||||
/// The returned value may be given to |nvim_open_win()|.
|
/// The returned value may be given to |nvim_open_win()|.
|
||||||
@ -301,26 +343,7 @@ Dictionary nvim_win_get_config(Window window, Error *err)
|
|||||||
}
|
}
|
||||||
PUT(rv, "border", ARRAY_OBJ(border));
|
PUT(rv, "border", ARRAY_OBJ(border));
|
||||||
if (config->title) {
|
if (config->title) {
|
||||||
Array titles = ARRAY_DICT_INIT;
|
rv = config_put_bordertext(rv, config, kBorderTextTitle);
|
||||||
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(title_datas.items[i].text));
|
|
||||||
if (title_datas.items[i].hl_id > 0) {
|
|
||||||
ADD(tuple, CSTR_TO_OBJ(syn_id2name(title_datas.items[i].hl_id)));
|
|
||||||
}
|
|
||||||
ADD(titles, ARRAY_OBJ(tuple));
|
|
||||||
}
|
|
||||||
PUT(rv, "title", ARRAY_OBJ(titles));
|
|
||||||
char *title_pos;
|
|
||||||
if (config->title_pos == kAlignLeft) {
|
|
||||||
title_pos = "left";
|
|
||||||
} else if (config->title_pos == kAlignCenter) {
|
|
||||||
title_pos = "center";
|
|
||||||
} else {
|
|
||||||
title_pos = "right";
|
|
||||||
}
|
|
||||||
PUT(rv, "title_pos", CSTR_TO_OBJ(title_pos));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -381,54 +404,72 @@ static bool parse_float_bufpos(Array bufpos, lpos_T *out)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void parse_border_title(Object title, FloatConfig *fconfig, Error *err)
|
static void parse_bordertext(Object bordertext, BorderTextType bordertext_type,
|
||||||
|
FloatConfig *fconfig, Error *err)
|
||||||
{
|
{
|
||||||
if (title.type == kObjectTypeString) {
|
bool *is_present;
|
||||||
if (title.data.string.size == 0) {
|
VirtText *chunks;
|
||||||
fconfig->title = false;
|
int *width;
|
||||||
|
if (bordertext_type == kBorderTextTitle) {
|
||||||
|
is_present = &fconfig->title;
|
||||||
|
chunks = &fconfig->title_chunks;
|
||||||
|
width = &fconfig->title_width;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bordertext.type == kObjectTypeString) {
|
||||||
|
if (bordertext.data.string.size == 0) {
|
||||||
|
*is_present = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int hl_id = syn_check_group(S_LEN("FloatTitle"));
|
int hl_id = syn_check_group(S_LEN("FloatTitle"));
|
||||||
kv_push(fconfig->title_chunks, ((VirtTextChunk){ .text = xstrdup(title.data.string.data),
|
kv_push(*chunks, ((VirtTextChunk){ .text = xstrdup(bordertext.data.string.data),
|
||||||
.hl_id = hl_id }));
|
.hl_id = hl_id }));
|
||||||
fconfig->title_width = (int)mb_string2cells(title.data.string.data);
|
*width = (int)mb_string2cells(bordertext.data.string.data);
|
||||||
fconfig->title = true;
|
*is_present = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (title.type != kObjectTypeArray) {
|
if (bordertext.type != kObjectTypeArray) {
|
||||||
api_set_error(err, kErrorTypeValidation, "title must be string or array");
|
api_set_error(err, kErrorTypeValidation, "title must be string or array");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (title.data.array.size == 0) {
|
if (bordertext.data.array.size == 0) {
|
||||||
api_set_error(err, kErrorTypeValidation, "title cannot be an empty array");
|
api_set_error(err, kErrorTypeValidation, "title cannot be an empty array");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fconfig->title_width = 0;
|
*width = 0;
|
||||||
fconfig->title_chunks = parse_virt_text(title.data.array, err, &fconfig->title_width);
|
*chunks = parse_virt_text(bordertext.data.array, err, width);
|
||||||
|
|
||||||
fconfig->title = true;
|
*is_present = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool parse_title_pos(String title_pos, FloatConfig *fconfig, Error *err)
|
static bool parse_bordertext_pos(String bordertext_pos, BorderTextType bordertext_type,
|
||||||
|
FloatConfig *fconfig, Error *err)
|
||||||
{
|
{
|
||||||
if (title_pos.size == 0) {
|
AlignTextPos *align;
|
||||||
fconfig->title_pos = kAlignLeft;
|
if (bordertext_type == kBorderTextTitle) {
|
||||||
|
align = &fconfig->title_pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bordertext_pos.size == 0) {
|
||||||
|
*align = kAlignLeft;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *pos = title_pos.data;
|
char *pos = bordertext_pos.data;
|
||||||
|
|
||||||
if (strequal(pos, "left")) {
|
if (strequal(pos, "left")) {
|
||||||
fconfig->title_pos = kAlignLeft;
|
*align = kAlignLeft;
|
||||||
} else if (strequal(pos, "center")) {
|
} else if (strequal(pos, "center")) {
|
||||||
fconfig->title_pos = kAlignCenter;
|
*align = kAlignCenter;
|
||||||
} else if (strequal(pos, "right")) {
|
} else if (strequal(pos, "right")) {
|
||||||
fconfig->title_pos = kAlignRight;
|
*align = kAlignRight;
|
||||||
} else {
|
} else {
|
||||||
api_set_error(err, kErrorTypeValidation, "invalid title_pos value");
|
if (bordertext_type == kBorderTextTitle) {
|
||||||
|
api_set_error(err, kErrorTypeValidation, "invalid title_pos value");
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -693,13 +734,13 @@ static bool parse_float_config(Dict(float_config) *config, FloatConfig *fconfig,
|
|||||||
clear_virttext(&fconfig->title_chunks);
|
clear_virttext(&fconfig->title_chunks);
|
||||||
}
|
}
|
||||||
|
|
||||||
parse_border_title(config->title, fconfig, err);
|
parse_bordertext(config->title, kBorderTextTitle, fconfig, err);
|
||||||
if (ERROR_SET(err)) {
|
if (ERROR_SET(err)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// handles unset 'title_pos' same as empty string
|
// handles unset 'title_pos' same as empty string
|
||||||
if (!parse_title_pos(config->title_pos, fconfig, err)) {
|
if (!parse_bordertext_pos(config->title_pos, kBorderTextTitle, fconfig, err)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "nvim/api/keysets.h"
|
#include "nvim/api/keysets.h"
|
||||||
#include "nvim/api/private/defs.h"
|
#include "nvim/api/private/defs.h"
|
||||||
|
#include "nvim/buffer_defs.h"
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
# include "api/win_config.h.generated.h"
|
# include "api/win_config.h.generated.h"
|
||||||
|
@ -936,6 +936,10 @@ typedef enum {
|
|||||||
kAlignRight = 2,
|
kAlignRight = 2,
|
||||||
} AlignTextPos;
|
} AlignTextPos;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
kBorderTextTitle = 0,
|
||||||
|
} BorderTextType;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Window window;
|
Window window;
|
||||||
lpos_T bufpos;
|
lpos_T bufpos;
|
||||||
|
@ -701,20 +701,32 @@ void end_search_hl(void)
|
|||||||
screen_search_hl.rm.regprog = NULL;
|
screen_search_hl.rm.regprog = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void win_border_redr_title(win_T *wp, ScreenGrid *grid, int col)
|
static void win_redr_bordertext(win_T *wp, ScreenGrid *grid, VirtText text_chunks, int row, int col)
|
||||||
{
|
{
|
||||||
VirtText title_chunks = wp->w_float_config.title_chunks;
|
for (size_t i = 0; i < text_chunks.size; i++) {
|
||||||
|
char *text = text_chunks.items[i].text;
|
||||||
for (size_t i = 0; i < title_chunks.size; i++) {
|
|
||||||
char *text = title_chunks.items[i].text;
|
|
||||||
int cell = (int)mb_string2cells(text);
|
int cell = (int)mb_string2cells(text);
|
||||||
int hl_id = title_chunks.items[i].hl_id;
|
int hl_id = text_chunks.items[i].hl_id;
|
||||||
int attr = hl_id ? syn_id2attr(hl_id) : 0;
|
int attr = hl_id ? syn_id2attr(hl_id) : 0;
|
||||||
grid_puts(grid, text, 0, col, attr);
|
grid_puts(grid, text, row, col, attr);
|
||||||
col += cell;
|
col += cell;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int win_get_bordertext_col(int total_col, int text_width, AlignTextPos align)
|
||||||
|
{
|
||||||
|
switch (align) {
|
||||||
|
case kAlignLeft:
|
||||||
|
return 1;
|
||||||
|
case kAlignCenter:
|
||||||
|
return (total_col - text_width) / 2 + 1;
|
||||||
|
case kAlignRight:
|
||||||
|
return total_col - text_width + 1;
|
||||||
|
default:
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void win_redr_border(win_T *wp)
|
static void win_redr_border(win_T *wp)
|
||||||
{
|
{
|
||||||
wp->w_redr_border = false;
|
wp->w_redr_border = false;
|
||||||
@ -741,17 +753,9 @@ static void win_redr_border(win_T *wp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (wp->w_float_config.title) {
|
if (wp->w_float_config.title) {
|
||||||
int title_col = 0;
|
int title_col = win_get_bordertext_col(icol, wp->w_float_config.title_width,
|
||||||
int title_width = wp->w_float_config.title_width;
|
wp->w_float_config.title_pos);
|
||||||
AlignTextPos title_pos = wp->w_float_config.title_pos;
|
win_redr_bordertext(wp, grid, wp->w_float_config.title_chunks, 0, title_col);
|
||||||
|
|
||||||
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]) {
|
if (adj[1]) {
|
||||||
grid_put_schar(grid, 0, icol + adj[3], chars[2], attrs[2]);
|
grid_put_schar(grid, 0, icol + adj[3], chars[2], attrs[2]);
|
||||||
|
Loading…
Reference in New Issue
Block a user