Skip to content

Commit

Permalink
Version 0.1: Initial upload
Browse files Browse the repository at this point in the history
  • Loading branch information
lyokha authored and vim-scripts committed Oct 7, 2012
0 parents commit babd615
Show file tree
Hide file tree
Showing 5 changed files with 631 additions and 0 deletions.
34 changes: 34 additions & 0 deletions README
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
This is a mirror of http://www.vim.org/scripts/script.php?script_id=4253

This plugin is capable of managing both tag jumps and highlights databases simultaneously for different projects. It consists of two standalone applications BuildTags and MakeVimHlTags and this file. To manage tag highlights it uses excellent plugin TagHighlight (http://www.vim.org/scripts/script.php?script_id=2646) as backend. The plugin also needs exuberant ctags and (optionally) cscope packages.

TagManager can manage both jumps and highlights tags incrementally, it means that projects may depend on other projects and user can setup his projects in such a way that he would need to update only small pieces of tags databases related to changes he would have made for a small project: all not changed dependencies would not be rebuilt and would be attached to the small projects as is. For example user can manage a small project my_proj which depends on large 3rd-party libraries libLarge1 and libLarge2 that he would definitely never change (we denote this sort of dependency as my_proj:libLarge1,libLarge2), then when he decide to update the tags of the project my_proj, tags from libLarge1 and libLarge2 will be attached to those from my_proj not having been rebuilt.

The plugin provides 3 commands:

UpdateProjectJumps
UpdateProjectHighlights
UpdateProjectTags

Normally you will need only UpdateProjectTags which is a simple sequence of the first two. Issuing :UpdateProjectTags will update both jumps and highlights tags in the project you are currently in.

To use the plugin efficiently add following lines in your .vimrc:

if !exists('g:TagHighlightSettings')
let g:TagHighlightSettings = {}
endif
let g:TagHighlightSettings['LanguageDetectionMethods'] =
\ ['Extension', 'FileType']
let g:TagHighlightSettings['FileTypeLanguageOverrides'] =
\ {'svn': 'c', 'tagbar': 'c'}
runtime plugin/TagManager.vim

Setting variable g:TagHighlightSettings['FileTypeLanguageOverrides'] will let you enjoy tag highlights in tagbar window and when committed svn changes. Sourcing the plugin code in .vimrc is needed as far as TagManager depends on TagHighlight plugin and autocommands from TagManager must go before corresponding autocommands from TagHighlight.

You also may want to put scripts BuildTags and MakeVimHlTags in some directory listed in your $PATH environment variable (by default this plugin expects to find them in $HOME/bin/), and create new environment variable $TAGSDIR where all plugin data will be saved. Now you can additionally use BuildTags and MakeVimHlTags as standalone scripts and create tags for vim directly from command line. To see available command-line options run the scripts with option --help.

By default plugin reads configuration file $HOME/.vim-TagManager.conf where a user defines settings for building and updating tags for his projects. Each line in the configuration file corresponds to one project and consists of 5 columns, separated with double semicolon (possibly surrounded by spaces or tabs). The first column is a directory match pattern used to define where the project resides, second column - name of the project with optionally appended (after colon) comma-separated list of other projects upon which this project depends, third column - language for building tag highlights (for example 'c' or 'python'), if user do not want to specify any language (i.e. highlights tags will be built for any languages that TagHighlight supports) then he can put in this column special placeholder - exclamation sign (!) which denotes empty value, fourth column - root directory for building jumps and highlights tags, fifth column - options for MakeVimHlTags, to see them run

MakeVimHlTags --help

in command line. Please make sure that you understand the difference between values in column 1 and column 4: the former will be used in autocommands for finding out if specific directory matches project directory pattern and thus may contain glob symbols like '*' or '?', whereas the latter denotes the root directory for building tags. Values in any column may refer to environment variables: they will be expanded. An example of configuration file is shipped with this distribution.
63 changes: 63 additions & 0 deletions TagManager/BuildTags
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#!/bin/bash

def_pref="Unnamed"
cscope_in_suf="cscope_files"
cscope_out_suf="cscope_out"
ctags_out_suf="ctags"

PrintUsage()
{
echo "Usage: `basename $0` [-p prefix] [-d dst_dir] [-c ctags_prog] [dirs...]"
echo " 'prefix' is prefix for output file names (default is $def_pref)"
echo " 'dst_dir' is the place where files will be put"
echo " (default is environment variable TAGSDIR or current dir"
echo " if TAGSDIR is not set)"
echo " 'ctags_prog' is path to ctags executable (default is the system path)"
echo " 'dirs' is a space-separated list of directories where to find source files,"
echo " if omitted then current directory is considered"
}

while [ $1 ]
do
case $1 in
-h|-help|--help) PrintUsage ; exit 0 ;;
-p) shift ; pref=$1 ;;
-d) shift ; dst_dir=$1 ;;
-c) shift ; ctags_prog=$1 ;;
*) if [ "${1:0:1}" = "/" ] ; then
src_dirs=$src_dirs' '$1
else
src_dirs=$src_dirs' '`pwd`/$1
fi ;;
esac
shift
done

