/// Sets the current tab page /// /// @param handle The tab page handle /// @param[out] err Details of an error that may have occurred void vim_set_current_tabpage(Tabpage tabpage, Error *err) { tabpage_T *tp = find_tab_by_handle(tabpage, err); if (!tp) { return; } try_start(); goto_tabpage_tp(tp, true, true); try_end(err); }
/* * Set the index of the currently selected item. The menu will scroll when * necessary. When "n" is out of range don't scroll. * This may be repeated when the preview window is used: * "repeat" == 0: open preview window normally * "repeat" == 1: open preview window but don't set the size * "repeat" == 2: don't open preview window * Returns TRUE when the window was resized and the location of the popup menu * must be recomputed. */ static int pum_set_selected(int n, int repeat) { int resized = FALSE; int context = pum_height / 2; pum_selected = n; if (pum_selected >= 0 && pum_selected < pum_size) { if (pum_first > pum_selected - 4) { /* scroll down; when we did a jump it's probably a PageUp then * scroll a whole page */ if (pum_first > pum_selected - 2) { pum_first -= pum_height - 2; if (pum_first < 0) pum_first = 0; else if (pum_first > pum_selected) pum_first = pum_selected; } else pum_first = pum_selected; } else if (pum_first < pum_selected - pum_height + 5) { /* scroll up; when we did a jump it's probably a PageDown then * scroll a whole page */ if (pum_first < pum_selected - pum_height + 1 + 2) { pum_first += pum_height - 2; if (pum_first < pum_selected - pum_height + 1) pum_first = pum_selected - pum_height + 1; } else pum_first = pum_selected - pum_height + 1; } /* Give a few lines of context when possible. */ if (context > 3) context = 3; if (pum_height > 2) { if (pum_first > pum_selected - context) { /* scroll down */ pum_first = pum_selected - context; if (pum_first < 0) pum_first = 0; } else if (pum_first < pum_selected + context - pum_height + 1) { /* scroll up */ pum_first = pum_selected + context - pum_height + 1; } } #if defined(FEAT_QUICKFIX) /* * Show extra info in the preview window if there is something and * 'completeopt' contains "preview". * Skip this when tried twice already. * Skip this also when there is not much room. * NOTE: Be very careful not to sync undo! */ if (pum_array[pum_selected].pum_info != NULL && Rows > 10 && repeat <= 1 && vim_strchr(p_cot, 'p') != NULL) { win_T *curwin_save = curwin; tabpage_T *curtab_save = curtab; int res = OK; /* Open a preview window. 3 lines by default. Prefer * 'previewheight' if set and smaller. */ g_do_tagpreview = 3; if (p_pvh > 0 && p_pvh < g_do_tagpreview) g_do_tagpreview = p_pvh; ++RedrawingDisabled; /* Prevent undo sync here, if an autocommand syncs undo weird * things can happen to the undo tree. */ ++no_u_sync; resized = prepare_tagpreview(FALSE); --no_u_sync; --RedrawingDisabled; g_do_tagpreview = 0; if (curwin->w_p_pvw) { if (!resized && curbuf->b_nwindows == 1 && curbuf->b_fname == NULL && curbuf->b_p_bt[0] == 'n' && curbuf->b_p_bt[2] == 'f' && curbuf->b_p_bh[0] == 'w') { /* Already a "wipeout" buffer, make it empty. */ while (!BUFEMPTY()) ml_delete((linenr_T)1, FALSE); } else { /* Don't want to sync undo in the current buffer. */ ++no_u_sync; res = do_ecmd(0, NULL, NULL, NULL, ECMD_ONE, 0, NULL); --no_u_sync; if (res == OK) { /* Edit a new, empty buffer. Set options for a "wipeout" * buffer. */ set_option_value((char_u *)"swf", 0L, NULL, OPT_LOCAL); set_option_value((char_u *)"bt", 0L, (char_u *)"nofile", OPT_LOCAL); set_option_value((char_u *)"bh", 0L, (char_u *)"wipe", OPT_LOCAL); set_option_value((char_u *)"diff", 0L, NULL, OPT_LOCAL); } } if (res == OK) { char_u *p, *e; linenr_T lnum = 0; for (p = pum_array[pum_selected].pum_info; *p != NUL; ) { e = vim_strchr(p, '\n'); if (e == NULL) { ml_append(lnum++, p, 0, FALSE); break; } else { *e = NUL; ml_append(lnum++, p, (int)(e - p + 1), FALSE); *e = '\n'; p = e + 1; } } /* Increase the height of the preview window to show the * text, but no more than 'previewheight' lines. */ if (repeat == 0) { if (lnum > p_pvh) lnum = p_pvh; if (curwin->w_height < lnum) { win_setheight((int)lnum); resized = TRUE; } } curbuf->b_changed = 0; curbuf->b_p_ma = FALSE; curwin->w_cursor.lnum = 1; curwin->w_cursor.col = 0; if ((curwin != curwin_save && win_valid(curwin_save)) || (curtab != curtab_save && valid_tabpage(curtab_save))) { if (curtab != curtab_save && valid_tabpage(curtab_save)) goto_tabpage_tp(curtab_save, FALSE, FALSE); /* When the first completion is done and the preview * window is not resized, skip the preview window's * status line redrawing. */ if (ins_compl_active() && !resized) curwin->w_redr_status = FALSE; /* Return cursor to where we were */ validate_cursor(); redraw_later(SOME_VALID); /* When the preview window was resized we need to * update the view on the buffer. Only go back to * the window when needed, otherwise it will always be * redraw. */ if (resized) { ++no_u_sync; win_enter(curwin_save, TRUE); --no_u_sync; update_topline(); } /* Update the screen before drawing the popup menu. * Enable updating the status lines. */ pum_do_redraw = TRUE; update_screen(0); pum_do_redraw = FALSE; if (!resized && win_valid(curwin_save)) { ++no_u_sync; win_enter(curwin_save, TRUE); --no_u_sync; } /* May need to update the screen again when there are * autocommands involved. */ pum_do_redraw = TRUE; update_screen(0); pum_do_redraw = FALSE; } } } } #endif } if (!resized) pum_redraw(); return resized; }