@@ -201,6 +201,10 @@ popup_start_drag(win_T *wp)
201201 drag_start_wantcol = wp -> w_wincol + 1 ;
202202 else
203203 drag_start_wantcol = wp -> w_wantcol ;
204+
205+ // Stop centering the popup
206+ if (wp -> w_popup_pos == POPPOS_CENTER )
207+ wp -> w_popup_pos = POPPOS_TOPLEFT ;
204208}
205209
206210/*
@@ -301,7 +305,9 @@ apply_options(win_T *wp, buf_T *buf UNUSED, dict_T *dict)
301305 wp -> w_p_wrap = nr != 0 ;
302306 }
303307
304- wp -> w_popup_drag = dict_get_number (dict , (char_u * )"drag" );
308+ di = dict_find (dict , (char_u * )"drag" , -1 );
309+ if (di != NULL )
310+ wp -> w_popup_drag = dict_get_number (dict , (char_u * )"drag" );
305311
306312 di = dict_find (dict , (char_u * )"callback" , -1 );
307313 if (di != NULL )
@@ -692,13 +698,13 @@ typedef enum
692698{
693699 TYPE_NORMAL ,
694700 TYPE_ATCURSOR ,
695- TYPE_NOTIFICATION
701+ TYPE_NOTIFICATION ,
702+ TYPE_DIALOG
696703} create_type_T ;
697704
698705/*
699706 * popup_create({text}, {options})
700707 * popup_atcursor({text}, {options})
701- * When called from f_popup_atcursor() "type" is TYPE_ATCURSOR.
702708 */
703709 static void
704710popup_create (typval_T * argvars , typval_T * rettv , create_type_T type )
@@ -871,6 +877,20 @@ popup_create(typval_T *argvars, typval_T *rettv, create_type_T type)
871877 OPT_FREE |OPT_LOCAL , 0 );
872878 }
873879
880+ if (type == TYPE_DIALOG )
881+ {
882+ int i ;
883+
884+ wp -> w_popup_pos = POPPOS_CENTER ;
885+ wp -> w_zindex = POPUPWIN_DIALOG_ZINDEX ;
886+ wp -> w_popup_drag = 1 ;
887+ for (i = 0 ; i < 4 ; ++ i )
888+ {
889+ wp -> w_popup_border [i ] = 1 ;
890+ wp -> w_popup_padding [i ] = 1 ;
891+ }
892+ }
893+
874894 // Deal with options.
875895 apply_options (wp , buf , argvars [1 ].vval .v_dict );
876896
@@ -912,33 +932,6 @@ f_popup_atcursor(typval_T *argvars, typval_T *rettv)
912932 popup_create (argvars , rettv , TYPE_ATCURSOR );
913933}
914934
915- /*
916- * popup_notification({text}, {options})
917- */
918- void
919- f_popup_notification (typval_T * argvars , typval_T * rettv )
920- {
921- popup_create (argvars , rettv , TYPE_NOTIFICATION );
922- }
923-
924- /*
925- * Find the popup window with window-ID "id".
926- * If the popup window does not exist NULL is returned.
927- * If the window is not a popup window, and error message is given.
928- */
929- static win_T *
930- find_popup_win (int id )
931- {
932- win_T * wp = win_id2wp (id );
933-
934- if (wp != NULL && !bt_popup (wp -> w_buffer ))
935- {
936- semsg (_ ("E993: window %d is not a popup window" ), id );
937- return NULL ;
938- }
939- return wp ;
940- }
941-
942935/*
943936 * Invoke the close callback for window "wp" with value "result".
944937 * Careful: The callback may make "wp" invalid!
@@ -985,6 +978,90 @@ popup_close_and_callback(win_T *wp, typval_T *arg)
985978 popup_close (id );
986979}
987980
981+ /*
982+ * popup_filter_yesno({text}, {options})
983+ */
984+ void
985+ f_popup_filter_yesno (typval_T * argvars , typval_T * rettv )
986+ {
987+ int id = tv_get_number (& argvars [0 ]);
988+ win_T * wp = win_id2wp (id );
989+ char_u * key = tv_get_string (& argvars [1 ]);
990+ typval_T res ;
991+
992+ // If the popup has been closed don't consume the key.
993+ if (wp == NULL )
994+ return ;
995+
996+ // consume all keys until done
997+ rettv -> vval .v_number = 1 ;
998+
999+ if (STRCMP (key , "y" ) == 0 || STRCMP (key , "Y" ) == 0 )
1000+ res .vval .v_number = 1 ;
1001+ else if (STRCMP (key , "n" ) == 0 || STRCMP (key , "N" ) == 0
1002+ || STRCMP (key , "x" ) == 0 || STRCMP (key , "X" ) == 0
1003+ || STRCMP (key , "\x1b" ) == 0 )
1004+ res .vval .v_number = 0 ;
1005+ else
1006+ {
1007+ int c = * key ;
1008+ int row = mouse_row ;
1009+ int col = mouse_col ;
1010+
1011+ if (c == K_SPECIAL && key [1 ] != NUL )
1012+ c = TO_SPECIAL (key [1 ], key [2 ]);
1013+ if (wp -> w_popup_drag
1014+ && is_mouse_key (c )
1015+ && (wp == popup_dragwin
1016+ || wp == mouse_find_win (& row , & col , FIND_POPUP )))
1017+ // allow for dragging the popup
1018+ rettv -> vval .v_number = 0 ;
1019+
1020+ // ignore this key
1021+ return ;
1022+ }
1023+
1024+ // Invoke callback
1025+ res .v_type = VAR_NUMBER ;
1026+ popup_close_and_callback (wp , & res );
1027+ }
1028+
1029+ /*
1030+ * popup_dialog({text}, {options})
1031+ */
1032+ void
1033+ f_popup_dialog (typval_T * argvars , typval_T * rettv )
1034+ {
1035+ popup_create (argvars , rettv , TYPE_DIALOG );
1036+ }
1037+
1038+ /*
1039+ * popup_notification({text}, {options})
1040+ */
1041+ void
1042+ f_popup_notification (typval_T * argvars , typval_T * rettv )
1043+ {
1044+ popup_create (argvars , rettv , TYPE_NOTIFICATION );
1045+ }
1046+
1047+ /*
1048+ * Find the popup window with window-ID "id".
1049+ * If the popup window does not exist NULL is returned.
1050+ * If the window is not a popup window, and error message is given.
1051+ */
1052+ static win_T *
1053+ find_popup_win (int id )
1054+ {
1055+ win_T * wp = win_id2wp (id );
1056+
1057+ if (wp != NULL && !bt_popup (wp -> w_buffer ))
1058+ {
1059+ semsg (_ ("E993: window %d is not a popup window" ), id );
1060+ return NULL ;
1061+ }
1062+ return wp ;
1063+ }
1064+
9881065/*
9891066 * popup_close({id})
9901067 */
@@ -1299,6 +1376,15 @@ invoke_popup_filter(win_T *wp, int c)
12991376 typval_T argv [3 ];
13001377 char_u buf [NUMBUFLEN ];
13011378
1379+ // Emergency exit: CTRL-C closes the popup.
1380+ if (c == Ctrl_C )
1381+ {
1382+ rettv .v_type = VAR_NUMBER ;
1383+ rettv .vval .v_number = -1 ;
1384+ popup_close_and_callback (wp , & rettv );
1385+ return 1 ;
1386+ }
1387+
13021388 argv [0 ].v_type = VAR_NUMBER ;
13031389 argv [0 ].vval .v_number = (varnumber_T )wp -> w_id ;
13041390
@@ -1310,6 +1396,7 @@ invoke_popup_filter(win_T *wp, int c)
13101396
13111397 argv [2 ].v_type = VAR_UNKNOWN ;
13121398
1399+ // NOTE: The callback might close the popup, thus make "wp" invalid.
13131400 call_callback (& wp -> w_filter_cb , -1 ,
13141401 & rettv , 2 , argv , NULL , 0L , 0L , & dummy , TRUE, NULL );
13151402 res = tv_get_number (& rettv );
@@ -1326,7 +1413,7 @@ invoke_popup_filter(win_T *wp, int c)
13261413popup_do_filter (int c )
13271414{
13281415 int res = FALSE;
1329- win_T * wp ;
1416+ win_T * wp ;
13301417
13311418 popup_reset_handled ();
13321419
0 commit comments