diff options
Diffstat (limited to 'src/nvim/window.c')
| -rw-r--r-- | src/nvim/window.c | 78 | 
1 files changed, 73 insertions, 5 deletions
| diff --git a/src/nvim/window.c b/src/nvim/window.c index 6861e19ca7..315b5ef759 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -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)  {    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);          row += row_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);      } @@ -745,6 +763,18 @@ static bool parse_float_relative(String relative, FloatRelative *out)    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,                          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_external = false, has_window = false;    bool has_width = false, has_height = false; +  bool has_bufpos = false;    for (size_t i = 0; i < config.size; i++) {      char *key = config.items[i].key.data; @@ -832,6 +863,18 @@ bool parse_float_config(Dictionary config, FloatConfig *fconfig, bool reconf,          return false;        }        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")) {        if (val.type == kObjectTypeInteger) {          fconfig->external = val.data.integer; @@ -886,6 +929,21 @@ bool parse_float_config(Dictionary config, FloatConfig *fconfig, bool reconf,      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) {      api_set_error(err, kErrorTypeValidation,                    "Only one of 'relative' and 'external' must be used"); @@ -4732,7 +4790,8 @@ void shell_new_rows(void)    if (!frame_check_height(topframe, h))      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();    curtab->tp_ch_used = p_ch; @@ -4753,7 +4812,8 @@ void shell_new_columns(void)      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); -  // 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) { -    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;  } +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   * height of the frames. | 
