I alway use vi to edit Fortran files. I can use ctags to know which variables and functions I have already defined. Now I use vi to edit Mathematica *.m files. I tried to use ctags for *.m files, but it does not work. I have searched for the solution in Google but no luck. Could you give me some suggestions?
-
2$\begingroup$ Using ctags for Mathematica is rather hard, because a variable/function can be defined in a bazillion ways, unlike C/Fortran which have a fixed syntax for defining them. I use YouCompleteMe to autocomplete existing symbols on-the-fly (regardless of whether they're "definitions" or not) and rely on memory/context to determine whether the suggestion is what I want. $\endgroup$– rm -rf ♦Dec 17, 2013 at 20:26
1 Answer
Assuming you mean vim for vi, you could build a searchable index that may be an acceptable compromise.
Suppose that you have a searchable convention that you use for marking each function. The obvious one to me is one where you precede each function with a usage, like
foo::usage = "..." ;
foo[ x_ ] = Module[{}, ... ] ;
That would allow use of grep to build an index that you could use with vim -q (although that's not quite as nice as tags that you could follow). For example:
grep -n ::usage *.m | tee index
vim -q index
or, if you want a more constrained search, say just foo:
grep -n foo::usage *.m | tee index
vim -q index
When using vim -q
you can use :cn, :cN to move between file:line pairs (this is probably more normally used for C compilation errors, but can be handy for more ad-hoc stuff like this too).
I'd imagine that it's possible that you could use Mathematica itself to read all your Modules and build a call graph of all the functions and variables defined along with their filename and line numbers. If that was done, it's probably not too much harder to make Mathematica produce a ctags format file that you could use within vi.
[EDIT] The ctags format isn't that complicated. Here's a quick hack of a perl script that can generate it (again provided that you have a ::usage for each symbol of interest)
#!/usr/bin/perl
use warnings ;
use strict ;
my @tags = () ;
open my $fh, "grep ::usage *.m | sed 's/::usage.*//'|" or die ;
while (<$fh>)
{
chomp ;
/(.*):(.*)/ or die ;
my ($filename, $symbolname) = ($1, $2) ;
push( @tags, "$symbolname\t$filename\t/${symbolname}::usage/\n" ) ;
}
close $fh or die ;
print $_ foreach (sort @tags) ;
This probably works for non-vim vi's too.