aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBjörn Linse <bjorn.linse@gmail.com>2019-04-13 14:25:15 +0200
committerBjörn Linse <bjorn.linse@gmail.com>2019-04-14 10:12:09 +0200
commitc8acbe3b623a4d7636e88b30f779c03845cf548f (patch)
tree7e8698c31b6e4988a10eb4fb4160ee9339b4c206 /src
parentd08692a8246039b938b5645a6c01b4ff7f51671e (diff)
downloadrneovim-c8acbe3b623a4d7636e88b30f779c03845cf548f.tar.gz
rneovim-c8acbe3b623a4d7636e88b30f779c03845cf548f.tar.bz2
rneovim-c8acbe3b623a4d7636e88b30f779c03845cf548f.zip
windows: float config changes
- Allow floating windows of width 1. #9846 - For a new floating window the size must be specified. Later on we might try to calculate a reasonable size by buffer contents - Remember the configured size of a window, just like its position. - Make get_config and set_config more consistent. Handle relative='' properly in set_config. get_config doesn't return keys that don't make sense for a non-floating window. - Don't use width=0 for non-changed width, just omit the key.
Diffstat (limited to 'src')
-rw-r--r--src/nvim/api/vim.c5
-rw-r--r--src/nvim/api/window.c31
-rw-r--r--src/nvim/screen.c2
-rw-r--r--src/nvim/window.c61
4 files changed, 56 insertions, 43 deletions
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c
index f56d37af90..d0327b241c 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.c
@@ -1003,7 +1003,8 @@ Buffer nvim_create_buf(Boolean listed, Boolean scratch, Error *err)
///
/// For a general overview of floats, see |api-floatwin|.
///
-/// Exactly one of `external` and `relative` must be specified.
+/// Exactly one of `external` and `relative` must be specified. The `width` and
+/// `height` of the new window must be specified.
///
/// With editor positioning row=0, col=0 refers to the top-left corner of the
/// screen-grid and row=Lines-1, Columns-1 refers to the bottom-right corner.
@@ -1035,7 +1036,7 @@ Buffer nvim_create_buf(Boolean listed, Boolean scratch, Error *err)
/// - "SW" south-west
/// - "SE" south-east
/// - `height`: window height (in character cells). Minimum of 1.
-/// - `width`: window width (in character cells). Minimum of 2.
+/// - `width`: window width (in character cells). Minimum of 1.
/// - `row`: row position. Screen cell height are used as unit. Can be
/// floating point.
/// - `col`: column position. Screen cell width is used as unit. Can be
diff --git a/src/nvim/api/window.c b/src/nvim/api/window.c
index 01cb9a6847..e1c50cb89d 100644
--- a/src/nvim/api/window.c
+++ b/src/nvim/api/window.c
@@ -466,8 +466,6 @@ void nvim_win_set_config(Window window, Dictionary config, Error *err)
if (!parse_float_config(config, &fconfig, !new_float, err)) {
return;
}
- fconfig.height = fconfig.height > 0 ? fconfig.height : win->w_height;
- fconfig.width = fconfig.width > 0 ? fconfig.width : win->w_width;
if (new_float) {
if (!win_new_float(win, fconfig, err)) {
return;
@@ -499,26 +497,25 @@ Dictionary nvim_win_get_config(Window window, Error *err)
return rv;
}
- PUT(rv, "width", INTEGER_OBJ(wp->w_float_config.width));
- PUT(rv, "height", INTEGER_OBJ(wp->w_float_config.height));
PUT(rv, "focusable", BOOLEAN_OBJ(wp->w_float_config.focusable));
PUT(rv, "external", BOOLEAN_OBJ(wp->w_float_config.external));
- PUT(rv, "anchor", STRING_OBJ(cstr_to_string(
- float_anchor_str[wp->w_float_config.anchor])));
- if (wp->w_float_config.relative == kFloatRelativeWindow) {
- PUT(rv, "win", INTEGER_OBJ(wp->w_float_config.window));
- }
-
- if (wp->w_float_config.external) {
- return rv;
+ if (wp->w_floating) {
+ PUT(rv, "width", INTEGER_OBJ(wp->w_float_config.width));
+ PUT(rv, "height", INTEGER_OBJ(wp->w_float_config.height));
+ if (!wp->w_float_config.external) {
+ if (wp->w_float_config.relative == kFloatRelativeWindow) {
+ PUT(rv, "win", INTEGER_OBJ(wp->w_float_config.window));
+ }
+ PUT(rv, "anchor", STRING_OBJ(cstr_to_string(
+ float_anchor_str[wp->w_float_config.anchor])));
+ PUT(rv, "row", FLOAT_OBJ(wp->w_float_config.row));
+ PUT(rv, "col", FLOAT_OBJ(wp->w_float_config.col));
+ }
}
- PUT(rv, "row", FLOAT_OBJ(wp->w_float_config.row));
- PUT(rv, "col", FLOAT_OBJ(wp->w_float_config.col));
-
- const char *rel =
- wp->w_floating ? float_relative_str[wp->w_float_config.relative] : "";
+ const char *rel = (wp->w_floating && !wp->w_float_config.external
+ ? float_relative_str[wp->w_float_config.relative] : "");
PUT(rv, "relative", STRING_OBJ(cstr_to_string(rel)));
return rv;
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index 55f3417bb9..b4ebf2ece5 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -363,7 +363,7 @@ void update_screen(int type)
need_wait_return = FALSE;
}
- if (type >= NOT_VALID) {
+ if (type >= CLEAR || !default_grid.valid) {
ui_comp_set_screen_valid(false);
}
win_ui_flush_positions();
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 9555c88138..9d8cd21dba 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -579,7 +579,7 @@ win_T *win_new_float(win_T *wp, FloatConfig fconfig, Error *err)
void win_config_float(win_T *wp, FloatConfig fconfig)
{
- wp->w_width = MAX(fconfig.width, 2);
+ wp->w_width = MAX(fconfig.width, 1);
wp->w_height = MAX(fconfig.height, 1);
if (fconfig.relative == kFloatRelativeCursor) {
@@ -617,13 +617,16 @@ static void ui_ext_win_position(win_T *wp)
FloatConfig c = wp->w_float_config;
if (!c.external) {
ScreenGrid *grid = &default_grid;
- int row = c.row, col = c.col;
+ float row = c.row, col = c.col;
if (c.relative == kFloatRelativeWindow) {
Error dummy = ERROR_INIT;
win_T *win = find_window_by_handle(c.window, &dummy);
if (win) {
grid = &win->w_grid;
- screen_adjust_grid(&grid, &row, &col);
+ int row_off = 0, col_off = 0;
+ screen_adjust_grid(&grid, &row_off, &col_off);
+ row += row_off;
+ col += col_off;
}
api_clear_error(&dummy);
}
@@ -637,16 +640,16 @@ static void ui_ext_win_position(win_T *wp)
bool east = c.anchor & kFloatAnchorEast;
bool south = c.anchor & kFloatAnchorSouth;
- row -= (south ? wp->w_height : 0);
- col -= (east ? wp->w_width : 0);
- row = MAX(MIN(row, Rows-wp->w_height-1), 0);
- col = MAX(MIN(col, Columns-wp->w_width), 0);
- wp->w_winrow = row;
- wp->w_wincol = col;
+ int comp_row = (int)row - (south ? wp->w_height : 0);
+ int comp_col = (int)col - (east ? wp->w_width : 0);
+ comp_row = MAX(MIN(comp_row, Rows-wp->w_height-1), 0);
+ comp_col = MAX(MIN(comp_col, Columns-wp->w_width), 0);
+ wp->w_winrow = comp_row;
+ wp->w_wincol = comp_col;
bool valid = (wp->w_redr_type == 0);
bool on_top = (curwin == wp) || !curwin->w_floating;
- ui_comp_put_grid(&wp->w_grid, row, col, wp->w_height, wp->w_width,
- valid, on_top);
+ ui_comp_put_grid(&wp->w_grid, comp_row, comp_col, wp->w_height,
+ wp->w_width, valid, on_top);
if (!valid) {
wp->w_grid.valid = false;
redraw_win_later(wp, NOT_VALID);
@@ -681,9 +684,6 @@ static bool parse_float_anchor(String anchor, FloatAnchor *out)
static bool parse_float_relative(String relative, FloatRelative *out)
{
- if (relative.size == 0) {
- *out = (FloatRelative)0;
- }
char *str = relative.data;
if (striequal(str, "editor")) {
*out = kFloatRelativeEditor;
@@ -700,8 +700,11 @@ static bool parse_float_relative(String relative, FloatRelative *out)
bool parse_float_config(Dictionary config, FloatConfig *fconfig, bool reconf,
Error *err)
{
+ // TODO(bfredl): use a get/has_key interface instead and get rid of extra
+ // flags
bool has_row = false, has_col = false, has_relative = false;
bool has_external = false, has_window = false;
+ bool has_width = false, has_height = false;
for (size_t i = 0; i < config.size; i++) {
char *key = config.items[i].key.data;
@@ -729,7 +732,8 @@ bool parse_float_config(Dictionary config, FloatConfig *fconfig, bool reconf,
return false;
}
} else if (strequal(key, "width")) {
- if (val.type == kObjectTypeInteger && val.data.integer >= 0) {
+ has_width = true;
+ if (val.type == kObjectTypeInteger && val.data.integer > 0) {
fconfig->width = val.data.integer;
} else {
api_set_error(err, kErrorTypeValidation,
@@ -737,7 +741,8 @@ bool parse_float_config(Dictionary config, FloatConfig *fconfig, bool reconf,
return false;
}
} else if (strequal(key, "height")) {
- if (val.type == kObjectTypeInteger && val.data.integer >= 0) {
+ has_height = true;
+ if (val.type == kObjectTypeInteger && val.data.integer > 0) {
fconfig->height= val.data.integer;
} else {
api_set_error(err, kErrorTypeValidation,
@@ -756,16 +761,19 @@ bool parse_float_config(Dictionary config, FloatConfig *fconfig, bool reconf,
return false;
}
} else if (!strcmp(key, "relative")) {
- has_relative = true;
if (val.type != kObjectTypeString) {
api_set_error(err, kErrorTypeValidation,
"'relative' key must be String");
return false;
}
- if (!parse_float_relative(val.data.string, &fconfig->relative)) {
- api_set_error(err, kErrorTypeValidation,
- "Invalid value of 'relative' key");
- return false;
+ // ignore empty string, to match nvim_win_get_config
+ if (val.data.string.size > 0) {
+ has_relative = true;
+ if (!parse_float_relative(val.data.string, &fconfig->relative)) {
+ api_set_error(err, kErrorTypeValidation,
+ "Invalid value of 'relative' key");
+ return false;
+ }
}
} else if (!strcmp(key, "win")) {
has_window = true;
@@ -828,6 +836,12 @@ bool parse_float_config(Dictionary config, FloatConfig *fconfig, bool reconf,
fconfig->external = false;
}
+ if (!reconf && !(has_height && has_width)) {
+ api_set_error(err, kErrorTypeValidation,
+ "Must specify 'width' and 'height'");
+ return false;
+ }
+
if (fconfig->external && !ui_has(kUIMultigrid)) {
api_set_error(err, kErrorTypeValidation,
"UI doesn't support external windows");
@@ -1135,6 +1149,8 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
} else if (wp->w_floating) {
new_frame(wp);
wp->w_floating = false;
+ // non-floating window doesn't store float config.
+ wp->w_float_config = FLOAT_CONFIG_INIT;
}
/*
@@ -4421,6 +4437,7 @@ static win_T *win_alloc(win_T *after, int hidden)
new_wp->w_cursor.lnum = 1;
new_wp->w_scbind_pos = 1;
new_wp->w_floating = 0;
+ new_wp->w_float_config = FLOAT_CONFIG_INIT;
/* We won't calculate w_fraction until resizing the window */
new_wp->w_fraction = 0;
@@ -4717,8 +4734,6 @@ int win_comp_pos(void)
// Too often, but when we support anchoring floats to split windows,
// this will be needed
for (win_T *wp = lastwin; wp && wp->w_floating; wp = wp->w_prev) {
- wp->w_float_config.width = wp->w_width;
- wp->w_float_config.height = wp->w_height;
win_config_float(wp, wp->w_float_config);
}