patch 8.1.1228: not possible to process tags with a function

Problem:    Not possible to process tags with a function.
Solution:   Add tagfunc() (Christian Brabandt, Andy Massimino, closes #4010)
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index 87d29a0..985137b 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -7458,6 +7458,16 @@
 	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
diff --git a/runtime/doc/tagsrch.txt b/runtime/doc/tagsrch.txt
index d7646e4..bc38452 100644
--- a/runtime/doc/tagsrch.txt
+++ b/runtime/doc/tagsrch.txt
@@ -1,4 +1,4 @@
-*tagsrch.txt*   For Vim version 8.1.  Last change: 2019 Mar 30
+*tagsrch.txt*   For Vim version 8.1.  Last change: 2019 Apr 28
 
 
 		  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -14,6 +14,7 @@
 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*
@@ -871,4 +872,70 @@
 <	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:
diff --git a/runtime/optwin.vim b/runtime/optwin.vim
index a2ef90c..4ba1ab1 100644
--- a/runtime/optwin.vim
+++ b/runtime/optwin.vim
@@ -300,6 +300,11 @@
 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)