[ -z "$pref" ] && pref=$def_pref
[ -z "$dst_dir" ] && dst_dir=$TAGSDIR
[ -z "$dst_dir" ] && dst_dir=`pwd`
[ -z "$src_dirs" ] && src_dirs=`pwd`

if [ ! -e "$dst_dir" ] ; then
echo "Error: $dst_dir does not exist"
exit 1
fi

[ -z "$ctags_prog" ] && ctags_prog=`which ctags`

if [ ! -x "$ctags_prog" ] ; then
echo "Error: $ctags_prog does not exist"
exit 1
fi

cscope_in_file=$dst_dir/$pref.$cscope_in_suf
cscope_out_file=$dst_dir/$pref.$cscope_out_suf
ctags_out_file=$dst_dir/$pref.$ctags_out_suf

echo "Building cscope tags ..."
find $src_dirs -name '*.[hxc]' -o -name '*.cc' -o -name '*.icc' > $cscope_in_file
cscope -u -b -q -i $cscope_in_file -f $cscope_out_file
rm -f $cscope_in_file

echo "Building ctags tags ..."
$ctags_prog -R --c++-kinds=+p --fields=+iaS --extra=+q -f $ctags_out_file $src_dirs
215 changes: 215 additions & 0 deletions TagManager/MakeVimHlTags
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
#!/usr/bin/env perl

# this is a standalone application using an internal python script from
# vim plugin TagHighlight by Al Budden

use Cwd;
use Getopt::Std;

$VERSION = "1.6";
( $PROGNAME = $0 ) =~ s/.*\///;

my $SILENTPTN = qr/^silent!*\s+/o;
my $EMPTYEXPRPTN = qr/^syn(?:tax)? keyword \w+\s*$/o;

my %LANG_KEYWORDS = (
cpp => [ 'bool', 'break', 'catch', 'class', 'const', 'delete', 'explicit',
'export', 'extern', 'false', 'friend', 'inline', 'mutable',
'namespace', 'new', 'operator', 'private', 'protected', 'public',
'reinterpret_cast', 'static_cast', 'template', 'this', 'throw',
'true', 'try', 'typeid', 'typename', 'using', 'virtual' ]
);

sub VERSION_MESSAGE
{
PrintUsage();
exit 0;
}

sub PrintUsage
{
print "$PROGNAME, version $VERSION\n";
print "Usage: $PROGNAME [-r] [-l] [-e <patterns>] [-a <projects>]\n";
print " [-c ctags_prog] [-L lang] [-d dst_dir] -p project_name\n";
print " [<directories>]\n";
print " $PROGNAME -k\n";
print " If <directories> is empty then current directory will be used\n";
print " -r recursive descending into <directories>\n";
print " -l include local variables\n";
print " -e list of comma-separated patterns corresponding to tags to be\n";
print " excluded, <patterns> may contain prepending and appending dots\n";
print " that mean any characters but spaces, for instance pattern\n";
print " 'G4.' matches all tags that start with 'G4'; also patterns may\n";
print " start with '\@' that prepends a programming language identifier\n";
print " which keywords must be excluded, list of supported languages\n";
print " and corresponding keywords is printed when using option -k\n";
print " -a add symbols from projects in <projects> to result file\n";
print " <projects> is a comma-separated list\n";
print " -c full path to 'ctags' executable, if omitted then system ctags\n";
print " will be used\n";
print " -L build tags only for specified language\n";
print " -d path where tags file will be put (if not set then check if\n";
print " environment variable TAGSDIR is set and use its value,\n";
print " if TAGSDIR is not set then use current directory)\n";
print " -k print list of languages that can be used in option -e and\n";
print " effective keywords for them\n";
}

sub PrintLangmap
{
for my $lang ( sort keys %LANG_KEYWORDS )
{
print " $lang:\n";
for my $keyword ( sort @{ $LANG_KEYWORDS{ $lang } } )
{
print " $keyword\n";
}
}
}

getopts( "a:p:d:e:lrc:L:k" );
unless ( $opt_p )
{
if ( $opt_k )
{
PrintLangmap();
exit 0;
}

PrintUsage();
exit 1;
}

PrintLangmap() if $opt_k;

chomp ( my $ctagsProg = $opt_c || `which ctags` );

die "ctags executable was not found" unless $ctagsProg;

my $mktypesPy = "$ENV{ HOME }/.vim/plugin/TagHighlight/TagHighlight.py";
die( "$mktypesPy not found" ) unless -f $mktypesPy;

