If you create tag files with Exuberant CTags using inheritance information ( see the --fields parameter ), then the following script will Work. He adds the command :Inherits , which accepts either a class name (for example :Inherits Foo ) or a regular expression.
Like the :tag command, you indicate that you want a regular expression search, preceded by a '\', for example. :Inherits \Foo.* .
The results are placed in the location list of the window that you are viewing with :ll :lne :lp , etc. VIM does not seem to allow scripts to modify the tag list, they prefer.
If you're wondering why I'm not using taglist() for this, because taglist() incredibly slow in large tag files. The original post had a version using taglist() , if you're interested, you can view the change history.
" Parse an Exuberant Ctags record using the same format as taglist() " " Throws CtagsParseErr if there is a general problem parsing the record function! ParseCtagsRec(record, tag_dir) let tag = {} " Parse the standard fields let sep_pos = stridx(a:record, "\t") if sep_pos < 1 throw 'CtagsParseErr' endif let tag['name'] = a:record[:sep_pos - 1] let tail = a:record[sep_pos + 1:] let sep_pos = stridx(tail, "\t") if sep_pos < 1 throw 'CtagsParseErr' endif " '/' will work as a path separator on most OS's, but there " should really be an OS independent way to build paths. let tag['filename'] = a:tag_dir.'/'.tail[:sep_pos - 1] let tail = tail[sep_pos + 1:] let sep_pos = stridx(tail, ";\"\t") if sep_pos < 1 throw 'CtagsParseErr' endif let tag['cmd'] = tail[:sep_pos - 1] " Parse the Exuberant Ctags extension fields let extensions = tail[sep_pos + 3:] for extension in split(extensions, '\t') let sep_pos = stridx(extension, ':') if sep_pos < 1 if has_key(tag, 'kind') throw 'CtagsParseErr' endif let tag['kind'] = extension else let tag[extension[:sep_pos - 1]] = extension[sep_pos + 1:] endif endfor return tag endfunction " Find all classes derived from a given class, or a regex (preceded by a '/') " The results are placed in the current windows location list. function! Inherits(cls_or_regex) if a:cls_or_regex[0] == '/' let regex = a:cls_or_regex[1:] else let regex = '\<'.a:cls_or_regex.'\>$' endif let loc_list = [] let tfiles = tagfiles() let tag_count = 0 let found_count = 0 for file in tfiles let tag_dir = fnamemodify(file, ':p:h') try for line in readfile(file) let tag_count += 1 if tag_count % 10000 == 0 echo tag_count 'tags scanned,' found_count 'matching classes found. Still searching...' redraw endif if line[0] == '!' continue endif let tag = ParseCtagsRec(line, tag_dir) if has_key(tag, 'inherits') let baselist = split(tag['inherits'], ',\s*') for base in baselist if match(base, regex) != -1 let location = {} let location['filename'] = tag['filename'] let cmd = tag['cmd'] if cmd[0] == '/' || cmd[0] == '?' let location['pattern'] = cmd[1:-2] else let location['lnum'] = str2nr(cmd) endif call add(loc_list, location) let found_count += 1 endif endfor endif endfor catch /^OptionErr$/ echo 'Parsing error: Failed to parse an option.' return catch /^CtagsParseErr$/ echo 'Parsing error: Tags files does not appear to be an Exuberant Ctags file.' return catch echo 'Could not read tag file:' file return endtry endfor call setloclist(0, loc_list) echo tag_count 'tags scanned,' found_count 'matching classes found.' endfunction command! -nargs=1 -complete=tag Inherits call Inherits('<args>')