Mercurial > vim
diff src/popupwin.c @ 17045:7fe328ad5573 v8.1.1522
patch 8.1.1522: poup_notification() not implemented yet
commit https://github.com/vim/vim/commit/68d48f40a4da79547b53e3164b658812e154d411
Author: Bram Moolenaar <Bram@vim.org>
Date: Wed Jun 12 22:42:41 2019 +0200
patch 8.1.1522: poup_notification() not implemented yet
Problem: Popup_notification() not implemented yet.
Solution: Implement it.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Wed, 12 Jun 2019 22:45:07 +0200 |
parents | 5ed4965ebc7b |
children | 6400d1ad5e4b |
line wrap: on
line diff
--- a/src/popupwin.c +++ b/src/popupwin.c @@ -110,7 +110,6 @@ get_padding_border(dict_T *dict, int *ar { dictitem_T *di; - vim_memset(array, 0, sizeof(int) * 4); di = dict_find(dict, (char_u *)name, -1); if (di != NULL) { @@ -165,6 +164,26 @@ set_moved_columns(win_T *wp, int flags) } } + +#if defined(FEAT_TIMERS) + static void +popup_add_timeout(win_T *wp, int time) +{ + char_u cbbuf[50]; + char_u *ptr = cbbuf; + typval_T tv; + + vim_snprintf((char *)cbbuf, sizeof(cbbuf), + "{_ -> popup_close(%d)}", wp->w_id); + if (get_lambda_tv(&ptr, &tv, TRUE) == OK) + { + wp->w_popup_timer = create_timer(time, 0); + wp->w_popup_timer->tr_callback = get_callback(&tv); + clear_tv(&tv); + } +} +#endif + /* * Go through the options in "dict" and apply them to buffer "buf" displayed in * popup window "wp". @@ -184,31 +203,22 @@ apply_options(win_T *wp, buf_T *buf UNUS get_pos_options(wp, dict); - wp->w_zindex = dict_get_number(dict, (char_u *)"zindex"); - if (wp->w_zindex < 1) - wp->w_zindex = POPUPWIN_DEFAULT_ZINDEX; - if (wp->w_zindex > 32000) - wp->w_zindex = 32000; + di = dict_find(dict, (char_u *)"zindex", -1); + if (di != NULL) + { + wp->w_zindex = dict_get_number(dict, (char_u *)"zindex"); + if (wp->w_zindex < 1) + wp->w_zindex = POPUPWIN_DEFAULT_ZINDEX; + if (wp->w_zindex > 32000) + wp->w_zindex = 32000; + } -# if defined(FEAT_TIMERS) +#if defined(FEAT_TIMERS) // Add timer to close the popup after some time. nr = dict_get_number(dict, (char_u *)"time"); if (nr > 0) - { - char_u cbbuf[50]; - char_u *ptr = cbbuf; - typval_T tv; - - vim_snprintf((char *)cbbuf, sizeof(cbbuf), - "{_ -> popup_close(%d)}", wp->w_id); - if (get_lambda_tv(&ptr, &tv, TRUE) == OK) - { - wp->w_popup_timer = create_timer(nr, 0); - wp->w_popup_timer->tr_callback = get_callback(&tv); - clear_tv(&tv); - } - } -# endif + popup_add_timeout(wp, nr); +#endif // Option values resulting in setting an option. str = dict_get_string(dict, (char_u *)"highlight", FALSE); @@ -601,7 +611,8 @@ popup_adjust_position(win_T *wp) typedef enum { TYPE_NORMAL, - TYPE_ATCURSOR + TYPE_ATCURSOR, + TYPE_NOTIFICATION } create_type_T; /* @@ -659,7 +670,13 @@ popup_create(typval_T *argvars, typval_T // Avoid that 'buftype' is reset when this buffer is entered. buf->b_p_initialized = TRUE; - nr = (int)dict_get_number(d, (char_u *)"tab"); + if (dict_find(d, (char_u *)"tab", -1) != NULL) + nr = (int)dict_get_number(d, (char_u *)"tab"); + else if (type == TYPE_NOTIFICATION) + nr = -1; // notifications are global by default + else + nr = 0; + if (nr == 0) { // popup on current tab @@ -668,9 +685,18 @@ popup_create(typval_T *argvars, typval_T } else if (nr < 0) { - // global popup - wp->w_next = first_popupwin; - first_popupwin = wp; + win_T *prev = first_popupwin; + + // Global popup: add at the end, so that it gets displayed on top of + // older ones with the same zindex. Matters for notifications. + if (first_popupwin == NULL) + first_popupwin = wp; + else + { + while (prev->w_next != NULL) + prev = prev->w_next; + prev->w_next = wp; + } } else // TODO: find tab page "nr" @@ -720,9 +746,52 @@ popup_create(typval_T *argvars, typval_T // set default values wp->w_zindex = POPUPWIN_DEFAULT_ZINDEX; + if (type == TYPE_NOTIFICATION) + { + win_T *twp, *nextwin; + int height = buf->b_ml.ml_line_count + 3; + int i; + + // Try to not overlap with another global popup. Guess we need 3 + // more screen lines than buffer lines. + wp->w_wantline = 1; + for (twp = first_popupwin; twp != NULL; twp = nextwin) + { + nextwin = twp->w_next; + if (twp != wp + && twp->w_zindex == POPUPWIN_NOTIFICATION_ZINDEX + && twp->w_winrow <= wp->w_wantline - 1 + height + && twp->w_winrow + popup_height(twp) > wp->w_wantline - 1) + { + // move to below this popup and restart the loop to check for + // overlap with other popups + wp->w_wantline = twp->w_winrow + popup_height(twp) + 1; + nextwin = first_popupwin; + } + } + if (wp->w_wantline + height > Rows) + { + // can't avoid overlap, put on top in the hope that message goes + // away soon. + wp->w_wantline = 1; + } + + wp->w_wantcol = 10; + wp->w_zindex = POPUPWIN_NOTIFICATION_ZINDEX; + for (i = 0; i < 4; ++i) + wp->w_popup_border[i] = 1; + wp->w_popup_padding[1] = 1; + wp->w_popup_padding[3] = 1; + set_string_option_direct_in_win(wp, (char_u *)"wincolor", -1, + (char_u *)"WarningMsg", OPT_FREE|OPT_LOCAL, 0); + } + // Deal with options. apply_options(wp, buf, argvars[1].vval.v_dict); + if (type == TYPE_NOTIFICATION && wp->w_popup_timer == NULL) + popup_add_timeout(wp, 3000); + popup_adjust_position(wp); wp->w_vsep_width = 0; @@ -759,6 +828,15 @@ f_popup_atcursor(typval_T *argvars, typv } /* + * popup_notification({text}, {options}) + */ + void +f_popup_notification(typval_T *argvars, typval_T *rettv) +{ + popup_create(argvars, rettv, TYPE_NOTIFICATION); +} + +/* * Find the popup window with window-ID "id". * If the popup window does not exist NULL is returned. * If the window is not a popup window, and error message is given. @@ -1017,8 +1095,10 @@ f_popup_getpos(typval_T *argvars, typval dict_add_number(dict, "line", wp->w_winrow + 1); dict_add_number(dict, "col", wp->w_wincol + 1); - dict_add_number(dict, "width", wp->w_width + left_extra + wp->w_popup_border[1] + wp->w_popup_padding[1]); - dict_add_number(dict, "height", wp->w_height + top_extra + wp->w_popup_border[2] + wp->w_popup_padding[2]); + dict_add_number(dict, "width", wp->w_width + left_extra + + wp->w_popup_border[1] + wp->w_popup_padding[1]); + dict_add_number(dict, "height", wp->w_height + top_extra + + wp->w_popup_border[2] + wp->w_popup_padding[2]); dict_add_number(dict, "core_line", wp->w_winrow + 1 + top_extra); dict_add_number(dict, "core_col", wp->w_wincol + 1 + left_extra);