summaryrefslogtreecommitdiff
path: root/data/vim/patches/8.1.1228
diff options
context:
space:
mode:
Diffstat (limited to 'data/vim/patches/8.1.1228')
-rw-r--r--data/vim/patches/8.1.12281467
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 ///