mirror of
https://github.com/neovim/neovim.git
synced 2025-09-29 14:38:32 +00:00
fix(nvim__set_complete): pum preview info truncated during completion #32555
Problem: 1. The original info text is truncated in pum_set_preview_text. 2. There is an extra newline character at the end of the info text. 3. Incorrect usage of plines_win leads to errors in calculating the window height. Solution: 1. Improved string handling in pum_preview_set_text to safely process line content without modifying the original text. Now, the preview info is correctly preserved while splitting lines. 2. Do not append a trailing newline to the preview buffer when one is present at the end. 3. Set w_widher_inner in advance; otherwise, plines_win cannot correctly calculate the wrapped line height.
This commit is contained in:
@@ -803,14 +803,25 @@ static void pum_preview_set_text(buf_T *buf, char *info, linenr_T *lnum, int *ma
|
||||
Error err = ERROR_INIT;
|
||||
Arena arena = ARENA_EMPTY;
|
||||
Array replacement = ARRAY_DICT_INIT;
|
||||
char *token = NULL;
|
||||
char *line = os_strtok(info, "\n", &token);
|
||||
buf->b_p_ma = true;
|
||||
while (line != NULL) {
|
||||
ADD(replacement, STRING_OBJ(cstr_to_string(line)));
|
||||
|
||||
// Iterate through the string line by line by temporarily replacing newlines with NUL
|
||||
for (char *curr = info, *next; curr; curr = next ? next + 1 : NULL) {
|
||||
if ((next = strchr(curr, '\n'))) {
|
||||
*next = NUL; // Temporarily replace the newline with a string terminator
|
||||
}
|
||||
// Only skip if this is an empty line AND it's the last line
|
||||
if (*curr == '\0' && !next) {
|
||||
break;
|
||||
}
|
||||
|
||||
*max_width = MAX(*max_width, (int)mb_string2cells(curr));
|
||||
ADD(replacement, STRING_OBJ(cstr_to_string(curr)));
|
||||
(*lnum)++;
|
||||
(*max_width) = MAX(*max_width, (int)mb_string2cells(line));
|
||||
line = os_strtok(NULL, "\n", &token);
|
||||
|
||||
if (next) {
|
||||
*next = '\n';
|
||||
}
|
||||
}
|
||||
|
||||
int original_textlock = textlock;
|
||||
@@ -828,8 +839,23 @@ static void pum_preview_set_text(buf_T *buf, char *info, linenr_T *lnum, int *ma
|
||||
buf->b_p_ma = false;
|
||||
}
|
||||
|
||||
/// Calculate the total height (in screen lines) of the first 'count' buffer lines in window 'wp'.
|
||||
/// Takes line wrapping and other display factors into account.
|
||||
///
|
||||
/// @param wp Window pointer
|
||||
/// @param count Number of buffer lines to measure (1-based)
|
||||
/// @return Total height in screen lines
|
||||
static inline int pum_preview_win_height(win_T *wp, linenr_T count)
|
||||
{
|
||||
int height = 0;
|
||||
for (int i = 1; i <= count; i++) {
|
||||
height += plines_win(wp, i, false);
|
||||
}
|
||||
return height;
|
||||
}
|
||||
|
||||
/// adjust floating info preview window position
|
||||
static void pum_adjust_info_position(win_T *wp, int height, int width)
|
||||
static void pum_adjust_info_position(win_T *wp, int width)
|
||||
{
|
||||
int col = pum_col + pum_width + pum_scrollbar + 1;
|
||||
// TODO(glepnir): support config align border by using completepopup
|
||||
@@ -850,8 +876,10 @@ static void pum_adjust_info_position(win_T *wp, int height, int width)
|
||||
}
|
||||
// when pum_above is SW otherwise is NW
|
||||
wp->w_config.anchor = pum_above ? kFloatAnchorSouth : 0;
|
||||
wp->w_config.row = pum_above ? pum_row + height : pum_row;
|
||||
wp->w_config.height = MIN(Rows, height);
|
||||
linenr_T count = wp->w_buffer->b_ml.ml_line_count;
|
||||
wp->w_width_inner = wp->w_config.width;
|
||||
wp->w_config.height = MIN(Rows, pum_preview_win_height(wp, count));
|
||||
wp->w_config.row = pum_above ? pum_row + wp->w_config.height : pum_row;
|
||||
wp->w_config.hide = false;
|
||||
win_config_float(wp, wp->w_config);
|
||||
}
|
||||
@@ -884,10 +912,7 @@ win_T *pum_set_info(int selected, char *info)
|
||||
RedrawingDisabled--;
|
||||
redraw_later(wp, UPD_NOT_VALID);
|
||||
|
||||
if (wp->w_p_wrap) {
|
||||
lnum += plines_win(wp, lnum, true);
|
||||
}
|
||||
pum_adjust_info_position(wp, lnum, max_info_width);
|
||||
pum_adjust_info_position(wp, max_info_width);
|
||||
unblock_autocmds();
|
||||
return wp;
|
||||
}
|
||||
@@ -1063,11 +1088,8 @@ static bool pum_set_selected(int n, int repeat)
|
||||
curwin->w_cursor.col = 0;
|
||||
|
||||
if (use_float) {
|
||||
if (curwin->w_p_wrap) {
|
||||
lnum += plines_win(curwin, lnum, true);
|
||||
}
|
||||
// adjust floating window by actually height and max info text width
|
||||
pum_adjust_info_position(curwin, lnum, max_info_width);
|
||||
pum_adjust_info_position(curwin, max_info_width);
|
||||
}
|
||||
|
||||
if ((curwin != curwin_save && win_valid(curwin_save))
|
||||
|
Reference in New Issue
Block a user