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 1


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)


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.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.