Mercurial > vim
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, ¬anum); | |
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, ¬anum); | |
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], ¬anum); | |
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, ¬anum); | |
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, ¬anum); | |
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) |