Patch 8.1.1548
Problem:    Popup_dialog() is not implemented.
Solution:   Implement popup_dialog() and popup_filter_yesno().
Files:      src/popupwin.c, src/proto/popupwin.pro, src/evalfunc.c,
            src/structs.h, src/globals.h, src/testdir/test_popupwin.vim,
            runtime/doc/popup.txt


*** ../vim-8.1.1547/src/popupwin.c      2019-06-15 14:31:33.774185476 +0200
--- src/popupwin.c      2019-06-15 21:40:51.129608271 +0200
***************
*** 201,206 ****
--- 201,210 ----
        drag_start_wantcol = wp->w_wincol + 1;
      else
        drag_start_wantcol = wp->w_wantcol;
+ 
+     // Stop centering the popup
+     if (wp->w_popup_pos == POPPOS_CENTER)
+       wp->w_popup_pos = POPPOS_TOPLEFT;
  }
  
  /*
***************
*** 301,307 ****
        wp->w_p_wrap = nr != 0;
      }
  
!     wp->w_popup_drag = dict_get_number(dict, (char_u *)"drag");
  
      di = dict_find(dict, (char_u *)"callback", -1);
      if (di != NULL)
--- 305,313 ----
        wp->w_p_wrap = nr != 0;
      }
  
!     di = dict_find(dict, (char_u *)"drag", -1);
!     if (di != NULL)
!       wp->w_popup_drag = dict_get_number(dict, (char_u *)"drag");
  
      di = dict_find(dict, (char_u *)"callback", -1);
      if (di != NULL)
***************
*** 692,704 ****
  {
      TYPE_NORMAL,
      TYPE_ATCURSOR,
!     TYPE_NOTIFICATION
  } create_type_T;
  
  /*
   * popup_create({text}, {options})
   * popup_atcursor({text}, {options})
-  * When called from f_popup_atcursor() "type" is TYPE_ATCURSOR.
   */
      static void
  popup_create(typval_T *argvars, typval_T *rettv, create_type_T type)
--- 698,710 ----
  {
      TYPE_NORMAL,
      TYPE_ATCURSOR,
!     TYPE_NOTIFICATION,
!     TYPE_DIALOG
  } create_type_T;
  
  /*
   * popup_create({text}, {options})
   * popup_atcursor({text}, {options})
   */
      static void
  popup_create(typval_T *argvars, typval_T *rettv, create_type_T type)
***************
*** 871,876 ****
--- 877,896 ----
                OPT_FREE|OPT_LOCAL, 0);
      }
  
+     if (type == TYPE_DIALOG)
+     {
+       int i;
+ 
+       wp->w_popup_pos = POPPOS_CENTER;
+       wp->w_zindex = POPUPWIN_DIALOG_ZINDEX;
+       wp->w_popup_drag = 1;
+       for (i = 0; i < 4; ++i)
+       {
+           wp->w_popup_border[i] = 1;
+           wp->w_popup_padding[i] = 1;
+       }
+     }
+ 
      // Deal with options.
      apply_options(wp, buf, argvars[1].vval.v_dict);
  
***************
*** 913,945 ****
  }
  
  /*
-  * 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.
-  */
-     static win_T *
- find_popup_win(int id)
- {
-     win_T *wp = win_id2wp(id);
- 
-     if (wp != NULL && !bt_popup(wp->w_buffer))
-     {
-       semsg(_("E993: window %d is not a popup window"), id);
-       return NULL;
-     }
-     return wp;
- }
- 
- /*
   * Invoke the close callback for window "wp" with value "result".
   * Careful: The callback may make "wp" invalid!
   */
