comparison src/evalfunc.c @ 15209:3a99b2e6d136 v8.1.0614

patch 8.1.0614: placing signs can be complicated commit https://github.com/vim/vim/commit/162b71479bd4dcdb3a2ef9198a1444f6f99e6843 Author: Bram Moolenaar <Bram@vim.org> Date: Fri Dec 21 15:17:36 2018 +0100 patch 8.1.0614: placing signs can be complicated Problem: Placing signs can be complicated. Solution: Add functions for defining and placing signs. Introduce a group name to avoid different plugins using the same signs. (Yegappan Lakshmanan, closes #3652)
author Bram Moolenaar <Bram@vim.org>
date Fri, 21 Dec 2018 15:30:07 +0100
parents 7903dce131d4
children de63593896b3
comparison
equal deleted inserted replaced
15208:acf68008ca43 15209:3a99b2e6d136
365 #ifdef FEAT_CRYPT 365 #ifdef FEAT_CRYPT
366 static void f_sha256(typval_T *argvars, typval_T *rettv); 366 static void f_sha256(typval_T *argvars, typval_T *rettv);
367 #endif /* FEAT_CRYPT */ 367 #endif /* FEAT_CRYPT */
368 static void f_shellescape(typval_T *argvars, typval_T *rettv); 368 static void f_shellescape(typval_T *argvars, typval_T *rettv);
369 static void f_shiftwidth(typval_T *argvars, typval_T *rettv); 369 static void f_shiftwidth(typval_T *argvars, typval_T *rettv);
370 #ifdef FEAT_SIGNS
371 static void f_sign_define(typval_T *argvars, typval_T *rettv);
372 static void f_sign_getdefined(typval_T *argvars, typval_T *rettv);
373 static void f_sign_getplaced(typval_T *argvars, typval_T *rettv);
374 static void f_sign_place(typval_T *argvars, typval_T *rettv);
375 static void f_sign_undefine(typval_T *argvars, typval_T *rettv);
376 static void f_sign_unplace(typval_T *argvars, typval_T *rettv);
377 #endif
370 static void f_simplify(typval_T *argvars, typval_T *rettv); 378 static void f_simplify(typval_T *argvars, typval_T *rettv);
371 #ifdef FEAT_FLOAT 379 #ifdef FEAT_FLOAT
372 static void f_sin(typval_T *argvars, typval_T *rettv); 380 static void f_sin(typval_T *argvars, typval_T *rettv);
373 static void f_sinh(typval_T *argvars, typval_T *rettv); 381 static void f_sinh(typval_T *argvars, typval_T *rettv);
374 #endif 382 #endif
845 #ifdef FEAT_CRYPT 853 #ifdef FEAT_CRYPT
846 {"sha256", 1, 1, f_sha256}, 854 {"sha256", 1, 1, f_sha256},
847 #endif 855 #endif
848 {"shellescape", 1, 2, f_shellescape}, 856 {"shellescape", 1, 2, f_shellescape},
849 {"shiftwidth", 0, 1, f_shiftwidth}, 857 {"shiftwidth", 0, 1, f_shiftwidth},
858 #ifdef FEAT_SIGNS
859 {"sign_define", 1, 2, f_sign_define},
860 {"sign_getdefined", 0, 1, f_sign_getdefined},
861 {"sign_getplaced", 0, 2, f_sign_getplaced},
862 {"sign_place", 4, 5, f_sign_place},
863 {"sign_undefine", 0, 1, f_sign_undefine},
864 {"sign_unplace", 1, 2, f_sign_unplace},
865 #endif
850 {"simplify", 1, 1, f_simplify}, 866 {"simplify", 1, 1, f_simplify},
851 #ifdef FEAT_FLOAT 867 #ifdef FEAT_FLOAT
852 {"sin", 1, 1, f_sin}, 868 {"sin", 1, 1, f_sin},
853 {"sinh", 1, 1, f_sinh}, 869 {"sinh", 1, 1, f_sinh},
854 #endif 870 #endif
4415 */ 4431 */
4416 static void 4432 static void
4417 get_buffer_signs(buf_T *buf, list_T *l) 4433 get_buffer_signs(buf_T *buf, list_T *l)
4418 { 4434 {
4419 signlist_T *sign; 4435 signlist_T *sign;
4420 4436 dict_T *d;
4421 for (sign = buf->b_signlist; sign; sign = sign->next) 4437
4422 { 4438 FOR_ALL_SIGNS_IN_BUF(buf)
4423 dict_T *d = dict_alloc(); 4439 {
4424 4440 if ((d = sign_get_info(sign)) != NULL)
4425 if (d != NULL)
4426 {
4427 dict_add_number(d, "id", sign->id);
4428 dict_add_number(d, "lnum", sign->lnum);
4429 dict_add_string(d, "name", sign_typenr2name(sign->typenr));
4430
4431 list_append_dict(l, d); 4441 list_append_dict(l, d);
4432 }
4433 } 4442 }
4434 } 4443 }
4435 #endif 4444 #endif
4436 4445
4437 /* 4446 /*
11283 } 11292 }
11284 11293
11285 rettv->vval.v_number = get_sw_value(curbuf); 11294 rettv->vval.v_number = get_sw_value(curbuf);
11286 } 11295 }
11287 11296
11297 #ifdef FEAT_SIGNS
11298 /*
11299 * "sign_define()" function
11300 */
11301 static void
11302 f_sign_define(typval_T *argvars, typval_T *rettv)
11303 {
11304 char_u *name;
11305 dict_T *dict;
11306 char_u *icon = NULL;
11307 char_u *linehl = NULL;
11308 char_u *text = NULL;
11309 char_u *texthl = NULL;
11310
11311 rettv->vval.v_number = -1;
11312
11313 name = get_tv_string_chk(&argvars[0]);
11314 if (name == NULL)
11315 return;
11316
11317 if (argvars[1].v_type != VAR_UNKNOWN)
11318 {
11319 if (argvars[1].v_type != VAR_DICT)
11320 {
11321 EMSG(_(e_dictreq));
11322 return;
11323 }
11324
11325 // sign attributes
11326 dict = argvars[1].vval.v_dict;
11327 if (dict_find(dict, (char_u *)"icon", -1) != NULL)
11328 icon = dict_get_string(dict, (char_u *)"icon", TRUE);
11329 if (dict_find(dict, (char_u *)"linehl", -1) != NULL)
11330 linehl = dict_get_string(dict, (char_u *)"linehl", TRUE);
11331 if (dict_find(dict, (char_u *)"text", -1) != NULL)
11332 text = dict_get_string(dict, (char_u *)"text", TRUE);
11333 if (dict_find(dict, (char_u *)"texthl", -1) != NULL)
11334 texthl = dict_get_string(dict, (char_u *)"texthl", TRUE);
11335 }
11336
11337 if (sign_define_by_name(name, icon, linehl, text, texthl) == OK)
11338 rettv->vval.v_number = 0;
11339
11340 vim_free(icon);
11341 vim_free(linehl);
11342 vim_free(text);
11343 vim_free(texthl);
11344 }
11345
11346 /*
11347 * "sign_getdefined()" function
11348 */
11349 static void
11350 f_sign_getdefined(typval_T *argvars, typval_T *rettv)
11351 {
11352 char_u *name = NULL;
11353
11354 if (rettv_list_alloc_id(rettv, aid_sign_getdefined) != OK)
11355 return;
11356
11357 if (argvars[0].v_type != VAR_UNKNOWN)
11358 name = get_tv_string(&argvars[0]);
11359
11360 sign_getlist(name, rettv->vval.v_list);
11361 }
11362
11363 /*
11364 * "sign_getplaced()" function
11365 */
11366 static void
11367 f_sign_getplaced(typval_T *argvars, typval_T *rettv)
11368 {
11369 buf_T *buf = NULL;
11370 dict_T *dict;
11371 dictitem_T *di;
11372 linenr_T lnum = 0;
11373 int sign_id = 0;
11374 char_u *group = NULL;
11375 int notanum = FALSE;
11376
11377 if (rettv_list_alloc_id(rettv, aid_sign_getplaced) != OK)
11378 return;
11379
11380 if (argvars[0].v_type != VAR_UNKNOWN)
11381 {
11382 // get signs placed in this buffer
11383 buf = find_buffer(&argvars[0]);
11384 if (buf == NULL)
11385 {
11386 EMSG2(_("E158: Invalid buffer name: %s"),
11387 get_tv_string(&argvars[0]));
11388 return;
11389 }
11390
11391 if (argvars[1].v_type != VAR_UNKNOWN)
11392 {
11393 if (argvars[1].v_type != VAR_DICT ||
11394 ((dict = argvars[1].vval.v_dict) == NULL))
11395 {
11396 EMSG(_(e_dictreq));
11397 return;
11398 }
11399 if ((di = dict_find(dict, (char_u *)"lnum", -1)) != NULL)
11400 {
11401 // get signs placed at this line
11402 (void)get_tv_number_chk(&di->di_tv, &notanum);
11403 if (notanum)
11404 return;
11405 lnum = get_tv_lnum(&di->di_tv);
11406 }
11407 if ((di = dict_find(dict, (char_u *)"id", -1)) != NULL)
11408 {
11409 // get sign placed with this identifier
11410 sign_id = (int)get_tv_number_chk(&di->di_tv, &notanum);
11411 if (notanum)
11412 return;
11413 }
11414 if ((di = dict_find(dict, (char_u *)"group", -1)) != NULL)
11415 {
11416 group = get_tv_string_chk(&di->di_tv);
11417 if (group == NULL)
11418 return;
11419 }
11420 }
11421 }
11422
11423 sign_get_placed(buf, lnum, sign_id, group, rettv->vval.v_list);
11424 }
11425
11426 /*
11427 * "sign_place()" function
11428 */
11429 static void
11430 f_sign_place(typval_T *argvars, typval_T *rettv)
11431 {
11432 int sign_id;
11433 char_u *group = NULL;
11434 char_u *sign_name;
11435 buf_T *buf;
11436 dict_T *dict;
11437 dictitem_T *di;
11438 linenr_T lnum = 0;
11439 int prio = SIGN_DEF_PRIO;
11440 int notanum = FALSE;
11441
11442 rettv->vval.v_number = -1;
11443
11444 // Sign identifer
11445 sign_id = (int)get_tv_number_chk(&argvars[0], &notanum);
11446 if (notanum)
11447 return;
11448 if (sign_id < 0)
11449 {
11450 EMSG(_(e_invarg));
11451 return;
11452 }
11453
11454 // Sign group
11455 group = get_tv_string_chk(&argvars[1]);
11456 if (group == NULL)
11457 return;
11458 if (group[0] == '\0')
11459 group = NULL; // global sign group
11460 else
11461 {
11462 group = vim_strsave(group);
11463 if (group == NULL)
11464 return;
11465 }
11466
11467 // Sign name
11468 sign_name = get_tv_string_chk(&argvars[2]);
11469 if (sign_name == NULL)
11470 goto cleanup;
11471
11472 // Buffer to place the sign
11473 buf = find_buffer(&argvars[3]);
11474 if (buf == NULL)
11475 {
11476 EMSG2(_("E158: Invalid buffer name: %s"), get_tv_string(&argvars[2]));
11477 goto cleanup;
11478 }
11479
11480 if (argvars[4].v_type != VAR_UNKNOWN)
11481 {
11482 if (argvars[4].v_type != VAR_DICT ||
11483 ((dict = argvars[4].vval.v_dict) == NULL))
11484 {
11485 EMSG(_(e_dictreq));
11486 goto cleanup;
11487 }
11488
11489 // Line number where the sign is to be placed
11490 if ((di = dict_find(dict, (char_u *)"lnum", -1)) != NULL)
11491 {
11492 (void)get_tv_number_chk(&di->di_tv, &notanum);
11493 if (notanum)
11494 goto cleanup;
11495 lnum = get_tv_lnum(&di->di_tv);
11496 }
11497 if ((di = dict_find(dict, (char_u *)"priority", -1)) != NULL)
11498 {
11499 // Sign priority
11500 prio = (int)get_tv_number_chk(&di->di_tv, &notanum);
11501 if (notanum)
11502 goto cleanup;
11503 }
11504 }
11505
11506 if (sign_place(&sign_id, group, sign_name, buf, lnum, prio) == OK)
11507 rettv->vval.v_number = sign_id;
11508
11509 cleanup:
11510 vim_free(group);
11511 }
11512
11513 /*
11514 * "sign_undefine()" function
11515 */
11516 static void
11517 f_sign_undefine(typval_T *argvars, typval_T *rettv)
11518 {
11519 char_u *name;
11520
11521 rettv->vval.v_number = -1;
11522
11523 if (argvars[0].v_type == VAR_UNKNOWN)
11524 {
11525 // Free all the signs
11526 free_signs();
11527 rettv->vval.v_number = 0;
11528 }
11529 else
11530 {
11531 // Free only the specified sign
11532 name = get_tv_string_chk(&argvars[0]);
11533 if (name == NULL)
11534 return;
11535
11536 if (sign_undefine_by_name(name) == OK)
11537 rettv->vval.v_number = 0;
11538 }
11539 }
11540
11541 /*
11542 * "sign_unplace()" function
11543 */
11544 static void
11545 f_sign_unplace(typval_T *argvars, typval_T *rettv)
11546 {
11547 dict_T *dict;
11548 dictitem_T *di;
11549 int sign_id = 0;
11550 buf_T *buf = NULL;
11551 char_u *group = NULL;
11552
11553 rettv->vval.v_number = -1;
11554
11555 if (argvars[0].v_type != VAR_STRING)
11556 {
11557 EMSG(_(e_invarg));
11558 return;
11559 }
11560
11561 group = get_tv_string(&argvars[0]);
11562 if (group[0] == '\0')
11563 group = NULL; // global sign group
11564 else
11565 {
11566 group = vim_strsave(group);
11567 if (group == NULL)
11568 return;
11569 }
11570
11571 if (argvars[1].v_type != VAR_UNKNOWN)
11572 {
11573 if (argvars[1].v_type != VAR_DICT)
11574 {
11575 EMSG(_(e_dictreq));
11576 return;
11577 }
11578 dict = argvars[1].vval.v_dict;
11579
11580 if ((di = dict_find(dict, (char_u *)"buffer", -1)) != NULL)
11581 {
11582 buf = find_buffer(&di->di_tv);
11583 if (buf == NULL)
11584 {
11585 EMSG2(_("E158: Invalid buffer name: %s"),
11586 get_tv_string(&di->di_tv));
11587 return;
11588 }
11589 }
11590 if (dict_find(dict, (char_u *)"id", -1) != NULL)
11591 sign_id = dict_get_number(dict, (char_u *)"id");
11592 }
11593
11594 if (buf == NULL)
11595 {
11596 // Delete the sign in all the buffers
11597 FOR_ALL_BUFFERS(buf)
11598 if (sign_unplace(sign_id, group, buf) == OK)
11599 rettv->vval.v_number = 0;
11600 }
11601 else
11602 {
11603 if (sign_unplace(sign_id, group, buf) == OK)
11604 rettv->vval.v_number = 0;
11605 }
11606 vim_free(group);
11607 }
11608 #endif
11609
11288 /* 11610 /*
11289 * "simplify()" function 11611 * "simplify()" function
11290 */ 11612 */
11291 static void 11613 static void
11292 f_simplify(typval_T *argvars, typval_T *rettv) 11614 f_simplify(typval_T *argvars, typval_T *rettv)