Hello list.  The attached patch allows optional regexs to be passed to
:tj and friends.  these regexs is then used to further refine available
tags before they are printed.

This patch is useful when you have many tags for a single identifier.
For example, suppose a large C++ project has initialize() methods for
100s of classes.  Going through the list of tags printed by :tj is
tedious.  Most of the time I know additional information about the
identifier I am looking for like the containing object type or source
filename.  The text after the '/' in the argument is used as a regex
(unless a '/' is the first character of the tag identifier, then the
text after the second '/' is used) to match against the "other" tag
fields (which often contains the containing type name).  If a '!' is
present, text after it is used to match against filenames.  With this
patch you can type:

:tj initialize/SomeClass

to list all tags that also contain "SomeClass" in their "other" fields
or

:ts initialize/!arch/amd64

to list all tags matching initialize that contain "arch/amd64" in the
containing file's pathname.  Or a mix:

:ts initialize/SomeClass!arch/amd64

The '/' and '!' characters were chosen somewhat arbitrarily--I'm not
sure if they are a safe choice.

Any comments are appreciated.

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.


diff -r acf7368a2acc src/edit.c
--- a/src/edit.c        Thu Mar 21 22:53:50 2013 +0100
+++ b/src/edit.c        Thu Mar 28 21:21:36 2013 -0400
@@ -4322,7 +4322,7 @@ ins_compl_get_exp(ini)
            if (find_tags(compl_pattern, &num_matches, &matches,
                    TAG_REGEXP | TAG_NAMES | TAG_NOIC |
                    TAG_INS_COMP | (ctrl_x_mode ? TAG_VERBOSE : 0),
-                   TAG_MANY, curbuf->b_ffname) == OK && num_matches > 0)
+                   TAG_MANY, curbuf->b_ffname, NULL) == OK && num_matches > 0)
            {
                ins_compl_add_matches(num_matches, matches, p_ic);
            }
