diff options
Diffstat (limited to 'data/vim/patches/8.1.0673')
-rw-r--r-- | data/vim/patches/8.1.0673 | 4323 |
1 files changed, 0 insertions, 4323 deletions
diff --git a/data/vim/patches/8.1.0673 b/data/vim/patches/8.1.0673 deleted file mode 100644 index 1e98b0e1d..000000000 --- a/data/vim/patches/8.1.0673 +++ /dev/null @@ -1,4323 +0,0 @@ -To: vim_dev@googlegroups.com -Subject: Patch 8.1.0673 -Fcc: outbox -From: Bram Moolenaar <Bram@moolenaar.net> -Mime-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit ------------- - -Patch 8.1.0673 -Problem: Functionality for signs is spread out over several files. -Solution: Move most of the sign functionality into sign.c. (Yegappan - Lakshmanan, closes #3751) -Files: Filelist, src/Make_bc5.mak, src/Make_cyg_ming.mak, - src/Make_dice.mak, src/Make_ivc.mak, src/Make_manx.mak, - src/Make_morph.mak, src/Make_mvc.mak, src/Make_sas.mak, - src/Make_vms.mms, src/Makefile, src/README.txt, src/buffer.c, - src/evalfunc.c, src/ex_cmds.c, src/proto.h, src/proto/buffer.pro, - src/proto/ex_cmds.pro, src/proto/sign.pro, src/sign.c - - -*** ../vim-8.1.0672/Filelist 2018-12-26 00:59:53.449011480 +0100 ---- Filelist 2019-01-01 13:01:50.678246698 +0100 -*************** -*** 81,90 **** - src/screen.c \ - src/search.c \ - src/sha256.c \ -! src/structs.h \ - src/spell.c \ - src/spell.h \ - src/spellfile.c \ - src/syntax.c \ - src/tag.c \ - src/term.c \ ---- 81,91 ---- - src/screen.c \ - src/search.c \ - src/sha256.c \ -! src/sign.c \ - src/spell.c \ - src/spell.h \ - src/spellfile.c \ -+ src/structs.h \ - src/syntax.c \ - src/tag.c \ - src/term.c \ -*************** -*** 192,197 **** ---- 193,199 ---- - src/proto/screen.pro \ - src/proto/search.pro \ - src/proto/sha256.pro \ -+ src/proto/sign.pro \ - src/proto/spell.pro \ - src/proto/spellfile.pro \ - src/proto/syntax.pro \ -*** ../vim-8.1.0672/src/Make_bc5.mak 2018-10-14 16:25:04.904583951 +0200 ---- src/Make_bc5.mak 2019-01-01 12:47:49.509502791 +0100 -*************** -*** 581,586 **** ---- 581,587 ---- - $(OBJDIR)\screen.obj \ - $(OBJDIR)\search.obj \ - $(OBJDIR)\sha256.obj \ -+ $(OBJDIR)\sign.obj \ - $(OBJDIR)\spell.obj \ - $(OBJDIR)\spellfile.obj \ - $(OBJDIR)\syntax.obj \ -*** ../vim-8.1.0672/src/Make_cyg_ming.mak 2018-12-19 21:05:53.912800490 +0100 ---- src/Make_cyg_ming.mak 2019-01-01 12:47:49.513502757 +0100 -*************** -*** 746,751 **** ---- 746,752 ---- - $(OUTDIR)/screen.o \ - $(OUTDIR)/search.o \ - $(OUTDIR)/sha256.o \ -+ $(OUTDIR)/sign.o \ - $(OUTDIR)/spell.o \ - $(OUTDIR)/spellfile.o \ - $(OUTDIR)/syntax.o \ -*** ../vim-8.1.0672/src/Make_dice.mak 2016-07-19 13:51:24.000000000 +0200 ---- src/Make_dice.mak 2019-01-01 12:47:49.513502757 +0100 -*************** -*** 71,76 **** ---- 71,77 ---- - screen.c \ - search.c \ - sha256.c \ -+ sign.c \ - spell.c \ - spellfile.c \ - syntax.c \ -*************** -*** 127,132 **** ---- 128,134 ---- - o/screen.o \ - o/search.o \ - o/sha256.o \ -+ o/sign.o \ - o/spell.o \ - o/spellfile.o \ - o/syntax.o \ -*************** -*** 252,257 **** ---- 254,261 ---- - - o/sha256.o: sha256.c $(SYMS) - -+ o/sign.o: sign.c $(SYMS) -+ - o/spell.o: spell.c $(SYMS) spell.h - - o/spellfile.o: spellfile.c $(SYMS) spell.h -*** ../vim-8.1.0672/src/Make_ivc.mak 2018-06-19 18:58:04.006489842 +0200 ---- src/Make_ivc.mak 2019-01-01 12:55:40.869451744 +0100 -*************** -*** 257,262 **** ---- 257,263 ---- - "$(INTDIR)/screen.obj" \ - "$(INTDIR)/search.obj" \ - "$(INTDIR)/sha256.obj" \ -+ "$(INTDIR)/sign.obj" \ - "$(INTDIR)/spell.obj" \ - "$(INTDIR)/spellfile.obj" \ - "$(INTDIR)/syntax.obj" \ -*************** -*** 675,680 **** ---- 676,685 ---- - # End Source File - # Begin Source File - -+ SOURCE=.\sign.c -+ # End Source File -+ # Begin Source File -+ - SOURCE=.\spell.c - # End Source File - # Begin Source File -*** ../vim-8.1.0672/src/Make_manx.mak 2016-07-19 13:52:17.000000000 +0200 ---- src/Make_manx.mak 2019-01-01 12:47:49.513502757 +0100 -*************** -*** 81,86 **** ---- 81,87 ---- - screen.c \ - search.c \ - sha256.c \ -+ sign.c \ - spell.c \ - spellfile.c \ - syntax.c \ -*************** -*** 139,144 **** ---- 140,146 ---- - obj/screen.o \ - obj/search.o \ - obj/sha256.o \ -+ obj/sign.o \ - obj/spell.o \ - obj/spellfile.o \ - obj/syntax.o \ -*************** -*** 195,200 **** ---- 197,203 ---- - proto/screen.pro \ - proto/search.pro \ - proto/sha256.pro \ -+ proto/sign.pro \ - proto/spell.pro \ - proto/spellfile.pro \ - proto/syntax.pro \ -*************** -*** 389,394 **** ---- 392,400 ---- - obj/sha256.o: sha256.c - $(CCSYM) $@ sha256.c - -+ obj/sign.o: sign.c -+ $(CCSYM) $@ sign.c -+ - obj/spell.o: spell.c - $(CCSYM) $@ spell.c - -*** ../vim-8.1.0672/src/Make_morph.mak 2016-07-19 13:52:32.000000000 +0200 ---- src/Make_morph.mak 2019-01-01 12:47:49.513502757 +0100 -*************** -*** 69,74 **** ---- 69,75 ---- - screen.c \ - search.c \ - sha256.c \ -+ sign.c \ - spell.c \ - spellfile.c \ - syntax.c \ -*** ../vim-8.1.0672/src/Make_mvc.mak 2018-12-19 21:05:53.912800490 +0100 ---- src/Make_mvc.mak 2019-01-01 12:47:49.513502757 +0100 -*************** -*** 749,754 **** ---- 749,755 ---- - $(OUTDIR)\screen.obj \ - $(OUTDIR)\search.obj \ - $(OUTDIR)\sha256.obj \ -+ $(OUTDIR)\sign.obj \ - $(OUTDIR)\spell.obj \ - $(OUTDIR)\spellfile.obj \ - $(OUTDIR)\syntax.obj \ -*************** -*** 1519,1524 **** ---- 1520,1527 ---- - - $(OUTDIR)/sha256.obj: $(OUTDIR) sha256.c $(INCL) - -+ $(OUTDIR)/sign.obj: $(OUTDIR) sign.c $(INCL) -+ - $(OUTDIR)/spell.obj: $(OUTDIR) spell.c $(INCL) - - $(OUTDIR)/spellfile.obj: $(OUTDIR) spellfile.c $(INCL) -*************** -*** 1664,1669 **** ---- 1667,1673 ---- - proto/screen.pro \ - proto/search.pro \ - proto/sha256.pro \ -+ proto/sign.pro \ - proto/spell.pro \ - proto/spellfile.pro \ - proto/syntax.pro \ -*** ../vim-8.1.0672/src/Make_sas.mak 2016-07-19 13:53:24.000000000 +0200 ---- src/Make_sas.mak 2019-01-01 12:57:19.092606414 +0100 -*************** -*** 134,139 **** ---- 134,140 ---- - screen.c \ - search.c \ - sha256.c \ -+ sign.c \ - spell.c \ - spellfile.c \ - syntax.c \ -*************** -*** 191,196 **** ---- 192,198 ---- - screen.o \ - search.o \ - sha256.o \ -+ sign.o \ - spell.o \ - spellfile.o \ - syntax.o \ -*************** -*** 248,253 **** ---- 250,256 ---- - proto/screen.pro \ - proto/search.pro \ - proto/sha256.pro \ -+ proto/sign.pro \ - proto/spell.pro \ - proto/spellfile.pro \ - proto/syntax.pro \ -*************** -*** 404,409 **** ---- 407,414 ---- - proto/search.pro: search.c - sha256.o: sha256.c - proto/sha256.pro: sha256.c -+ sign.o: sign.c -+ proto/sign.pro: sign.c - spell.o: spell.c - proto/spell.pro: spell.c - spellfile.o: spellfile.c -*** ../vim-8.1.0672/src/Make_vms.mms 2017-11-18 21:08:23.000000000 +0100 ---- src/Make_vms.mms 2019-01-01 12:47:49.513502757 +0100 -*************** -*** 302,308 **** - SRC = arabic.c beval.obj blowfish.c buffer.c charset.c crypt.c crypt_zip.c dict.c diff.c digraph.c edit.c eval.c evalfunc.c \ - ex_cmds.c ex_cmds2.c ex_docmd.c ex_eval.c ex_getln.c if_cscope.c if_xcmdsrv.c farsi.c fileio.c fold.c getchar.c \ - hardcopy.c hashtab.c json.c list.c main.c mark.c menu.c mbyte.c memfile.c memline.c message.c misc1.c \ -! misc2.c move.c normal.c ops.c option.c popupmnu.c quickfix.c regexp.c search.c sha256.c\ - spell.c spellfile.c syntax.c tag.c term.c termlib.c ui.c undo.c userfunc.c version.c screen.c \ - window.c os_unix.c os_vms.c pathdef.c \ - $(GUI_SRC) $(PERL_SRC) $(PYTHON_SRC) $(TCL_SRC) \ ---- 302,308 ---- - SRC = arabic.c beval.obj blowfish.c buffer.c charset.c crypt.c crypt_zip.c dict.c diff.c digraph.c edit.c eval.c evalfunc.c \ - ex_cmds.c ex_cmds2.c ex_docmd.c ex_eval.c ex_getln.c if_cscope.c if_xcmdsrv.c farsi.c fileio.c fold.c getchar.c \ - hardcopy.c hashtab.c json.c list.c main.c mark.c menu.c mbyte.c memfile.c memline.c message.c misc1.c \ -! misc2.c move.c normal.c ops.c option.c popupmnu.c quickfix.c regexp.c search.c sha256.c sign.c \ - spell.c spellfile.c syntax.c tag.c term.c termlib.c ui.c undo.c userfunc.c version.c screen.c \ - window.c os_unix.c os_vms.c pathdef.c \ - $(GUI_SRC) $(PERL_SRC) $(PYTHON_SRC) $(TCL_SRC) \ -*************** -*** 313,319 **** - if_xcmdsrv.obj farsi.obj fileio.obj fold.obj getchar.obj hardcopy.obj hashtab.obj json.obj list.obj main.obj mark.obj \ - menu.obj memfile.obj memline.obj message.obj misc1.obj misc2.obj \ - move.obj mbyte.obj normal.obj ops.obj option.obj popupmnu.obj quickfix.obj \ -! regexp.obj search.obj sha256.obj spell.obj spellfile.obj syntax.obj tag.obj term.obj termlib.obj \ - ui.obj undo.obj userfunc.obj screen.obj version.obj window.obj os_unix.obj \ - os_vms.obj pathdef.obj if_mzsch.obj\ - $(GUI_OBJ) $(PERL_OBJ) $(PYTHON_OBJ) $(TCL_OBJ) \ ---- 313,319 ---- - if_xcmdsrv.obj farsi.obj fileio.obj fold.obj getchar.obj hardcopy.obj hashtab.obj json.obj list.obj main.obj mark.obj \ - menu.obj memfile.obj memline.obj message.obj misc1.obj misc2.obj \ - move.obj mbyte.obj normal.obj ops.obj option.obj popupmnu.obj quickfix.obj \ -! regexp.obj search.obj sha256.obj sign.obj spell.obj spellfile.obj syntax.obj tag.obj term.obj termlib.obj \ - ui.obj undo.obj userfunc.obj screen.obj version.obj window.obj os_unix.obj \ - os_vms.obj pathdef.obj if_mzsch.obj\ - $(GUI_OBJ) $(PERL_OBJ) $(PYTHON_OBJ) $(TCL_OBJ) \ -*************** -*** 677,682 **** ---- 677,686 ---- - ascii.h keymap.h term.h macros.h option.h structs.h regexp.h gui.h \ - beval.h [.proto]gui_beval.pro alloc.h ex_cmds.h spell.h proto.h \ - globals.h farsi.h arabic.h -+ sign.obj : sign.c vim.h [.auto]config.h feature.h os_unix.h \ -+ ascii.h keymap.h term.h macros.h option.h structs.h regexp.h gui.h \ -+ beval.h [.proto]gui_beval.pro alloc.h ex_cmds.h spell.h proto.h \ -+ globals.h farsi.h arabic.h - spell.obj : spell.c vim.h [.auto]config.h feature.h os_unix.h \ - ascii.h keymap.h term.h macros.h structs.h regexp.h \ - gui.h beval.h [.proto]gui_beval.pro option.h ex_cmds.h proto.h \ -*** ../vim-8.1.0672/src/Makefile 2018-12-22 17:27:08.982517207 +0100 ---- src/Makefile 2019-01-01 12:47:49.513502757 +0100 -*************** -*** 1626,1631 **** ---- 1628,1634 ---- - screen.c \ - search.c \ - sha256.c \ -+ sign.c \ - spell.c \ - spellfile.c \ - syntax.c \ -*************** -*** 1736,1741 **** ---- 1739,1745 ---- - objects/screen.o \ - objects/search.o \ - objects/sha256.o \ -+ objects/sign.o \ - objects/spell.o \ - objects/spellfile.o \ - objects/syntax.o \ -*************** -*** 1870,1875 **** ---- 1874,1880 ---- - screen.pro \ - search.pro \ - sha256.pro \ -+ sign.pro \ - spell.pro \ - spellfile.pro \ - syntax.pro \ -*************** -*** 3200,3205 **** ---- 3205,3213 ---- - objects/sha256.o: sha256.c - $(CCC) -o $@ sha256.c - -+ objects/sign.o: sign.c -+ $(CCC) -o $@ sign.c -+ - objects/spell.o: spell.c - $(CCC) -o $@ spell.c - -*************** -*** 3586,3591 **** ---- 3594,3603 ---- - auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ - proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ - proto.h globals.h farsi.h arabic.h -+ objects/sign.o: sign.c vim.h protodef.h auto/config.h feature.h os_unix.h \ -+ auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ -+ proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ -+ proto.h globals.h farsi.h arabic.h - objects/spell.o: spell.c vim.h protodef.h auto/config.h feature.h os_unix.h \ - auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ - proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ -*** ../vim-8.1.0672/src/README.txt 2017-11-12 16:49:36.000000000 +0100 ---- src/README.txt 2019-01-01 12:47:49.513502757 +0100 -*************** -*** 35,40 **** ---- 35,41 ---- - regexp.c pattern matching - screen.c updating the windows - search.c pattern searching -+ sign.c signs - spell.c spell checking - syntax.c syntax and other highlighting - tag.c tags -*** ../vim-8.1.0672/src/buffer.c 2018-12-29 18:53:07.839607468 +0100 ---- src/buffer.c 2019-01-01 12:47:49.513502757 +0100 -*************** -*** 5864,6505 **** - } - #endif - -- #if defined(FEAT_SIGNS) || defined(PROTO) -- static hashtab_T sg_table; // sign group (signgroup_T) hashtable -- static int next_sign_id = 1; // next sign id in the global group -- -- /* -- * Initialize data needed for managing signs -- */ -- void -- init_signs(void) -- { -- hash_init(&sg_table); // sign group hash table -- } -- -- /* -- * A new sign in group 'groupname' is added. If the group is not present, -- * create it. Otherwise reference the group. -- */ -- static signgroup_T * -- sign_group_ref(char_u *groupname) -- { -- hash_T hash; -- hashitem_T *hi; -- signgroup_T *group; -- -- hash = hash_hash(groupname); -- hi = hash_lookup(&sg_table, groupname, hash); -- if (HASHITEM_EMPTY(hi)) -- { -- // new group -- group = (signgroup_T *)alloc( -- (unsigned)(sizeof(signgroup_T) + STRLEN(groupname))); -- if (group == NULL) -- return NULL; -- STRCPY(group->sg_name, groupname); -- group->refcount = 1; -- group->next_sign_id = 1; -- hash_add_item(&sg_table, hi, group->sg_name, hash); -- } -- else -- { -- // existing group -- group = HI2SG(hi); -- group->refcount++; -- } -- -- return group; -- } -- -- /* -- * A sign in group 'groupname' is removed. If all the signs in this group are -- * removed, then remove the group. -- */ -- static void -- sign_group_unref(char_u *groupname) -- { -- hashitem_T *hi; -- signgroup_T *group; -- -- hi = hash_find(&sg_table, groupname); -- if (!HASHITEM_EMPTY(hi)) -- { -- group = HI2SG(hi); -- group->refcount--; -- if (group->refcount == 0) -- { -- // All the signs in this group are removed -- hash_remove(&sg_table, hi); -- vim_free(group); -- } -- } -- } -- -- /* -- * Get the next free sign identifier in the specified group -- */ -- int -- sign_group_get_next_signid(buf_T *buf, char_u *groupname) -- { -- int id = 1; -- signgroup_T *group = NULL; -- signlist_T *sign; -- hashitem_T *hi; -- int found = FALSE; -- -- if (groupname != NULL) -- { -- hi = hash_find(&sg_table, groupname); -- if (HASHITEM_EMPTY(hi)) -- return id; -- group = HI2SG(hi); -- } -- -- // Search for the next usuable sign identifier -- while (!found) -- { -- if (group == NULL) -- id = next_sign_id++; // global group -- else -- id = group->next_sign_id++; -- -- // Check whether this sign is already placed in the buffer -- found = TRUE; -- FOR_ALL_SIGNS_IN_BUF(buf, sign) -- { -- if (id == sign->id && sign_in_group(sign, groupname)) -- { -- found = FALSE; // sign identifier is in use -- break; -- } -- } -- } -- -- return id; -- } -- -- /* -- * Insert a new sign into the signlist for buffer 'buf' between the 'prev' and -- * 'next' signs. -- */ -- static void -- insert_sign( -- buf_T *buf, // buffer to store sign in -- signlist_T *prev, // previous sign entry -- signlist_T *next, // next sign entry -- int id, // sign ID -- char_u *group, // sign group; NULL for global group -- int prio, // sign priority -- linenr_T lnum, // line number which gets the mark -- int typenr) // typenr of sign we are adding -- { -- signlist_T *newsign; -- -- newsign = (signlist_T *)lalloc_id((long_u)sizeof(signlist_T), FALSE, -- aid_insert_sign); -- if (newsign != NULL) -- { -- newsign->id = id; -- newsign->lnum = lnum; -- newsign->typenr = typenr; -- if (group != NULL) -- { -- newsign->group = sign_group_ref(group); -- if (newsign->group == NULL) -- { -- vim_free(newsign); -- return; -- } -- } -- else -- newsign->group = NULL; -- newsign->priority = prio; -- newsign->next = next; -- newsign->prev = prev; -- if (next != NULL) -- next->prev = newsign; -- -- if (prev == NULL) -- { -- // When adding first sign need to redraw the windows to create the -- // column for signs. -- if (buf->b_signlist == NULL) -- { -- redraw_buf_later(buf, NOT_VALID); -- changed_cline_bef_curs(); -- } -- -- // first sign in signlist -- buf->b_signlist = newsign; -- #ifdef FEAT_NETBEANS_INTG -- if (netbeans_active()) -- buf->b_has_sign_column = TRUE; -- #endif -- } -- else -- prev->next = newsign; -- } -- } -- -- /* -- * Insert a new sign sorted by line number and sign priority. -- */ -- static void -- insert_sign_by_lnum_prio( -- buf_T *buf, // buffer to store sign in -- signlist_T *prev, // previous sign entry -- int id, // sign ID -- char_u *group, // sign group; NULL for global group -- int prio, // sign priority -- linenr_T lnum, // line number which gets the mark -- int typenr) // typenr of sign we are adding -- { -- signlist_T *sign; -- -- // keep signs sorted by lnum and by priority: insert new sign at -- // the proper position in the list for this lnum. -- while (prev != NULL && prev->lnum == lnum && prev->priority <= prio) -- prev = prev->prev; -- if (prev == NULL) -- sign = buf->b_signlist; -- else -- sign = prev->next; -- -- insert_sign(buf, prev, sign, id, group, prio, lnum, typenr); -- } -- -- /* -- * Returns TRUE if 'sign' is in 'group'. -- * A sign can either be in the global group (sign->group == NULL) -- * or in a named group. If 'group' is '*', then the sign is part of the group. -- */ -- int -- sign_in_group(signlist_T *sign, char_u *group) -- { -- return ((group != NULL && STRCMP(group, "*") == 0) -- || (group == NULL && sign->group == NULL) -- || (group != NULL && sign->group != NULL -- && STRCMP(group, sign->group->sg_name) == 0)); -- } -- -- /* -- * Return information about a sign in a Dict -- */ -- dict_T * -- sign_get_info(signlist_T *sign) -- { -- dict_T *d; -- -- if ((d = dict_alloc_id(aid_sign_getinfo)) == NULL) -- return NULL; -- dict_add_number(d, "id", sign->id); -- dict_add_string(d, "group", (sign->group == NULL) ? -- (char_u *)"" : sign->group->sg_name); -- dict_add_number(d, "lnum", sign->lnum); -- dict_add_string(d, "name", sign_typenr2name(sign->typenr)); -- dict_add_number(d, "priority", sign->priority); -- -- return d; -- } -- -- /* -- * Add the sign into the signlist. Find the right spot to do it though. -- */ -- void -- buf_addsign( -- buf_T *buf, // buffer to store sign in -- int id, // sign ID -- char_u *groupname, // sign group -- int prio, // sign priority -- linenr_T lnum, // line number which gets the mark -- int typenr) // typenr of sign we are adding -- { -- signlist_T *sign; // a sign in the signlist -- signlist_T *prev; // the previous sign -- -- prev = NULL; -- FOR_ALL_SIGNS_IN_BUF(buf, sign) -- { -- if (lnum == sign->lnum && id == sign->id && -- sign_in_group(sign, groupname)) -- { -- // Update an existing sign -- sign->typenr = typenr; -- return; -- } -- else if (lnum < sign->lnum) -- { -- insert_sign_by_lnum_prio(buf, prev, id, groupname, prio, -- lnum, typenr); -- return; -- } -- prev = sign; -- } -- -- insert_sign_by_lnum_prio(buf, prev, id, groupname, prio, lnum, typenr); -- return; -- } -- -- /* -- * For an existing, placed sign "markId" change the type to "typenr". -- * Returns the line number of the sign, or zero if the sign is not found. -- */ -- linenr_T -- buf_change_sign_type( -- buf_T *buf, // buffer to store sign in -- int markId, // sign ID -- char_u *group, // sign group -- int typenr) // typenr of sign we are adding -- { -- signlist_T *sign; // a sign in the signlist -- -- FOR_ALL_SIGNS_IN_BUF(buf, sign) -- { -- if (sign->id == markId && sign_in_group(sign, group)) -- { -- sign->typenr = typenr; -- return sign->lnum; -- } -- } -- -- return (linenr_T)0; -- } -- -- /* -- * Return the type number of the sign at line number 'lnum' in buffer 'buf' -- * which has the attribute specifed by 'type'. Returns 0 if a sign is not found -- * at the line number or it doesn't have the specified attribute. -- */ -- int -- buf_getsigntype( -- buf_T *buf, -- linenr_T lnum, -- int type) /* SIGN_ICON, SIGN_TEXT, SIGN_ANY, SIGN_LINEHL */ -- { -- signlist_T *sign; /* a sign in a b_signlist */ -- -- FOR_ALL_SIGNS_IN_BUF(buf, sign) -- if (sign->lnum == lnum -- && (type == SIGN_ANY -- # ifdef FEAT_SIGN_ICONS -- || (type == SIGN_ICON -- && sign_get_image(sign->typenr) != NULL) -- # endif -- || (type == SIGN_TEXT -- && sign_get_text(sign->typenr) != NULL) -- || (type == SIGN_LINEHL -- && sign_get_attr(sign->typenr, TRUE) != 0))) -- return sign->typenr; -- return 0; -- } -- -- /* -- * Delete sign 'id' in group 'group' from buffer 'buf'. -- * If 'id' is zero, then delete all the signs in group 'group'. Otherwise -- * delete only the specified sign. -- * If 'group' is '*', then delete the sign in all the groups. If 'group' is -- * NULL, then delete the sign in the global group. Otherwise delete the sign in -- * the specified group. -- * Returns the line number of the deleted sign. If multiple signs are deleted, -- * then returns the line number of the last sign deleted. -- */ -- linenr_T -- buf_delsign( -- buf_T *buf, // buffer sign is stored in -- linenr_T atlnum, // sign at this line, 0 - at any line -- int id, // sign id -- char_u *group) // sign group -- { -- signlist_T **lastp; // pointer to pointer to current sign -- signlist_T *sign; // a sign in a b_signlist -- signlist_T *next; // the next sign in a b_signlist -- linenr_T lnum; // line number whose sign was deleted -- -- lastp = &buf->b_signlist; -- lnum = 0; -- for (sign = buf->b_signlist; sign != NULL; sign = next) -- { -- next = sign->next; -- if ((id == 0 || sign->id == id) && -- (atlnum == 0 || sign->lnum == atlnum) && -- sign_in_group(sign, group)) -- -- { -- *lastp = next; -- if (next != NULL) -- next->prev = sign->prev; -- lnum = sign->lnum; -- if (sign->group != NULL) -- sign_group_unref(sign->group->sg_name); -- vim_free(sign); -- update_debug_sign(buf, lnum); -- // Check whether only one sign needs to be deleted -- // If deleting a sign with a specific identifer in a particular -- // group or deleting any sign at a particular line number, delete -- // only one sign. -- if (group == NULL -- || (*group != '*' && id != 0) -- || (*group == '*' && atlnum != 0)) -- break; -- } -- else -- lastp = &sign->next; -- } -- -- // When deleted the last sign need to redraw the windows to remove the -- // sign column. -- if (buf->b_signlist == NULL) -- { -- redraw_buf_later(buf, NOT_VALID); -- changed_cline_bef_curs(); -- } -- -- return lnum; -- } -- -- -- /* -- * Find the line number of the sign with the requested id in group 'group'. If -- * the sign does not exist, return 0 as the line number. This will still let -- * the correct file get loaded. -- */ -- int -- buf_findsign( -- buf_T *buf, // buffer to store sign in -- int id, // sign ID -- char_u *group) // sign group -- { -- signlist_T *sign; // a sign in the signlist -- -- FOR_ALL_SIGNS_IN_BUF(buf, sign) -- if (sign->id == id && sign_in_group(sign, group)) -- return sign->lnum; -- -- return 0; -- } -- -- /* -- * Return the sign at line 'lnum' in buffer 'buf'. Returns NULL if a sign is -- * not found at the line. If 'groupname' is NULL, searches in the global group. -- */ -- static signlist_T * -- buf_getsign_at_line( -- buf_T *buf, // buffer whose sign we are searching for -- linenr_T lnum, // line number of sign -- char_u *groupname) // sign group name -- { -- signlist_T *sign; // a sign in the signlist -- -- FOR_ALL_SIGNS_IN_BUF(buf, sign) -- if (sign->lnum == lnum && sign_in_group(sign, groupname)) -- return sign; -- -- return NULL; -- } -- -- /* -- * Return the sign with identifier 'id' in group 'group' placed in buffer 'buf' -- */ -- signlist_T * -- buf_getsign_with_id( -- buf_T *buf, // buffer whose sign we are searching for -- int id, // sign identifier -- char_u *group) // sign group -- { -- signlist_T *sign; // a sign in the signlist -- -- FOR_ALL_SIGNS_IN_BUF(buf, sign) -- if (sign->id == id && sign_in_group(sign, group)) -- return sign; -- -- return NULL; -- } -- -- /* -- * Return the identifier of the sign at line number 'lnum' in buffer 'buf'. -- */ -- int -- buf_findsign_id( -- buf_T *buf, // buffer whose sign we are searching for -- linenr_T lnum, // line number of sign -- char_u *groupname) // sign group name -- { -- signlist_T *sign; // a sign in the signlist -- -- sign = buf_getsign_at_line(buf, lnum, groupname); -- if (sign != NULL) -- return sign->id; -- -- return 0; -- } -- -- # if defined(FEAT_NETBEANS_INTG) || defined(PROTO) -- /* -- * See if a given type of sign exists on a specific line. -- */ -- int -- buf_findsigntype_id( -- buf_T *buf, /* buffer whose sign we are searching for */ -- linenr_T lnum, /* line number of sign */ -- int typenr) /* sign type number */ -- { -- signlist_T *sign; /* a sign in the signlist */ -- -- FOR_ALL_SIGNS_IN_BUF(buf, sign) -- if (sign->lnum == lnum && sign->typenr == typenr) -- return sign->id; -- -- return 0; -- } -- -- -- # if defined(FEAT_SIGN_ICONS) || defined(PROTO) -- /* -- * Return the number of icons on the given line. -- */ -- int -- buf_signcount(buf_T *buf, linenr_T lnum) -- { -- signlist_T *sign; // a sign in the signlist -- int count = 0; -- -- FOR_ALL_SIGNS_IN_BUF(buf, sign) -- if (sign->lnum == lnum) -- if (sign_get_image(sign->typenr) != NULL) -- count++; -- -- return count; -- } -- # endif /* FEAT_SIGN_ICONS */ -- # endif /* FEAT_NETBEANS_INTG */ -- -- /* -- * Delete signs in group 'group' in buffer "buf". If 'group' is '*', then -- * delete all the signs. -- */ -- void -- buf_delete_signs(buf_T *buf, char_u *group) -- { -- signlist_T *sign; -- signlist_T **lastp; // pointer to pointer to current sign -- signlist_T *next; -- -- // When deleting the last sign need to redraw the windows to remove the -- // sign column. Not when curwin is NULL (this means we're exiting). -- if (buf->b_signlist != NULL && curwin != NULL) -- { -- redraw_buf_later(buf, NOT_VALID); -- changed_cline_bef_curs(); -- } -- -- lastp = &buf->b_signlist; -- for (sign = buf->b_signlist; sign != NULL; sign = next) -- { -- next = sign->next; -- if (sign_in_group(sign, group)) -- { -- *lastp = next; -- if (next != NULL) -- next->prev = sign->prev; -- if (sign->group != NULL) -- sign_group_unref(sign->group->sg_name); -- vim_free(sign); -- } -- else -- lastp = &sign->next; -- } -- } -- -- /* -- * Delete all the signs in the specified group in all the buffers. -- */ -- void -- buf_delete_all_signs(char_u *groupname) -- { -- buf_T *buf; /* buffer we are checking for signs */ -- -- FOR_ALL_BUFFERS(buf) -- if (buf->b_signlist != NULL) -- buf_delete_signs(buf, groupname); -- } -- -- /* -- * List placed signs for "rbuf". If "rbuf" is NULL do it for all buffers. -- */ -- void -- sign_list_placed(buf_T *rbuf, char_u *sign_group) -- { -- buf_T *buf; -- signlist_T *sign; -- char lbuf[BUFSIZ]; -- char group[BUFSIZ]; -- -- MSG_PUTS_TITLE(_("\n--- Signs ---")); -- msg_putchar('\n'); -- if (rbuf == NULL) -- buf = firstbuf; -- else -- buf = rbuf; -- while (buf != NULL && !got_int) -- { -- if (buf->b_signlist != NULL) -- { -- vim_snprintf(lbuf, BUFSIZ, _("Signs for %s:"), buf->b_fname); -- MSG_PUTS_ATTR(lbuf, HL_ATTR(HLF_D)); -- msg_putchar('\n'); -- } -- FOR_ALL_SIGNS_IN_BUF(buf, sign) -- { -- if (got_int) -- break; -- if (!sign_in_group(sign, sign_group)) -- continue; -- if (sign->group != NULL) -- vim_snprintf(group, BUFSIZ, " group=%s", -- sign->group->sg_name); -- else -- group[0] = '\0'; -- vim_snprintf(lbuf, BUFSIZ, _(" line=%ld id=%d%s name=%s " -- "priority=%d"), -- (long)sign->lnum, sign->id, group, -- sign_typenr2name(sign->typenr), sign->priority); -- MSG_PUTS(lbuf); -- msg_putchar('\n'); -- } -- if (rbuf != NULL) -- break; -- buf = buf->b_next; -- } -- } -- -- /* -- * Adjust a placed sign for inserted/deleted lines. -- */ -- void -- sign_mark_adjust( -- linenr_T line1, -- linenr_T line2, -- long amount, -- long amount_after) -- { -- signlist_T *sign; /* a sign in a b_signlist */ -- -- FOR_ALL_SIGNS_IN_BUF(curbuf, sign) -- { -- if (sign->lnum >= line1 && sign->lnum <= line2) -- { -- if (amount == MAXLNUM) -- sign->lnum = line1; -- else -- sign->lnum += amount; -- } -- else if (sign->lnum > line2) -- sign->lnum += amount_after; -- } -- } -- #endif /* FEAT_SIGNS */ -- - /* - * Set 'buflisted' for curbuf to "on" and trigger autocommands if it changed. - */ ---- 5864,5869 ---- -*** ../vim-8.1.0672/src/evalfunc.c 2018-12-29 21:00:20.953498877 +0100 ---- src/evalfunc.c 2019-01-01 12:47:49.517502724 +0100 -*************** -*** 4424,4447 **** - copy_tv(tv, rettv); - } - -- #ifdef FEAT_SIGNS -- /* -- * Returns information about signs placed in a buffer as list of dicts. -- */ -- static void -- get_buffer_signs(buf_T *buf, list_T *l) -- { -- signlist_T *sign; -- dict_T *d; -- -- FOR_ALL_SIGNS_IN_BUF(buf, sign) -- { -- if ((d = sign_get_info(sign)) != NULL) -- list_append_dict(l, d); -- } -- } -- #endif -- - /* - * Returns buffer options, variables and other attributes in a dictionary. - */ ---- 4424,4429 ---- -*** ../vim-8.1.0672/src/ex_cmds.c 2018-12-31 22:02:24.081890522 +0100 ---- src/ex_cmds.c 2019-01-01 12:47:49.517502724 +0100 -*************** -*** 7579,8830 **** - } - } - -- #if defined(FEAT_SIGNS) || defined(PROTO) -- -- /* -- * Struct to hold the sign properties. -- */ -- typedef struct sign sign_T; -- -- struct sign -- { -- sign_T *sn_next; /* next sign in list */ -- int sn_typenr; /* type number of sign */ -- char_u *sn_name; /* name of sign */ -- char_u *sn_icon; /* name of pixmap */ -- # ifdef FEAT_SIGN_ICONS -- void *sn_image; /* icon image */ -- # endif -- char_u *sn_text; /* text used instead of pixmap */ -- int sn_line_hl; /* highlight ID for line */ -- int sn_text_hl; /* highlight ID for text */ -- }; -- -- static sign_T *first_sign = NULL; -- static int next_sign_typenr = 1; -- -- static void sign_list_defined(sign_T *sp); -- static void sign_undefine(sign_T *sp, sign_T *sp_prev); -- -- static char *cmds[] = { -- "define", -- # define SIGNCMD_DEFINE 0 -- "undefine", -- # define SIGNCMD_UNDEFINE 1 -- "list", -- # define SIGNCMD_LIST 2 -- "place", -- # define SIGNCMD_PLACE 3 -- "unplace", -- # define SIGNCMD_UNPLACE 4 -- "jump", -- # define SIGNCMD_JUMP 5 -- NULL -- # define SIGNCMD_LAST 6 -- }; -- -- /* -- * Find index of a ":sign" subcmd from its name. -- * "*end_cmd" must be writable. -- */ -- static int -- sign_cmd_idx( -- char_u *begin_cmd, /* begin of sign subcmd */ -- char_u *end_cmd) /* just after sign subcmd */ -- { -- int idx; -- char save = *end_cmd; -- -- *end_cmd = NUL; -- for (idx = 0; ; ++idx) -- if (cmds[idx] == NULL || STRCMP(begin_cmd, cmds[idx]) == 0) -- break; -- *end_cmd = save; -- return idx; -- } -- -- /* -- * Find a sign by name. Also returns pointer to the previous sign. -- */ -- static sign_T * -- sign_find(char_u *name, sign_T **sp_prev) -- { -- sign_T *sp; -- -- if (sp_prev != NULL) -- *sp_prev = NULL; -- for (sp = first_sign; sp != NULL; sp = sp->sn_next) -- { -- if (STRCMP(sp->sn_name, name) == 0) -- break; -- if (sp_prev != NULL) -- *sp_prev = sp; -- } -- -- return sp; -- } -- -- /* -- * Define a new sign or update an existing sign -- */ -- int -- sign_define_by_name( -- char_u *name, -- char_u *icon, -- char_u *linehl, -- char_u *text, -- char_u *texthl) -- { -- sign_T *sp_prev; -- sign_T *sp; -- -- sp = sign_find(name, &sp_prev); -- if (sp == NULL) -- { -- sign_T *lp; -- int start = next_sign_typenr; -- -- // Allocate a new sign. -- sp = (sign_T *)alloc_clear_id((unsigned)sizeof(sign_T), -- aid_sign_define_by_name); -- if (sp == NULL) -- return FAIL; -- -- // Check that next_sign_typenr is not already being used. -- // This only happens after wrapping around. Hopefully -- // another one got deleted and we can use its number. -- for (lp = first_sign; lp != NULL; ) -- { -- if (lp->sn_typenr == next_sign_typenr) -- { -- ++next_sign_typenr; -- if (next_sign_typenr == MAX_TYPENR) -- next_sign_typenr = 1; -- if (next_sign_typenr == start) -- { -- vim_free(sp); -- EMSG(_("E612: Too many signs defined")); -- return FAIL; -- } -- lp = first_sign; // start all over -- continue; -- } -- lp = lp->sn_next; -- } -- -- sp->sn_typenr = next_sign_typenr; -- if (++next_sign_typenr == MAX_TYPENR) -- next_sign_typenr = 1; // wrap around -- -- sp->sn_name = vim_strsave(name); -- if (sp->sn_name == NULL) // out of memory -- { -- vim_free(sp); -- return FAIL; -- } -- -- // add the new sign to the list of signs -- if (sp_prev == NULL) -- first_sign = sp; -- else -- sp_prev->sn_next = sp; -- } -- -- // set values for a defined sign. -- if (icon != NULL) -- { -- vim_free(sp->sn_icon); -- sp->sn_icon = vim_strsave(icon); -- backslash_halve(sp->sn_icon); -- # ifdef FEAT_SIGN_ICONS -- if (gui.in_use) -- { -- out_flush(); -- if (sp->sn_image != NULL) -- gui_mch_destroy_sign(sp->sn_image); -- sp->sn_image = gui_mch_register_sign(sp->sn_icon); -- } -- # endif -- } -- -- if (text != NULL) -- { -- char_u *s; -- char_u *endp; -- int cells; -- int len; -- -- endp = text + (int)STRLEN(text); -- for (s = text; s + 1 < endp; ++s) -- if (*s == '\\') -- { -- // Remove a backslash, so that it is possible -- // to use a space. -- STRMOVE(s, s + 1); -- --endp; -- } -- # ifdef FEAT_MBYTE -- // Count cells and check for non-printable chars -- if (has_mbyte) -- { -- cells = 0; -- for (s = text; s < endp; s += (*mb_ptr2len)(s)) -- { -- if (!vim_isprintc((*mb_ptr2char)(s))) -- break; -- cells += (*mb_ptr2cells)(s); -- } -- } -- else -- # endif -- { -- for (s = text; s < endp; ++s) -- if (!vim_isprintc(*s)) -- break; -- cells = (int)(s - text); -- } -- // Currently must be one or two display cells -- if (s != endp || cells < 1 || cells > 2) -- { -- EMSG2(_("E239: Invalid sign text: %s"), text); -- return FAIL; -- } -- -- vim_free(sp->sn_text); -- // Allocate one byte more if we need to pad up -- // with a space. -- len = (int)(endp - text + ((cells == 1) ? 1 : 0)); -- sp->sn_text = vim_strnsave(text, len); -- -- if (sp->sn_text != NULL && cells == 1) -- STRCPY(sp->sn_text + len - 1, " "); -- } -- -- if (linehl != NULL) -- sp->sn_line_hl = syn_check_group(linehl, (int)STRLEN(linehl)); -- -- if (texthl != NULL) -- sp->sn_text_hl = syn_check_group(texthl, (int)STRLEN(texthl)); -- -- return OK; -- } -- -- /* -- * Free the sign specified by 'name'. -- */ -- int -- sign_undefine_by_name(char_u *name) -- { -- sign_T *sp_prev; -- sign_T *sp; -- -- sp = sign_find(name, &sp_prev); -- if (sp == NULL) -- { -- EMSG2(_("E155: Unknown sign: %s"), name); -- return FAIL; -- } -- sign_undefine(sp, sp_prev); -- -- return OK; -- } -- -- /* -- * List the signs matching 'name' -- */ -- static void -- sign_list_by_name(char_u *name) -- { -- sign_T *sp; -- -- sp = sign_find(name, NULL); -- if (sp != NULL) -- sign_list_defined(sp); -- else -- EMSG2(_("E155: Unknown sign: %s"), name); -- } -- -- /* -- * Place a sign at the specifed file location or update a sign. -- */ -- int -- sign_place( -- int *sign_id, -- char_u *sign_group, -- char_u *sign_name, -- buf_T *buf, -- linenr_T lnum, -- int prio) -- { -- sign_T *sp; -- -- // Check for reserved character '*' in group name -- if (sign_group != NULL && (*sign_group == '*' || *sign_group == '\0')) -- return FAIL; -- -- for (sp = first_sign; sp != NULL; sp = sp->sn_next) -- if (STRCMP(sp->sn_name, sign_name) == 0) -- break; -- if (sp == NULL) -- { -- EMSG2(_("E155: Unknown sign: %s"), sign_name); -- return FAIL; -- } -- if (*sign_id == 0) -- *sign_id = sign_group_get_next_signid(buf, sign_group); -- -- if (lnum > 0) -- // ":sign place {id} line={lnum} name={name} file={fname}": -- // place a sign -- buf_addsign(buf, *sign_id, sign_group, prio, lnum, sp->sn_typenr); -- else -- // ":sign place {id} file={fname}": change sign type -- lnum = buf_change_sign_type(buf, *sign_id, sign_group, sp->sn_typenr); -- if (lnum > 0) -- update_debug_sign(buf, lnum); -- else -- { -- EMSG2(_("E885: Not possible to change sign %s"), sign_name); -- return FAIL; -- } -- -- return OK; -- } -- -- /* -- * Unplace the specified sign -- */ -- int -- sign_unplace(int sign_id, char_u *sign_group, buf_T *buf, linenr_T atlnum) -- { -- if (buf->b_signlist == NULL) // No signs in the buffer -- return OK; -- -- if (sign_id == 0) -- { -- // Delete all the signs in the specified buffer -- redraw_buf_later(buf, NOT_VALID); -- buf_delete_signs(buf, sign_group); -- } -- else -- { -- linenr_T lnum; -- -- // Delete only the specified signs -- lnum = buf_delsign(buf, atlnum, sign_id, sign_group); -- if (lnum == 0) -- return FAIL; -- } -- -- return OK; -- } -- -- /* -- * Unplace the sign at the current cursor line. -- */ -- static void -- sign_unplace_at_cursor(char_u *groupname) -- { -- int id = -1; -- -- id = buf_findsign_id(curwin->w_buffer, curwin->w_cursor.lnum, groupname); -- if (id > 0) -- sign_unplace(id, groupname, curwin->w_buffer, curwin->w_cursor.lnum); -- else -- EMSG(_("E159: Missing sign number")); -- } -- -- /* -- * sign define command -- * ":sign define {name} ..." -- */ -- static void -- sign_define_cmd(char_u *sign_name, char_u *cmdline) -- { -- char_u *arg; -- char_u *p = cmdline; -- char_u *icon = NULL; -- char_u *text = NULL; -- char_u *linehl = NULL; -- char_u *texthl = NULL; -- int failed = FALSE; -- -- // set values for a defined sign. -- for (;;) -- { -- arg = skipwhite(p); -- if (*arg == NUL) -- break; -- p = skiptowhite_esc(arg); -- if (STRNCMP(arg, "icon=", 5) == 0) -- { -- arg += 5; -- icon = vim_strnsave(arg, (int)(p - arg)); -- } -- else if (STRNCMP(arg, "text=", 5) == 0) -- { -- arg += 5; -- text = vim_strnsave(arg, (int)(p - arg)); -- } -- else if (STRNCMP(arg, "linehl=", 7) == 0) -- { -- arg += 7; -- linehl = vim_strnsave(arg, (int)(p - arg)); -- } -- else if (STRNCMP(arg, "texthl=", 7) == 0) -- { -- arg += 7; -- texthl = vim_strnsave(arg, (int)(p - arg)); -- } -- else -- { -- EMSG2(_(e_invarg2), arg); -- failed = TRUE; -- break; -- } -- } -- -- if (!failed) -- sign_define_by_name(sign_name, icon, linehl, text, texthl); -- -- vim_free(icon); -- vim_free(text); -- vim_free(linehl); -- vim_free(texthl); -- } -- -- /* -- * :sign place command -- */ -- static void -- sign_place_cmd( -- buf_T *buf, -- linenr_T lnum, -- char_u *sign_name, -- int id, -- char_u *group, -- int prio) -- { -- if (id <= 0) -- { -- // List signs placed in a file/buffer -- // :sign place file={fname} -- // :sign place group={group} file={fname} -- // :sign place group=* file={fname} -- // :sign place buffer={nr} -- // :sign place group={group} buffer={nr} -- // :sign place group=* buffer={nr} -- // :sign place -- // :sign place group={group} -- // :sign place group=* -- if (lnum >= 0 || sign_name != NULL || -- (group != NULL && *group == '\0')) -- EMSG(_(e_invarg)); -- else -- sign_list_placed(buf, group); -- } -- else -- { -- // Place a new sign -- if (sign_name == NULL || buf == NULL || -- (group != NULL && *group == '\0')) -- { -- EMSG(_(e_invarg)); -- return; -- } -- -- sign_place(&id, group, sign_name, buf, lnum, prio); -- } -- } -- -- /* -- * :sign unplace command -- */ -- static void -- sign_unplace_cmd( -- buf_T *buf, -- linenr_T lnum, -- char_u *sign_name, -- int id, -- char_u *group) -- { -- if (lnum >= 0 || sign_name != NULL || (group != NULL && *group == '\0')) -- { -- EMSG(_(e_invarg)); -- return; -- } -- -- if (id == -2) -- { -- if (buf != NULL) -- // :sign unplace * file={fname} -- // :sign unplace * group={group} file={fname} -- // :sign unplace * group=* file={fname} -- // :sign unplace * buffer={nr} -- // :sign unplace * group={group} buffer={nr} -- // :sign unplace * group=* buffer={nr} -- sign_unplace(0, group, buf, 0); -- else -- // :sign unplace * -- // :sign unplace * group={group} -- // :sign unplace * group=* -- FOR_ALL_BUFFERS(buf) -- if (buf->b_signlist != NULL) -- buf_delete_signs(buf, group); -- } -- else -- { -- if (buf != NULL) -- // :sign unplace {id} file={fname} -- // :sign unplace {id} group={group} file={fname} -- // :sign unplace {id} group=* file={fname} -- // :sign unplace {id} buffer={nr} -- // :sign unplace {id} group={group} buffer={nr} -- // :sign unplace {id} group=* buffer={nr} -- sign_unplace(id, group, buf, 0); -- else -- { -- if (id == -1) -- { -- // :sign unplace group={group} -- // :sign unplace group=* -- sign_unplace_at_cursor(group); -- } -- else -- { -- // :sign unplace {id} -- // :sign unplace {id} group={group} -- // :sign unplace {id} group=* -- FOR_ALL_BUFFERS(buf) -- sign_unplace(id, group, buf, 0); -- } -- } -- } -- } -- -- /* -- * Jump to a placed sign -- * :sign jump {id} file={fname} -- * :sign jump {id} buffer={nr} -- * :sign jump {id} group={group} file={fname} -- * :sign jump {id} group={group} buffer={nr} -- */ -- static void -- sign_jump_cmd( -- buf_T *buf, -- linenr_T lnum, -- char_u *sign_name, -- int id, -- char_u *group) -- { -- if (buf == NULL && sign_name == NULL && group == NULL && id == -1) -- { -- EMSG(_(e_argreq)); -- return; -- } -- -- if (buf == NULL || (group != NULL && *group == '\0') || -- lnum >= 0 || sign_name != NULL) -- { -- // File or buffer is not specified or an empty group is used -- // or a line number or a sign name is specified. -- EMSG(_(e_invarg)); -- return; -- } -- -- if ((lnum = buf_findsign(buf, id, group)) <= 0) -- { -- EMSGN(_("E157: Invalid sign ID: %ld"), id); -- return; -- } -- -- // goto a sign ... -- if (buf_jump_open_win(buf) != NULL) -- { // ... in a current window -- curwin->w_cursor.lnum = lnum; -- check_cursor_lnum(); -- beginline(BL_WHITE); -- } -- else -- { // ... not currently in a window -- char_u *cmd; -- -- if (buf->b_fname == NULL) -- { -- EMSG(_("E934: Cannot jump to a buffer that does not have a name")); -- return; -- } -- cmd = alloc((unsigned)STRLEN(buf->b_fname) + 25); -- if (cmd == NULL) -- return; -- sprintf((char *)cmd, "e +%ld %s", (long)lnum, buf->b_fname); -- do_cmdline_cmd(cmd); -- vim_free(cmd); -- } -- # ifdef FEAT_FOLDING -- foldOpenCursor(); -- # endif -- } -- -- /* -- * Parse the command line arguments for the ":sign place", ":sign unplace" and -- * ":sign jump" commands. -- * The supported arguments are: line={lnum} name={name} group={group} -- * priority={prio} and file={fname} or buffer={nr}. -- */ -- static int -- parse_sign_cmd_args( -- int cmd, -- char_u *arg, -- char_u **sign_name, -- int *signid, -- char_u **group, -- int *prio, -- buf_T **buf, -- linenr_T *lnum) -- { -- char_u *arg1; -- char_u *name; -- char_u *filename = NULL; -- -- // first arg could be placed sign id -- arg1 = arg; -- if (VIM_ISDIGIT(*arg)) -- { -- *signid = getdigits(&arg); -- if (!VIM_ISWHITE(*arg) && *arg != NUL) -- { -- *signid = -1; -- arg = arg1; -- } -- else -- arg = skipwhite(arg); -- } -- -- while (*arg != NUL) -- { -- if (STRNCMP(arg, "line=", 5) == 0) -- { -- arg += 5; -- *lnum = atoi((char *)arg); -- arg = skiptowhite(arg); -- } -- else if (STRNCMP(arg, "*", 1) == 0 && cmd == SIGNCMD_UNPLACE) -- { -- if (*signid != -1) -- { -- EMSG(_(e_invarg)); -- return FAIL; -- } -- *signid = -2; -- arg = skiptowhite(arg + 1); -- } -- else if (STRNCMP(arg, "name=", 5) == 0) -- { -- arg += 5; -- name = arg; -- arg = skiptowhite(arg); -- if (*arg != NUL) -- *arg++ = NUL; -- while (name[0] == '0' && name[1] != NUL) -- ++name; -- *sign_name = name; -- } -- else if (STRNCMP(arg, "group=", 6) == 0) -- { -- arg += 6; -- *group = arg; -- arg = skiptowhite(arg); -- if (*arg != NUL) -- *arg++ = NUL; -- } -- else if (STRNCMP(arg, "priority=", 9) == 0) -- { -- arg += 9; -- *prio = atoi((char *)arg); -- arg = skiptowhite(arg); -- } -- else if (STRNCMP(arg, "file=", 5) == 0) -- { -- arg += 5; -- filename = arg; -- *buf = buflist_findname_exp(arg); -- break; -- } -- else if (STRNCMP(arg, "buffer=", 7) == 0) -- { -- arg += 7; -- filename = arg; -- *buf = buflist_findnr((int)getdigits(&arg)); -- if (*skipwhite(arg) != NUL) -- EMSG(_(e_trailing)); -- break; -- } -- else -- { -- EMSG(_(e_invarg)); -- return FAIL; -- } -- arg = skipwhite(arg); -- } -- -- if (filename != NULL && *buf == NULL) -- { -- EMSG2(_("E158: Invalid buffer name: %s"), filename); -- return FAIL; -- } -- -- return OK; -- } -- -- /* -- * ":sign" command -- */ -- void -- ex_sign(exarg_T *eap) -- { -- char_u *arg = eap->arg; -- char_u *p; -- int idx; -- sign_T *sp; -- buf_T *buf = NULL; -- -- // Parse the subcommand. -- p = skiptowhite(arg); -- idx = sign_cmd_idx(arg, p); -- if (idx == SIGNCMD_LAST) -- { -- EMSG2(_("E160: Unknown sign command: %s"), arg); -- return; -- } -- arg = skipwhite(p); -- -- if (idx <= SIGNCMD_LIST) -- { -- // Define, undefine or list signs. -- if (idx == SIGNCMD_LIST && *arg == NUL) -- { -- // ":sign list": list all defined signs -- for (sp = first_sign; sp != NULL && !got_int; sp = sp->sn_next) -- sign_list_defined(sp); -- } -- else if (*arg == NUL) -- EMSG(_("E156: Missing sign name")); -- else -- { -- char_u *name; -- -- // Isolate the sign name. If it's a number skip leading zeroes, -- // so that "099" and "99" are the same sign. But keep "0". -- p = skiptowhite(arg); -- if (*p != NUL) -- *p++ = NUL; -- while (arg[0] == '0' && arg[1] != NUL) -- ++arg; -- name = vim_strsave(arg); -- -- if (idx == SIGNCMD_DEFINE) -- sign_define_cmd(name, p); -- else if (idx == SIGNCMD_LIST) -- // ":sign list {name}" -- sign_list_by_name(name); -- else -- // ":sign undefine {name}" -- sign_undefine_by_name(name); -- -- vim_free(name); -- return; -- } -- } -- else -- { -- int id = -1; -- linenr_T lnum = -1; -- char_u *sign_name = NULL; -- char_u *group = NULL; -- int prio = SIGN_DEF_PRIO; -- -- // Parse command line arguments -- if (parse_sign_cmd_args(idx, arg, &sign_name, &id, &group, &prio, -- &buf, &lnum) == FAIL) -- return; -- -- if (idx == SIGNCMD_PLACE) -- sign_place_cmd(buf, lnum, sign_name, id, group, prio); -- else if (idx == SIGNCMD_UNPLACE) -- sign_unplace_cmd(buf, lnum, sign_name, id, group); -- else if (idx == SIGNCMD_JUMP) -- sign_jump_cmd(buf, lnum, sign_name, id, group); -- } -- } -- -- /* -- * Return information about a specified sign -- */ -- static void -- sign_getinfo(sign_T *sp, dict_T *retdict) -- { -- char_u *p; -- -- dict_add_string(retdict, "name", (char_u *)sp->sn_name); -- if (sp->sn_icon != NULL) -- dict_add_string(retdict, "icon", (char_u *)sp->sn_icon); -- if (sp->sn_text != NULL) -- dict_add_string(retdict, "text", (char_u *)sp->sn_text); -- if (sp->sn_line_hl > 0) -- { -- p = get_highlight_name_ext(NULL, sp->sn_line_hl - 1, FALSE); -- if (p == NULL) -- p = (char_u *)"NONE"; -- dict_add_string(retdict, "linehl", (char_u *)p); -- } -- if (sp->sn_text_hl > 0) -- { -- p = get_highlight_name_ext(NULL, sp->sn_text_hl - 1, FALSE); -- if (p == NULL) -- p = (char_u *)"NONE"; -- dict_add_string(retdict, "texthl", (char_u *)p); -- } -- } -- -- /* -- * If 'name' is NULL, return a list of all the defined signs. -- * Otherwise, return information about the specified sign. -- */ -- void -- sign_getlist(char_u *name, list_T *retlist) -- { -- sign_T *sp = first_sign; -- dict_T *dict; -- -- if (name != NULL) -- { -- sp = sign_find(name, NULL); -- if (sp == NULL) -- return; -- } -- -- for (; sp != NULL && !got_int; sp = sp->sn_next) -- { -- if ((dict = dict_alloc_id(aid_sign_getlist)) == NULL) -- return; -- if (list_append_dict(retlist, dict) == FAIL) -- return; -- sign_getinfo(sp, dict); -- -- if (name != NULL) // handle only the specified sign -- break; -- } -- } -- -- /* -- * Return information about all the signs placed in a buffer -- */ -- static void -- sign_get_placed_in_buf( -- buf_T *buf, -- linenr_T lnum, -- int sign_id, -- char_u *sign_group, -- list_T *retlist) -- { -- dict_T *d; -- list_T *l; -- signlist_T *sign; -- dict_T *sdict; -- -- if ((d = dict_alloc_id(aid_sign_getplaced_dict)) == NULL) -- return; -- list_append_dict(retlist, d); -- -- dict_add_number(d, "bufnr", (long)buf->b_fnum); -- -- if ((l = list_alloc_id(aid_sign_getplaced_list)) == NULL) -- return; -- dict_add_list(d, "signs", l); -- -- FOR_ALL_SIGNS_IN_BUF(buf, sign) -- { -- if (!sign_in_group(sign, sign_group)) -- continue; -- if ((lnum == 0 && sign_id == 0) || -- (sign_id == 0 && lnum == sign->lnum) || -- (lnum == 0 && sign_id == sign->id) || -- (lnum == sign->lnum && sign_id == sign->id)) -- { -- if ((sdict = sign_get_info(sign)) != NULL) -- list_append_dict(l, sdict); -- } -- } -- } -- -- /* -- * Get a list of signs placed in buffer 'buf'. If 'num' is non-zero, return the -- * sign placed at the line number. If 'lnum' is zero, return all the signs -- * placed in 'buf'. If 'buf' is NULL, return signs placed in all the buffers. -- */ -- void -- sign_get_placed( -- buf_T *buf, -- linenr_T lnum, -- int sign_id, -- char_u *sign_group, -- list_T *retlist) -- { -- if (buf != NULL) -- sign_get_placed_in_buf(buf, lnum, sign_id, sign_group, retlist); -- else -- { -- FOR_ALL_BUFFERS(buf) -- { -- if (buf->b_signlist != NULL) -- sign_get_placed_in_buf(buf, 0, sign_id, sign_group, retlist); -- } -- } -- } -- -- # if defined(FEAT_SIGN_ICONS) || defined(PROTO) -- /* -- * Allocate the icons. Called when the GUI has started. Allows defining -- * signs before it starts. -- */ -- void -- sign_gui_started(void) -- { -- sign_T *sp; -- -- for (sp = first_sign; sp != NULL; sp = sp->sn_next) -- if (sp->sn_icon != NULL) -- sp->sn_image = gui_mch_register_sign(sp->sn_icon); -- } -- # endif -- -- /* -- * List one sign. -- */ -- static void -- sign_list_defined(sign_T *sp) -- { -- char_u *p; -- -- smsg((char_u *)"sign %s", sp->sn_name); -- if (sp->sn_icon != NULL) -- { -- MSG_PUTS(" icon="); -- msg_outtrans(sp->sn_icon); -- # ifdef FEAT_SIGN_ICONS -- if (sp->sn_image == NULL) -- MSG_PUTS(_(" (NOT FOUND)")); -- # else -- MSG_PUTS(_(" (not supported)")); -- # endif -- } -- if (sp->sn_text != NULL) -- { -- MSG_PUTS(" text="); -- msg_outtrans(sp->sn_text); -- } -- if (sp->sn_line_hl > 0) -- { -- MSG_PUTS(" linehl="); -- p = get_highlight_name_ext(NULL, sp->sn_line_hl - 1, FALSE); -- if (p == NULL) -- MSG_PUTS("NONE"); -- else -- msg_puts(p); -- } -- if (sp->sn_text_hl > 0) -- { -- MSG_PUTS(" texthl="); -- p = get_highlight_name_ext(NULL, sp->sn_text_hl - 1, FALSE); -- if (p == NULL) -- MSG_PUTS("NONE"); -- else -- msg_puts(p); -- } -- } -- -- /* -- * Undefine a sign and free its memory. -- */ -- static void -- sign_undefine(sign_T *sp, sign_T *sp_prev) -- { -- vim_free(sp->sn_name); -- vim_free(sp->sn_icon); -- # ifdef FEAT_SIGN_ICONS -- if (sp->sn_image != NULL) -- { -- out_flush(); -- gui_mch_destroy_sign(sp->sn_image); -- } -- # endif -- vim_free(sp->sn_text); -- if (sp_prev == NULL) -- first_sign = sp->sn_next; -- else -- sp_prev->sn_next = sp->sn_next; -- vim_free(sp); -- } -- -- /* -- * Get highlighting attribute for sign "typenr". -- * If "line" is TRUE: line highl, if FALSE: text highl. -- */ -- int -- sign_get_attr(int typenr, int line) -- { -- sign_T *sp; -- -- for (sp = first_sign; sp != NULL; sp = sp->sn_next) -- if (sp->sn_typenr == typenr) -- { -- if (line) -- { -- if (sp->sn_line_hl > 0) -- return syn_id2attr(sp->sn_line_hl); -- } -- else -- { -- if (sp->sn_text_hl > 0) -- return syn_id2attr(sp->sn_text_hl); -- } -- break; -- } -- return 0; -- } -- -- /* -- * Get text mark for sign "typenr". -- * Returns NULL if there isn't one. -- */ -- char_u * -- sign_get_text(int typenr) -- { -- sign_T *sp; -- -- for (sp = first_sign; sp != NULL; sp = sp->sn_next) -- if (sp->sn_typenr == typenr) -- return sp->sn_text; -- return NULL; -- } -- -- # if defined(FEAT_SIGN_ICONS) || defined(PROTO) -- void * -- sign_get_image( -- int typenr) /* the attribute which may have a sign */ -- { -- sign_T *sp; -- -- for (sp = first_sign; sp != NULL; sp = sp->sn_next) -- if (sp->sn_typenr == typenr) -- return sp->sn_image; -- return NULL; -- } -- # endif -- -- /* -- * Get the name of a sign by its typenr. -- */ -- char_u * -- sign_typenr2name(int typenr) -- { -- sign_T *sp; -- -- for (sp = first_sign; sp != NULL; sp = sp->sn_next) -- if (sp->sn_typenr == typenr) -- return sp->sn_name; -- return (char_u *)_("[Deleted]"); -- } -- -- /* -- * Undefine/free all signs. -- */ -- void -- free_signs(void) -- { -- while (first_sign != NULL) -- sign_undefine(first_sign, NULL); -- } -- -- # if defined(FEAT_CMDL_COMPL) || defined(PROTO) -- static enum -- { -- EXP_SUBCMD, /* expand :sign sub-commands */ -- EXP_DEFINE, /* expand :sign define {name} args */ -- EXP_PLACE, /* expand :sign place {id} args */ -- EXP_UNPLACE, /* expand :sign unplace" */ -- EXP_SIGN_NAMES /* expand with name of placed signs */ -- } expand_what; -- -- /* -- * Function given to ExpandGeneric() to obtain the sign command -- * expansion. -- */ -- char_u * -- get_sign_name(expand_T *xp UNUSED, int idx) -- { -- sign_T *sp; -- int current_idx; -- -- switch (expand_what) -- { -- case EXP_SUBCMD: -- return (char_u *)cmds[idx]; -- case EXP_DEFINE: -- { -- char *define_arg[] = -- { -- "icon=", "linehl=", "text=", "texthl=", NULL -- }; -- return (char_u *)define_arg[idx]; -- } -- case EXP_PLACE: -- { -- char *place_arg[] = -- { -- "line=", "name=", "group=", "priority=", "file=", -- "buffer=", NULL -- }; -- return (char_u *)place_arg[idx]; -- } -- case EXP_UNPLACE: -- { -- char *unplace_arg[] = { "group=", "file=", "buffer=", NULL }; -- return (char_u *)unplace_arg[idx]; -- } -- case EXP_SIGN_NAMES: -- /* Complete with name of signs already defined */ -- current_idx = 0; -- for (sp = first_sign; sp != NULL; sp = sp->sn_next) -- if (current_idx++ == idx) -- return sp->sn_name; -- return NULL; -- default: -- return NULL; -- } -- } -- -- /* -- * Handle command line completion for :sign command. -- */ -- void -- set_context_in_sign_cmd(expand_T *xp, char_u *arg) -- { -- char_u *p; -- char_u *end_subcmd; -- char_u *last; -- int cmd_idx; -- char_u *begin_subcmd_args; -- -- /* Default: expand subcommands. */ -- xp->xp_context = EXPAND_SIGN; -- expand_what = EXP_SUBCMD; -- xp->xp_pattern = arg; -- -- end_subcmd = skiptowhite(arg); -- if (*end_subcmd == NUL) -- /* expand subcmd name -- * :sign {subcmd}<CTRL-D>*/ -- return; -- -- cmd_idx = sign_cmd_idx(arg, end_subcmd); -- -- /* :sign {subcmd} {subcmd_args} -- * | -- * begin_subcmd_args */ -- begin_subcmd_args = skipwhite(end_subcmd); -- p = skiptowhite(begin_subcmd_args); -- if (*p == NUL) -- { -- /* -- * Expand first argument of subcmd when possible. -- * For ":jump {id}" and ":unplace {id}", we could -- * possibly expand the ids of all signs already placed. -- */ -- xp->xp_pattern = begin_subcmd_args; -- switch (cmd_idx) -- { -- case SIGNCMD_LIST: -- case SIGNCMD_UNDEFINE: -- /* :sign list <CTRL-D> -- * :sign undefine <CTRL-D> */ -- expand_what = EXP_SIGN_NAMES; -- break; -- default: -- xp->xp_context = EXPAND_NOTHING; -- } -- return; -- } -- -- /* expand last argument of subcmd */ -- -- /* :sign define {name} {args}... -- * | -- * p */ -- -- /* Loop until reaching last argument. */ -- do -- { -- p = skipwhite(p); -- last = p; -- p = skiptowhite(p); -- } while (*p != NUL); -- -- p = vim_strchr(last, '='); -- -- /* :sign define {name} {args}... {last}= -- * | | -- * last p */ -- if (p == NULL) -- { -- /* Expand last argument name (before equal sign). */ -- xp->xp_pattern = last; -- switch (cmd_idx) -- { -- case SIGNCMD_DEFINE: -- expand_what = EXP_DEFINE; -- break; -- case SIGNCMD_PLACE: -- expand_what = EXP_PLACE; -- break; -- case SIGNCMD_JUMP: -- case SIGNCMD_UNPLACE: -- expand_what = EXP_UNPLACE; -- break; -- default: -- xp->xp_context = EXPAND_NOTHING; -- } -- } -- else -- { -- /* Expand last argument value (after equal sign). */ -- xp->xp_pattern = p + 1; -- switch (cmd_idx) -- { -- case SIGNCMD_DEFINE: -- if (STRNCMP(last, "texthl", p - last) == 0 || -- STRNCMP(last, "linehl", p - last) == 0) -- xp->xp_context = EXPAND_HIGHLIGHT; -- else if (STRNCMP(last, "icon", p - last) == 0) -- xp->xp_context = EXPAND_FILES; -- else -- xp->xp_context = EXPAND_NOTHING; -- break; -- case SIGNCMD_PLACE: -- if (STRNCMP(last, "name", p - last) == 0) -- expand_what = EXP_SIGN_NAMES; -- else -- xp->xp_context = EXPAND_NOTHING; -- break; -- default: -- xp->xp_context = EXPAND_NOTHING; -- } -- } -- } -- # endif -- #endif -- - /* - * Make the user happy. - */ ---- 7579,7584 ---- -*** ../vim-8.1.0672/src/proto.h 2018-12-13 22:17:52.877941474 +0100 ---- src/proto.h 2019-01-01 12:47:49.517502724 +0100 -*************** -*** 172,177 **** ---- 172,180 ---- - # include "sha256.pro" - # endif - # include "search.pro" -+ # ifdef FEAT_SIGNS -+ # include "sign.pro" -+ # endif - # include "spell.pro" - # include "spellfile.pro" - # include "syntax.pro" -*** ../vim-8.1.0672/src/proto/buffer.pro 2018-12-29 18:53:07.843607433 +0100 ---- src/proto/buffer.pro 2019-01-01 13:07:45.075144726 +0100 -*************** -*** 69,91 **** - void switch_to_win_for_buf(buf_T *buf, win_T **save_curwinp, tabpage_T **save_curtabp, bufref_T *save_curbuf); - void restore_win_for_buf(win_T *save_curwin, tabpage_T *save_curtab, bufref_T *save_curbuf); - int find_win_for_buf(buf_T *buf, win_T **wp, tabpage_T **tp); -- void init_signs(void); -- int sign_group_get_next_signid(buf_T *buf, char_u *groupname); -- int sign_in_group(signlist_T *sign, char_u *group); -- dict_T *sign_get_info(signlist_T *sign); -- void buf_addsign(buf_T *buf, int id, char_u *groupname, int prio, linenr_T lnum, int typenr); -- linenr_T buf_change_sign_type(buf_T *buf, int markId, char_u *group, int typenr); -- int buf_getsigntype(buf_T *buf, linenr_T lnum, int type); -- linenr_T buf_delsign(buf_T *buf, linenr_T atlnum, int id, char_u *group); -- int buf_findsign(buf_T *buf, int id, char_u *group); -- signlist_T *buf_getsign_with_id(buf_T *buf, int id, char_u *group); -- int buf_findsign_id(buf_T *buf, linenr_T lnum, char_u *groupname); -- int buf_findsigntype_id(buf_T *buf, linenr_T lnum, int typenr); -- int buf_signcount(buf_T *buf, linenr_T lnum); -- void buf_delete_signs(buf_T *buf, char_u *group); -- void buf_delete_all_signs(char_u *groupname); -- void sign_list_placed(buf_T *rbuf, char_u *sign_group); -- void sign_mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_after); - void set_buflisted(int on); - int buf_contents_changed(buf_T *buf); - void wipe_buffer(buf_T *buf, int aucmd); ---- 69,74 ---- -*** ../vim-8.1.0672/src/proto/ex_cmds.pro 2018-12-29 18:53:07.843607433 +0100 ---- src/proto/ex_cmds.pro 2019-01-01 12:47:49.517502724 +0100 -*************** -*** 54,74 **** - void ex_exusage(exarg_T *eap); - void ex_viusage(exarg_T *eap); - void ex_helptags(exarg_T *eap); -- int sign_define_by_name(char_u *name, char_u *icon, char_u *linehl, char_u *text, char_u *texthl); -- int sign_undefine_by_name(char_u *name); -- int sign_place(int *sign_id, char_u *sign_group, char_u *sign_name, buf_T *buf, linenr_T lnum, int prio); -- int sign_unplace(int sign_id, char_u *sign_group, buf_T *buf, linenr_T atlnum); -- void ex_sign(exarg_T *eap); -- void sign_getlist(char_u *name, list_T *retlist); -- void sign_get_placed(buf_T *buf, linenr_T lnum, int sign_id, char_u *sign_group, list_T *retlist); -- void sign_gui_started(void); -- int sign_get_attr(int typenr, int line); -- char_u *sign_get_text(int typenr); -- void *sign_get_image(int typenr); -- char_u *sign_typenr2name(int typenr); -- void free_signs(void); -- char_u *get_sign_name(expand_T *xp, int idx); -- void set_context_in_sign_cmd(expand_T *xp, char_u *arg); - void ex_smile(exarg_T *eap); - void ex_drop(exarg_T *eap); - char_u *skip_vimgrep_pat(char_u *p, char_u **s, int *flags); ---- 54,59 ---- -*** ../vim-8.1.0672/src/proto/sign.pro 2019-01-01 13:18:57.745301984 +0100 ---- src/proto/sign.pro 2019-01-01 12:47:49.517502724 +0100 -*************** -*** 0 **** ---- 1,25 ---- -+ /* sign.c */ -+ void init_signs(void); -+ int buf_getsigntype(buf_T *buf, linenr_T lnum, int type); -+ linenr_T buf_delsign(buf_T *buf, linenr_T atlnum, int id, char_u *group); -+ int buf_findsign(buf_T *buf, int id, char_u *group); -+ int buf_findsign_id(buf_T *buf, linenr_T lnum, char_u *groupname); -+ int buf_findsigntype_id(buf_T *buf, linenr_T lnum, int typenr); -+ int buf_signcount(buf_T *buf, linenr_T lnum); -+ void buf_delete_signs(buf_T *buf, char_u *group); -+ void sign_mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_after); -+ int sign_define_by_name(char_u *name, char_u *icon, char_u *linehl, char_u *text, char_u *texthl); -+ int sign_undefine_by_name(char_u *name); -+ int sign_place(int *sign_id, char_u *sign_group, char_u *sign_name, buf_T *buf, linenr_T lnum, int prio); -+ int sign_unplace(int sign_id, char_u *sign_group, buf_T *buf, linenr_T atlnum); -+ void ex_sign(exarg_T *eap); -+ void sign_getlist(char_u *name, list_T *retlist); -+ void get_buffer_signs(buf_T *buf, list_T *l); -+ void sign_get_placed(buf_T *buf, linenr_T lnum, int sign_id, char_u *sign_group, list_T *retlist); -+ void sign_gui_started(void); -+ int sign_get_attr(int typenr, int line); -+ char_u *sign_get_text(int typenr); -+ void *sign_get_image(int typenr); -+ void free_signs(void); -+ char_u *get_sign_name(expand_T *xp, int idx); -+ void set_context_in_sign_cmd(expand_T *xp, char_u *arg); -*** ../vim-8.1.0672/src/sign.c 2019-01-01 13:18:57.749301949 +0100 ---- src/sign.c 2019-01-01 12:47:49.517502724 +0100 -*************** -*** 0 **** ---- 1,1880 ---- -+ /* vi:set ts=8 sts=4 sw=4 noet: -+ * -+ * VIM - Vi IMproved by Bram Moolenaar -+ * -+ * Do ":help uganda" in Vim to read copying and usage conditions. -+ * Do ":help credits" in Vim to see a list of people who contributed. -+ * See README.txt for an overview of the Vim source code. -+ */ -+ -+ /* -+ * sign.c: functions for managing signs -+ */ -+ -+ #include "vim.h" -+ -+ #if defined(FEAT_SIGNS) || defined(PROTO) -+ -+ /* -+ * Struct to hold the sign properties. -+ */ -+ typedef struct sign sign_T; -+ -+ struct sign -+ { -+ sign_T *sn_next; /* next sign in list */ -+ int sn_typenr; /* type number of sign */ -+ char_u *sn_name; /* name of sign */ -+ char_u *sn_icon; /* name of pixmap */ -+ # ifdef FEAT_SIGN_ICONS -+ void *sn_image; /* icon image */ -+ # endif -+ char_u *sn_text; /* text used instead of pixmap */ -+ int sn_line_hl; /* highlight ID for line */ -+ int sn_text_hl; /* highlight ID for text */ -+ }; -+ -+ static sign_T *first_sign = NULL; -+ static int next_sign_typenr = 1; -+ -+ static void sign_list_defined(sign_T *sp); -+ static void sign_undefine(sign_T *sp, sign_T *sp_prev); -+ -+ static char *cmds[] = { -+ "define", -+ # define SIGNCMD_DEFINE 0 -+ "undefine", -+ # define SIGNCMD_UNDEFINE 1 -+ "list", -+ # define SIGNCMD_LIST 2 -+ "place", -+ # define SIGNCMD_PLACE 3 -+ "unplace", -+ # define SIGNCMD_UNPLACE 4 -+ "jump", -+ # define SIGNCMD_JUMP 5 -+ NULL -+ # define SIGNCMD_LAST 6 -+ }; -+ -+ static hashtab_T sg_table; // sign group (signgroup_T) hashtable -+ static int next_sign_id = 1; // next sign id in the global group -+ -+ /* -+ * Initialize data needed for managing signs -+ */ -+ void -+ init_signs(void) -+ { -+ hash_init(&sg_table); // sign group hash table -+ } -+ -+ /* -+ * A new sign in group 'groupname' is added. If the group is not present, -+ * create it. Otherwise reference the group. -+ */ -+ static signgroup_T * -+ sign_group_ref(char_u *groupname) -+ { -+ hash_T hash; -+ hashitem_T *hi; -+ signgroup_T *group; -+ -+ hash = hash_hash(groupname); -+ hi = hash_lookup(&sg_table, groupname, hash); -+ if (HASHITEM_EMPTY(hi)) -+ { -+ // new group -+ group = (signgroup_T *)alloc( -+ (unsigned)(sizeof(signgroup_T) + STRLEN(groupname))); -+ if (group == NULL) -+ return NULL; -+ STRCPY(group->sg_name, groupname); -+ group->refcount = 1; -+ group->next_sign_id = 1; -+ hash_add_item(&sg_table, hi, group->sg_name, hash); -+ } -+ else -+ { -+ // existing group -+ group = HI2SG(hi); -+ group->refcount++; -+ } -+ -+ return group; -+ } -+ -+ /* -+ * A sign in group 'groupname' is removed. If all the signs in this group are -+ * removed, then remove the group. -+ */ -+ static void -+ sign_group_unref(char_u *groupname) -+ { -+ hashitem_T *hi; -+ signgroup_T *group; -+ -+ hi = hash_find(&sg_table, groupname); -+ if (!HASHITEM_EMPTY(hi)) -+ { -+ group = HI2SG(hi); -+ group->refcount--; -+ if (group->refcount == 0) -+ { -+ // All the signs in this group are removed -+ hash_remove(&sg_table, hi); -+ vim_free(group); -+ } -+ } -+ } -+ -+ /* -+ * Returns TRUE if 'sign' is in 'group'. -+ * A sign can either be in the global group (sign->group == NULL) -+ * or in a named group. If 'group' is '*', then the sign is part of the group. -+ */ -+ static int -+ sign_in_group(signlist_T *sign, char_u *group) -+ { -+ return ((group != NULL && STRCMP(group, "*") == 0) -+ || (group == NULL && sign->group == NULL) -+ || (group != NULL && sign->group != NULL -+ && STRCMP(group, sign->group->sg_name) == 0)); -+ } -+ -+ /* -+ * Get the next free sign identifier in the specified group -+ */ -+ static int -+ sign_group_get_next_signid(buf_T *buf, char_u *groupname) -+ { -+ int id = 1; -+ signgroup_T *group = NULL; -+ signlist_T *sign; -+ hashitem_T *hi; -+ int found = FALSE; -+ -+ if (groupname != NULL) -+ { -+ hi = hash_find(&sg_table, groupname); -+ if (HASHITEM_EMPTY(hi)) -+ return id; -+ group = HI2SG(hi); -+ } -+ -+ // Search for the next usuable sign identifier -+ while (!found) -+ { -+ if (group == NULL) -+ id = next_sign_id++; // global group -+ else -+ id = group->next_sign_id++; -+ -+ // Check whether this sign is already placed in the buffer -+ found = TRUE; -+ FOR_ALL_SIGNS_IN_BUF(buf, sign) -+ { -+ if (id == sign->id && sign_in_group(sign, groupname)) -+ { -+ found = FALSE; // sign identifier is in use -+ break; -+ } -+ } -+ } -+ -+ return id; -+ } -+ -+ /* -+ * Insert a new sign into the signlist for buffer 'buf' between the 'prev' and -+ * 'next' signs. -+ */ -+ static void -+ insert_sign( -+ buf_T *buf, // buffer to store sign in -+ signlist_T *prev, // previous sign entry -+ signlist_T *next, // next sign entry -+ int id, // sign ID -+ char_u *group, // sign group; NULL for global group -+ int prio, // sign priority -+ linenr_T lnum, // line number which gets the mark -+ int typenr) // typenr of sign we are adding -+ { -+ signlist_T *newsign; -+ -+ newsign = (signlist_T *)lalloc_id((long_u)sizeof(signlist_T), FALSE, -+ aid_insert_sign); -+ if (newsign != NULL) -+ { -+ newsign->id = id; -+ newsign->lnum = lnum; -+ newsign->typenr = typenr; -+ if (group != NULL) -+ { -+ newsign->group = sign_group_ref(group); -+ if (newsign->group == NULL) -+ { -+ vim_free(newsign); -+ return; -+ } -+ } -+ else -+ newsign->group = NULL; -+ newsign->priority = prio; -+ newsign->next = next; -+ newsign->prev = prev; -+ if (next != NULL) -+ next->prev = newsign; -+ -+ if (prev == NULL) -+ { -+ // When adding first sign need to redraw the windows to create the -+ // column for signs. -+ if (buf->b_signlist == NULL) -+ { -+ redraw_buf_later(buf, NOT_VALID); -+ changed_cline_bef_curs(); -+ } -+ -+ // first sign in signlist -+ buf->b_signlist = newsign; -+ #ifdef FEAT_NETBEANS_INTG -+ if (netbeans_active()) -+ buf->b_has_sign_column = TRUE; -+ #endif -+ } -+ else -+ prev->next = newsign; -+ } -+ } -+ -+ /* -+ * Insert a new sign sorted by line number and sign priority. -+ */ -+ static void -+ insert_sign_by_lnum_prio( -+ buf_T *buf, // buffer to store sign in -+ signlist_T *prev, // previous sign entry -+ int id, // sign ID -+ char_u *group, // sign group; NULL for global group -+ int prio, // sign priority -+ linenr_T lnum, // line number which gets the mark -+ int typenr) // typenr of sign we are adding -+ { -+ signlist_T *sign; -+ -+ // keep signs sorted by lnum and by priority: insert new sign at -+ // the proper position in the list for this lnum. -+ while (prev != NULL && prev->lnum == lnum && prev->priority <= prio) -+ prev = prev->prev; -+ if (prev == NULL) -+ sign = buf->b_signlist; -+ else -+ sign = prev->next; -+ -+ insert_sign(buf, prev, sign, id, group, prio, lnum, typenr); -+ } -+ -+ /* -+ * Get the name of a sign by its typenr. -+ */ -+ static char_u * -+ sign_typenr2name(int typenr) -+ { -+ sign_T *sp; -+ -+ for (sp = first_sign; sp != NULL; sp = sp->sn_next) -+ if (sp->sn_typenr == typenr) -+ return sp->sn_name; -+ return (char_u *)_("[Deleted]"); -+ } -+ -+ /* -+ * Return information about a sign in a Dict -+ */ -+ static dict_T * -+ sign_get_info(signlist_T *sign) -+ { -+ dict_T *d; -+ -+ if ((d = dict_alloc_id(aid_sign_getinfo)) == NULL) -+ return NULL; -+ dict_add_number(d, "id", sign->id); -+ dict_add_string(d, "group", (sign->group == NULL) ? -+ (char_u *)"" : sign->group->sg_name); -+ dict_add_number(d, "lnum", sign->lnum); -+ dict_add_string(d, "name", sign_typenr2name(sign->typenr)); -+ dict_add_number(d, "priority", sign->priority); -+ -+ return d; -+ } -+ -+ /* -+ * Add the sign into the signlist. Find the right spot to do it though. -+ */ -+ static void -+ buf_addsign( -+ buf_T *buf, // buffer to store sign in -+ int id, // sign ID -+ char_u *groupname, // sign group -+ int prio, // sign priority -+ linenr_T lnum, // line number which gets the mark -+ int typenr) // typenr of sign we are adding -+ { -+ signlist_T *sign; // a sign in the signlist -+ signlist_T *prev; // the previous sign -+ -+ prev = NULL; -+ FOR_ALL_SIGNS_IN_BUF(buf, sign) -+ { -+ if (lnum == sign->lnum && id == sign->id && -+ sign_in_group(sign, groupname)) -+ { -+ // Update an existing sign -+ sign->typenr = typenr; -+ return; -+ } -+ else if (lnum < sign->lnum) -+ { -+ insert_sign_by_lnum_prio(buf, prev, id, groupname, prio, -+ lnum, typenr); -+ return; -+ } -+ prev = sign; -+ } -+ -+ insert_sign_by_lnum_prio(buf, prev, id, groupname, prio, lnum, typenr); -+ return; -+ } -+ -+ /* -+ * For an existing, placed sign "markId" change the type to "typenr". -+ * Returns the line number of the sign, or zero if the sign is not found. -+ */ -+ static linenr_T -+ buf_change_sign_type( -+ buf_T *buf, // buffer to store sign in -+ int markId, // sign ID -+ char_u *group, // sign group -+ int typenr) // typenr of sign we are adding -+ { -+ signlist_T *sign; // a sign in the signlist -+ -+ FOR_ALL_SIGNS_IN_BUF(buf, sign) -+ { -+ if (sign->id == markId && sign_in_group(sign, group)) -+ { -+ sign->typenr = typenr; -+ return sign->lnum; -+ } -+ } -+ -+ return (linenr_T)0; -+ } -+ -+ /* -+ * Return the type number of the sign at line number 'lnum' in buffer 'buf' -+ * which has the attribute specifed by 'type'. Returns 0 if a sign is not found -+ * at the line number or it doesn't have the specified attribute. -+ */ -+ int -+ buf_getsigntype( -+ buf_T *buf, -+ linenr_T lnum, -+ int type) /* SIGN_ICON, SIGN_TEXT, SIGN_ANY, SIGN_LINEHL */ -+ { -+ signlist_T *sign; /* a sign in a b_signlist */ -+ -+ FOR_ALL_SIGNS_IN_BUF(buf, sign) -+ if (sign->lnum == lnum -+ && (type == SIGN_ANY -+ # ifdef FEAT_SIGN_ICONS -+ || (type == SIGN_ICON -+ && sign_get_image(sign->typenr) != NULL) -+ # endif -+ || (type == SIGN_TEXT -+ && sign_get_text(sign->typenr) != NULL) -+ || (type == SIGN_LINEHL -+ && sign_get_attr(sign->typenr, TRUE) != 0))) -+ return sign->typenr; -+ return 0; -+ } -+ -+ /* -+ * Delete sign 'id' in group 'group' from buffer 'buf'. -+ * If 'id' is zero, then delete all the signs in group 'group'. Otherwise -+ * delete only the specified sign. -+ * If 'group' is '*', then delete the sign in all the groups. If 'group' is -+ * NULL, then delete the sign in the global group. Otherwise delete the sign in -+ * the specified group. -+ * Returns the line number of the deleted sign. If multiple signs are deleted, -+ * then returns the line number of the last sign deleted. -+ */ -+ linenr_T -+ buf_delsign( -+ buf_T *buf, // buffer sign is stored in -+ linenr_T atlnum, // sign at this line, 0 - at any line -+ int id, // sign id -+ char_u *group) // sign group -+ { -+ signlist_T **lastp; // pointer to pointer to current sign -+ signlist_T *sign; // a sign in a b_signlist -+ signlist_T *next; // the next sign in a b_signlist -+ linenr_T lnum; // line number whose sign was deleted -+ -+ lastp = &buf->b_signlist; -+ lnum = 0; -+ for (sign = buf->b_signlist; sign != NULL; sign = next) -+ { -+ next = sign->next; -+ if ((id == 0 || sign->id == id) && -+ (atlnum == 0 || sign->lnum == atlnum) && -+ sign_in_group(sign, group)) -+ -+ { -+ *lastp = next; -+ if (next != NULL) -+ next->prev = sign->prev; -+ lnum = sign->lnum; -+ if (sign->group != NULL) -+ sign_group_unref(sign->group->sg_name); -+ vim_free(sign); -+ update_debug_sign(buf, lnum); -+ // Check whether only one sign needs to be deleted -+ // If deleting a sign with a specific identifer in a particular -+ // group or deleting any sign at a particular line number, delete -+ // only one sign. -+ if (group == NULL -+ || (*group != '*' && id != 0) -+ || (*group == '*' && atlnum != 0)) -+ break; -+ } -+ else -+ lastp = &sign->next; -+ } -+ -+ // When deleted the last sign need to redraw the windows to remove the -+ // sign column. -+ if (buf->b_signlist == NULL) -+ { -+ redraw_buf_later(buf, NOT_VALID); -+ changed_cline_bef_curs(); -+ } -+ -+ return lnum; -+ } -+ -+ -+ /* -+ * Find the line number of the sign with the requested id in group 'group'. If -+ * the sign does not exist, return 0 as the line number. This will still let -+ * the correct file get loaded. -+ */ -+ int -+ buf_findsign( -+ buf_T *buf, // buffer to store sign in -+ int id, // sign ID -+ char_u *group) // sign group -+ { -+ signlist_T *sign; // a sign in the signlist -+ -+ FOR_ALL_SIGNS_IN_BUF(buf, sign) -+ if (sign->id == id && sign_in_group(sign, group)) -+ return sign->lnum; -+ -+ return 0; -+ } -+ -+ /* -+ * Return the sign at line 'lnum' in buffer 'buf'. Returns NULL if a sign is -+ * not found at the line. If 'groupname' is NULL, searches in the global group. -+ */ -+ static signlist_T * -+ buf_getsign_at_line( -+ buf_T *buf, // buffer whose sign we are searching for -+ linenr_T lnum, // line number of sign -+ char_u *groupname) // sign group name -+ { -+ signlist_T *sign; // a sign in the signlist -+ -+ FOR_ALL_SIGNS_IN_BUF(buf, sign) -+ if (sign->lnum == lnum && sign_in_group(sign, groupname)) -+ return sign; -+ -+ return NULL; -+ } -+ -+ /* -+ * Return the identifier of the sign at line number 'lnum' in buffer 'buf'. -+ */ -+ int -+ buf_findsign_id( -+ buf_T *buf, // buffer whose sign we are searching for -+ linenr_T lnum, // line number of sign -+ char_u *groupname) // sign group name -+ { -+ signlist_T *sign; // a sign in the signlist -+ -+ sign = buf_getsign_at_line(buf, lnum, groupname); -+ if (sign != NULL) -+ return sign->id; -+ -+ return 0; -+ } -+ -+ # if defined(FEAT_NETBEANS_INTG) || defined(PROTO) -+ /* -+ * See if a given type of sign exists on a specific line. -+ */ -+ int -+ buf_findsigntype_id( -+ buf_T *buf, /* buffer whose sign we are searching for */ -+ linenr_T lnum, /* line number of sign */ -+ int typenr) /* sign type number */ -+ { -+ signlist_T *sign; /* a sign in the signlist */ -+ -+ FOR_ALL_SIGNS_IN_BUF(buf, sign) -+ if (sign->lnum == lnum && sign->typenr == typenr) -+ return sign->id; -+ -+ return 0; -+ } -+ -+ -+ # if defined(FEAT_SIGN_ICONS) || defined(PROTO) -+ /* -+ * Return the number of icons on the given line. -+ */ -+ int -+ buf_signcount(buf_T *buf, linenr_T lnum) -+ { -+ signlist_T *sign; // a sign in the signlist -+ int count = 0; -+ -+ FOR_ALL_SIGNS_IN_BUF(buf, sign) -+ if (sign->lnum == lnum) -+ if (sign_get_image(sign->typenr) != NULL) -+ count++; -+ -+ return count; -+ } -+ # endif /* FEAT_SIGN_ICONS */ -+ # endif /* FEAT_NETBEANS_INTG */ -+ -+ /* -+ * Delete signs in group 'group' in buffer "buf". If 'group' is '*', then -+ * delete all the signs. -+ */ -+ void -+ buf_delete_signs(buf_T *buf, char_u *group) -+ { -+ signlist_T *sign; -+ signlist_T **lastp; // pointer to pointer to current sign -+ signlist_T *next; -+ -+ // When deleting the last sign need to redraw the windows to remove the -+ // sign column. Not when curwin is NULL (this means we're exiting). -+ if (buf->b_signlist != NULL && curwin != NULL) -+ { -+ redraw_buf_later(buf, NOT_VALID); -+ changed_cline_bef_curs(); -+ } -+ -+ lastp = &buf->b_signlist; -+ for (sign = buf->b_signlist; sign != NULL; sign = next) -+ { -+ next = sign->next; -+ if (sign_in_group(sign, group)) -+ { -+ *lastp = next; -+ if (next != NULL) -+ next->prev = sign->prev; -+ if (sign->group != NULL) -+ sign_group_unref(sign->group->sg_name); -+ vim_free(sign); -+ } -+ else -+ lastp = &sign->next; -+ } -+ } -+ -+ /* -+ * List placed signs for "rbuf". If "rbuf" is NULL do it for all buffers. -+ */ -+ static void -+ sign_list_placed(buf_T *rbuf, char_u *sign_group) -+ { -+ buf_T *buf; -+ signlist_T *sign; -+ char lbuf[BUFSIZ]; -+ char group[BUFSIZ]; -+ -+ MSG_PUTS_TITLE(_("\n--- Signs ---")); -+ msg_putchar('\n'); -+ if (rbuf == NULL) -+ buf = firstbuf; -+ else -+ buf = rbuf; -+ while (buf != NULL && !got_int) -+ { -+ if (buf->b_signlist != NULL) -+ { -+ vim_snprintf(lbuf, BUFSIZ, _("Signs for %s:"), buf->b_fname); -+ MSG_PUTS_ATTR(lbuf, HL_ATTR(HLF_D)); -+ msg_putchar('\n'); -+ } -+ FOR_ALL_SIGNS_IN_BUF(buf, sign) -+ { -+ if (got_int) -+ break; -+ if (!sign_in_group(sign, sign_group)) -+ continue; -+ if (sign->group != NULL) -+ vim_snprintf(group, BUFSIZ, " group=%s", -+ sign->group->sg_name); -+ else -+ group[0] = '\0'; -+ vim_snprintf(lbuf, BUFSIZ, _(" line=%ld id=%d%s name=%s " -+ "priority=%d"), -+ (long)sign->lnum, sign->id, group, -+ sign_typenr2name(sign->typenr), sign->priority); -+ MSG_PUTS(lbuf); -+ msg_putchar('\n'); -+ } -+ if (rbuf != NULL) -+ break; -+ buf = buf->b_next; -+ } -+ } -+ -+ /* -+ * Adjust a placed sign for inserted/deleted lines. -+ */ -+ void -+ sign_mark_adjust( -+ linenr_T line1, -+ linenr_T line2, -+ long amount, -+ long amount_after) -+ { -+ signlist_T *sign; /* a sign in a b_signlist */ -+ -+ FOR_ALL_SIGNS_IN_BUF(curbuf, sign) -+ { -+ if (sign->lnum >= line1 && sign->lnum <= line2) -+ { -+ if (amount == MAXLNUM) -+ sign->lnum = line1; -+ else -+ sign->lnum += amount; -+ } -+ else if (sign->lnum > line2) -+ sign->lnum += amount_after; -+ } -+ } -+ -+ /* -+ * Find index of a ":sign" subcmd from its name. -+ * "*end_cmd" must be writable. -+ */ -+ static int -+ sign_cmd_idx( -+ char_u *begin_cmd, /* begin of sign subcmd */ -+ char_u *end_cmd) /* just after sign subcmd */ -+ { -+ int idx; -+ char save = *end_cmd; -+ -+ *end_cmd = NUL; -+ for (idx = 0; ; ++idx) -+ if (cmds[idx] == NULL || STRCMP(begin_cmd, cmds[idx]) == 0) -+ break; -+ *end_cmd = save; -+ return idx; -+ } -+ -+ /* -+ * Find a sign by name. Also returns pointer to the previous sign. -+ */ -+ static sign_T * -+ sign_find(char_u *name, sign_T **sp_prev) -+ { -+ sign_T *sp; -+ -+ if (sp_prev != NULL) -+ *sp_prev = NULL; -+ for (sp = first_sign; sp != NULL; sp = sp->sn_next) -+ { -+ if (STRCMP(sp->sn_name, name) == 0) -+ break; -+ if (sp_prev != NULL) -+ *sp_prev = sp; -+ } -+ -+ return sp; -+ } -+ -+ /* -+ * Define a new sign or update an existing sign -+ */ -+ int -+ sign_define_by_name( -+ char_u *name, -+ char_u *icon, -+ char_u *linehl, -+ char_u *text, -+ char_u *texthl) -+ { -+ sign_T *sp_prev; -+ sign_T *sp; -+ -+ sp = sign_find(name, &sp_prev); -+ if (sp == NULL) -+ { -+ sign_T *lp; -+ int start = next_sign_typenr; -+ -+ // Allocate a new sign. -+ sp = (sign_T *)alloc_clear_id((unsigned)sizeof(sign_T), -+ aid_sign_define_by_name); -+ if (sp == NULL) -+ return FAIL; -+ -+ // Check that next_sign_typenr is not already being used. -+ // This only happens after wrapping around. Hopefully -+ // another one got deleted and we can use its number. -+ for (lp = first_sign; lp != NULL; ) -+ { -+ if (lp->sn_typenr == next_sign_typenr) -+ { -+ ++next_sign_typenr; -+ if (next_sign_typenr == MAX_TYPENR) -+ next_sign_typenr = 1; -+ if (next_sign_typenr == start) -+ { -+ vim_free(sp); -+ EMSG(_("E612: Too many signs defined")); -+ return FAIL; -+ } -+ lp = first_sign; // start all over -+ continue; -+ } -+ lp = lp->sn_next; -+ } -+ -+ sp->sn_typenr = next_sign_typenr; -+ if (++next_sign_typenr == MAX_TYPENR) -+ next_sign_typenr = 1; // wrap around -+ -+ sp->sn_name = vim_strsave(name); -+ if (sp->sn_name == NULL) // out of memory -+ { -+ vim_free(sp); -+ return FAIL; -+ } -+ -+ // add the new sign to the list of signs -+ if (sp_prev == NULL) -+ first_sign = sp; -+ else -+ sp_prev->sn_next = sp; -+ } -+ -+ // set values for a defined sign. -+ if (icon != NULL) -+ { -+ vim_free(sp->sn_icon); -+ sp->sn_icon = vim_strsave(icon); -+ backslash_halve(sp->sn_icon); -+ # ifdef FEAT_SIGN_ICONS -+ if (gui.in_use) -+ { -+ out_flush(); -+ if (sp->sn_image != NULL) -+ gui_mch_destroy_sign(sp->sn_image); -+ sp->sn_image = gui_mch_register_sign(sp->sn_icon); -+ } -+ # endif -+ } -+ -+ if (text != NULL) -+ { -+ char_u *s; -+ char_u *endp; -+ int cells; -+ int len; -+ -+ endp = text + (int)STRLEN(text); -+ for (s = text; s + 1 < endp; ++s) -+ if (*s == '\\') -+ { -+ // Remove a backslash, so that it is possible -+ // to use a space. -+ STRMOVE(s, s + 1); -+ --endp; -+ } -+ # ifdef FEAT_MBYTE -+ // Count cells and check for non-printable chars -+ if (has_mbyte) -+ { -+ cells = 0; -+ for (s = text; s < endp; s += (*mb_ptr2len)(s)) -+ { -+ if (!vim_isprintc((*mb_ptr2char)(s))) -+ break; -+ cells += (*mb_ptr2cells)(s); -+ } -+ } -+ else -+ # endif -+ { -+ for (s = text; s < endp; ++s) -+ if (!vim_isprintc(*s)) -+ break; -+ cells = (int)(s - text); -+ } -+ // Currently must be one or two display cells -+ if (s != endp || cells < 1 || cells > 2) -+ { -+ EMSG2(_("E239: Invalid sign text: %s"), text); -+ return FAIL; -+ } -+ -+ vim_free(sp->sn_text); -+ // Allocate one byte more if we need to pad up -+ // with a space. -+ len = (int)(endp - text + ((cells == 1) ? 1 : 0)); -+ sp->sn_text = vim_strnsave(text, len); -+ -+ if (sp->sn_text != NULL && cells == 1) -+ STRCPY(sp->sn_text + len - 1, " "); -+ } -+ -+ if (linehl != NULL) -+ sp->sn_line_hl = syn_check_group(linehl, (int)STRLEN(linehl)); -+ -+ if (texthl != NULL) -+ sp->sn_text_hl = syn_check_group(texthl, (int)STRLEN(texthl)); -+ -+ return OK; -+ } -+ -+ /* -+ * Free the sign specified by 'name'. -+ */ -+ int -+ sign_undefine_by_name(char_u *name) -+ { -+ sign_T *sp_prev; -+ sign_T *sp; -+ -+ sp = sign_find(name, &sp_prev); -+ if (sp == NULL) -+ { -+ EMSG2(_("E155: Unknown sign: %s"), name); -+ return FAIL; -+ } -+ sign_undefine(sp, sp_prev); -+ -+ return OK; -+ } -+ -+ /* -+ * List the signs matching 'name' -+ */ -+ static void -+ sign_list_by_name(char_u *name) -+ { -+ sign_T *sp; -+ -+ sp = sign_find(name, NULL); -+ if (sp != NULL) -+ sign_list_defined(sp); -+ else -+ EMSG2(_("E155: Unknown sign: %s"), name); -+ } -+ -+ /* -+ * Place a sign at the specifed file location or update a sign. -+ */ -+ int -+ sign_place( -+ int *sign_id, -+ char_u *sign_group, -+ char_u *sign_name, -+ buf_T *buf, -+ linenr_T lnum, -+ int prio) -+ { -+ sign_T *sp; -+ -+ // Check for reserved character '*' in group name -+ if (sign_group != NULL && (*sign_group == '*' || *sign_group == '\0')) -+ return FAIL; -+ -+ for (sp = first_sign; sp != NULL; sp = sp->sn_next) -+ if (STRCMP(sp->sn_name, sign_name) == 0) -+ break; -+ if (sp == NULL) -+ { -+ EMSG2(_("E155: Unknown sign: %s"), sign_name); -+ return FAIL; -+ } -+ if (*sign_id == 0) -+ *sign_id = sign_group_get_next_signid(buf, sign_group); -+ -+ if (lnum > 0) -+ // ":sign place {id} line={lnum} name={name} file={fname}": -+ // place a sign -+ buf_addsign(buf, *sign_id, sign_group, prio, lnum, sp->sn_typenr); -+ else -+ // ":sign place {id} file={fname}": change sign type -+ lnum = buf_change_sign_type(buf, *sign_id, sign_group, sp->sn_typenr); -+ if (lnum > 0) -+ update_debug_sign(buf, lnum); -+ else -+ { -+ EMSG2(_("E885: Not possible to change sign %s"), sign_name); -+ return FAIL; -+ } -+ -+ return OK; -+ } -+ -+ /* -+ * Unplace the specified sign -+ */ -+ int -+ sign_unplace(int sign_id, char_u *sign_group, buf_T *buf, linenr_T atlnum) -+ { -+ if (buf->b_signlist == NULL) // No signs in the buffer -+ return OK; -+ -+ if (sign_id == 0) -+ { -+ // Delete all the signs in the specified buffer -+ redraw_buf_later(buf, NOT_VALID); -+ buf_delete_signs(buf, sign_group); -+ } -+ else -+ { -+ linenr_T lnum; -+ -+ // Delete only the specified signs -+ lnum = buf_delsign(buf, atlnum, sign_id, sign_group); -+ if (lnum == 0) -+ return FAIL; -+ } -+ -+ return OK; -+ } -+ -+ /* -+ * Unplace the sign at the current cursor line. -+ */ -+ static void -+ sign_unplace_at_cursor(char_u *groupname) -+ { -+ int id = -1; -+ -+ id = buf_findsign_id(curwin->w_buffer, curwin->w_cursor.lnum, groupname); -+ if (id > 0) -+ sign_unplace(id, groupname, curwin->w_buffer, curwin->w_cursor.lnum); -+ else -+ EMSG(_("E159: Missing sign number")); -+ } -+ -+ /* -+ * sign define command -+ * ":sign define {name} ..." -+ */ -+ static void -+ sign_define_cmd(char_u *sign_name, char_u *cmdline) -+ { -+ char_u *arg; -+ char_u *p = cmdline; -+ char_u *icon = NULL; -+ char_u *text = NULL; -+ char_u *linehl = NULL; -+ char_u *texthl = NULL; -+ int failed = FALSE; -+ -+ // set values for a defined sign. -+ for (;;) -+ { -+ arg = skipwhite(p); -+ if (*arg == NUL) -+ break; -+ p = skiptowhite_esc(arg); -+ if (STRNCMP(arg, "icon=", 5) == 0) -+ { -+ arg += 5; -+ icon = vim_strnsave(arg, (int)(p - arg)); -+ } -+ else if (STRNCMP(arg, "text=", 5) == 0) -+ { -+ arg += 5; -+ text = vim_strnsave(arg, (int)(p - arg)); -+ } -+ else if (STRNCMP(arg, "linehl=", 7) == 0) -+ { -+ arg += 7; -+ linehl = vim_strnsave(arg, (int)(p - arg)); -+ } -+ else if (STRNCMP(arg, "texthl=", 7) == 0) -+ { -+ arg += 7; -+ texthl = vim_strnsave(arg, (int)(p - arg)); -+ } -+ else -+ { -+ EMSG2(_(e_invarg2), arg); -+ failed = TRUE; -+ break; -+ } -+ } -+ -+ if (!failed) -+ sign_define_by_name(sign_name, icon, linehl, text, texthl); -+ -+ vim_free(icon); -+ vim_free(text); -+ vim_free(linehl); -+ vim_free(texthl); -+ } -+ -+ /* -+ * :sign place command -+ */ -+ static void -+ sign_place_cmd( -+ buf_T *buf, -+ linenr_T lnum, -+ char_u *sign_name, -+ int id, -+ char_u *group, -+ int prio) -+ { -+ if (id <= 0) -+ { -+ // List signs placed in a file/buffer -+ // :sign place file={fname} -+ // :sign place group={group} file={fname} -+ // :sign place group=* file={fname} -+ // :sign place buffer={nr} -+ // :sign place group={group} buffer={nr} -+ // :sign place group=* buffer={nr} -+ // :sign place -+ // :sign place group={group} -+ // :sign place group=* -+ if (lnum >= 0 || sign_name != NULL || -+ (group != NULL && *group == '\0')) -+ EMSG(_(e_invarg)); -+ else -+ sign_list_placed(buf, group); -+ } -+ else -+ { -+ // Place a new sign -+ if (sign_name == NULL || buf == NULL || -+ (group != NULL && *group == '\0')) -+ { -+ EMSG(_(e_invarg)); -+ return; -+ } -+ -+ sign_place(&id, group, sign_name, buf, lnum, prio); -+ } -+ } -+ -+ /* -+ * :sign unplace command -+ */ -+ static void -+ sign_unplace_cmd( -+ buf_T *buf, -+ linenr_T lnum, -+ char_u *sign_name, -+ int id, -+ char_u *group) -+ { -+ if (lnum >= 0 || sign_name != NULL || (group != NULL && *group == '\0')) -+ { -+ EMSG(_(e_invarg)); -+ return; -+ } -+ -+ if (id == -2) -+ { -+ if (buf != NULL) -+ // :sign unplace * file={fname} -+ // :sign unplace * group={group} file={fname} -+ // :sign unplace * group=* file={fname} -+ // :sign unplace * buffer={nr} -+ // :sign unplace * group={group} buffer={nr} -+ // :sign unplace * group=* buffer={nr} -+ sign_unplace(0, group, buf, 0); -+ else -+ // :sign unplace * -+ // :sign unplace * group={group} -+ // :sign unplace * group=* -+ FOR_ALL_BUFFERS(buf) -+ if (buf->b_signlist != NULL) -+ buf_delete_signs(buf, group); -+ } -+ else -+ { -+ if (buf != NULL) -+ // :sign unplace {id} file={fname} -+ // :sign unplace {id} group={group} file={fname} -+ // :sign unplace {id} group=* file={fname} -+ // :sign unplace {id} buffer={nr} -+ // :sign unplace {id} group={group} buffer={nr} -+ // :sign unplace {id} group=* buffer={nr} -+ sign_unplace(id, group, buf, 0); -+ else -+ { -+ if (id == -1) -+ { -+ // :sign unplace group={group} -+ // :sign unplace group=* -+ sign_unplace_at_cursor(group); -+ } -+ else -+ { -+ // :sign unplace {id} -+ // :sign unplace {id} group={group} -+ // :sign unplace {id} group=* -+ FOR_ALL_BUFFERS(buf) -+ sign_unplace(id, group, buf, 0); -+ } -+ } -+ } -+ } -+ -+ /* -+ * Jump to a placed sign -+ * :sign jump {id} file={fname} -+ * :sign jump {id} buffer={nr} -+ * :sign jump {id} group={group} file={fname} -+ * :sign jump {id} group={group} buffer={nr} -+ */ -+ static void -+ sign_jump_cmd( -+ buf_T *buf, -+ linenr_T lnum, -+ char_u *sign_name, -+ int id, -+ char_u *group) -+ { -+ if (buf == NULL && sign_name == NULL && group == NULL && id == -1) -+ { -+ EMSG(_(e_argreq)); -+ return; -+ } -+ -+ if (buf == NULL || (group != NULL && *group == '\0') || -+ lnum >= 0 || sign_name != NULL) -+ { -+ // File or buffer is not specified or an empty group is used -+ // or a line number or a sign name is specified. -+ EMSG(_(e_invarg)); -+ return; -+ } -+ -+ if ((lnum = buf_findsign(buf, id, group)) <= 0) -+ { -+ EMSGN(_("E157: Invalid sign ID: %ld"), id); -+ return; -+ } -+ -+ // goto a sign ... -+ if (buf_jump_open_win(buf) != NULL) -+ { // ... in a current window -+ curwin->w_cursor.lnum = lnum; -+ check_cursor_lnum(); -+ beginline(BL_WHITE); -+ } -+ else -+ { // ... not currently in a window -+ char_u *cmd; -+ -+ if (buf->b_fname == NULL) -+ { -+ EMSG(_("E934: Cannot jump to a buffer that does not have a name")); -+ return; -+ } -+ cmd = alloc((unsigned)STRLEN(buf->b_fname) + 25); -+ if (cmd == NULL) -+ return; -+ sprintf((char *)cmd, "e +%ld %s", (long)lnum, buf->b_fname); -+ do_cmdline_cmd(cmd); -+ vim_free(cmd); -+ } -+ # ifdef FEAT_FOLDING -+ foldOpenCursor(); -+ # endif -+ } -+ -+ /* -+ * Parse the command line arguments for the ":sign place", ":sign unplace" and -+ * ":sign jump" commands. -+ * The supported arguments are: line={lnum} name={name} group={group} -+ * priority={prio} and file={fname} or buffer={nr}. -+ */ -+ static int -+ parse_sign_cmd_args( -+ int cmd, -+ char_u *arg, -+ char_u **sign_name, -+ int *signid, -+ char_u **group, -+ int *prio, -+ buf_T **buf, -+ linenr_T *lnum) -+ { -+ char_u *arg1; -+ char_u *name; -+ char_u *filename = NULL; -+ -+ // first arg could be placed sign id -+ arg1 = arg; -+ if (VIM_ISDIGIT(*arg)) -+ { -+ *signid = getdigits(&arg); -+ if (!VIM_ISWHITE(*arg) && *arg != NUL) -+ { -+ *signid = -1; -+ arg = arg1; -+ } -+ else -+ arg = skipwhite(arg); -+ } -+ -+ while (*arg != NUL) -+ { -+ if (STRNCMP(arg, "line=", 5) == 0) -+ { -+ arg += 5; -+ *lnum = atoi((char *)arg); -+ arg = skiptowhite(arg); -+ } -+ else if (STRNCMP(arg, "*", 1) == 0 && cmd == SIGNCMD_UNPLACE) -+ { -+ if (*signid != -1) -+ { -+ EMSG(_(e_invarg)); -+ return FAIL; -+ } -+ *signid = -2; -+ arg = skiptowhite(arg + 1); -+ } -+ else if (STRNCMP(arg, "name=", 5) == 0) -+ { -+ arg += 5; -+ name = arg; -+ arg = skiptowhite(arg); -+ if (*arg != NUL) -+ *arg++ = NUL; -+ while (name[0] == '0' && name[1] != NUL) -+ ++name; -+ *sign_name = name; -+ } -+ else if (STRNCMP(arg, "group=", 6) == 0) -+ { -+ arg += 6; -+ *group = arg; -+ arg = skiptowhite(arg); -+ if (*arg != NUL) -+ *arg++ = NUL; -+ } -+ else if (STRNCMP(arg, "priority=", 9) == 0) -+ { -+ arg += 9; -+ *prio = atoi((char *)arg); -+ arg = skiptowhite(arg); -+ } -+ else if (STRNCMP(arg, "file=", 5) == 0) -+ { -+ arg += 5; -+ filename = arg; -+ *buf = buflist_findname_exp(arg); -+ break; -+ } -+ else if (STRNCMP(arg, "buffer=", 7) == 0) -+ { -+ arg += 7; -+ filename = arg; -+ *buf = buflist_findnr((int)getdigits(&arg)); -+ if (*skipwhite(arg) != NUL) -+ EMSG(_(e_trailing)); -+ break; -+ } -+ else -+ { -+ EMSG(_(e_invarg)); -+ return FAIL; -+ } -+ arg = skipwhite(arg); -+ } -+ -+ if (filename != NULL && *buf == NULL) -+ { -+ EMSG2(_("E158: Invalid buffer name: %s"), filename); -+ return FAIL; -+ } -+ -+ return OK; -+ } -+ -+ /* -+ * ":sign" command -+ */ -+ void -+ ex_sign(exarg_T *eap) -+ { -+ char_u *arg = eap->arg; -+ char_u *p; -+ int idx; -+ sign_T *sp; -+ buf_T *buf = NULL; -+ -+ // Parse the subcommand. -+ p = skiptowhite(arg); -+ idx = sign_cmd_idx(arg, p); -+ if (idx == SIGNCMD_LAST) -+ { -+ EMSG2(_("E160: Unknown sign command: %s"), arg); -+ return; -+ } -+ arg = skipwhite(p); -+ -+ if (idx <= SIGNCMD_LIST) -+ { -+ // Define, undefine or list signs. -+ if (idx == SIGNCMD_LIST && *arg == NUL) -+ { -+ // ":sign list": list all defined signs -+ for (sp = first_sign; sp != NULL && !got_int; sp = sp->sn_next) -+ sign_list_defined(sp); -+ } -+ else if (*arg == NUL) -+ EMSG(_("E156: Missing sign name")); -+ else -+ { -+ char_u *name; -+ -+ // Isolate the sign name. If it's a number skip leading zeroes, -+ // so that "099" and "99" are the same sign. But keep "0". -+ p = skiptowhite(arg); -+ if (*p != NUL) -+ *p++ = NUL; -+ while (arg[0] == '0' && arg[1] != NUL) -+ ++arg; -+ name = vim_strsave(arg); -+ -+ if (idx == SIGNCMD_DEFINE) -+ sign_define_cmd(name, p); -+ else if (idx == SIGNCMD_LIST) -+ // ":sign list {name}" -+ sign_list_by_name(name); -+ else -+ // ":sign undefine {name}" -+ sign_undefine_by_name(name); -+ -+ vim_free(name); -+ return; -+ } -+ } -+ else -+ { -+ int id = -1; -+ linenr_T lnum = -1; -+ char_u *sign_name = NULL; -+ char_u *group = NULL; -+ int prio = SIGN_DEF_PRIO; -+ -+ // Parse command line arguments -+ if (parse_sign_cmd_args(idx, arg, &sign_name, &id, &group, &prio, -+ &buf, &lnum) == FAIL) -+ return; -+ -+ if (idx == SIGNCMD_PLACE) -+ sign_place_cmd(buf, lnum, sign_name, id, group, prio); -+ else if (idx == SIGNCMD_UNPLACE) -+ sign_unplace_cmd(buf, lnum, sign_name, id, group); -+ else if (idx == SIGNCMD_JUMP) -+ sign_jump_cmd(buf, lnum, sign_name, id, group); -+ } -+ } -+ -+ /* -+ * Return information about a specified sign -+ */ -+ static void -+ sign_getinfo(sign_T *sp, dict_T *retdict) -+ { -+ char_u *p; -+ -+ dict_add_string(retdict, "name", (char_u *)sp->sn_name); -+ if (sp->sn_icon != NULL) -+ dict_add_string(retdict, "icon", (char_u *)sp->sn_icon); -+ if (sp->sn_text != NULL) -+ dict_add_string(retdict, "text", (char_u *)sp->sn_text); -+ if (sp->sn_line_hl > 0) -+ { -+ p = get_highlight_name_ext(NULL, sp->sn_line_hl - 1, FALSE); -+ if (p == NULL) -+ p = (char_u *)"NONE"; -+ dict_add_string(retdict, "linehl", (char_u *)p); -+ } -+ if (sp->sn_text_hl > 0) -+ { -+ p = get_highlight_name_ext(NULL, sp->sn_text_hl - 1, FALSE); -+ if (p == NULL) -+ p = (char_u *)"NONE"; -+ dict_add_string(retdict, "texthl", (char_u *)p); -+ } -+ } -+ -+ /* -+ * If 'name' is NULL, return a list of all the defined signs. -+ * Otherwise, return information about the specified sign. -+ */ -+ void -+ sign_getlist(char_u *name, list_T *retlist) -+ { -+ sign_T *sp = first_sign; -+ dict_T *dict; -+ -+ if (name != NULL) -+ { -+ sp = sign_find(name, NULL); -+ if (sp == NULL) -+ return; -+ } -+ -+ for (; sp != NULL && !got_int; sp = sp->sn_next) -+ { -+ if ((dict = dict_alloc_id(aid_sign_getlist)) == NULL) -+ return; -+ if (list_append_dict(retlist, dict) == FAIL) -+ return; -+ sign_getinfo(sp, dict); -+ -+ if (name != NULL) // handle only the specified sign -+ break; -+ } -+ } -+ -+ /* -+ * Returns information about signs placed in a buffer as list of dicts. -+ */ -+ void -+ get_buffer_signs(buf_T *buf, list_T *l) -+ { -+ signlist_T *sign; -+ dict_T *d; -+ -+ FOR_ALL_SIGNS_IN_BUF(buf, sign) -+ { -+ if ((d = sign_get_info(sign)) != NULL) -+ list_append_dict(l, d); -+ } -+ } -+ -+ /* -+ * Return information about all the signs placed in a buffer -+ */ -+ static void -+ sign_get_placed_in_buf( -+ buf_T *buf, -+ linenr_T lnum, -+ int sign_id, -+ char_u *sign_group, -+ list_T *retlist) -+ { -+ dict_T *d; -+ list_T *l; -+ signlist_T *sign; -+ dict_T *sdict; -+ -+ if ((d = dict_alloc_id(aid_sign_getplaced_dict)) == NULL) -+ return; -+ list_append_dict(retlist, d); -+ -+ dict_add_number(d, "bufnr", (long)buf->b_fnum); -+ -+ if ((l = list_alloc_id(aid_sign_getplaced_list)) == NULL) -+ return; -+ dict_add_list(d, "signs", l); -+ -+ FOR_ALL_SIGNS_IN_BUF(buf, sign) -+ { -+ if (!sign_in_group(sign, sign_group)) -+ continue; -+ if ((lnum == 0 && sign_id == 0) || -+ (sign_id == 0 && lnum == sign->lnum) || -+ (lnum == 0 && sign_id == sign->id) || -+ (lnum == sign->lnum && sign_id == sign->id)) -+ { -+ if ((sdict = sign_get_info(sign)) != NULL) -+ list_append_dict(l, sdict); -+ } -+ } -+ } -+ -+ /* -+ * Get a list of signs placed in buffer 'buf'. If 'num' is non-zero, return the -+ * sign placed at the line number. If 'lnum' is zero, return all the signs -+ * placed in 'buf'. If 'buf' is NULL, return signs placed in all the buffers. -+ */ -+ void -+ sign_get_placed( -+ buf_T *buf, -+ linenr_T lnum, -+ int sign_id, -+ char_u *sign_group, -+ list_T *retlist) -+ { -+ if (buf != NULL) -+ sign_get_placed_in_buf(buf, lnum, sign_id, sign_group, retlist); -+ else -+ { -+ FOR_ALL_BUFFERS(buf) -+ { -+ if (buf->b_signlist != NULL) -+ sign_get_placed_in_buf(buf, 0, sign_id, sign_group, retlist); -+ } -+ } -+ } -+ -+ # if defined(FEAT_SIGN_ICONS) || defined(PROTO) -+ /* -+ * Allocate the icons. Called when the GUI has started. Allows defining -+ * signs before it starts. -+ */ -+ void -+ sign_gui_started(void) -+ { -+ sign_T *sp; -+ -+ for (sp = first_sign; sp != NULL; sp = sp->sn_next) -+ if (sp->sn_icon != NULL) -+ sp->sn_image = gui_mch_register_sign(sp->sn_icon); -+ } -+ # endif -+ -+ /* -+ * List one sign. -+ */ -+ static void -+ sign_list_defined(sign_T *sp) -+ { -+ char_u *p; -+ -+ smsg((char_u *)"sign %s", sp->sn_name); -+ if (sp->sn_icon != NULL) -+ { -+ MSG_PUTS(" icon="); -+ msg_outtrans(sp->sn_icon); -+ # ifdef FEAT_SIGN_ICONS -+ if (sp->sn_image == NULL) -+ MSG_PUTS(_(" (NOT FOUND)")); -+ # else -+ MSG_PUTS(_(" (not supported)")); -+ # endif -+ } -+ if (sp->sn_text != NULL) -+ { -+ MSG_PUTS(" text="); -+ msg_outtrans(sp->sn_text); -+ } -+ if (sp->sn_line_hl > 0) -+ { -+ MSG_PUTS(" linehl="); -+ p = get_highlight_name_ext(NULL, sp->sn_line_hl - 1, FALSE); -+ if (p == NULL) -+ MSG_PUTS("NONE"); -+ else -+ msg_puts(p); -+ } -+ if (sp->sn_text_hl > 0) -+ { -+ MSG_PUTS(" texthl="); -+ p = get_highlight_name_ext(NULL, sp->sn_text_hl - 1, FALSE); -+ if (p == NULL) -+ MSG_PUTS("NONE"); -+ else -+ msg_puts(p); -+ } -+ } -+ -+ /* -+ * Undefine a sign and free its memory. -+ */ -+ static void -+ sign_undefine(sign_T *sp, sign_T *sp_prev) -+ { -+ vim_free(sp->sn_name); -+ vim_free(sp->sn_icon); -+ # ifdef FEAT_SIGN_ICONS -+ if (sp->sn_image != NULL) -+ { -+ out_flush(); -+ gui_mch_destroy_sign(sp->sn_image); -+ } -+ # endif -+ vim_free(sp->sn_text); -+ if (sp_prev == NULL) -+ first_sign = sp->sn_next; -+ else -+ sp_prev->sn_next = sp->sn_next; -+ vim_free(sp); -+ } -+ -+ /* -+ * Get highlighting attribute for sign "typenr". -+ * If "line" is TRUE: line highl, if FALSE: text highl. -+ */ -+ int -+ sign_get_attr(int typenr, int line) -+ { -+ sign_T *sp; -+ -+ for (sp = first_sign; sp != NULL; sp = sp->sn_next) -+ if (sp->sn_typenr == typenr) -+ { -+ if (line) -+ { -+ if (sp->sn_line_hl > 0) -+ return syn_id2attr(sp->sn_line_hl); -+ } -+ else -+ { -+ if (sp->sn_text_hl > 0) -+ return syn_id2attr(sp->sn_text_hl); -+ } -+ break; -+ } -+ return 0; -+ } -+ -+ /* -+ * Get text mark for sign "typenr". -+ * Returns NULL if there isn't one. -+ */ -+ char_u * -+ sign_get_text(int typenr) -+ { -+ sign_T *sp; -+ -+ for (sp = first_sign; sp != NULL; sp = sp->sn_next) -+ if (sp->sn_typenr == typenr) -+ return sp->sn_text; -+ return NULL; -+ } -+ -+ # if defined(FEAT_SIGN_ICONS) || defined(PROTO) -+ void * -+ sign_get_image( -+ int typenr) /* the attribute which may have a sign */ -+ { -+ sign_T *sp; -+ -+ for (sp = first_sign; sp != NULL; sp = sp->sn_next) -+ if (sp->sn_typenr == typenr) -+ return sp->sn_image; -+ return NULL; -+ } -+ # endif -+ -+ /* -+ * Undefine/free all signs. -+ */ -+ void -+ free_signs(void) -+ { -+ while (first_sign != NULL) -+ sign_undefine(first_sign, NULL); -+ } -+ -+ # if defined(FEAT_CMDL_COMPL) || defined(PROTO) -+ static enum -+ { -+ EXP_SUBCMD, /* expand :sign sub-commands */ -+ EXP_DEFINE, /* expand :sign define {name} args */ -+ EXP_PLACE, /* expand :sign place {id} args */ -+ EXP_UNPLACE, /* expand :sign unplace" */ -+ EXP_SIGN_NAMES /* expand with name of placed signs */ -+ } expand_what; -+ -+ /* -+ * Function given to ExpandGeneric() to obtain the sign command -+ * expansion. -+ */ -+ char_u * -+ get_sign_name(expand_T *xp UNUSED, int idx) -+ { -+ sign_T *sp; -+ int current_idx; -+ -+ switch (expand_what) -+ { -+ case EXP_SUBCMD: -+ return (char_u *)cmds[idx]; -+ case EXP_DEFINE: -+ { -+ char *define_arg[] = -+ { -+ "icon=", "linehl=", "text=", "texthl=", NULL -+ }; -+ return (char_u *)define_arg[idx]; -+ } -+ case EXP_PLACE: -+ { -+ char *place_arg[] = -+ { -+ "line=", "name=", "group=", "priority=", "file=", -+ "buffer=", NULL -+ }; -+ return (char_u *)place_arg[idx]; -+ } -+ case EXP_UNPLACE: -+ { -+ char *unplace_arg[] = { "group=", "file=", "buffer=", NULL }; -+ return (char_u *)unplace_arg[idx]; -+ } -+ case EXP_SIGN_NAMES: -+ /* Complete with name of signs already defined */ -+ current_idx = 0; -+ for (sp = first_sign; sp != NULL; sp = sp->sn_next) -+ if (current_idx++ == idx) -+ return sp->sn_name; -+ return NULL; -+ default: -+ return NULL; -+ } -+ } -+ -+ /* -+ * Handle command line completion for :sign command. -+ */ -+ void -+ set_context_in_sign_cmd(expand_T *xp, char_u *arg) -+ { -+ char_u *p; -+ char_u *end_subcmd; -+ char_u *last; -+ int cmd_idx; -+ char_u *begin_subcmd_args; -+ -+ /* Default: expand subcommands. */ -+ xp->xp_context = EXPAND_SIGN; -+ expand_what = EXP_SUBCMD; -+ xp->xp_pattern = arg; -+ -+ end_subcmd = skiptowhite(arg); -+ if (*end_subcmd == NUL) -+ /* expand subcmd name -+ * :sign {subcmd}<CTRL-D>*/ -+ return; -+ -+ cmd_idx = sign_cmd_idx(arg, end_subcmd); -+ -+ /* :sign {subcmd} {subcmd_args} -+ * | -+ * begin_subcmd_args */ -+ begin_subcmd_args = skipwhite(end_subcmd); -+ p = skiptowhite(begin_subcmd_args); -+ if (*p == NUL) -+ { -+ /* -+ * Expand first argument of subcmd when possible. -+ * For ":jump {id}" and ":unplace {id}", we could -+ * possibly expand the ids of all signs already placed. -+ */ -+ xp->xp_pattern = begin_subcmd_args; -+ switch (cmd_idx) -+ { -+ case SIGNCMD_LIST: -+ case SIGNCMD_UNDEFINE: -+ /* :sign list <CTRL-D> -+ * :sign undefine <CTRL-D> */ -+ expand_what = EXP_SIGN_NAMES; -+ break; -+ default: -+ xp->xp_context = EXPAND_NOTHING; -+ } -+ return; -+ } -+ -+ /* expand last argument of subcmd */ -+ -+ /* :sign define {name} {args}... -+ * | -+ * p */ -+ -+ /* Loop until reaching last argument. */ -+ do -+ { -+ p = skipwhite(p); -+ last = p; -+ p = skiptowhite(p); -+ } while (*p != NUL); -+ -+ p = vim_strchr(last, '='); -+ -+ /* :sign define {name} {args}... {last}= -+ * | | -+ * last p */ -+ if (p == NULL) -+ { -+ /* Expand last argument name (before equal sign). */ -+ xp->xp_pattern = last; -+ switch (cmd_idx) -+ { -+ case SIGNCMD_DEFINE: -+ expand_what = EXP_DEFINE; -+ break; -+ case SIGNCMD_PLACE: -+ expand_what = EXP_PLACE; -+ break; -+ case SIGNCMD_JUMP: -+ case SIGNCMD_UNPLACE: -+ expand_what = EXP_UNPLACE; -+ break; -+ default: -+ xp->xp_context = EXPAND_NOTHING; -+ } -+ } -+ else -+ { -+ /* Expand last argument value (after equal sign). */ -+ xp->xp_pattern = p + 1; -+ switch (cmd_idx) -+ { -+ case SIGNCMD_DEFINE: -+ if (STRNCMP(last, "texthl", p - last) == 0 || -+ STRNCMP(last, "linehl", p - last) == 0) -+ xp->xp_context = EXPAND_HIGHLIGHT; -+ else if (STRNCMP(last, "icon", p - last) == 0) -+ xp->xp_context = EXPAND_FILES; -+ else -+ xp->xp_context = EXPAND_NOTHING; -+ break; -+ case SIGNCMD_PLACE: -+ if (STRNCMP(last, "name", p - last) == 0) -+ expand_what = EXP_SIGN_NAMES; -+ else -+ xp->xp_context = EXPAND_NOTHING; -+ break; -+ default: -+ xp->xp_context = EXPAND_NOTHING; -+ } -+ } -+ } -+ # endif -+ -+ #endif /* FEAT_SIGNS */ -*** ../vim-8.1.0672/src/version.c 2019-01-01 00:41:50.040176062 +0100 ---- src/version.c 2019-01-01 12:50:56.371898216 +0100 -*************** -*** 801,802 **** ---- 801,804 ---- - { /* Add new patch number below this line */ -+ /**/ -+ 673, - /**/ - --- -From "know your smileys": - 8-O "Omigod!!" (done "rm -rf *" ?) - - /// Bram Moolenaar -- Bram@Moolenaar.net -- 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 /// |