diff options
Diffstat (limited to 'data/vim/patches/8.1.1228')
-rw-r--r-- | data/vim/patches/8.1.1228 | 1467 |
1 files changed, 0 insertions, 1467 deletions
diff --git a/data/vim/patches/8.1.1228 b/data/vim/patches/8.1.1228 deleted file mode 100644 index b584c9e6b..000000000 --- a/data/vim/patches/8.1.1228 +++ /dev/null @@ -1,1467 +0,0 @@ -To: vim_dev@googlegroups.com -Subject: Patch 8.1.1228 -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.1228 -Problem: Not possible to process tags with a function. -Solution: Add tagfunc() (Christian Brabandt, Andy Massimino, closes #4010) -Files: runtime/doc/options.txt, runtime/doc/tagsrch.txt, - runtime/optwin.vim, src/buffer.c, src/dict.c, src/ex_cmds.c, - src/globals.h, src/insexpand.c, src/normal.c, src/option.c, - src/option.h, src/proto/dict.pro, src/structs.h, src/tag.c, - src/testdir/Make_all.mak, src/testdir/test_alot.vim, - src/testdir/test_tagfunc.vim, src/vim.h, src/window.c - - -*** ../vim-8.1.1227/runtime/doc/options.txt 2019-04-28 16:00:05.367613425 +0200 ---- runtime/doc/options.txt 2019-04-28 16:53:38.066933372 +0200 -*************** -*** 7458,7463 **** ---- 7458,7473 ---- - NOTE: This option is set to the Vi default value when 'compatible' is - set and to the Vim default value when 'compatible' is reset. - -+ *'tagfunc'* *'tfu'* -+ 'tagfunc' 'tfu' string (default: empty) -+ local to buffer -+ {not available when compiled without the |+eval| -+ feature} -+ This option specifies a function to be used to perform tag searches. -+ The function gets the tag pattern and should return a List of matching -+ tags. See |tag-function| for an explanation of how to write the -+ function and an example. -+ - *'taglength'* *'tl'* - 'taglength' 'tl' number (default 0) - global -*** ../vim-8.1.1227/runtime/doc/tagsrch.txt 2019-03-30 21:19:16.426170240 +0100 ---- runtime/doc/tagsrch.txt 2019-04-28 17:43:27.976705157 +0200 -*************** -*** 14,19 **** ---- 14,20 ---- - 4. Tags details |tag-details| - 5. Tags file format |tags-file-format| - 6. Include file searches |include-search| -+ 7. Using 'tagfunc' |tag-function| - - ============================================================================== - 1. Jump to a tag *tag-commands* -*************** -*** 179,186 **** - 1 1 main 1 harddisk2:text/vim/test - 2 1 FuncB 59 harddisk2:text/vim/src/main.c - -! The gettagstack() function returns the tag stack of a specified window. The -! settagstack() function modifies the tag stack of a window. - - *E73* - When you try to use the tag stack while it doesn't contain anything you will ---- 180,187 ---- - 1 1 main 1 harddisk2:text/vim/test - 2 1 FuncB 59 harddisk2:text/vim/src/main.c - -! The |gettagstack()| function returns the tag stack of a specified window. The -! |settagstack()| function modifies the tag stack of a window. - - *E73* - When you try to use the tag stack while it doesn't contain anything you will -*************** -*** 570,576 **** - the bar) and ;" is used to have Vi ignore the rest of the - line. Example: - APP file.c call cursor(3, 4)|;" v -! - {field} .. A list of optional fields. Each field has the form: - - <Tab>{fieldname}:{value} ---- 571,577 ---- - the bar) and ;" is used to have Vi ignore the rest of the - line. Example: - APP file.c call cursor(3, 4)|;" v -! - {field} .. A list of optional fields. Each field has the form: - - <Tab>{fieldname}:{value} -*************** -*** 591,596 **** ---- 592,598 ---- - The only other field currently recognized by Vim is "file:" - (with an empty value). It is used for a static tag. - -+ - The first lines in the tags file can contain lines that start with - !_TAG_ - These are sorted to the first lines, only rare tags that start with "!" can -*************** -*** 870,873 **** - < For a ":djump", ":dsplit", ":dlist" and ":dsearch" command the pattern - is used as a literal string, not as a search pattern. - -! vim:tw=78:ts=8:ft=help:norl: ---- 872,941 ---- - < For a ":djump", ":dsplit", ":dlist" and ":dsearch" command the pattern - is used as a literal string, not as a search pattern. - -! ============================================================================== -! 7. Using 'tagfunc' *tag-function* -! -! It is possible to provide Vim with a function which will generate a list of -! tags used for commands like |:tag|, |:tselect| and Normal mode tag commands -! like |CTRL-]|. -! -! The function used for generating the taglist is specified by setting the -! 'tagfunc' option. The function will be called with three arguments: -! a:pattern The tag identifier used during the tag search. -! a:flags List of flags to control the function behavior. -! a:info Dict containing the following entries: -! buf_ffname Full filename which can be used for priority. -! user_data Custom data String, if stored in the tag -! stack previously by tagfunc. -! -! Currently two flags may be passed to the tag function: -! 'c' The function was invoked by a normal command being processed -! (mnemonic: the tag function may use the context around the -! cursor to perform a better job of generating the tag list.) -! 'i' In Insert mode, the user was completing a tag (with -! |i_CTRL-X_CTRL-]|). -! -! Note that when 'tagfunc' is set, the priority of the tags described in -! |tag-priority| does not apply. Instead, the priority is exactly as the -! ordering of the elements in the list returned by the function. -! *E987* -! The function should return a List of Dict entries. Each Dict must at least -! include the following entries and each value must be a string: -! name Name of the tag. -! filename Name of the file where the tag is defined. It is -! either relative to the current directory or a full path. -! cmd Ex command used to locate the tag in the file. This -! can be either an Ex search pattern or a line number. -! Note that the format is similar to that of |taglist()|, which makes it possible -! to use its output to generate the result. -! The following fields are optional: -! kind Type of the tag. -! user_data String of custom data stored in the tag stack which -! can be used to disambiguate tags between operations. -! -! If the function returns |v:null| instead of a List, a standard tag lookup will -! be performed instead. -! -! It is not allowed to change the tagstack from inside 'tagfunc'. *E986* -! -! The following is a hypothetical example of a function used for 'tagfunc'. It -! uses the output of |taglist()| to generate the result: a list of tags in the -! inverse order of file names. -! > -! function! TagFunc(pattern, flags, info) -! function! CompareFilenames(item1, item2) -! let f1 = a:item1['filename'] -! let f2 = a:item2['filename'] -! return f1 >=# f2 ? -! \ -1 : f1 <=# f2 ? 1 : 0 -! endfunction -! -! let result = taglist(a:pattern) -! call sort(result, "CompareFilenames") -! -! return result -! endfunc -! set tagfunc=TagFunc -! < -! -! vim:tw=78:ts=8:noet:ft=help:norl: -*** ../vim-8.1.1227/runtime/optwin.vim 2019-02-17 17:53:46.681219289 +0100 ---- runtime/optwin.vim 2019-04-28 16:47:48.252732139 +0200 -*************** -*** 300,305 **** ---- 300,310 ---- - call <SID>BinOptionG("tgst", &tgst) - call append("$", "showfulltag\twhen completing tags in Insert mode show more info") - call <SID>BinOptionG("sft", &sft) -+ if has("eval") -+ call append("$", "tagfunc\ta function to be used to perform tag searches") -+ call append("$", "\t(local to buffer)") -+ call <SID>OptionL("tfu") -+ endif - if has("cscope") - call append("$", "cscopeprg\tcommand for executing cscope") - call <SID>OptionG("csprg", &csprg) -*** ../vim-8.1.1227/src/buffer.c 2019-04-27 13:03:20.000715982 +0200 ---- src/buffer.c 2019-04-28 16:47:48.252732139 +0200 -*************** -*** 2219,2224 **** ---- 2219,2227 ---- - clear_string_option(&buf->b_p_path); - clear_string_option(&buf->b_p_tags); - clear_string_option(&buf->b_p_tc); -+ #ifdef FEAT_EVAL -+ clear_string_option(&buf->b_p_tfu); -+ #endif - #ifdef FEAT_INS_EXPAND - clear_string_option(&buf->b_p_dict); - clear_string_option(&buf->b_p_tsr); -*** ../vim-8.1.1227/src/dict.c 2019-04-08 18:15:36.464223229 +0200 ---- src/dict.c 2019-04-28 17:48:48.959179176 +0200 -*************** -*** 449,454 **** ---- 449,503 ---- - } - - /* -+ * Initializes "iter" for iterating over dictionary items with -+ * dict_iterate_next(). -+ * If "var" is not a Dict or an empty Dict then there will be nothing to -+ * iterate over, no error is given. -+ * NOTE: The dictionary must not change until iterating is finished! -+ */ -+ void -+ dict_iterate_start(typval_T *var, dict_iterator_T *iter) -+ { -+ if (var->v_type != VAR_DICT || var->vval.v_dict == NULL) -+ iter->dit_todo = 0; -+ else -+ { -+ dict_T *d = var->vval.v_dict; -+ -+ iter->dit_todo = d->dv_hashtab.ht_used; -+ iter->dit_hi = d->dv_hashtab.ht_array; -+ } -+ } -+ -+ /* -+ * Iterate over the items referred to by "iter". It should be initialized with -+ * dict_iterate_start(). -+ * Returns a pointer to the key. -+ * "*tv_result" is set to point to the value for that key. -+ * If there are no more items, NULL is returned. -+ */ -+ char_u * -+ dict_iterate_next(dict_iterator_T *iter, typval_T **tv_result) -+ { -+ dictitem_T *di; -+ char_u *result; -+ -+ if (iter->dit_todo == 0) -+ return NULL; -+ -+ while (HASHITEM_EMPTY(iter->dit_hi)) -+ ++iter->dit_hi; -+ -+ di = HI2DI(iter->dit_hi); -+ result = di->di_key; -+ *tv_result = &di->di_tv; -+ -+ --iter->dit_todo; -+ ++iter->dit_hi; -+ return result; -+ } -+ -+ /* - * Add a dict entry to dictionary "d". - * Returns FAIL when out of memory and when key already exists. - */ -*** ../vim-8.1.1227/src/ex_cmds.c 2019-03-30 18:46:57.344077426 +0100 ---- src/ex_cmds.c 2019-04-28 17:16:35.452393443 +0200 -*************** -*** 6813,6819 **** - - *matches = (char_u **)""; - *num_matches = 0; -! flags = TAG_HELP | TAG_REGEXP | TAG_NAMES | TAG_VERBOSE; - if (keep_lang) - flags |= TAG_KEEP_LANG; - if (find_tags(IObuff, num_matches, matches, flags, (int)MAXCOL, NULL) == OK ---- 6813,6819 ---- - - *matches = (char_u **)""; - *num_matches = 0; -! flags = TAG_HELP | TAG_REGEXP | TAG_NAMES | TAG_VERBOSE | TAG_NO_TAGFUNC; - if (keep_lang) - flags |= TAG_KEEP_LANG; - if (find_tags(IObuff, num_matches, matches, flags, (int)MAXCOL, NULL) == OK -*** ../vim-8.1.1227/src/globals.h 2019-04-20 23:38:02.189504258 +0200 ---- src/globals.h 2019-04-28 17:21:49.430854857 +0200 -*************** -*** 1067,1075 **** - EXTERN int postponed_split_flags INIT(= 0); /* args for win_split() */ - EXTERN int postponed_split_tab INIT(= 0); /* cmdmod.tab */ - #ifdef FEAT_QUICKFIX -! EXTERN int g_do_tagpreview INIT(= 0); /* for tag preview commands: -! height of preview window */ - #endif - EXTERN int replace_offset INIT(= 0); /* offset for replace_push() */ - - EXTERN char_u *escape_chars INIT(= (char_u *)" \t\\\"|"); ---- 1067,1079 ---- - EXTERN int postponed_split_flags INIT(= 0); /* args for win_split() */ - EXTERN int postponed_split_tab INIT(= 0); /* cmdmod.tab */ - #ifdef FEAT_QUICKFIX -! EXTERN int g_do_tagpreview INIT(= 0); // for tag preview commands: -! // height of preview window - #endif -+ EXTERN int g_tag_at_cursor INIT(= FALSE); // whether the tag command comes -+ // from the command line (0) or was -+ // invoked as a normal command (1) -+ - EXTERN int replace_offset INIT(= 0); /* offset for replace_push() */ - - EXTERN char_u *escape_chars INIT(= (char_u *)" \t\\\"|"); -*** ../vim-8.1.1227/src/insexpand.c 2019-04-08 18:15:36.464223229 +0200 ---- src/insexpand.c 2019-04-28 17:21:29.878951043 +0200 -*************** -*** 2654,2664 **** ---- 2654,2666 ---- - - // Find up to TAG_MANY matches. Avoids that an enormous number - // of matches is found when compl_pattern is empty -+ g_tag_at_cursor = TRUE; - if (find_tags(compl_pattern, &num_matches, &matches, - TAG_REGEXP | TAG_NAMES | TAG_NOIC | TAG_INS_COMP - | (ctrl_x_mode != CTRL_X_NORMAL ? TAG_VERBOSE : 0), - TAG_MANY, curbuf->b_ffname) == OK && num_matches > 0) - ins_compl_add_matches(num_matches, matches, p_ic); -+ g_tag_at_cursor = FALSE; - p_ic = save_p_ic; - break; - -*** ../vim-8.1.1227/src/normal.c 2019-03-30 18:46:57.356077354 +0100 ---- src/normal.c 2019-04-28 17:21:37.030915863 +0200 -*************** -*** 5724,5730 **** ---- 5724,5734 ---- - (void)normal_search(cap, cmdchar == '*' ? '/' : '?', buf, 0); - } - else -+ { -+ g_tag_at_cursor = TRUE; - do_cmdline_cmd(buf); -+ g_tag_at_cursor = FALSE; -+ } - - vim_free(buf); - } -*** ../vim-8.1.1227/src/option.c 2019-04-27 22:06:33.348200718 +0200 ---- src/option.c 2019-04-28 16:47:48.256732118 +0200 -*************** -*** 167,172 **** ---- 167,175 ---- - #endif - #define PV_SW OPT_BUF(BV_SW) - #define PV_SWF OPT_BUF(BV_SWF) -+ #ifdef FEAT_EVAL -+ # define PV_TFU OPT_BUF(BV_TFU) -+ #endif - #define PV_TAGS OPT_BOTH(OPT_BUF(BV_TAGS)) - #define PV_TC OPT_BOTH(OPT_BUF(BV_TC)) - #define PV_TS OPT_BUF(BV_TS) -*************** -*** 303,308 **** ---- 306,314 ---- - static char_u *p_cfu; - static char_u *p_ofu; - #endif -+ #ifdef FEAT_EVAL -+ static char_u *p_tfu; -+ #endif - static int p_eol; - static int p_fixeol; - static int p_et; -*************** -*** 2642,2647 **** ---- 2648,2662 ---- - {"tagcase", "tc", P_STRING|P_VIM, - (char_u *)&p_tc, PV_TC, - {(char_u *)"followic", (char_u *)"followic"} SCTX_INIT}, -+ {"tagfunc", "tfu", P_STRING|P_ALLOCED|P_VI_DEF|P_SECURE, -+ #ifdef FEAT_EVAL -+ (char_u *)&p_tfu, PV_TFU, -+ {(char_u *)"", (char_u *)0L} -+ #else -+ (char_u *)NULL, PV_NONE, -+ {(char_u *)0L, (char_u *)0L} -+ #endif -+ SCTX_INIT}, - {"taglength", "tl", P_NUM|P_VI_DEF, - (char_u *)&p_tl, PV_NONE, - {(char_u *)0L, (char_u *)0L} SCTX_INIT}, -*************** -*** 5689,5694 **** ---- 5704,5712 ---- - check_string_option(&buf->b_p_cfu); - check_string_option(&buf->b_p_ofu); - #endif -+ #ifdef FEAT_EVAL -+ check_string_option(&buf->b_p_tfu); -+ #endif - #ifdef FEAT_KEYMAP - check_string_option(&buf->b_p_keymap); - #endif -*************** -*** 10944,10949 **** ---- 10962,10970 ---- - case PV_CFU: return (char_u *)&(curbuf->b_p_cfu); - case PV_OFU: return (char_u *)&(curbuf->b_p_ofu); - #endif -+ #ifdef FEAT_EVAL -+ case PV_TFU: return (char_u *)&(curbuf->b_p_tfu); -+ #endif - case PV_EOL: return (char_u *)&(curbuf->b_p_eol); - case PV_FIXEOL: return (char_u *)&(curbuf->b_p_fixeol); - case PV_ET: return (char_u *)&(curbuf->b_p_et); -*************** -*** 11332,11337 **** ---- 11353,11361 ---- - buf->b_p_cfu = vim_strsave(p_cfu); - buf->b_p_ofu = vim_strsave(p_ofu); - #endif -+ #ifdef FEAT_EVAL -+ buf->b_p_tfu = vim_strsave(p_tfu); -+ #endif - buf->b_p_sts = p_sts; - buf->b_p_sts_nopaste = p_sts_nopaste; - #ifdef FEAT_VARTABS -*** ../vim-8.1.1227/src/option.h 2019-03-02 10:13:36.796974835 +0100 ---- src/option.h 2019-04-28 16:47:48.256732118 +0200 -*************** -*** 1068,1073 **** ---- 1068,1076 ---- - #endif - , BV_SW - , BV_SWF -+ #ifdef FEAT_EVAL -+ , BV_TFU -+ #endif - , BV_TAGS - , BV_TC - , BV_TS -*** ../vim-8.1.1227/src/proto/dict.pro 2019-04-08 18:15:36.472223190 +0200 ---- src/proto/dict.pro 2019-04-28 17:11:15.121943721 +0200 -*************** -*** 18,23 **** ---- 18,25 ---- - int dict_add_string(dict_T *d, char *key, char_u *str); - int dict_add_string_len(dict_T *d, char *key, char_u *str, int len); - int dict_add_list(dict_T *d, char *key, list_T *list); -+ void dict_iterate_start(typval_T *var, dict_iterator_T *iter); -+ char_u *dict_iterate_next(dict_iterator_T *iter, typval_T **tv_result); - int dict_add_dict(dict_T *d, char *key, dict_T *dict); - long dict_len(dict_T *d); - dictitem_T *dict_find(dict_T *d, char_u *key, int len); -*** ../vim-8.1.1227/src/structs.h 2019-04-27 20:36:52.534303564 +0200 ---- src/structs.h 2019-04-28 17:31:05.364108835 +0200 -*************** -*** 147,156 **** - */ - typedef struct taggy - { -! char_u *tagname; /* tag name */ -! fmark_T fmark; /* cursor position BEFORE ":tag" */ -! int cur_match; /* match number */ -! int cur_fnum; /* buffer number used for cur_match */ - } taggy_T; - - /* ---- 147,157 ---- - */ - typedef struct taggy - { -! char_u *tagname; // tag name -! fmark_T fmark; // cursor position BEFORE ":tag" -! int cur_match; // match number -! int cur_fnum; // buffer number used for cur_match -! char_u *user_data; // used with tagfunc - } taggy_T; - - /* -*************** -*** 1885,1890 **** ---- 1886,1901 ---- - struct list_stack_S *prev; - } list_stack_T; - -+ /* -+ * Structure used for iterating over dictionary items. -+ * Initialize with dict_iterate_start(). -+ */ -+ typedef struct -+ { -+ long_u dit_todo; -+ hashitem_T *dit_hi; -+ } dict_iterator_T; -+ - /* values for b_syn_spell: what to do with toplevel text */ - #define SYNSPL_DEFAULT 0 /* spell check if @Spell not defined */ - #define SYNSPL_TOP 1 /* spell check toplevel text */ -*************** -*** 2245,2250 **** ---- 2256,2264 ---- - char_u *b_p_cfu; /* 'completefunc' */ - char_u *b_p_ofu; /* 'omnifunc' */ - #endif -+ #ifdef FEAT_EVAL -+ char_u *b_p_tfu; /* 'tagfunc' */ -+ #endif - int b_p_eol; /* 'endofline' */ - int b_p_fixeol; /* 'fixendofline' */ - int b_p_et; /* 'expandtab' */ -*** ../vim-8.1.1227/src/tag.c 2019-04-21 00:00:07.942354840 +0200 ---- src/tag.c 2019-04-28 17:44:56.956284972 +0200 -*************** -*** 18,37 **** - */ - typedef struct tag_pointers - { -! /* filled in by parse_tag_line(): */ -! char_u *tagname; /* start of tag name (skip "file:") */ -! char_u *tagname_end; /* char after tag name */ -! char_u *fname; /* first char of file name */ -! char_u *fname_end; /* char after file name */ -! char_u *command; /* first char of command */ -! /* filled in by parse_match(): */ -! char_u *command_end; /* first char after command */ -! char_u *tag_fname; /* file name of the tags file */ - #ifdef FEAT_EMACS_TAGS -! int is_etag; /* TRUE for emacs tag */ - #endif -! char_u *tagkind; /* "kind:" value */ -! char_u *tagkind_end; /* end of tagkind */ - } tagptrs_T; - - /* ---- 18,40 ---- - */ - typedef struct tag_pointers - { -! // filled in by parse_tag_line(): -! char_u *tagname; // start of tag name (skip "file:") -! char_u *tagname_end; // char after tag name -! char_u *fname; // first char of file name -! char_u *fname_end; // char after file name -! char_u *command; // first char of command -! // filled in by parse_match(): -! char_u *command_end; // first char after command -! char_u *tag_fname; // file name of the tags file. This is used -! // when 'tr' is set. - #ifdef FEAT_EMACS_TAGS -! int is_etag; // TRUE for emacs tag - #endif -! char_u *tagkind; // "kind:" value -! char_u *tagkind_end; // end of tagkind -! char_u *user_data; // user_data string -! char_u *user_data_end; // end of user_data - } tagptrs_T; - - /* -*************** -*** 78,86 **** ---- 81,94 ---- - #if defined(FEAT_QUICKFIX) && defined(FEAT_EVAL) - static int add_llist_tags(char_u *tag, int num_matches, char_u **matches); - #endif -+ static void tagstack_clear_entry(taggy_T *item); - - static char_u *bottommsg = (char_u *)N_("E555: at bottom of tag stack"); - static char_u *topmsg = (char_u *)N_("E556: at top of tag stack"); -+ #ifdef FEAT_EVAL -+ static char_u *recurmsg = (char_u *)N_("E986: cannot modify the tag stack within tagfunc"); -+ static char_u *tfu_inv_ret_msg = (char_u *)N_("E987: invalid return value from tagfunc"); -+ #endif - - static char_u *tagmatchname = NULL; /* name of last used tag */ - -*************** -*** 89,97 **** - * Tag for preview window is remembered separately, to avoid messing up the - * normal tagstack. - */ -! static taggy_T ptag_entry = {NULL, {{0, 0, 0}, 0}, 0, 0}; - #endif - - /* - * Jump to tag; handling of tag commands and tag stack - * ---- 97,112 ---- - * Tag for preview window is remembered separately, to avoid messing up the - * normal tagstack. - */ -! static taggy_T ptag_entry = {NULL, {{0, 0, 0}, 0}, 0, 0, NULL}; -! #endif -! -! #ifdef FEAT_EVAL -! static int tfu_in_use = FALSE; // disallow recursive call of tagfunc - #endif - -+ // Used instead of NUL to separate tag fields in the growarrays. -+ #define TAG_SEP 0x02 -+ - /* - * Jump to tag; handling of tag commands and tag stack - * -*************** -*** 144,149 **** ---- 159,165 ---- - int skip_msg = FALSE; - char_u *buf_ffname = curbuf->b_ffname; /* name to use for - priority computation */ -+ int use_tfu = 1; - - /* remember the matches for the last used tag */ - static int num_matches = 0; -*************** -*** 151,156 **** ---- 167,180 ---- - static char_u **matches = NULL; - static int flags; - -+ #ifdef FEAT_EVAL -+ if (tfu_in_use) -+ { -+ emsg(_(recurmsg)); -+ return FALSE; -+ } -+ #endif -+ - #ifdef EXITFREE - if (type == DT_FREE) - { -*************** -*** 168,173 **** ---- 192,198 ---- - { - type = DT_TAG; - no_regexp = TRUE; -+ use_tfu = 0; - } - - prev_num_matches = num_matches; -*************** -*** 187,193 **** - #if defined(FEAT_QUICKFIX) - if (g_do_tagpreview != 0) - { -! vim_free(ptag_entry.tagname); - if ((ptag_entry.tagname = vim_strsave(tag)) == NULL) - goto end_do_tag; - } ---- 212,218 ---- - #if defined(FEAT_QUICKFIX) - if (g_do_tagpreview != 0) - { -! tagstack_clear_entry(&ptag_entry); - if ((ptag_entry.tagname = vim_strsave(tag)) == NULL) - goto end_do_tag; - } -*************** -*** 226,232 **** - } - else - { -! vim_free(ptag_entry.tagname); - if ((ptag_entry.tagname = vim_strsave(tag)) == NULL) - goto end_do_tag; - } ---- 251,257 ---- - } - else - { -! tagstack_clear_entry(&ptag_entry); - if ((ptag_entry.tagname = vim_strsave(tag)) == NULL) - goto end_do_tag; - } -*************** -*** 239,251 **** - * stack entries above it. - */ - while (tagstackidx < tagstacklen) -! vim_free(tagstack[--tagstacklen].tagname); - - /* if the tagstack is full: remove oldest entry */ - if (++tagstacklen > TAGSTACKSIZE) - { - tagstacklen = TAGSTACKSIZE; -! vim_free(tagstack[0].tagname); - for (i = 1; i < tagstacklen; ++i) - tagstack[i - 1] = tagstack[i]; - --tagstackidx; ---- 264,276 ---- - * stack entries above it. - */ - while (tagstackidx < tagstacklen) -! tagstack_clear_entry(&tagstack[--tagstacklen]); - - /* if the tagstack is full: remove oldest entry */ - if (++tagstacklen > TAGSTACKSIZE) - { - tagstacklen = TAGSTACKSIZE; -! tagstack_clear_entry(&tagstack[0]); - for (i = 1; i < tagstacklen; ++i) - tagstack[i - 1] = tagstack[i]; - --tagstackidx; -*************** -*** 529,534 **** ---- 554,563 ---- - #endif - if (verbose) - flags |= TAG_VERBOSE; -+ -+ if (!use_tfu) -+ flags |= TAG_NO_TAGFUNC; -+ - if (find_tags(name, &new_num_matches, &new_matches, flags, - max_num_matches, buf_ffname) == OK - && new_num_matches < max_num_matches) -*************** -*** 647,654 **** ---- 676,695 ---- - } - if (use_tagstack) - { -+ tagptrs_T tagp; -+ - tagstack[tagstackidx].cur_match = cur_match; - tagstack[tagstackidx].cur_fnum = cur_fnum; -+ -+ // store user-provided data originating from tagfunc -+ if (use_tfu && parse_match(matches[cur_match], &tagp) == OK -+ && tagp.user_data) -+ { -+ VIM_CLEAR(tagstack[tagstackidx].user_data); -+ tagstack[tagstackidx].user_data = vim_strnsave( -+ tagp.user_data, tagp.user_data_end - tagp.user_data); -+ } -+ - ++tagstackidx; - } - #if defined(FEAT_QUICKFIX) -*************** -*** 1243,1248 **** ---- 1284,1520 ---- - pats->regmatch.regprog = NULL; - } - -+ #ifdef FEAT_EVAL -+ /* -+ * Call the user-defined function to generate a list of tags used by -+ * find_tags(). -+ * -+ * Return OK if at least 1 tag has been successfully found, -+ * NOTDONE if the function returns v:null, and FAIL otherwise. -+ */ -+ static int -+ find_tagfunc_tags( -+ char_u *pat, // pattern supplied to the user-defined function -+ garray_T *ga, // the tags will be placed here -+ int *match_count, // here the number of tags found will be placed -+ int flags, // flags from find_tags (TAG_*) -+ char_u *buf_ffname) // name of buffer for priority -+ { -+ pos_T save_pos; -+ list_T *taglist; -+ listitem_T *item; -+ int ntags = 0; -+ int result = FAIL; -+ typval_T args[4]; -+ typval_T rettv; -+ char_u flagString[3]; -+ dict_T *d; -+ taggy_T *tag = &curwin->w_tagstack[curwin->w_tagstackidx]; -+ -+ if (*curbuf->b_p_tfu == NUL) -+ return FAIL; -+ -+ args[0].v_type = VAR_STRING; -+ args[0].vval.v_string = pat; -+ args[1].v_type = VAR_STRING; -+ args[1].vval.v_string = flagString; -+ -+ // create 'info' dict argument -+ if ((d = dict_alloc_lock(VAR_FIXED)) == NULL) -+ return FAIL; -+ if (tag->user_data != NULL) -+ dict_add_string(d, "user_data", tag->user_data); -+ if (buf_ffname != NULL) -+ dict_add_string(d, "buf_ffname", buf_ffname); -+ -+ ++d->dv_refcount; -+ args[2].v_type = VAR_DICT; -+ args[2].vval.v_dict = d; -+ -+ args[3].v_type = VAR_UNKNOWN; -+ -+ vim_snprintf((char *)flagString, sizeof(flagString), -+ "%s%s", -+ g_tag_at_cursor ? "c": "", -+ flags & TAG_INS_COMP ? "i": ""); -+ -+ save_pos = curwin->w_cursor; -+ result = call_vim_function(curbuf->b_p_tfu, 3, args, &rettv); -+ curwin->w_cursor = save_pos; // restore the cursor position -+ --d->dv_refcount; -+ -+ if (result == FAIL) -+ return FAIL; -+ if (rettv.v_type == VAR_SPECIAL && rettv.vval.v_number == VVAL_NULL) -+ { -+ clear_tv(&rettv); -+ return NOTDONE; -+ } -+ if (rettv.v_type != VAR_LIST || !rettv.vval.v_list) -+ { -+ clear_tv(&rettv); -+ emsg(_(tfu_inv_ret_msg)); -+ return FAIL; -+ } -+ taglist = rettv.vval.v_list; -+ -+ for (item = taglist->lv_first; item != NULL; item = item->li_next) -+ { -+ char_u *mfp; -+ char_u *res_name, *res_fname, *res_cmd, *res_kind; -+ int len; -+ dict_iterator_T iter; -+ char_u *dict_key; -+ typval_T *tv; -+ int has_extra = 0; -+ int name_only = flags & TAG_NAMES; -+ -+ if (item->li_tv.v_type != VAR_DICT) -+ { -+ emsg(_(tfu_inv_ret_msg)); -+ break; -+ } -+ -+ #ifdef FEAT_EMACS_TAGS -+ len = 3; -+ #else -+ len = 2; -+ #endif -+ res_name = NULL; -+ res_fname = NULL; -+ res_cmd = NULL; -+ res_kind = NULL; -+ -+ dict_iterate_start(&item->li_tv, &iter); -+ while (NULL != (dict_key = dict_iterate_next(&iter, &tv))) -+ { -+ if (tv->v_type != VAR_STRING || tv->vval.v_string == NULL) -+ continue; -+ -+ len += STRLEN(tv->vval.v_string) + 1; // Space for "\tVALUE" -+ if (!STRCMP(dict_key, "name")) -+ { -+ res_name = tv->vval.v_string; -+ continue; -+ } -+ if (!STRCMP(dict_key, "filename")) -+ { -+ res_fname = tv->vval.v_string; -+ continue; -+ } -+ if (!STRCMP(dict_key, "cmd")) -+ { -+ res_cmd = tv->vval.v_string; -+ continue; -+ } -+ has_extra = 1; -+ if (!STRCMP(dict_key, "kind")) -+ { -+ res_kind = tv->vval.v_string; -+ continue; -+ } -+ // Other elements will be stored as "\tKEY:VALUE" -+ // Allocate space for the key and the colon -+ len += STRLEN(dict_key) + 1; -+ } -+ -+ if (has_extra) -+ len += 2; // need space for ;" -+ -+ if (!res_name || !res_fname || !res_cmd) -+ { -+ emsg(_(tfu_inv_ret_msg)); -+ break; -+ } -+ -+ if (name_only) -+ mfp = vim_strsave(res_name); -+ else -+ mfp = (char_u *)alloc((int)sizeof(char_u) + len + 1); -+ -+ if (mfp == NULL) -+ continue; -+ -+ if (!name_only) -+ { -+ char_u *p = mfp; -+ -+ *p++ = MT_GL_OTH + 1; // mtt -+ *p++ = TAG_SEP; // no tag file name -+ #ifdef FEAT_EMACS_TAGS -+ *p++ = TAG_SEP; -+ #endif -+ -+ STRCPY(p, res_name); -+ p += STRLEN(p); -+ -+ *p++ = TAB; -+ STRCPY(p, res_fname); -+ p += STRLEN(p); -+ -+ *p++ = TAB; -+ STRCPY(p, res_cmd); -+ p += STRLEN(p); -+ -+ if (has_extra) -+ { -+ STRCPY(p, ";\""); -+ p += STRLEN(p); -+ -+ if (res_kind) -+ { -+ *p++ = TAB; -+ STRCPY(p, res_kind); -+ p += STRLEN(p); -+ } -+ -+ dict_iterate_start(&item->li_tv, &iter); -+ while (NULL != (dict_key = dict_iterate_next(&iter, &tv))) -+ { -+ if (tv->v_type != VAR_STRING || tv->vval.v_string == NULL) -+ continue; -+ -+ if (!STRCMP(dict_key, "name")) -+ continue; -+ if (!STRCMP(dict_key, "filename")) -+ continue; -+ if (!STRCMP(dict_key, "cmd")) -+ continue; -+ if (!STRCMP(dict_key, "kind")) -+ continue; -+ -+ *p++ = TAB; -+ STRCPY(p, dict_key); -+ p += STRLEN(p); -+ STRCPY(p, ":"); -+ p += STRLEN(p); -+ STRCPY(p, tv->vval.v_string); -+ p += STRLEN(p); -+ } -+ } -+ } -+ -+ // Add all matches because tagfunc should do filtering. -+ if (ga_grow(ga, 1) == OK) -+ { -+ ((char_u **)(ga->ga_data))[ga->ga_len++] = mfp; -+ ++ntags; -+ result = OK; -+ } -+ else -+ { -+ vim_free(mfp); -+ break; -+ } -+ } -+ -+ clear_tv(&rettv); -+ -+ *match_count = ntags; -+ return result; -+ } -+ #endif -+ - /* - * find_tags() - search for tags in tags files - * -*************** -*** 1268,1273 **** ---- 1540,1546 ---- - * TAG_NOIC don't always ignore case - * TAG_KEEP_LANG keep language - * TAG_CSCOPE use cscope results for tags -+ * TAG_NO_TAGFUNC do not call the 'tagfunc' function - */ - int - find_tags( -*************** -*** 1385,1390 **** ---- 1658,1666 ---- - int use_cscope = (flags & TAG_CSCOPE); - #endif - int verbose = (flags & TAG_VERBOSE); -+ #ifdef FEAT_EVAL -+ int use_tfu = ((flags & TAG_NO_TAGFUNC) == 0); -+ #endif - int save_p_ic = p_ic; - - /* -*************** -*** 1480,1485 **** ---- 1756,1773 ---- - vim_memset(&search_info, 0, (size_t)1); - #endif - -+ #ifdef FEAT_EVAL -+ if (*curbuf->b_p_tfu != NUL && use_tfu && !tfu_in_use) -+ { -+ tfu_in_use = TRUE; -+ retval = find_tagfunc_tags(pat, &ga_match[0], &match_count, -+ flags, buf_ffname); -+ tfu_in_use = FALSE; -+ if (retval != NOTDONE) -+ goto findtag_end; -+ } -+ #endif -+ - /* - * When finding a specified number of matches, first try with matching - * case, so binary search can be used, and try ignore-case matches in a -*************** -*** 2308,2314 **** - } - else - { -- #define TAG_SEP 0x02 - size_t tag_fname_len = STRLEN(tag_fname); - #ifdef FEAT_EMACS_TAGS - size_t ebuf_len = 0; ---- 2596,2601 ---- -*************** -*** 2577,2584 **** - tag_freematch(); - - # if defined(FEAT_QUICKFIX) -! if (ptag_entry.tagname) -! VIM_CLEAR(ptag_entry.tagname); - # endif - } - #endif ---- 2864,2870 ---- - tag_freematch(); - - # if defined(FEAT_QUICKFIX) -! tagstack_clear_entry(&ptag_entry); - # endif - } - #endif -*************** -*** 2940,2945 **** ---- 3226,3232 ---- - tagp); - - tagp->tagkind = NULL; -+ tagp->user_data = NULL; - tagp->command_end = NULL; - - if (retval == OK) -*************** -*** 2957,2973 **** - while (ASCII_ISALPHA(*p)) - { - if (STRNCMP(p, "kind:", 5) == 0) -- { - tagp->tagkind = p + 5; - break; -- } - pc = vim_strchr(p, ':'); - pt = vim_strchr(p, '\t'); - if (pc == NULL || (pt != NULL && pc > pt)) -- { - tagp->tagkind = p; -- break; -- } - if (pt == NULL) - break; - p = pt + 1; ---- 3244,3258 ---- - while (ASCII_ISALPHA(*p)) - { - if (STRNCMP(p, "kind:", 5) == 0) - tagp->tagkind = p + 5; -+ else if (STRNCMP(p, "user_data:", 10) == 0) -+ tagp->user_data = p + 10; -+ if (tagp->tagkind != NULL && tagp->user_data != NULL) - break; - pc = vim_strchr(p, ':'); - pt = vim_strchr(p, '\t'); - if (pc == NULL || (pt != NULL && pc > pt)) - tagp->tagkind = p; - if (pt == NULL) - break; - p = pt + 1; -*************** -*** 2980,2985 **** ---- 3265,3277 ---- - ; - tagp->tagkind_end = p; - } -+ if (tagp->user_data != NULL) -+ { -+ for (p = tagp->user_data; -+ *p && *p != '\t' && *p != '\r' && *p != '\n'; ++p) -+ ; -+ tagp->user_data_end = p; -+ } - } - return retval; - } -*************** -*** 3547,3552 **** ---- 3839,3854 ---- - return FAIL; - } - -+ /* -+ * Free a single entry in a tag stack -+ */ -+ static void -+ tagstack_clear_entry(taggy_T *item) -+ { -+ VIM_CLEAR(item->tagname); -+ VIM_CLEAR(item->user_data); -+ } -+ - #if defined(FEAT_CMDL_COMPL) || defined(PROTO) - int - expand_tags( -*************** -*** 3568,3578 **** - tagnmflag = 0; - if (pat[0] == '/') - ret = find_tags(pat + 1, num_file, file, -! TAG_REGEXP | tagnmflag | TAG_VERBOSE, - TAG_MANY, curbuf->b_ffname); - else - ret = find_tags(pat, num_file, file, -! TAG_REGEXP | tagnmflag | TAG_VERBOSE | TAG_NOIC, - TAG_MANY, curbuf->b_ffname); - if (ret == OK && !tagnames) - { ---- 3870,3880 ---- - tagnmflag = 0; - if (pat[0] == '/') - ret = find_tags(pat + 1, num_file, file, -! TAG_REGEXP | tagnmflag | TAG_VERBOSE | TAG_NO_TAGFUNC, - TAG_MANY, curbuf->b_ffname); - else - ret = find_tags(pat, num_file, file, -! TAG_REGEXP | tagnmflag | TAG_VERBOSE | TAG_NO_TAGFUNC | TAG_NOIC, - TAG_MANY, curbuf->b_ffname); - if (ret == OK && !tagnames) - { -*************** -*** 3753,3758 **** ---- 4055,4062 ---- - dict_add_string(retdict, "tagname", tag->tagname); - dict_add_number(retdict, "matchnr", tag->cur_match + 1); - dict_add_number(retdict, "bufnr", tag->cur_fnum); -+ if (tag->user_data) -+ dict_add_string(retdict, "user_data", tag->user_data); - - if ((pos = list_alloc_id(aid_tagstack_from)) == NULL) - return; -*************** -*** 3805,3811 **** - - // Free the current tag stack - for (i = 0; i < wp->w_tagstacklen; ++i) -! vim_free(wp->w_tagstack[i].tagname); - wp->w_tagstacklen = 0; - wp->w_tagstackidx = 0; - } ---- 4109,4115 ---- - - // Free the current tag stack - for (i = 0; i < wp->w_tagstacklen; ++i) -! tagstack_clear_entry(&wp->w_tagstack[i]); - wp->w_tagstacklen = 0; - wp->w_tagstackidx = 0; - } -*************** -*** 3820,3826 **** - taggy_T *tagstack = wp->w_tagstack; - int i; - -! vim_free(tagstack[0].tagname); - for (i = 1; i < wp->w_tagstacklen; ++i) - tagstack[i - 1] = tagstack[i]; - wp->w_tagstacklen--; ---- 4124,4130 ---- - taggy_T *tagstack = wp->w_tagstack; - int i; - -! tagstack_clear_entry(&tagstack[0]); - for (i = 1; i < wp->w_tagstacklen; ++i) - tagstack[i - 1] = tagstack[i]; - wp->w_tagstacklen--; -*************** -*** 3836,3842 **** - int cur_fnum, - int cur_match, - pos_T mark, -! int fnum) - { - taggy_T *tagstack = wp->w_tagstack; - int idx = wp->w_tagstacklen; // top of the stack ---- 4140,4147 ---- - int cur_fnum, - int cur_match, - pos_T mark, -! int fnum, -! char_u *user_data) - { - taggy_T *tagstack = wp->w_tagstack; - int idx = wp->w_tagstacklen; // top of the stack -*************** -*** 3856,3861 **** ---- 4161,4167 ---- - tagstack[idx].cur_match = 0; - tagstack[idx].fmark.mark = mark; - tagstack[idx].fmark.fnum = fnum; -+ tagstack[idx].user_data = user_data; - } - - /* -*************** -*** 3892,3898 **** - tagstack_push_item(wp, tagname, - (int)dict_get_number(itemdict, (char_u *)"bufnr"), - (int)dict_get_number(itemdict, (char_u *)"matchnr") - 1, -! mark, fnum); - } - } - ---- 4198,4205 ---- - tagstack_push_item(wp, tagname, - (int)dict_get_number(itemdict, (char_u *)"bufnr"), - (int)dict_get_number(itemdict, (char_u *)"matchnr") - 1, -! mark, fnum, -! dict_get_string(itemdict, (char_u *)"user_data", TRUE)); - } - } - -*************** -*** 3920,3925 **** ---- 4227,4241 ---- - dictitem_T *di; - list_T *l; - -+ #ifdef FEAT_EVAL -+ // not allowed to alter the tag stack entries from inside tagfunc -+ if (tfu_in_use) -+ { -+ emsg(_(recurmsg)); -+ return FAIL; -+ } -+ #endif -+ - if ((di = dict_find(d, (char_u *)"items", -1)) != NULL) - { - if (di->di_tv.v_type != VAR_LIST) -*** ../vim-8.1.1227/src/testdir/Make_all.mak 2019-04-27 18:00:29.851064563 +0200 ---- src/testdir/Make_all.mak 2019-04-28 16:47:48.260732097 +0200 -*************** -*** 244,249 **** ---- 244,250 ---- - test_tabline \ - test_tabpage \ - test_tagcase \ -+ test_tagfunc \ - test_tagjump \ - test_taglist \ - test_tcl \ -*** ../vim-8.1.1227/src/testdir/test_alot.vim 2019-03-02 06:41:34.345330494 +0100 ---- src/testdir/test_alot.vim 2019-04-28 16:47:48.260732097 +0200 -*************** -*** 60,65 **** ---- 60,66 ---- - source test_tabline.vim - source test_tabpage.vim - source test_tagcase.vim -+ source test_tagfunc.vim - source test_tagjump.vim - source test_taglist.vim - source test_timers.vim -*** ../vim-8.1.1227/src/testdir/test_tagfunc.vim 2019-04-28 18:02:57.627069396 +0200 ---- src/testdir/test_tagfunc.vim 2019-04-28 17:48:10.655362588 +0200 -*************** -*** 0 **** ---- 1,84 ---- -+ " Test 'tagfunc' -+ -+ func TagFunc(pat, flag, info) -+ let g:tagfunc_args = [a:pat, a:flag, a:info] -+ let tags = [] -+ for num in range(1,10) -+ let tags += [{ -+ \ 'cmd': '2', 'name': 'nothing'.num, 'kind': 'm', -+ \ 'filename': 'Xfile1', 'user_data': 'somedata'.num, -+ \}] -+ endfor -+ return tags -+ endfunc -+ -+ func Test_tagfunc() -+ set tagfunc=TagFunc -+ new Xfile1 -+ call setline(1, ['empty', 'one()', 'empty']) -+ write -+ -+ call assert_equal({'cmd': '2', 'static': 0, -+ \ 'name': 'nothing2', 'user_data': 'somedata2', -+ \ 'kind': 'm', 'filename': 'Xfile1'}, taglist('.')[1]) -+ -+ call settagstack(win_getid(), {'items': []}) -+ -+ tag arbitrary -+ call assert_equal('arbitrary', g:tagfunc_args[0]) -+ call assert_equal('', g:tagfunc_args[1]) -+ call assert_equal('somedata1', gettagstack().items[0].user_data) -+ 5tag arbitrary -+ call assert_equal('arbitrary', g:tagfunc_args[0]) -+ call assert_equal('', g:tagfunc_args[1]) -+ call assert_equal('somedata5', gettagstack().items[1].user_data) -+ pop -+ tag -+ call assert_equal('arbitrary', g:tagfunc_args[0]) -+ call assert_equal('', g:tagfunc_args[1]) -+ call assert_equal('somedata5', gettagstack().items[1].user_data) -+ -+ let g:tagfunc_args=[] -+ execute "normal! \<c-]>" -+ call assert_equal('one', g:tagfunc_args[0]) -+ call assert_equal('c', g:tagfunc_args[1]) -+ -+ set cpt=t -+ let g:tagfunc_args=[] -+ execute "normal! i\<c-n>\<c-y>" -+ call assert_equal('ci', g:tagfunc_args[1]) -+ call assert_equal('nothing1', getline('.')[0:7]) -+ -+ func BadTagFunc1(...) -+ return 0 -+ endfunc -+ func BadTagFunc2(...) -+ return [1] -+ endfunc -+ func BadTagFunc3(...) -+ return [{'name': 'foo'}] -+ endfunc -+ -+ for &tagfunc in ['BadTagFunc1', 'BadTagFunc2', 'BadTagFunc3'] -+ try -+ tag nothing -+ call assert_false(1, 'tag command should have failed') -+ catch -+ call assert_exception('E987:') -+ endtry -+ exe 'delf' &tagfunc -+ endfor -+ -+ func NullTagFunc(...) -+ return v:null -+ endfunc -+ set tags= tfu=NullTagFunc -+ call assert_fails('tag nothing', 'E426') -+ delf NullTagFunc -+ -+ bwipe! -+ set tags& tfu& cpt& -+ call delete('Xfile1') -+ endfunc -+ -+ " vim: shiftwidth=2 sts=2 expandtab -*** ../vim-8.1.1227/src/vim.h 2019-04-08 18:15:36.472223190 +0200 ---- src/vim.h 2019-04-28 17:18:43.131769441 +0200 -*************** -*** 1133,1151 **** - /* - * flags for find_tags(). - */ -! #define TAG_HELP 1 /* only search for help tags */ -! #define TAG_NAMES 2 /* only return name of tag */ -! #define TAG_REGEXP 4 /* use tag pattern as regexp */ -! #define TAG_NOIC 8 /* don't always ignore case */ - #ifdef FEAT_CSCOPE -! # define TAG_CSCOPE 16 /* cscope tag */ - #endif -! #define TAG_VERBOSE 32 /* message verbosity */ -! #define TAG_INS_COMP 64 /* Currently doing insert completion */ -! #define TAG_KEEP_LANG 128 /* keep current language */ - -! #define TAG_MANY 300 /* When finding many tags (for completion), -! find up to this many tags */ - - /* - * Types of dialogs passed to do_vim_dialog(). ---- 1133,1152 ---- - /* - * flags for find_tags(). - */ -! #define TAG_HELP 1 // only search for help tags -! #define TAG_NAMES 2 // only return name of tag -! #define TAG_REGEXP 4 // use tag pattern as regexp -! #define TAG_NOIC 8 // don't always ignore case - #ifdef FEAT_CSCOPE -! # define TAG_CSCOPE 16 // cscope tag - #endif -! #define TAG_VERBOSE 32 // message verbosity -! #define TAG_INS_COMP 64 // Currently doing insert completion -! #define TAG_KEEP_LANG 128 // keep current language -! #define TAG_NO_TAGFUNC 256 // do not use 'tagfunc' - -! #define TAG_MANY 300 // When finding many tags (for completion), -! // find up to this many tags - - /* - * Types of dialogs passed to do_vim_dialog(). -*** ../vim-8.1.1227/src/window.c 2019-04-27 20:36:52.534303564 +0200 ---- src/window.c 2019-04-28 16:47:48.260732097 +0200 -*************** -*** 1326,1335 **** - /* copy tagstack and folds */ - for (i = 0; i < oldp->w_tagstacklen; i++) - { -! newp->w_tagstack[i] = oldp->w_tagstack[i]; -! if (newp->w_tagstack[i].tagname != NULL) -! newp->w_tagstack[i].tagname = -! vim_strsave(newp->w_tagstack[i].tagname); - } - newp->w_tagstackidx = oldp->w_tagstackidx; - newp->w_tagstacklen = oldp->w_tagstacklen; ---- 1326,1337 ---- - /* copy tagstack and folds */ - for (i = 0; i < oldp->w_tagstacklen; i++) - { -! taggy_T *tag = &newp->w_tagstack[i]; -! *tag = oldp->w_tagstack[i]; -! if (tag->tagname != NULL) -! tag->tagname = vim_strsave(tag->tagname); -! if (tag->user_data != NULL) -! tag->user_data = vim_strsave(tag->user_data); - } - newp->w_tagstackidx = oldp->w_tagstackidx; - newp->w_tagstacklen = oldp->w_tagstacklen; -*** ../vim-8.1.1227/src/version.c 2019-04-28 16:08:26.813234002 +0200 ---- src/version.c 2019-04-28 18:03:04.703034923 +0200 -*************** -*** 769,770 **** ---- 769,772 ---- - { /* Add new patch number below this line */ -+ /**/ -+ 1228, - /**/ - --- -Courtroom Quote #19: -Q: Doctor, how many autopsies have you performed on dead people? -A: All my autopsies have been performed on dead people. - - /// 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 /// |