diff -r acf7368a2acc src/ex_cmds.c
--- a/src/ex_cmds.c     Thu Mar 21 22:53:50 2013 +0100
+++ b/src/ex_cmds.c     Thu Mar 28 21:21:36 2013 -0400
@@ -6074,7 +6074,7 @@ find_help_tags(arg, num_matches, matches
     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
+    if (find_tags(IObuff, num_matches, matches, flags, (int)MAXCOL, NULL, 
NULL) == OK
            && *num_matches > 0)
     {
        /* Sort the matches found on the heuristic number that is after the
diff -r acf7368a2acc src/proto/tag.pro
--- a/src/proto/tag.pro Thu Mar 21 22:53:50 2013 +0100
+++ b/src/proto/tag.pro Thu Mar 28 21:21:36 2013 -0400
@@ -2,7 +2,7 @@
 int do_tag __ARGS((char_u *tag, int type, int count, int forceit, int 
verbose));
 void tag_freematch __ARGS((void));
 void do_tags __ARGS((exarg_T *eap));
-int find_tags __ARGS((char_u *pat, int *num_matches, char_u ***matchesp, int 
flags, int mincount, char_u *buf_ffname));
+int find_tags __ARGS((char_u *pat, int *num_matches, char_u ***matchesp, int 
flags, int mincount, char_u *buf_ffname, char_u *refpat));
 void free_tag_stuff __ARGS((void));
 int get_tagfname __ARGS((tagname_T *tnp, int first, char_u *buf));
 void tagname_free __ARGS((tagname_T *tnp));
diff -r acf7368a2acc src/tag.c
--- a/src/tag.c Thu Mar 21 22:53:50 2013 +0100
+++ b/src/tag.c Thu Mar 28 21:21:36 2013 -0400
@@ -160,6 +160,7 @@ do_tag(tag, type, count, forceit, verbos
     int                skip_msg = FALSE;
     char_u     *buf_ffname = curbuf->b_ffname;     /* name to use for
                                                       priority computation */
+    char_u     *refpat;
 
     /* remember the matches for the last used tag */
     static int         num_matches = 0;
@@ -532,6 +533,10 @@ do_tag(tag, type, count, forceit, verbos
            else
                flags = TAG_NOIC;
 
+           /* set tag refine pattern, if any */
+           if ((refpat = vim_strchr(name, '/')) != NULL)
+               *refpat++ = NUL;
+
 #ifdef FEAT_CSCOPE
            if (type == DT_CSCOPE)
                flags = TAG_CSCOPE;
@@ -539,7 +544,7 @@ do_tag(tag, type, count, forceit, verbos
            if (verbose)
                flags |= TAG_VERBOSE;
            if (find_tags(name, &new_num_matches, &new_matches, flags,
-                                           max_num_matches, buf_ffname) == OK
+                                           max_num_matches, buf_ffname, 
refpat) == OK
                    && new_num_matches < max_num_matches)
                max_num_matches = MAXCOL; /* If less than max_num_matches
                                             found: all matches found. */
@@ -1266,7 +1271,7 @@ prepare_pats(pats, has_re)
  * TAG_KEEP_LANG  keep language
  */
     int
-find_tags(pat, num_matches, matchesp, flags, mincount, buf_ffname)
+find_tags(pat, num_matches, matchesp, flags, mincount, buf_ffname, refpat)
     char_u     *pat;                   /* pattern to search for */
     int                *num_matches;           /* return: number of matches 
found */
     char_u     ***matchesp;            /* return: array of matches found */
@@ -1274,6 +1279,7 @@ find_tags(pat, num_matches, matchesp, fl
     int                mincount;               /*  MAXCOL: find all matches
                                             other: minimal number of matches */
     char_u     *buf_ffname;            /* name of buffer for priority */
+    char_u     *refpat;                /* optional refining pattern */
 {
     FILE       *fp;
     char_u     *lbuf;                  /* line buffer */
@@ -2173,6 +2179,62 @@ line_read_in:
                match_re = TRUE;
            }
 
+           if (match && refpat) {
+
+               regmatch_T rm;
+               char_u *tmp;
+               int bail = FALSE;
+
+               rm.rm_ic = FALSE;
+               rm.regprog = NULL;
+
+               /* See if filename field is specified */
+               /* identifier/{other info regex}!{filename regex} */
+               if ((tmp = vim_strchr(refpat, '!')) != NULL) {
+                   tmp++;
+                   rm.regprog = vim_regcomp(tmp, RE_MAGIC + RE_STRING);
+
+                   if (!rm.regprog)
+                       EMSG(_("Couldn't compile file regex"));
+                   else {
+
+                       /* Null terminate file name */
+                       char_u old = *tagp.fname_end;
+                       *tagp.fname_end = NUL;
+
+                       if (!vim_regexec(&rm, tagp.fname, (colnr_T)0)) {
+                           match = FALSE;
+                           bail = TRUE;
+                       }
+
+                       *tagp.fname_end = old;
+                       vim_free(rm.regprog);
+                   }
+                   tmp--;  // tmp points to '!' again
+               }
+
+               if (!bail && refpat != tmp && tagp.command) {
+
+                   if (tmp)
+                       *tmp = NUL;
+
+                   rm.regprog = vim_regcomp(refpat, RE_MAGIC + RE_STRING);
+
+                   if (rm.regprog) {
+
+                       if (!vim_regexec(&rm, tagp.command, (colnr_T)0))
+                           match = FALSE;
+
+                       vim_free(rm.regprog);
+                   } else
+                       EMSG(_("Couldn't compile regex"));
+
+                   /* Repair refpat */
+                   if (tmp)
+                       *tmp = '!';
+               }
+           }
+
            /*
             * If a match is found, add it to ga_match[].
             */
@@ -3756,11 +3818,11 @@ expand_tags(tagnames, pat, num_file, fil
     if (pat[0] == '/')
        ret = find_tags(pat + 1, num_file, file,
                TAG_REGEXP | tagnmflag | TAG_VERBOSE,
-               TAG_MANY, curbuf->b_ffname);
+               TAG_MANY, curbuf->b_ffname, NULL);
     else
        ret = find_tags(pat, num_file, file,
                TAG_REGEXP | tagnmflag | TAG_VERBOSE | TAG_NOIC,
-               TAG_MANY, curbuf->b_ffname);
+               TAG_MANY, curbuf->b_ffname, NULL);
     if (ret == OK && !tagnames)
     {
         /* Reorganize the tags for display and matching as strings of:
@@ -3852,7 +3914,7 @@ get_tags(list, pat)
     long       is_static;
 
     ret = find_tags(pat, &num_matches, &matches,
-                                   TAG_REGEXP | TAG_NOIC, (int)MAXCOL, NULL);
+                                   TAG_REGEXP | TAG_NOIC, (int)MAXCOL, NULL, 
NULL);
     if (ret == OK && num_matches > 0)
     {
        for (i = 0; i < num_matches; ++i)

Raspunde prin e-mail lui