--- 933,938 ----
***************
*** 986,991 ****
--- 979,1068 ----
  }
  
  /*
+  * popup_filter_yesno({text}, {options})
+  */
+     void
+ f_popup_filter_yesno(typval_T *argvars, typval_T *rettv)
+ {
+     int               id = tv_get_number(&argvars[0]);
+     win_T     *wp = win_id2wp(id);
+     char_u    *key = tv_get_string(&argvars[1]);
+     typval_T  res;
+ 
+     // If the popup has been closed don't consume the key.
+     if (wp == NULL)
+       return;
+ 
+     // consume all keys until done
+     rettv->vval.v_number = 1;
+ 
+     if (STRCMP(key, "y") == 0 || STRCMP(key, "Y") == 0)
+       res.vval.v_number = 1;
+     else if (STRCMP(key, "n") == 0 || STRCMP(key, "N") == 0
+           || STRCMP(key, "x") == 0 || STRCMP(key, "X") == 0
+           || STRCMP(key, "\x1b") == 0)
+       res.vval.v_number = 0;
+     else
+     {
+       int     c = *key;
+       int     row = mouse_row;
+       int     col = mouse_col;
+ 
+       if (c == K_SPECIAL && key[1] != NUL)
+           c = TO_SPECIAL(key[1], key[2]);
+       if (wp->w_popup_drag
+               && is_mouse_key(c)
+               && (wp == popup_dragwin
+                             || wp == mouse_find_win(&row, &col, FIND_POPUP)))
+           // allow for dragging the popup
+           rettv->vval.v_number = 0;
+ 
+       // ignore this key
+       return;
+     }
+ 
+     // Invoke callback
+     res.v_type = VAR_NUMBER;
+     popup_close_and_callback(wp, &res);
+ }
+ 
+ /*
+  * popup_dialog({text}, {options})
+  */
+     void
+ f_popup_dialog(typval_T *argvars, typval_T *rettv)
+ {
+     popup_create(argvars, rettv, TYPE_DIALOG);
+ }
+ 
+ /*
+  * 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.
+  */
+     static win_T *
+ find_popup_win(int id)
+ {
+     win_T *wp = win_id2wp(id);
+ 
+     if (wp != NULL && !bt_popup(wp->w_buffer))
+     {
+       semsg(_("E993: window %d is not a popup window"), id);
+       return NULL;
+     }
+     return wp;
+ }
+ 
+ /*
   * popup_close({id})
   */
      void
***************
*** 1299,1304 ****
--- 1376,1390 ----
      typval_T  argv[3];
      char_u    buf[NUMBUFLEN];
  
+     // Emergency exit: CTRL-C closes the popup.
+     if (c == Ctrl_C)
+     {
+       rettv.v_type = VAR_NUMBER;
+       rettv.vval.v_number = -1;
+       popup_close_and_callback(wp, &rettv);
+       return 1;
+     }
+ 
      argv[0].v_type = VAR_NUMBER;
      argv[0].vval.v_number = (varnumber_T)wp->w_id;
  
***************
*** 1310,1315 ****
--- 1396,1402 ----
  
      argv[2].v_type = VAR_UNKNOWN;
  
+     // NOTE: The callback might close the popup, thus make "wp" invalid.
      call_callback(&wp->w_filter_cb, -1,
                            &rettv, 2, argv, NULL, 0L, 0L, &dummy, TRUE, NULL);
      res = tv_get_number(&rettv);
