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)