mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
anchor float to buffer position
vim-patch:8.1.1645: cannot use a popup window for a balloon
This commit is contained in:
parent
d7aea13fee
commit
d5162afa2a
@ -2297,6 +2297,7 @@ rpcrequest({channel}, {method}[, {args}...])
|
|||||||
screenattr({row}, {col}) Number attribute at screen position
|
screenattr({row}, {col}) Number attribute at screen position
|
||||||
screenchar({row}, {col}) Number character at screen position
|
screenchar({row}, {col}) Number character at screen position
|
||||||
screencol() Number current cursor column
|
screencol() Number current cursor column
|
||||||
|
screenpos({winid}, {lnum}, {col}) Dict screen row and col of a text character
|
||||||
screenrow() Number current cursor row
|
screenrow() Number current cursor row
|
||||||
search({pattern} [, {flags} [, {stopline} [, {timeout}]]])
|
search({pattern} [, {flags} [, {stopline} [, {timeout}]]])
|
||||||
Number search for {pattern}
|
Number search for {pattern}
|
||||||
@ -6794,7 +6795,25 @@ screencol() *screencol()*
|
|||||||
the following mappings: >
|
the following mappings: >
|
||||||
nnoremap <expr> GG ":echom ".screencol()."\n"
|
nnoremap <expr> GG ":echom ".screencol()."\n"
|
||||||
nnoremap <silent> GG :echom screencol()<CR>
|
nnoremap <silent> GG :echom screencol()<CR>
|
||||||
|
noremap GG <Cmd>echom screencol()<Cr>
|
||||||
<
|
<
|
||||||
|
screenpos({winid}, {lnum}, {col}) *screenpos()*
|
||||||
|
The result is a Dict with the screen position of the text
|
||||||
|
character in window {winid} at buffer line {lnum} and column
|
||||||
|
{col}. {col} is a one-based byte index.
|
||||||
|
The Dict has these members:
|
||||||
|
row screen row
|
||||||
|
col first screen column
|
||||||
|
endcol last screen column
|
||||||
|
curscol cursor screen column
|
||||||
|
If the specified position is not visible, all values are zero.
|
||||||
|
The "endcol" value differs from "col" when the character
|
||||||
|
occupies more than one screen cell. E.g. for a Tab "col" can
|
||||||
|
be 1 and "endcol" can be 8.
|
||||||
|
The "curscol" value is where the cursor would be placed. For
|
||||||
|
a Tab it would be the same as "endcol", while for a double
|
||||||
|
width character it would be the same as "col".
|
||||||
|
|
||||||
screenrow() *screenrow()*
|
screenrow() *screenrow()*
|
||||||
The result is a Number, which is the current screen row of the
|
The result is a Number, which is the current screen row of the
|
||||||
cursor. The top line has number one.
|
cursor. The top line has number one.
|
||||||
|
@ -1059,6 +1059,12 @@ fail:
|
|||||||
/// - "SE" south-east
|
/// - "SE" south-east
|
||||||
/// - `height`: window height (in character cells). Minimum of 1.
|
/// - `height`: window height (in character cells). Minimum of 1.
|
||||||
/// - `width`: window width (in character cells). Minimum of 1.
|
/// - `width`: window width (in character cells). Minimum of 1.
|
||||||
|
/// - 'bufpos': position float relative text inside the window `win` (only
|
||||||
|
/// when relative="win"). Takes a tuple of [line, column] where
|
||||||
|
/// both are zero-index. Note: `row` and `col` if present, still
|
||||||
|
/// applies relative this positio. By default `row=1` and `col=0`
|
||||||
|
/// is used (with default NW anchor), to make the float
|
||||||
|
/// behave like a tooltip under the buffer text.
|
||||||
/// - `row`: row position. Screen cell height are used as unit. Can be
|
/// - `row`: row position. Screen cell height are used as unit. Can be
|
||||||
/// floating point.
|
/// floating point.
|
||||||
/// - `col`: column position. Screen cell width is used as unit. Can be
|
/// - `col`: column position. Screen cell width is used as unit. Can be
|
||||||
|
@ -503,25 +503,33 @@ Dictionary nvim_win_get_config(Window window, Error *err)
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
PUT(rv, "focusable", BOOLEAN_OBJ(wp->w_float_config.focusable));
|
FloatConfig *config = &wp->w_float_config;
|
||||||
PUT(rv, "external", BOOLEAN_OBJ(wp->w_float_config.external));
|
|
||||||
|
PUT(rv, "focusable", BOOLEAN_OBJ(config->focusable));
|
||||||
|
PUT(rv, "external", BOOLEAN_OBJ(config->external));
|
||||||
|
|
||||||
if (wp->w_floating) {
|
if (wp->w_floating) {
|
||||||
PUT(rv, "width", INTEGER_OBJ(wp->w_float_config.width));
|
PUT(rv, "width", INTEGER_OBJ(config->width));
|
||||||
PUT(rv, "height", INTEGER_OBJ(wp->w_float_config.height));
|
PUT(rv, "height", INTEGER_OBJ(config->height));
|
||||||
if (!wp->w_float_config.external) {
|
if (!config->external) {
|
||||||
if (wp->w_float_config.relative == kFloatRelativeWindow) {
|
if (config->relative == kFloatRelativeWindow) {
|
||||||
PUT(rv, "win", INTEGER_OBJ(wp->w_float_config.window));
|
PUT(rv, "win", INTEGER_OBJ(config->window));
|
||||||
|
if (config->bufpos.lnum >= 0) {
|
||||||
|
Array pos = ARRAY_DICT_INIT;
|
||||||
|
ADD(pos, INTEGER_OBJ(config->bufpos.lnum));
|
||||||
|
ADD(pos, INTEGER_OBJ(config->bufpos.col));
|
||||||
|
PUT(rv, "bufpos", ARRAY_OBJ(pos));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
PUT(rv, "anchor", STRING_OBJ(cstr_to_string(
|
PUT(rv, "anchor", STRING_OBJ(cstr_to_string(
|
||||||
float_anchor_str[wp->w_float_config.anchor])));
|
float_anchor_str[config->anchor])));
|
||||||
PUT(rv, "row", FLOAT_OBJ(wp->w_float_config.row));
|
PUT(rv, "row", FLOAT_OBJ(config->row));
|
||||||
PUT(rv, "col", FLOAT_OBJ(wp->w_float_config.col));
|
PUT(rv, "col", FLOAT_OBJ(config->col));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *rel = (wp->w_floating && !wp->w_float_config.external
|
const char *rel = (wp->w_floating && !config->external
|
||||||
? float_relative_str[wp->w_float_config.relative] : "");
|
? float_relative_str[config->relative] : "");
|
||||||
PUT(rv, "relative", STRING_OBJ(cstr_to_string(rel)));
|
PUT(rv, "relative", STRING_OBJ(cstr_to_string(rel)));
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
|
@ -1006,7 +1006,7 @@ typedef enum {
|
|||||||
kFloatRelativeCursor = 2,
|
kFloatRelativeCursor = 2,
|
||||||
} FloatRelative;
|
} FloatRelative;
|
||||||
|
|
||||||
EXTERN const char *const float_relative_str[] INIT(= { "editor", "window",
|
EXTERN const char *const float_relative_str[] INIT(= { "editor", "win",
|
||||||
"cursor" });
|
"cursor" });
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -1016,6 +1016,7 @@ typedef enum {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Window window;
|
Window window;
|
||||||
|
lpos_T bufpos;
|
||||||
int height, width;
|
int height, width;
|
||||||
double row, col;
|
double row, col;
|
||||||
FloatAnchor anchor;
|
FloatAnchor anchor;
|
||||||
@ -1026,6 +1027,7 @@ typedef struct {
|
|||||||
} FloatConfig;
|
} FloatConfig;
|
||||||
|
|
||||||
#define FLOAT_CONFIG_INIT ((FloatConfig){ .height = 0, .width = 0, \
|
#define FLOAT_CONFIG_INIT ((FloatConfig){ .height = 0, .width = 0, \
|
||||||
|
.bufpos = { -1, 0 }, \
|
||||||
.row = 0, .col = 0, .anchor = 0, \
|
.row = 0, .col = 0, .anchor = 0, \
|
||||||
.relative = 0, .external = false, \
|
.relative = 0, .external = false, \
|
||||||
.focusable = true, \
|
.focusable = true, \
|
||||||
|
@ -14781,6 +14781,32 @@ static void f_screencol(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
rettv->vval.v_number = ui_current_col() + 1;
|
rettv->vval.v_number = ui_current_col() + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// "screenpos({winid}, {lnum}, {col})" function
|
||||||
|
static void f_screenpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||||
|
{
|
||||||
|
pos_T pos;
|
||||||
|
int row = 0;
|
||||||
|
int scol = 0, ccol = 0, ecol = 0;
|
||||||
|
|
||||||
|
tv_dict_alloc_ret(rettv);
|
||||||
|
dict_T *dict = rettv->vval.v_dict;
|
||||||
|
|
||||||
|
win_T *wp = find_win_by_nr_or_id(&argvars[0]);
|
||||||
|
if (wp == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos.lnum = tv_get_number(&argvars[1]);
|
||||||
|
pos.col = tv_get_number(&argvars[2]) - 1;
|
||||||
|
pos.coladd = 0;
|
||||||
|
textpos2screenpos(wp, &pos, &row, &scol, &ccol, &ecol, false);
|
||||||
|
|
||||||
|
tv_dict_add_nr(dict, S_LEN("row"), row);
|
||||||
|
tv_dict_add_nr(dict, S_LEN("col"), scol);
|
||||||
|
tv_dict_add_nr(dict, S_LEN("curscol"), ccol);
|
||||||
|
tv_dict_add_nr(dict, S_LEN("endcol"), ecol);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "screenrow()" function
|
* "screenrow()" function
|
||||||
*/
|
*/
|
||||||
|
@ -266,6 +266,7 @@ return {
|
|||||||
screenattr={args=2},
|
screenattr={args=2},
|
||||||
screenchar={args=2},
|
screenchar={args=2},
|
||||||
screencol={},
|
screencol={},
|
||||||
|
screenpos={args=3},
|
||||||
screenrow={},
|
screenrow={},
|
||||||
search={args={1, 4}},
|
search={args={1, 4}},
|
||||||
searchdecl={args={1, 3}},
|
searchdecl={args={1, 3}},
|
||||||
|
@ -95,6 +95,8 @@ static void comp_botline(win_T *wp)
|
|||||||
wp->w_valid |= VALID_BOTLINE|VALID_BOTLINE_AP;
|
wp->w_valid |= VALID_BOTLINE|VALID_BOTLINE_AP;
|
||||||
|
|
||||||
set_empty_rows(wp, done);
|
set_empty_rows(wp, done);
|
||||||
|
|
||||||
|
win_check_anchored_floats(wp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset_cursorline(void)
|
void reset_cursorline(void)
|
||||||
@ -310,6 +312,7 @@ void update_topline(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
curwin->w_valid |= VALID_TOPLINE;
|
curwin->w_valid |= VALID_TOPLINE;
|
||||||
|
win_check_anchored_floats(curwin);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Need to redraw when topline changed.
|
* Need to redraw when topline changed.
|
||||||
@ -827,7 +830,8 @@ void curs_columns(
|
|||||||
new_leftcol = 0;
|
new_leftcol = 0;
|
||||||
if (new_leftcol != (int)curwin->w_leftcol) {
|
if (new_leftcol != (int)curwin->w_leftcol) {
|
||||||
curwin->w_leftcol = new_leftcol;
|
curwin->w_leftcol = new_leftcol;
|
||||||
/* screen has to be redrawn with new curwin->w_leftcol */
|
win_check_anchored_floats(curwin);
|
||||||
|
// screen has to be redrawn with new curwin->w_leftcol
|
||||||
redraw_later(NOT_VALID);
|
redraw_later(NOT_VALID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -943,6 +947,74 @@ void curs_columns(
|
|||||||
curwin->w_valid |= VALID_WCOL|VALID_WROW|VALID_VIRTCOL;
|
curwin->w_valid |= VALID_WCOL|VALID_WROW|VALID_VIRTCOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Compute the screen position of text character at "pos" in window "wp"
|
||||||
|
/// The resulting values are one-based, zero when character is not visible.
|
||||||
|
///
|
||||||
|
/// @param[out] rowp screen row
|
||||||
|
/// @param[out] scolp start screen column
|
||||||
|
/// @param[out] ccolp cursor screen column
|
||||||
|
/// @param[out] ecolp end screen column
|
||||||
|
void textpos2screenpos(win_T *wp, pos_T *pos, int *rowp, int *scolp,
|
||||||
|
int *ccolp, int *ecolp, bool local)
|
||||||
|
{
|
||||||
|
colnr_T scol = 0, ccol = 0, ecol = 0;
|
||||||
|
int row = 0;
|
||||||
|
int rowoff = 0;
|
||||||
|
colnr_T coloff = 0;
|
||||||
|
bool visible_row = false;
|
||||||
|
|
||||||
|
if (pos->lnum >= wp->w_topline && pos->lnum < wp->w_botline) {
|
||||||
|
row = plines_m_win(wp, wp->w_topline, pos->lnum - 1) + 1;
|
||||||
|
visible_row = true;
|
||||||
|
} else if (pos->lnum < wp->w_topline) {
|
||||||
|
row = 0;
|
||||||
|
} else {
|
||||||
|
row = wp->w_height_inner;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool existing_row = (pos->lnum > 0
|
||||||
|
&& pos->lnum <= wp->w_buffer->b_ml.ml_line_count);
|
||||||
|
|
||||||
|
if ((local && existing_row) || visible_row) {
|
||||||
|
colnr_T off;
|
||||||
|
colnr_T col;
|
||||||
|
int width;
|
||||||
|
|
||||||
|
getvcol(wp, pos, &scol, &ccol, &ecol);
|
||||||
|
|
||||||
|
// similar to what is done in validate_cursor_col()
|
||||||
|
col = scol;
|
||||||
|
off = win_col_off(wp);
|
||||||
|
col += off;
|
||||||
|
width = wp->w_width - off + win_col_off2(wp);
|
||||||
|
|
||||||
|
// long line wrapping, adjust row
|
||||||
|
if (wp->w_p_wrap && col >= (colnr_T)wp->w_width && width > 0) {
|
||||||
|
// use same formula as what is used in curs_columns()
|
||||||
|
rowoff = visible_row ? ((col - wp->w_width) / width + 1) : 0;
|
||||||
|
col -= rowoff * width;
|
||||||
|
}
|
||||||
|
|
||||||
|
col -= wp->w_leftcol;
|
||||||
|
|
||||||
|
if (col >= 0 && col < width) {
|
||||||
|
coloff = col - scol + (local ? 0 : wp->w_wincol) + 1;
|
||||||
|
} else {
|
||||||
|
scol = ccol = ecol = 0;
|
||||||
|
// character is left or right of the window
|
||||||
|
if (local) {
|
||||||
|
coloff = col < 0 ? -1 : wp->w_width_inner + 1;
|
||||||
|
} else {
|
||||||
|
row = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*rowp = (local ? 0 : wp->w_winrow) + row + rowoff;
|
||||||
|
*scolp = scol + coloff;
|
||||||
|
*ccolp = ccol + coloff;
|
||||||
|
*ecolp = ecol + coloff;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Scroll the current window down by "line_count" logical lines. "CTRL-Y"
|
* Scroll the current window down by "line_count" logical lines. "CTRL-Y"
|
||||||
*/
|
*/
|
||||||
@ -1099,6 +1171,7 @@ check_topfill (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
win_check_anchored_floats(curwin);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -64,3 +64,31 @@ func Test_curswant_with_cursorline()
|
|||||||
call assert_equal(6, winsaveview().curswant)
|
call assert_equal(6, winsaveview().curswant)
|
||||||
quit!
|
quit!
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Test_screenpos()
|
||||||
|
rightbelow new
|
||||||
|
rightbelow 20vsplit
|
||||||
|
call setline(1, ["\tsome text", "long wrapping line here", "next line"])
|
||||||
|
redraw
|
||||||
|
let winid = win_getid()
|
||||||
|
let [winrow, wincol] = win_screenpos(winid)
|
||||||
|
call assert_equal({'row': winrow,
|
||||||
|
\ 'col': wincol + 0,
|
||||||
|
\ 'curscol': wincol + 7,
|
||||||
|
\ 'endcol': wincol + 7}, screenpos(winid, 1, 1))
|
||||||
|
call assert_equal({'row': winrow,
|
||||||
|
\ 'col': wincol + 13,
|
||||||
|
\ 'curscol': wincol + 13,
|
||||||
|
\ 'endcol': wincol + 13}, screenpos(winid, 1, 7))
|
||||||
|
call assert_equal({'row': winrow + 2,
|
||||||
|
\ 'col': wincol + 1,
|
||||||
|
\ 'curscol': wincol + 1,
|
||||||
|
\ 'endcol': wincol + 1}, screenpos(winid, 2, 22))
|
||||||
|
setlocal number
|
||||||
|
call assert_equal({'row': winrow + 3,
|
||||||
|
\ 'col': wincol + 9,
|
||||||
|
\ 'curscol': wincol + 9,
|
||||||
|
\ 'endcol': wincol + 9}, screenpos(winid, 2, 22))
|
||||||
|
close
|
||||||
|
bwipe!
|
||||||
|
endfunc
|
||||||
|
@ -652,6 +652,17 @@ void win_config_float(win_T *wp, FloatConfig fconfig)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void win_check_anchored_floats(win_T *win)
|
||||||
|
{
|
||||||
|
for (win_T *wp = lastwin; wp && wp->w_floating; wp = wp->w_prev) {
|
||||||
|
// float might be anchored to moved window
|
||||||
|
if (wp->w_float_config.relative == kFloatRelativeWindow
|
||||||
|
&& wp->w_float_config.window == win->handle) {
|
||||||
|
wp->w_pos_changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void ui_ext_win_position(win_T *wp)
|
static void ui_ext_win_position(win_T *wp)
|
||||||
{
|
{
|
||||||
if (!wp->w_floating) {
|
if (!wp->w_floating) {
|
||||||
@ -673,6 +684,13 @@ static void ui_ext_win_position(win_T *wp)
|
|||||||
screen_adjust_grid(&grid, &row_off, &col_off);
|
screen_adjust_grid(&grid, &row_off, &col_off);
|
||||||
row += row_off;
|
row += row_off;
|
||||||
col += col_off;
|
col += col_off;
|
||||||
|
if (c.bufpos.lnum >= 0) {
|
||||||
|
pos_T pos = { c.bufpos.lnum+1, c.bufpos.col, 0 };
|
||||||
|
int trow, tcol, tcolc, tcole;
|
||||||
|
textpos2screenpos(win, &pos, &trow, &tcol, &tcolc, &tcole, true);
|
||||||
|
row += trow-1;
|
||||||
|
col += tcol-1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
api_clear_error(&dummy);
|
api_clear_error(&dummy);
|
||||||
}
|
}
|
||||||
@ -745,6 +763,18 @@ static bool parse_float_relative(String relative, FloatRelative *out)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool parse_float_bufpos(Array bufpos, lpos_T *out)
|
||||||
|
{
|
||||||
|
if (bufpos.size != 2
|
||||||
|
|| bufpos.items[0].type != kObjectTypeInteger
|
||||||
|
|| bufpos.items[1].type != kObjectTypeInteger) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
out->lnum = bufpos.items[0].data.integer;
|
||||||
|
out->col = bufpos.items[1].data.integer;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool parse_float_config(Dictionary config, FloatConfig *fconfig, bool reconf,
|
bool parse_float_config(Dictionary config, FloatConfig *fconfig, bool reconf,
|
||||||
Error *err)
|
Error *err)
|
||||||
{
|
{
|
||||||
@ -753,6 +783,7 @@ bool parse_float_config(Dictionary config, FloatConfig *fconfig, bool reconf,
|
|||||||
bool has_row = false, has_col = false, has_relative = false;
|
bool has_row = false, has_col = false, has_relative = false;
|
||||||
bool has_external = false, has_window = false;
|
bool has_external = false, has_window = false;
|
||||||
bool has_width = false, has_height = false;
|
bool has_width = false, has_height = false;
|
||||||
|
bool has_bufpos = false;
|
||||||
|
|
||||||
for (size_t i = 0; i < config.size; i++) {
|
for (size_t i = 0; i < config.size; i++) {
|
||||||
char *key = config.items[i].key.data;
|
char *key = config.items[i].key.data;
|
||||||
@ -832,6 +863,18 @@ bool parse_float_config(Dictionary config, FloatConfig *fconfig, bool reconf,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
fconfig->window = val.data.integer;
|
fconfig->window = val.data.integer;
|
||||||
|
} else if (!strcmp(key, "bufpos")) {
|
||||||
|
if (val.type != kObjectTypeArray) {
|
||||||
|
api_set_error(err, kErrorTypeValidation,
|
||||||
|
"'bufpos' key must be Array");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!parse_float_bufpos(val.data.array, &fconfig->bufpos)) {
|
||||||
|
api_set_error(err, kErrorTypeValidation,
|
||||||
|
"Invalid value of 'bufpos' key");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
has_bufpos = true;
|
||||||
} else if (!strcmp(key, "external")) {
|
} else if (!strcmp(key, "external")) {
|
||||||
if (val.type == kObjectTypeInteger) {
|
if (val.type == kObjectTypeInteger) {
|
||||||
fconfig->external = val.data.integer;
|
fconfig->external = val.data.integer;
|
||||||
@ -886,6 +929,21 @@ bool parse_float_config(Dictionary config, FloatConfig *fconfig, bool reconf,
|
|||||||
fconfig->window = curwin->handle;
|
fconfig->window = curwin->handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (has_window && !has_bufpos) {
|
||||||
|
fconfig->bufpos.lnum = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_bufpos) {
|
||||||
|
if (!has_row) {
|
||||||
|
fconfig->row = (fconfig->anchor & kFloatAnchorSouth) ? 0 : 1;
|
||||||
|
has_row = true;
|
||||||
|
}
|
||||||
|
if (!has_col) {
|
||||||
|
fconfig->col = 0;
|
||||||
|
has_col = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (has_relative && has_external) {
|
if (has_relative && has_external) {
|
||||||
api_set_error(err, kErrorTypeValidation,
|
api_set_error(err, kErrorTypeValidation,
|
||||||
"Only one of 'relative' and 'external' must be used");
|
"Only one of 'relative' and 'external' must be used");
|
||||||
@ -4732,7 +4790,8 @@ void shell_new_rows(void)
|
|||||||
if (!frame_check_height(topframe, h))
|
if (!frame_check_height(topframe, h))
|
||||||
frame_new_height(topframe, h, FALSE, FALSE);
|
frame_new_height(topframe, h, FALSE, FALSE);
|
||||||
|
|
||||||
(void)win_comp_pos(); /* recompute w_winrow and w_wincol */
|
(void)win_comp_pos(); // recompute w_winrow and w_wincol
|
||||||
|
win_reconfig_floats(); // The size of floats might change
|
||||||
compute_cmdrow();
|
compute_cmdrow();
|
||||||
curtab->tp_ch_used = p_ch;
|
curtab->tp_ch_used = p_ch;
|
||||||
|
|
||||||
@ -4753,7 +4812,8 @@ void shell_new_columns(void)
|
|||||||
frame_new_width(topframe, Columns, false, false);
|
frame_new_width(topframe, Columns, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
(void)win_comp_pos(); /* recompute w_winrow and w_wincol */
|
(void)win_comp_pos(); // recompute w_winrow and w_wincol
|
||||||
|
win_reconfig_floats(); // The size of floats might change
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -4809,15 +4869,23 @@ int win_comp_pos(void)
|
|||||||
|
|
||||||
frame_comp_pos(topframe, &row, &col);
|
frame_comp_pos(topframe, &row, &col);
|
||||||
|
|
||||||
// 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) {
|
for (win_T *wp = lastwin; wp && wp->w_floating; wp = wp->w_prev) {
|
||||||
win_config_float(wp, wp->w_float_config);
|
// float might be anchored to moved window
|
||||||
|
if (wp->w_float_config.relative == kFloatRelativeWindow) {
|
||||||
|
wp->w_pos_changed = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return row;
|
return row;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void win_reconfig_floats(void)
|
||||||
|
{
|
||||||
|
for (win_T *wp = lastwin; wp && wp->w_floating; wp = wp->w_prev) {
|
||||||
|
win_config_float(wp, wp->w_float_config);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Update the position of the windows in frame "topfrp", using the width and
|
* Update the position of the windows in frame "topfrp", using the width and
|
||||||
* height of the frames.
|
* height of the frames.
|
||||||
|
@ -963,6 +963,335 @@ describe('floating windows', function()
|
|||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('can be placed relative text in a window', function()
|
||||||
|
screen:try_resize(30,5)
|
||||||
|
local firstwin = meths.get_current_win().id
|
||||||
|
meths.buf_set_lines(0, 0, -1, true, {'just some', 'example text that is wider than the window', '', '', 'more text'})
|
||||||
|
if multigrid then
|
||||||
|
screen:expect{grid=[[
|
||||||
|
## grid 1
|
||||||
|
[2:------------------------------]|
|
||||||
|
[2:------------------------------]|
|
||||||
|
[2:------------------------------]|
|
||||||
|
[2:------------------------------]|
|
||||||
|
[3:------------------------------]|
|
||||||
|
## grid 2
|
||||||
|
^just some |
|
||||||
|
example text that is wider tha|
|
||||||
|
n the window |
|
||||||
|
|
|
||||||
|
## grid 3
|
||||||
|
|
|
||||||
|
]]}
|
||||||
|
else
|
||||||
|
screen:expect{grid=[[
|
||||||
|
^just some |
|
||||||
|
example text that is wider tha|
|
||||||
|
n the window |
|
||||||
|
|
|
||||||
|
|
|
||||||
|
]]}
|
||||||
|
end
|
||||||
|
|
||||||
|
local buf = meths.create_buf(false,false)
|
||||||
|
meths.buf_set_lines(buf, 0, -1, true, {'some info!'})
|
||||||
|
|
||||||
|
local win = meths.open_win(buf, false, {relative='win', width=12, height=1, bufpos={1,32}})
|
||||||
|
if multigrid then
|
||||||
|
screen:expect{grid=[[
|
||||||
|
## grid 1
|
||||||
|
[2:------------------------------]|
|
||||||
|
[2:------------------------------]|
|
||||||
|
[2:------------------------------]|
|
||||||
|
[2:------------------------------]|
|
||||||
|
[3:------------------------------]|
|
||||||
|
## grid 2
|
||||||
|
^just some |
|
||||||
|
example text that is wider tha|
|
||||||
|
n the window |
|
||||||
|
|
|
||||||
|
## grid 3
|
||||||
|
|
|
||||||
|
## grid 5
|
||||||
|
{1:some info! }|
|
||||||
|
]], float_pos={
|
||||||
|
[5] = { {
|
||||||
|
id = 1002
|
||||||
|
}, "NW", 2, 3, 2, true }
|
||||||
|
}}
|
||||||
|
else
|
||||||
|
screen:expect{grid=[[
|
||||||
|
^just some |
|
||||||
|
example text that is wider tha|
|
||||||
|
n the window |
|
||||||
|
{1:some info! } |
|
||||||
|
|
|
||||||
|
]]}
|
||||||
|
end
|
||||||
|
eq({relative='win', width=12, height=1, bufpos={1,32}, anchor='NW',
|
||||||
|
external=false, col=0, row=1, win=firstwin, focusable=true}, meths.win_get_config(win))
|
||||||
|
|
||||||
|
feed('<c-e>')
|
||||||
|
if multigrid then
|
||||||
|
screen:expect{grid=[[
|
||||||
|
## grid 1
|
||||||
|
[2:------------------------------]|
|
||||||
|
[2:------------------------------]|
|
||||||
|
[2:------------------------------]|
|
||||||
|
[2:------------------------------]|
|
||||||
|
[3:------------------------------]|
|
||||||
|
## grid 2
|
||||||
|
^example text that is wider tha|
|
||||||
|
n the window |
|
||||||
|
|
|
||||||
|
|
|
||||||
|
## grid 3
|
||||||
|
|
|
||||||
|
## grid 5
|
||||||
|
{1:some info! }|
|
||||||
|
]], float_pos={
|
||||||
|
[5] = { {
|
||||||
|
id = 1002
|
||||||
|
}, "NW", 2, 2, 2, true }
|
||||||
|
}}
|
||||||
|
else
|
||||||
|
screen:expect{grid=[[
|
||||||
|
^example text that is wider tha|
|
||||||
|
n the window |
|
||||||
|
{1:some info! } |
|
||||||
|
|
|
||||||
|
|
|
||||||
|
]]}
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
screen:try_resize(45,5)
|
||||||
|
if multigrid then
|
||||||
|
screen:expect{grid=[[
|
||||||
|
## grid 1
|
||||||
|
[2:---------------------------------------------]|
|
||||||
|
[2:---------------------------------------------]|
|
||||||
|
[2:---------------------------------------------]|
|
||||||
|
[2:---------------------------------------------]|
|
||||||
|
[3:---------------------------------------------]|
|
||||||
|
## grid 2
|
||||||
|
^example text that is wider than the window |
|
||||||
|
|
|
||||||
|
|
|
||||||
|
more text |
|
||||||
|
## grid 3
|
||||||
|
|
|
||||||
|
## grid 5
|
||||||
|
{1:some info! }|
|
||||||
|
]], float_pos={
|
||||||
|
[5] = { {
|
||||||
|
id = 1002
|
||||||
|
}, "NW", 2, 1, 32, true }
|
||||||
|
}}
|
||||||
|
else
|
||||||
|
-- note: appears misalinged due to cursor
|
||||||
|
screen:expect{grid=[[
|
||||||
|
^example text that is wider than the window |
|
||||||
|
{1:some info! } |
|
||||||
|
|
|
||||||
|
more text |
|
||||||
|
|
|
||||||
|
]]}
|
||||||
|
end
|
||||||
|
|
||||||
|
screen:try_resize(25,10)
|
||||||
|
if multigrid then
|
||||||
|
screen:expect{grid=[[
|
||||||
|
## grid 1
|
||||||
|
[2:-------------------------]|
|
||||||
|
[2:-------------------------]|
|
||||||
|
[2:-------------------------]|
|
||||||
|
[2:-------------------------]|
|
||||||
|
[2:-------------------------]|
|
||||||
|
[2:-------------------------]|
|
||||||
|
[2:-------------------------]|
|
||||||
|
[2:-------------------------]|
|
||||||
|
[2:-------------------------]|
|
||||||
|
[3:-------------------------]|
|
||||||
|
## grid 2
|
||||||
|
^example text that is wide|
|
||||||
|
r than the window |
|
||||||
|
|
|
||||||
|
|
|
||||||
|
more text |
|
||||||
|
{0:~ }|
|
||||||
|
{0:~ }|
|
||||||
|
{0:~ }|
|
||||||
|
{0:~ }|
|
||||||
|
## grid 3
|
||||||
|
|
|
||||||
|
## grid 5
|
||||||
|
{1:some info! }|
|
||||||
|
]], float_pos={
|
||||||
|
[5] = { {
|
||||||
|
id = 1002
|
||||||
|
}, "NW", 2, 2, 7, true }
|
||||||
|
}}
|
||||||
|
else
|
||||||
|
screen:expect{grid=[[
|
||||||
|
^example text that is wide|
|
||||||
|
r than the window |
|
||||||
|
{1:some info! } |
|
||||||
|
|
|
||||||
|
more text |
|
||||||
|
{0:~ }|
|
||||||
|
{0:~ }|
|
||||||
|
{0:~ }|
|
||||||
|
{0:~ }|
|
||||||
|
|
|
||||||
|
]]}
|
||||||
|
end
|
||||||
|
|
||||||
|
meths.win_set_config(win, {relative='win', bufpos={1,32}, anchor='SW'})
|
||||||
|
if multigrid then
|
||||||
|
screen:expect{grid=[[
|
||||||
|
## grid 1
|
||||||
|
[2:-------------------------]|
|
||||||
|
[2:-------------------------]|
|
||||||
|
[2:-------------------------]|
|
||||||
|
[2:-------------------------]|
|
||||||
|
[2:-------------------------]|
|
||||||
|
[2:-------------------------]|
|
||||||
|
[2:-------------------------]|
|
||||||
|
[2:-------------------------]|
|
||||||
|
[2:-------------------------]|
|
||||||
|
[3:-------------------------]|
|
||||||
|
## grid 2
|
||||||
|
^example text that is wide|
|
||||||
|
r than the window |
|
||||||
|
|
|
||||||
|
|
|
||||||
|
more text |
|
||||||
|
{0:~ }|
|
||||||
|
{0:~ }|
|
||||||
|
{0:~ }|
|
||||||
|
{0:~ }|
|
||||||
|
## grid 3
|
||||||
|
|
|
||||||
|
## grid 5
|
||||||
|
{1:some info! }|
|
||||||
|
]], float_pos={
|
||||||
|
[5] = { {
|
||||||
|
id = 1002
|
||||||
|
}, "SW", 2, 1, 7, true }
|
||||||
|
}}
|
||||||
|
else
|
||||||
|
screen:expect{grid=[[
|
||||||
|
^example{1:some info! }s wide|
|
||||||
|
r than the window |
|
||||||
|
|
|
||||||
|
|
|
||||||
|
more text |
|
||||||
|
{0:~ }|
|
||||||
|
{0:~ }|
|
||||||
|
{0:~ }|
|
||||||
|
{0:~ }|
|
||||||
|
|
|
||||||
|
]]}
|
||||||
|
end
|
||||||
|
|
||||||
|
meths.win_set_config(win, {relative='win', bufpos={1,32}, anchor='NW', col=-2})
|
||||||
|
if multigrid then
|
||||||
|
screen:expect{grid=[[
|
||||||
|
## grid 1
|
||||||
|
[2:-------------------------]|
|
||||||
|
[2:-------------------------]|
|
||||||
|
[2:-------------------------]|
|
||||||
|
[2:-------------------------]|
|
||||||
|
[2:-------------------------]|
|
||||||
|
[2:-------------------------]|
|
||||||
|
[2:-------------------------]|
|
||||||
|
[2:-------------------------]|
|
||||||
|
[2:-------------------------]|
|
||||||
|
[3:-------------------------]|
|
||||||
|
## grid 2
|
||||||
|
^example text that is wide|
|
||||||
|
r than the window |
|
||||||
|
|
|
||||||
|
|
|
||||||
|
more text |
|
||||||
|
{0:~ }|
|
||||||
|
{0:~ }|
|
||||||
|
{0:~ }|
|
||||||
|
{0:~ }|
|
||||||
|
## grid 3
|
||||||
|
|
|
||||||
|
## grid 5
|
||||||
|
{1:some info! }|
|
||||||
|
]], float_pos={
|
||||||
|
[5] = { {
|
||||||
|
id = 1002
|
||||||
|
}, "NW", 2, 2, 5, true }
|
||||||
|
}}
|
||||||
|
else
|
||||||
|
screen:expect{grid=[[
|
||||||
|
^example text that is wide|
|
||||||
|
r than the window |
|
||||||
|
{1:some info! } |
|
||||||
|
|
|
||||||
|
more text |
|
||||||
|
{0:~ }|
|
||||||
|
{0:~ }|
|
||||||
|
{0:~ }|
|
||||||
|
{0:~ }|
|
||||||
|
|
|
||||||
|
]]}
|
||||||
|
end
|
||||||
|
|
||||||
|
meths.win_set_config(win, {relative='win', bufpos={1,32}, row=2})
|
||||||
|
if multigrid then
|
||||||
|
screen:expect{grid=[[
|
||||||
|
## grid 1
|
||||||
|
[2:-------------------------]|
|
||||||
|
[2:-------------------------]|
|
||||||
|
[2:-------------------------]|
|
||||||
|
[2:-------------------------]|
|
||||||
|
[2:-------------------------]|
|
||||||
|
[2:-------------------------]|
|
||||||
|
[2:-------------------------]|
|
||||||
|
[2:-------------------------]|
|
||||||
|
[2:-------------------------]|
|
||||||
|
[3:-------------------------]|
|
||||||
|
## grid 2
|
||||||
|
^example text that is wide|
|
||||||
|
r than the window |
|
||||||
|
|
|
||||||
|
|
|
||||||
|
more text |
|
||||||
|
{0:~ }|
|
||||||
|
{0:~ }|
|
||||||
|
{0:~ }|
|
||||||
|
{0:~ }|
|
||||||
|
## grid 3
|
||||||
|
|
|
||||||
|
## grid 5
|
||||||
|
{1:some info! }|
|
||||||
|
]], float_pos={
|
||||||
|
[5] = { {
|
||||||
|
id = 1002
|
||||||
|
}, "NW", 2, 3, 7, true }
|
||||||
|
}}
|
||||||
|
else
|
||||||
|
screen:expect{grid=[[
|
||||||
|
^example text that is wide|
|
||||||
|
r than the window |
|
||||||
|
|
|
||||||
|
{1:some info! } |
|
||||||
|
more text |
|
||||||
|
{0:~ }|
|
||||||
|
{0:~ }|
|
||||||
|
{0:~ }|
|
||||||
|
{0:~ }|
|
||||||
|
|
|
||||||
|
]]}
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
it('validates cursor even when window is not entered', function()
|
it('validates cursor even when window is not entered', function()
|
||||||
screen:try_resize(30,5)
|
screen:try_resize(30,5)
|
||||||
command("set nowrap")
|
command("set nowrap")
|
||||||
|
Loading…
Reference in New Issue
Block a user