diff options
Diffstat (limited to 'src/nvim/popupmnu.c')
-rw-r--r-- | src/nvim/popupmnu.c | 82 |
1 files changed, 58 insertions, 24 deletions
diff --git a/src/nvim/popupmnu.c b/src/nvim/popupmnu.c index 056770f2c0..86cb66c6f3 100644 --- a/src/nvim/popupmnu.c +++ b/src/nvim/popupmnu.c @@ -19,6 +19,7 @@ #include "nvim/move.h" #include "nvim/option.h" #include "nvim/screen.h" +#include "nvim/ui_compositor.h" #include "nvim/search.h" #include "nvim/strings.h" #include "nvim/memory.h" @@ -43,6 +44,8 @@ static int pum_col; // left column of pum static bool pum_is_visible = false; static bool pum_external = false; +static ScreenGrid pum_grid = SCREEN_GRID_INIT; + #ifdef INCLUDE_GENERATED_DECLARATIONS # include "popupmnu.c.generated.h" #endif @@ -317,7 +320,7 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed) /// Redraw the popup menu, using "pum_first" and "pum_selected". void pum_redraw(void) { - int row = pum_row; + int row = 0; int col; int attr_norm = win_hl_attr(curwin, HLF_PNI); int attr_select = win_hl_attr(curwin, HLF_PSI); @@ -334,6 +337,37 @@ void pum_redraw(void) int round; int n; + int grid_width = pum_width; + int col_off = 0; + bool extra_space = false; + if (curwin->w_p_rl) { + col_off = pum_width; + if (pum_col < curwin->w_wincol + curwin->w_width - 1) { + grid_width += 1; + extra_space = true; + } + } else if (pum_col > 0) { + grid_width += 1; + col_off = 1; + extra_space = true; + } + if (pum_scrollbar > 0) { + grid_width++; + } + + grid_assign_handle(&pum_grid); + bool moved = ui_comp_put_grid(&pum_grid, pum_row, pum_col-col_off, + pum_height, grid_width); + + if (!pum_grid.chars + || pum_grid.Rows != pum_height || pum_grid.Columns != grid_width) { + grid_alloc(&pum_grid, pum_height, grid_width, !moved); + ui_call_grid_resize(pum_grid.handle, pum_grid.Columns, pum_grid.Rows); + } else if (moved) { + grid_invalidate(&pum_grid); + } + + // Never display more than we have if (pum_first > pum_size - pum_height) { pum_first = pum_size - pum_height; @@ -356,17 +390,17 @@ void pum_redraw(void) screen_puts_line_start(row); // prepend a space if there is room - if (curwin->w_p_rl) { - if (pum_col < curwin->w_wincol + curwin->w_width - 1) { - grid_putchar(&default_grid, ' ', row, pum_col + 1, attr); + if (extra_space) { + if (curwin->w_p_rl) { + grid_putchar(&pum_grid, ' ', row, col_off + 1, attr); + } else { + grid_putchar(&pum_grid, ' ', row, col_off - 1, attr); } - } else if (pum_col > 0) { - grid_putchar(&default_grid, ' ', row, pum_col - 1, attr); } // Display each entry, use two spaces for a Tab. // Do this 3 times: For the main text, kind and extra info - col = pum_col; + col = col_off; totwidth = 0; for (round = 1; round <= 3; ++round) { @@ -423,13 +457,13 @@ void pum_redraw(void) size++; } } - grid_puts_len(&default_grid, rt, (int)STRLEN(rt), row, + grid_puts_len(&pum_grid, rt, (int)STRLEN(rt), row, col - size + 1, attr); xfree(rt_start); xfree(st); col -= width; } else { - grid_puts_len(&default_grid, st, (int)STRLEN(st), row, col, attr); + grid_puts_len(&pum_grid, st, (int)STRLEN(st), row, col, attr); xfree(st); col += width; } @@ -440,11 +474,11 @@ void pum_redraw(void) // Display two spaces for a Tab. if (curwin->w_p_rl) { - grid_puts_len(&default_grid, (char_u *)" ", 2, row, col - 1, + grid_puts_len(&pum_grid, (char_u *)" ", 2, row, col - 1, attr); col -= 2; } else { - grid_puts_len(&default_grid, (char_u *)" ", 2, row, col, attr); + grid_puts_len(&pum_grid, (char_u *)" ", 2, row, col, attr); col += 2; } totwidth += 2; @@ -475,37 +509,37 @@ void pum_redraw(void) } if (curwin->w_p_rl) { - grid_fill(&default_grid, row, row + 1, pum_col - pum_base_width - n + 1, + grid_fill(&pum_grid, row, row + 1, col_off - pum_base_width - n + 1, col + 1, ' ', ' ', attr); - col = pum_col - pum_base_width - n + 1; + col = col_off - pum_base_width - n + 1; } else { - grid_fill(&default_grid, row, row + 1, col, - pum_col + pum_base_width + n, ' ', ' ', attr); - col = pum_col + pum_base_width + n; + grid_fill(&pum_grid, row, row + 1, col, + col_off + pum_base_width + n, ' ', ' ', attr); + col = pum_base_width + n; } totwidth = pum_base_width + n; } if (curwin->w_p_rl) { - grid_fill(&default_grid, row, row + 1, pum_col - pum_width + 1, col + 1, + grid_fill(&pum_grid, row, row + 1, col_off - pum_width + 1, col + 1, ' ', ' ', attr); } else { - grid_fill(&default_grid, row, row + 1, col, pum_col + pum_width, ' ', ' ', + grid_fill(&pum_grid, row, row + 1, col, col_off + pum_width, ' ', ' ', attr); } if (pum_scrollbar > 0) { if (curwin->w_p_rl) { - grid_putchar(&default_grid, ' ', row, pum_col - pum_width, + grid_putchar(&pum_grid, ' ', row, col_off - pum_width, i >= thumb_pos && i < thumb_pos + thumb_heigth ? attr_thumb : attr_scroll); } else { - grid_putchar(&default_grid, ' ', row, pum_col + pum_width, + grid_putchar(&pum_grid, ' ', row, col_off + pum_width, i >= thumb_pos && i < thumb_pos + thumb_heigth ? attr_thumb : attr_scroll); } } - grid_puts_line_flush(&default_grid, false); + grid_puts_line_flush(&pum_grid, false); row++; } } @@ -733,9 +767,9 @@ void pum_undisplay(void) if (pum_external) { ui_call_popupmenu_hide(); } else { - redraw_all_later(SOME_VALID); - redraw_tabline = true; - status_redraw_all(); + ui_comp_remove_grid(&pum_grid); + // TODO(bfredl): consider the possibility of keeping float grids allocated. + grid_free(&pum_grid); } } |