my $tmpDir = $ENV{ TMPDIR } || "/tmp";
my $typesLink = "types_${opt_p}_". $ENV{ USER };
my $tagsFile = "tags_${opt_p}_" . $ENV{ USER };
my $lang = $opt_L || "c";

my $mktypesPyArgs = "";
$mktypesPyArgs .= " --include-language=$lang" if $opt_L;
$mktypesPyArgs .= " --include-locals" if $opt_l;
$mktypesPyArgs .= " --no-recurse" unless $opt_r;
$mktypesPyArgs .= " --types-file-location=$tmpDir";
$mktypesPyArgs .= " --types-file-prefix=$typesLink";
$mktypesPyArgs .= " --ctags-file-dir=$tmpDir";
$mktypesPyArgs .= " --ctags-file=$tagsFile";
$mktypesPyArgs .= " --ctags-exe-full-path=$ctagsProg";
#$mktypesPyArgs .= " --include-invalid-keywords-as-matches";

# add some debug information if needed:
#$mktypesPyArgs .= " --debug=Information" .
#" --debug-file=$tmpDir/${PROGNAME}_$ENV{ USER }_LOG";

$typesLink = $tmpDir . "/" . $typesLink . "_$lang.taghl";
$tagsFile = $tmpDir . "/" . $tagsFile;

my $dstDir = $opt_d || $ENV{ TAGSDIR } || ".";
my $resFile = "$dstDir/${opt_p}_$lang.vim";

my @excl = (); # hold patterns of tags to be excluded

foreach ( split ',', $opt_e )
{
my $e = $_;
if ( /^@(.*)/o )
{
my $lang = $1;
if ( ! exists $LANG_KEYWORDS{ $lang } )
{
print "Language '$lang' is not supported, run\n\n";
print "$PROGNAME -k\n\n";
print "to see all supported languages\n";
exit 2;
}
push @excl, map { "\\b" . $_ . "\\b" } @{ $LANG_KEYWORDS{ $lang } };
next;
}
if ( /^\./o )
{
$e = "\\b\\w+" . s/^\.//o;
}
else
{
$e = "\\b" . $e;
}
if ( /\w+\.$/o )
{
$e =~ s/\.$//o;
$e .= "\\w+\\b";
}
else
{
$e .= "\\b";
}
push @excl, $e;
}

open( RESULT, "> $resFile" ) or die( $! );

foreach ( split ',', $opt_a )
{
my $file = "$dstDir/$_" . "_$lang.vim";
unless ( open SOURCE, "< $file" )
{
print "project '$_' does not exist, skipped\n";
next;
}
my @fileContent = <SOURCE>;
print RESULT @fileContent;
close SOURCE;
}

my @dirs = @ARGV;
push @dirs, "." if @dirs == 0;

foreach ( @dirs )
{
print $_, ":\n";

system( "python $mktypesPy $mktypesPyArgs -d$_" );

if ( open( ORIG, "< $typesLink" ) )
{
print RESULT "\n\"$_\n";

while ( <ORIG> )
{
next if /$SILENTPTN/;
foreach my $e ( @excl )
{
s/$e//g;
}
next if /$EMPTYEXPRPTN/;
print RESULT $_;
}
close( ORIG ) or die $!;
if ( unlink( $typesLink ) != 1 )
{
warn( "cannot delete '$typesLink' file" );
}
else
{
print "Temporary file '$typesLink' removed\n";
}
}
if ( unlink( $tagsFile ) != 1 )
{
warn( "cannot delete '$tagsFile' file" );
}
else
{
print "Temporary file '$tagsFile' removed\n";
}
}

close( RESULT );

11 changes: 11 additions & 0 deletions TagManager/vim-TagManager.conf.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Directory match pattern :: Project name and dependencies :: Lang :: Tags root directory :: Hl builder options

$HOME/devel/my_proj/* :: my_proj:libLarge1,libLarge2 :: c :: $HOME/devel/my_proj/src :: -r -l -elibLarge.
/usr/*/sources/libLarge1/* :: libLarge1:qt_src :: c :: /usr/share/sources/libLarge1 :: -r -e@cpp
/usr/*/sources/libLarge2/* :: libLarge2 :: c :: /usr/share/sources/libLarge2 :: -r -e@cpp
# Tags for project qt_src were created by running BuildTags and MakeVimHlTags in command line
# They are not supposed to be changed from within a vim session, therefore Tag root directory and Hl builder options are empty
/usr/*/qt/src/* :: qt_src :: c :: ! :: !

# BEWARE: 1) Shell variables are expanded, but glob symbols '*' and '?' - not. 2) Use symbol '!' to denote empty value.

Loading

0 comments on commit babd615

Please sign in to comment.