comparison src/popupwin.c @ 17123:efc6f5e3b543 v8.1.1561

patch 8.1.1561: popup_setoptions() is not implemented yet commit https://github.com/vim/vim/commit/ae943150d3a2868a89df802c9f530331474451ec Author: Bram Moolenaar <Bram@vim.org> Date: Sun Jun 16 22:54:14 2019 +0200 patch 8.1.1561: popup_setoptions() is not implemented yet Problem: Popup_setoptions() is not implemented yet. Solution: Implement popup_setoptions(). Also add more fields to popup_getoptions().
author Bram Moolenaar <Bram@vim.org>
date Sun, 16 Jun 2019 23:00:05 +0200
parents 808ea76535a9
children b4eb06233448
comparison
equal deleted inserted replaced
17122:310e8655d123 17123:efc6f5e3b543
104 semsg(_(e_invarg2), str); 104 semsg(_(e_invarg2), str);
105 } 105 }
106 } 106 }
107 107
108 static void 108 static void
109 get_padding_border(dict_T *dict, int *array, char *name, int max_val) 109 set_padding_border(dict_T *dict, int *array, char *name, int max_val)
110 { 110 {
111 dictitem_T *di; 111 dictitem_T *di;
112 112
113 di = dict_find(dict, (char_u *)name, -1); 113 di = dict_find(dict, (char_u *)name, -1);
114 if (di != NULL) 114 if (di != NULL)
249 } 249 }
250 } 250 }
251 #endif 251 #endif
252 252
253 /* 253 /*
254 * Go through the options in "dict" and apply them to buffer "buf" displayed in 254 * Shared between popup_create() and f_popup_move().
255 * popup window "wp".
256 */ 255 */
257 static void 256 static void
258 apply_options(win_T *wp, buf_T *buf UNUSED, dict_T *dict) 257 apply_move_options(win_T *wp, dict_T *d)
259 { 258 {
259 int nr;
260
261 if ((nr = dict_get_number(d, (char_u *)"minwidth")) > 0)
262 wp->w_minwidth = nr;
263 if ((nr = dict_get_number(d, (char_u *)"minheight")) > 0)
264 wp->w_minheight = nr;
265 if ((nr = dict_get_number(d, (char_u *)"maxwidth")) > 0)
266 wp->w_maxwidth = nr;
267 if ((nr = dict_get_number(d, (char_u *)"maxheight")) > 0)
268 wp->w_maxheight = nr;
269 get_pos_options(wp, d);
270 }
271
272 /*
273 * Shared between popup_create() and f_popup_setoptions().
274 */
275 static void
276 apply_general_options(win_T *wp, dict_T *dict)
277 {
278 dictitem_T *di;
260 int nr; 279 int nr;
261 char_u *str; 280 char_u *str;
262 dictitem_T *di; 281
263 int i; 282 // TODO: flip
264 283
265 di = dict_find(dict, (char_u *)"minwidth", -1); 284 di = dict_find(dict, (char_u *)"firstline", -1);
266 if (di != NULL) 285 if (di != NULL)
267 wp->w_minwidth = dict_get_number(dict, (char_u *)"minwidth"); 286 wp->w_firstline = dict_get_number(dict, (char_u *)"firstline");
268 wp->w_minheight = dict_get_number(dict, (char_u *)"minheight"); 287 if (wp->w_firstline < 1)
269 wp->w_maxwidth = dict_get_number(dict, (char_u *)"maxwidth"); 288 wp->w_firstline = 1;
270 wp->w_maxheight = dict_get_number(dict, (char_u *)"maxheight"); 289
271 290 str = dict_get_string(dict, (char_u *)"title", FALSE);
272 get_pos_options(wp, dict); 291 if (str != NULL)
273 292 {
274 di = dict_find(dict, (char_u *)"zindex", -1); 293 vim_free(wp->w_popup_title);
294 wp->w_popup_title = vim_strsave(str);
295 }
296
297 di = dict_find(dict, (char_u *)"wrap", -1);
275 if (di != NULL) 298 if (di != NULL)
276 { 299 {
277 wp->w_zindex = dict_get_number(dict, (char_u *)"zindex"); 300 nr = dict_get_number(dict, (char_u *)"wrap");
278 if (wp->w_zindex < 1) 301 wp->w_p_wrap = nr != 0;
279 wp->w_zindex = POPUPWIN_DEFAULT_ZINDEX; 302 }
280 if (wp->w_zindex > 32000) 303
281 wp->w_zindex = 32000; 304 di = dict_find(dict, (char_u *)"drag", -1);
282 } 305 if (di != NULL)
283 306 wp->w_popup_drag = dict_get_number(dict, (char_u *)"drag");
284 #if defined(FEAT_TIMERS) 307
285 // Add timer to close the popup after some time.
286 nr = dict_get_number(dict, (char_u *)"time");
287 if (nr > 0)
288 popup_add_timeout(wp, nr);
289 #endif
290
291 // Option values resulting in setting an option.
292 str = dict_get_string(dict, (char_u *)"highlight", FALSE); 308 str = dict_get_string(dict, (char_u *)"highlight", FALSE);
293 if (str != NULL) 309 if (str != NULL)
294 set_string_option_direct_in_win(wp, (char_u *)"wincolor", -1, 310 set_string_option_direct_in_win(wp, (char_u *)"wincolor", -1,
295 str, OPT_FREE|OPT_LOCAL, 0); 311 str, OPT_FREE|OPT_LOCAL, 0);
296 312
297 str = dict_get_string(dict, (char_u *)"title", FALSE); 313 set_padding_border(dict, wp->w_popup_padding, "padding", 999);
298 if (str != NULL) 314 set_padding_border(dict, wp->w_popup_border, "border", 1);
299 { 315
300 vim_free(wp->w_popup_title);
301 wp->w_popup_title = vim_strsave(str);
302 }
303
304 wp->w_firstline = dict_get_number(dict, (char_u *)"firstline");
305 if (wp->w_firstline < 1)
306 wp->w_firstline = 1;
307
308 di = dict_find(dict, (char_u *)"wrap", -1);
309 if (di != NULL)
310 {
311 nr = dict_get_number(dict, (char_u *)"wrap");
312 wp->w_p_wrap = nr != 0;
313 }
314
315 di = dict_find(dict, (char_u *)"drag", -1);
316 if (di != NULL)
317 wp->w_popup_drag = dict_get_number(dict, (char_u *)"drag");
318
319 di = dict_find(dict, (char_u *)"callback", -1);
320 if (di != NULL)
321 {
322 callback_T callback = get_callback(&di->di_tv);
323
324 if (callback.cb_name != NULL)
325 set_callback(&wp->w_close_cb, &callback);
326 }
327
328 di = dict_find(dict, (char_u *)"filter", -1);
329 if (di != NULL)
330 {
331 callback_T callback = get_callback(&di->di_tv);
332
333 if (callback.cb_name != NULL)
334 set_callback(&wp->w_filter_cb, &callback);
335 }
336
337 get_padding_border(dict, wp->w_popup_padding, "padding", 999);
338 get_padding_border(dict, wp->w_popup_border, "border", 1);
339
340 for (i = 0; i < 4; ++i)
341 VIM_CLEAR(wp->w_border_highlight[i]);
342 di = dict_find(dict, (char_u *)"borderhighlight", -1); 316 di = dict_find(dict, (char_u *)"borderhighlight", -1);
343 if (di != NULL) 317 if (di != NULL)
344 { 318 {
345 if (di->di_tv.v_type != VAR_LIST) 319 if (di->di_tv.v_type != VAR_LIST)
346 emsg(_(e_listreq)); 320 emsg(_(e_listreq));
347 else 321 else
348 { 322 {
349 list_T *list = di->di_tv.vval.v_list; 323 list_T *list = di->di_tv.vval.v_list;
350 listitem_T *li; 324 listitem_T *li;
325 int i;
351 326
352 if (list != NULL) 327 if (list != NULL)
353 for (i = 0, li = list->lv_first; i < 4 && i < list->lv_len; 328 for (i = 0, li = list->lv_first; i < 4 && i < list->lv_len;
354 ++i, li = li->li_next) 329 ++i, li = li->li_next)
355 { 330 {
362 wp->w_border_highlight[i] = 337 wp->w_border_highlight[i] =
363 vim_strsave(wp->w_border_highlight[0]); 338 vim_strsave(wp->w_border_highlight[0]);
364 } 339 }
365 } 340 }
366 341
367 for (i = 0; i < 8; ++i)
368 wp->w_border_char[i] = 0;
369 di = dict_find(dict, (char_u *)"borderchars", -1); 342 di = dict_find(dict, (char_u *)"borderchars", -1);
370 if (di != NULL) 343 if (di != NULL)
371 { 344 {
372 if (di->di_tv.v_type != VAR_LIST) 345 if (di->di_tv.v_type != VAR_LIST)
373 emsg(_(e_listreq)); 346 emsg(_(e_listreq));
374 else 347 else
375 { 348 {
376 list_T *list = di->di_tv.vval.v_list; 349 list_T *list = di->di_tv.vval.v_list;
377 listitem_T *li; 350 listitem_T *li;
351 int i;
378 352
379 if (list != NULL) 353 if (list != NULL)
380 for (i = 0, li = list->lv_first; i < 8 && i < list->lv_len; 354 for (i = 0, li = list->lv_first; i < 8 && i < list->lv_len;
381 ++i, li = li->li_next) 355 ++i, li = li->li_next)
382 { 356 {
395 wp->w_border_char[i] = wp->w_border_char[0]; 369 wp->w_border_char[i] = wp->w_border_char[0];
396 } 370 }
397 } 371 }
398 } 372 }
399 373
374 di = dict_find(dict, (char_u *)"zindex", -1);
375 if (di != NULL)
376 {
377 wp->w_zindex = dict_get_number(dict, (char_u *)"zindex");
378 if (wp->w_zindex < 1)
379 wp->w_zindex = POPUPWIN_DEFAULT_ZINDEX;
380 if (wp->w_zindex > 32000)
381 wp->w_zindex = 32000;
382 }
383
384 #if defined(FEAT_TIMERS)
385 // Add timer to close the popup after some time.
386 nr = dict_get_number(dict, (char_u *)"time");
387 if (nr > 0)
388 popup_add_timeout(wp, nr);
389 #endif
390
400 di = dict_find(dict, (char_u *)"moved", -1); 391 di = dict_find(dict, (char_u *)"moved", -1);
401 if (di != NULL) 392 if (di != NULL)
402 { 393 {
403 set_moved_values(wp); 394 set_moved_values(wp);
404 if (di->di_tv.v_type == VAR_STRING && di->di_tv.vval.v_string != NULL) 395 if (di->di_tv.v_type == VAR_STRING && di->di_tv.vval.v_string != NULL)
425 wp->w_popup_maxcol = tv_get_number(&l->lv_first->li_next->li_tv); 416 wp->w_popup_maxcol = tv_get_number(&l->lv_first->li_next->li_tv);
426 } 417 }
427 else 418 else
428 semsg(_(e_invarg2), tv_get_string(&di->di_tv)); 419 semsg(_(e_invarg2), tv_get_string(&di->di_tv));
429 } 420 }
421
422 di = dict_find(dict, (char_u *)"filter", -1);
423 if (di != NULL)
424 {
425 callback_T callback = get_callback(&di->di_tv);
426
427 if (callback.cb_name != NULL)
428 {
429 free_callback(&wp->w_filter_cb);
430 set_callback(&wp->w_filter_cb, &callback);
431 }
432 }
433
434 di = dict_find(dict, (char_u *)"callback", -1);
435 if (di != NULL)
436 {
437 callback_T callback = get_callback(&di->di_tv);
438
439 if (callback.cb_name != NULL)
440 {
441 free_callback(&wp->w_close_cb);
442 set_callback(&wp->w_close_cb, &callback);
443 }
444 }
445 }
446
447 /*
448 * Go through the options in "dict" and apply them to popup window "wp".
449 */
450 static void
451 apply_options(win_T *wp, dict_T *dict)
452 {
453 int nr;
454
455 apply_move_options(wp, dict);
456 apply_general_options(wp, dict);
430 457
431 nr = dict_get_number(dict, (char_u *)"hidden"); 458 nr = dict_get_number(dict, (char_u *)"hidden");
432 if (nr > 0) 459 if (nr > 0)
433 { 460 {
434 wp->w_popup_flags |= POPF_HIDDEN; 461 wp->w_popup_flags |= POPF_HIDDEN;
802 { 829 {
803 win_T *wp; 830 win_T *wp;
804 buf_T *buf; 831 buf_T *buf;
805 dict_T *d; 832 dict_T *d;
806 int nr; 833 int nr;
834 int i;
807 835
808 // Check arguments look OK. 836 // Check arguments look OK.
809 if (!(argvars[0].v_type == VAR_STRING && argvars[0].vval.v_string != NULL) 837 if (!(argvars[0].v_type == VAR_STRING && argvars[0].vval.v_string != NULL)
810 && !(argvars[0].v_type == VAR_LIST && argvars[0].vval.v_list != NULL)) 838 && !(argvars[0].v_type == VAR_LIST && argvars[0].vval.v_list != NULL))
811 { 839 {
901 929
902 if (type == TYPE_NOTIFICATION) 930 if (type == TYPE_NOTIFICATION)
903 { 931 {
904 win_T *twp, *nextwin; 932 win_T *twp, *nextwin;
905 int height = buf->b_ml.ml_line_count + 3; 933 int height = buf->b_ml.ml_line_count + 3;
906 int i;
907 934
908 // Try to not overlap with another global popup. Guess we need 3 935 // Try to not overlap with another global popup. Guess we need 3
909 // more screen lines than buffer lines. 936 // more screen lines than buffer lines.
910 wp->w_wantline = 1; 937 wp->w_wantline = 1;
911 for (twp = first_popupwin; twp != NULL; twp = nextwin) 938 for (twp = first_popupwin; twp != NULL; twp = nextwin)
944 OPT_FREE|OPT_LOCAL, 0); 971 OPT_FREE|OPT_LOCAL, 0);
945 } 972 }
946 973
947 if (type == TYPE_DIALOG || type == TYPE_MENU) 974 if (type == TYPE_DIALOG || type == TYPE_MENU)
948 { 975 {
949 int i;
950
951 wp->w_popup_pos = POPPOS_CENTER; 976 wp->w_popup_pos = POPPOS_CENTER;
952 wp->w_zindex = POPUPWIN_DIALOG_ZINDEX; 977 wp->w_zindex = POPUPWIN_DIALOG_ZINDEX;
953 wp->w_popup_drag = 1; 978 wp->w_popup_drag = 1;
954 for (i = 0; i < 4; ++i) 979 for (i = 0; i < 4; ++i)
955 { 980 {
970 set_callback(&wp->w_filter_cb, &callback); 995 set_callback(&wp->w_filter_cb, &callback);
971 996
972 wp->w_p_wrap = 0; 997 wp->w_p_wrap = 0;
973 } 998 }
974 999
1000 for (i = 0; i < 4; ++i)
1001 VIM_CLEAR(wp->w_border_highlight[i]);
1002 for (i = 0; i < 8; ++i)
1003 wp->w_border_char[i] = 0;
1004
975 // Deal with options. 1005 // Deal with options.
976 apply_options(wp, buf, argvars[1].vval.v_dict); 1006 apply_options(wp, argvars[1].vval.v_dict);
977 1007
978 if (type == TYPE_NOTIFICATION && wp->w_popup_timer == NULL) 1008 if (type == TYPE_NOTIFICATION && wp->w_popup_timer == NULL)
979 popup_add_timeout(wp, 3000); 1009 popup_add_timeout(wp, 3000);
980 1010
981 popup_adjust_position(wp); 1011 popup_adjust_position(wp);
1373 * popup_move({id}, {options}) 1403 * popup_move({id}, {options})
1374 */ 1404 */
1375 void 1405 void
1376 f_popup_move(typval_T *argvars, typval_T *rettv UNUSED) 1406 f_popup_move(typval_T *argvars, typval_T *rettv UNUSED)
1377 { 1407 {
1378 dict_T *d; 1408 dict_T *dict;
1379 int nr;
1380 int id = (int)tv_get_number(argvars); 1409 int id = (int)tv_get_number(argvars);
1381 win_T *wp = find_popup_win(id); 1410 win_T *wp = find_popup_win(id);
1382 1411
1383 if (wp == NULL) 1412 if (wp == NULL)
1384 return; // invalid {id} 1413 return; // invalid {id}
1386 if (argvars[1].v_type != VAR_DICT || argvars[1].vval.v_dict == NULL) 1415 if (argvars[1].v_type != VAR_DICT || argvars[1].vval.v_dict == NULL)
1387 { 1416 {
1388 emsg(_(e_dictreq)); 1417 emsg(_(e_dictreq));
1389 return; 1418 return;
1390 } 1419 }
1391 d = argvars[1].vval.v_dict; 1420 dict = argvars[1].vval.v_dict;
1392 1421
1393 if ((nr = dict_get_number(d, (char_u *)"minwidth")) > 0) 1422 apply_move_options(wp, dict);
1394 wp->w_minwidth = nr;
1395 if ((nr = dict_get_number(d, (char_u *)"minheight")) > 0)
1396 wp->w_minheight = nr;
1397 if ((nr = dict_get_number(d, (char_u *)"maxwidth")) > 0)
1398 wp->w_maxwidth = nr;
1399 if ((nr = dict_get_number(d, (char_u *)"maxheight")) > 0)
1400 wp->w_maxheight = nr;
1401 get_pos_options(wp, d);
1402 1423
1403 if (wp->w_winrow + wp->w_height >= cmdline_row) 1424 if (wp->w_winrow + wp->w_height >= cmdline_row)
1404 clear_cmdline = TRUE; 1425 clear_cmdline = TRUE;
1426 popup_adjust_position(wp);
1427 }
1428
1429 /*
1430 * popup_setoptions({id}, {options})
1431 */
1432 void
1433 f_popup_setoptions(typval_T *argvars, typval_T *rettv UNUSED)
1434 {
1435 dict_T *dict;
1436 int id = (int)tv_get_number(argvars);
1437 win_T *wp = find_popup_win(id);
1438
1439 if (wp == NULL)
1440 return; // invalid {id}
1441
1442 if (argvars[1].v_type != VAR_DICT || argvars[1].vval.v_dict == NULL)
1443 {
1444 emsg(_(e_dictreq));
1445 return;
1446 }
1447 dict = argvars[1].vval.v_dict;
1448
1449 apply_move_options(wp, dict);
1450 apply_general_options(wp, dict);
1451
1405 popup_adjust_position(wp); 1452 popup_adjust_position(wp);
1406 } 1453 }
1407 1454
1408 /* 1455 /*
1409 * popup_getpos({id}) 1456 * popup_getpos({id})
1438 dict_add_number(dict, "core_width", wp->w_width); 1485 dict_add_number(dict, "core_width", wp->w_width);
1439 dict_add_number(dict, "core_height", wp->w_height); 1486 dict_add_number(dict, "core_height", wp->w_height);
1440 1487
1441 dict_add_number(dict, "visible", 1488 dict_add_number(dict, "visible",
1442 win_valid(wp) && (wp->w_popup_flags & POPF_HIDDEN) == 0); 1489 win_valid(wp) && (wp->w_popup_flags & POPF_HIDDEN) == 0);
1490 }
1491 }
1492
1493 /*
1494 * For popup_getoptions(): add a "border" or "padding" entry to "dict".
1495 */
1496 static void
1497 get_padding_border(dict_T *dict, int *array, char *name)
1498 {
1499 list_T *list;
1500 int i;
1501
1502 if (array[0] == 0 && array[1] == 0 && array[2] == 0 && array[3] == 0)
1503 return;
1504
1505 list = list_alloc();
1506 if (list != NULL)
1507 {
1508 dict_add_list(dict, name, list);
1509 if (array[0] != 1 || array[1] != 1 || array[2] != 1 || array[3] != 1)
1510 for (i = 0; i < 4; ++i)
1511 list_append_number(list, array[i]);
1512 }
1513 }
1514
1515 /*
1516 * For popup_getoptions(): add a "borderhighlight" entry to "dict".
1517 */
1518 static void
1519 get_borderhighlight(dict_T *dict, win_T *wp)
1520 {
1521 list_T *list;
1522 int i;
1523
1524 for (i = 0; i < 4; ++i)
1525 if (wp->w_border_highlight[i] != NULL)
1526 break;
1527 if (i == 4)
1528 return;
1529
1530 list = list_alloc();
1531 if (list != NULL)
1532 {
1533 dict_add_list(dict, "borderhighlight", list);
1534 for (i = 0; i < 4; ++i)
1535 list_append_string(list, wp->w_border_highlight[i], -1);
1536 }
1537 }
1538
1539 /*
1540 * For popup_getoptions(): add a "borderchars" entry to "dict".
1541 */
1542 static void
1543 get_borderchars(dict_T *dict, win_T *wp)
1544 {
1545 list_T *list;
1546 int i;
1547 char_u buf[NUMBUFLEN];
1548 int len;
1549
1550 for (i = 0; i < 8; ++i)
1551 if (wp->w_border_char[i] != 0)
1552 break;
1553 if (i == 8)
1554 return;
1555
1556 list = list_alloc();
1557 if (list != NULL)
1558 {
1559 dict_add_list(dict, "borderchars", list);
1560 for (i = 0; i < 8; ++i)
1561 {
1562 len = mb_char2bytes(wp->w_border_char[i], buf);
1563 list_append_string(list, buf, len);
1564 }
1565 }
1566 }
1567
1568 /*
1569 * For popup_getoptions(): add a "moved" entry to "dict".
1570 */
1571 static void
1572 get_moved_list(dict_T *dict, win_T *wp)
1573 {
1574 list_T *list;
1575
1576 list = list_alloc();
1577 if (list != NULL)
1578 {
1579 dict_add_list(dict, "moved", list);
1580 list_append_number(list, wp->w_popup_mincol);
1581 list_append_number(list, wp->w_popup_maxcol);
1443 } 1582 }
1444 } 1583 }
1445 1584
1446 /* 1585 /*
1447 * popup_getoptions({id}) 1586 * popup_getoptions({id})
1467 dict_add_number(dict, "maxheight", wp->w_maxheight); 1606 dict_add_number(dict, "maxheight", wp->w_maxheight);
1468 dict_add_number(dict, "maxwidth", wp->w_maxwidth); 1607 dict_add_number(dict, "maxwidth", wp->w_maxwidth);
1469 dict_add_number(dict, "firstline", wp->w_firstline); 1608 dict_add_number(dict, "firstline", wp->w_firstline);
1470 dict_add_number(dict, "zindex", wp->w_zindex); 1609 dict_add_number(dict, "zindex", wp->w_zindex);
1471 dict_add_number(dict, "fixed", wp->w_popup_fixed); 1610 dict_add_number(dict, "fixed", wp->w_popup_fixed);
1611 dict_add_string(dict, "title", wp->w_popup_title);
1612 dict_add_number(dict, "wrap", wp->w_p_wrap);
1613 dict_add_number(dict, "drag", wp->w_popup_drag);
1614 dict_add_string(dict, "highlight", wp->w_p_wcr);
1615
1616 get_padding_border(dict, wp->w_popup_padding, "padding");
1617 get_padding_border(dict, wp->w_popup_border, "border");
1618 get_borderhighlight(dict, wp);
1619 get_borderchars(dict, wp);
1620 get_moved_list(dict, wp);
1621
1622 if (wp->w_filter_cb.cb_name != NULL)
1623 dict_add_callback(dict, "filter", &wp->w_filter_cb);
1624 if (wp->w_close_cb.cb_name != NULL)
1625 dict_add_callback(dict, "callback", &wp->w_close_cb);
1472 1626
1473 for (i = 0; i < (int)(sizeof(poppos_entries) / sizeof(poppos_entry_T)); 1627 for (i = 0; i < (int)(sizeof(poppos_entries) / sizeof(poppos_entry_T));
1474 ++i) 1628 ++i)
1475 if (wp->w_popup_pos == poppos_entries[i].pp_val) 1629 if (wp->w_popup_pos == poppos_entries[i].pp_val)
1476 { 1630 {