diff options
Diffstat (limited to 'src/popupwin.c')
-rw-r--r-- | src/popupwin.c | 51 |
1 files changed, 50 insertions, 1 deletions
diff --git a/src/popupwin.c b/src/popupwin.c index 810987aace..dc3b56468b 100644 --- a/src/popupwin.c +++ b/src/popupwin.c @@ -201,6 +201,15 @@ apply_options(win_T *wp, buf_T *buf UNUSED, dict_T *dict, int atcursor) wp->w_p_wrap = nr != 0; } + di = dict_find(dict, (char_u *)"callback", -1); + if (di != NULL) + { + callback_T callback = get_callback(&di->di_tv); + + if (callback.cb_name != NULL) + set_callback(&wp->w_close_cb, &callback); + } + di = dict_find(dict, (char_u *)"filter", -1); if (di != NULL) { @@ -632,14 +641,53 @@ popup_any_visible(void) } /* + * Invoke the close callback for window "wp" with value "result". + * Careful: The callback may make "wp" invalid! + */ + static void +invoke_popup_callback(win_T *wp, typval_T *result) +{ + typval_T rettv; + int dummy; + typval_T argv[3]; + + argv[0].v_type = VAR_NUMBER; + argv[0].vval.v_number = (varnumber_T)wp->w_id; + + if (result != NULL && result->v_type != VAR_UNKNOWN) + copy_tv(result, &argv[1]); + else + { + argv[1].v_type = VAR_NUMBER; + argv[1].vval.v_number = 0; + } + + argv[2].v_type = VAR_UNKNOWN; + + call_callback(&wp->w_close_cb, -1, + &rettv, 2, argv, NULL, 0L, 0L, &dummy, TRUE, NULL); + if (result != NULL) + clear_tv(&argv[1]); + clear_tv(&rettv); +} + +/* * popup_close({id}) */ void f_popup_close(typval_T *argvars, typval_T *rettv UNUSED) { int id = (int)tv_get_number(argvars); + win_T *wp = find_popup_win(id); + + if (wp != NULL) + { + if (wp->w_close_cb.cb_name != NULL) + // Careful: This may make "wp" invalid. + invoke_popup_callback(wp, &argvars[1]); - popup_close(id); + popup_close(id); + } } /* @@ -688,6 +736,7 @@ popup_free(win_T *wp) /* * Close a popup window by Window-id. + * Does not invoke the callback. */ void popup_close(int id) |