***************
*** 1326,1332 ****
  popup_do_filter(int c)
  {
      int               res = FALSE;
!     win_T   *wp;
  
      popup_reset_handled();
  
--- 1413,1419 ----
  popup_do_filter(int c)
  {
      int               res = FALSE;
!     win_T     *wp;
  
      popup_reset_handled();
  
*** ../vim-8.1.1547/src/proto/popupwin.pro      2019-06-14 20:00:45.374401154 
+0200
--- src/proto/popupwin.pro      2019-06-15 20:13:13.546643737 +0200
***************
*** 8,13 ****
--- 8,15 ----
  void f_popup_clear(typval_T *argvars, typval_T *rettv);
  void f_popup_create(typval_T *argvars, typval_T *rettv);
  void f_popup_atcursor(typval_T *argvars, typval_T *rettv);
+ void f_popup_filter_yesno(typval_T *argvars, typval_T *rettv);
+ void f_popup_dialog(typval_T *argvars, typval_T *rettv);
  void f_popup_notification(typval_T *argvars, typval_T *rettv);
  void f_popup_close(typval_T *argvars, typval_T *rettv);
  void f_popup_hide(typval_T *argvars, typval_T *rettv);
*** ../vim-8.1.1547/src/evalfunc.c      2019-06-15 19:37:11.676608528 +0200
--- src/evalfunc.c      2019-06-15 19:59:56.176792018 +0200
***************
*** 815,820 ****
--- 815,822 ----
      {"popup_clear",   0, 0, f_popup_clear},
      {"popup_close",   1, 2, f_popup_close},
      {"popup_create",  2, 2, f_popup_create},
+     {"popup_dialog",  2, 2, f_popup_dialog},
+     {"popup_filter_yesno", 2, 2, f_popup_filter_yesno},
      {"popup_getoptions", 1, 1, f_popup_getoptions},
      {"popup_getpos",  1, 1, f_popup_getpos},
      {"popup_hide",    1, 1, f_popup_hide},
*** ../vim-8.1.1547/src/structs.h       2019-06-15 17:12:01.569914997 +0200
--- src/structs.h       2019-06-15 20:16:13.761858641 +0200
***************
*** 1998,2004 ****
  
  # define POPUPWIN_DEFAULT_ZINDEX       50
  # define POPUPMENU_ZINDEX             100
! # define POPUPWIN_NOTIFICATION_ZINDEX   200
  #endif
  
  /*
--- 1998,2005 ----
  
  # define POPUPWIN_DEFAULT_ZINDEX       50
  # define POPUPMENU_ZINDEX             100
! # define POPUPWIN_DIALOG_ZINDEX               200
! # define POPUPWIN_NOTIFICATION_ZINDEX   300
  #endif
  
  /*
*** ../vim-8.1.1547/src/globals.h       2019-06-14 21:36:51.018437479 +0200
--- src/globals.h       2019-06-15 21:23:42.381987109 +0200
***************
*** 599,605 ****
  EXTERN int    aucmd_win_used INIT(= FALSE);   /* aucmd_win is being used */
  
  #ifdef FEAT_TEXT_PROP
! EXTERN win_T    *first_popupwin;      // first global popup window
  #endif
  
  /*
--- 599,606 ----
  EXTERN int    aucmd_win_used INIT(= FALSE);   /* aucmd_win is being used */
  
  #ifdef FEAT_TEXT_PROP
! EXTERN win_T    *first_popupwin;              // first global popup window
! EXTERN win_T  *popup_dragwin INIT(= NULL);    // popup window being dragged
  #endif
  
  /*
*** ../vim-8.1.1547/src/testdir/test_popupwin.vim       2019-06-15 
17:57:43.972724036 +0200
--- src/testdir/test_popupwin.vim       2019-06-15 21:42:29.825319235 +0200
***************
*** 870,875 ****
--- 870,905 ----
    call popup_clear()
  endfunc
  
+ func ShowDialog(key, result)
+   let s:cb_res = 999
+   let winid = popup_dialog('do you want to quit (Yes/no)?', {
+         \ 'filter': 'popup_filter_yesno',
+         \ 'callback': 'QuitCallback',
+         \ })
+   redraw
+   call feedkeys(a:key, "xt")
+   call assert_equal(winid, s:cb_winid)
+   call assert_equal(a:result, s:cb_res)
+ endfunc
+ 
+ func Test_popup_dialog()
+   func QuitCallback(id, res)
+     let s:cb_winid = a:id
+     let s:cb_res = a:res
+   endfunc
+ 
+   let winid = ShowDialog("y", 1)
+   let winid = ShowDialog("Y", 1)
+   let winid = ShowDialog("n", 0)
+   let winid = ShowDialog("N", 0)
+   let winid = ShowDialog("x", 0)
+   let winid = ShowDialog("X", 0)
+   let winid = ShowDialog("\<Esc>", 0)
+   let winid = ShowDialog("\<C-C>", -1)
+ 
+   delfunc QuitCallback
+ endfunc
+ 
  func Test_popup_close_callback()
    func PopupDone(id, result)
      let g:result = a:result
*** ../vim-8.1.1547/runtime/doc/popup.txt       2019-06-15 14:31:33.774185476 
+0200
--- runtime/doc/popup.txt       2019-06-15 21:37:35.846448429 +0200
***************
*** 103,112 ****
  - When drawing on top half a double-wide character, display ">" or "<" in the
    incomplete cell.
  - Can the buffer be re-used, to avoid using up lots of buffer numbers?
  - Implement:
-       popup_dialog({text}, {options})
        popup_filter_menu({id}, {key})
-       popup_filter_yesno({id}, {key})
        popup_menu({text}, {options})
        popup_setoptions({id}, {options})
        flip option
--- 103,112 ----
  - When drawing on top half a double-wide character, display ">" or "<" in the
    incomplete cell.
  - Can the buffer be re-used, to avoid using up lots of buffer numbers?
+ - Use a popup window for the "info" item of completion instead of using a
+   preview window.
  - Implement:
        popup_filter_menu({id}, {key})
        popup_menu({text}, {options})
        popup_setoptions({id}, {options})
        flip option
***************
*** 196,211 ****
  
  
  popup_dialog({text}, {options})                               *popup_dialog()*
-               {not implemented yet}
                Just like |popup_create()| but with these default options: >
                        call popup_create({text}, {
                                \ 'pos': 'center',
                                \ 'zindex': 200,
                                \ 'border': [],
                                \ 'padding': [],
                                \})
  <             Use {options} to change the properties. E.g. add a 'filter'
!               option with value 'popup_filter_yesno'.
  
  
  popup_filter_menu({id}, {key})                                
*popup_filter_menu()*
--- 196,218 ----
  
  
  popup_dialog({text}, {options})                               *popup_dialog()*
                Just like |popup_create()| but with these default options: >
                        call popup_create({text}, {
                                \ 'pos': 'center',
                                \ 'zindex': 200,
+                               \ 'drag': 1,
                                \ 'border': [],
                                \ 'padding': [],
                                \})
  <             Use {options} to change the properties. E.g. add a 'filter'
!               option with value 'popup_filter_yesno'.  Example: >
!                       call popup_create('do you want to quit (Yes/no)?', {
!                               \ 'filter': 'popup_filter_yesno',
!                               \ 'callback': 'QuitCallback',
!                               \ })
! 
! <             By default the dialog can be dragged, so that text below it
!               can be read if needed.
  
  
  popup_filter_menu({id}, {key})                                
*popup_filter_menu()*
***************
*** 218,229 ****
  
  
  popup_filter_yesno({id}, {key})                               
*popup_filter_yesno()*
-               {not implemented yet}
                Filter that can be used for a popup. It handles only the keys
                'y', 'Y' and 'n' or 'N'.  Invokes the "callback" of the
                popup menu with the 1 for 'y' or 'Y' and zero for 'n' or 'N'
!               as the second argument.  Pressing Esc and CTRL-C works like
!               pressing 'n'.  Other keys are ignored.
  
  
  popup_getoptions({id})                                        
*popup_getoptions()*
--- 225,236 ----
  
  
  popup_filter_yesno({id}, {key})                               
*popup_filter_yesno()*
                Filter that can be used for a popup. It handles only the keys
                'y', 'Y' and 'n' or 'N'.  Invokes the "callback" of the
                popup menu with the 1 for 'y' or 'Y' and zero for 'n' or 'N'
!               as the second argument.  Pressing Esc and 'x' works like
!               pressing 'n'.  CTRL-C invokes the callback with -1.  Other
!               keys are ignored.
  
  
  popup_getoptions({id})                                        
*popup_getoptions()*
***************
*** 301,307 ****
                                \ 'minwidth': 20,
                                \ 'time': 3000,
                                \ 'tabpage': -1,
!                               \ 'zindex': 200,
                                \ 'drag': 1,
                                \ 'highlight': 'WarningMsg',
                                \ 'border': [],
--- 308,314 ----
                                \ 'minwidth': 20,
                                \ 'time': 3000,
                                \ 'tabpage': -1,
!                               \ 'zindex': 300,
                                \ 'drag': 1,
                                \ 'highlight': 'WarningMsg',
                                \ 'border': [],
***************
*** 521,527 ****
  is called first.
  
  The filter function is called with two arguments: the ID of the popup and the
! key, e.g.: >
        func MyFilter(winid, key)
          if a:key == "\<F2>"
            " do something
--- 528,534 ----
  is called first.
  
  The filter function is called with two arguments: the ID of the popup and the
! key as a string, e.g.: >
        func MyFilter(winid, key)
          if a:key == "\<F2>"
            " do something
***************
*** 556,570 ****
  
  POPUP CALLBACK                                                *popup-callback*
  
! A callback that is invoked when the popup closes.  Used by
! |popup_filter_menu()|.
  
  The callback is invoked with two arguments: the ID of the popup window and the
  result, which could be an index in the popup lines, or whatever was passed as
  the second argument of `popup_close()`.
  
! If the popup is closed because the cursor moved, the number -1 is passed to
! the callback.
  
  ==============================================================================
  3. Examples                                           *popup-examples*
--- 563,576 ----
  
  POPUP CALLBACK                                                *popup-callback*
  
! A callback that is invoked when the popup closes.
  
  The callback is invoked with two arguments: the ID of the popup window and the
  result, which could be an index in the popup lines, or whatever was passed as
  the second argument of `popup_close()`.
  
! If the popup is force-closed, e.g. because the cursor moved or CTRL-C was
! pressed, the number -1 is passed to the callback.
  
  ==============================================================================
  3. Examples                                           *popup-examples*
*** ../vim-8.1.1547/src/version.c       2019-06-15 19:37:11.680608505 +0200
--- src/version.c       2019-06-15 20:32:52.776940398 +0200
***************
*** 779,780 ****
--- 779,782 ----
  {   /* Add new patch number below this line */
+ /**/
+     1548,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
195. Your cat has its own home page.

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/201906151946.x5FJkl9t005402%40masaka.moolenaar.net.
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui