This is my preferred way to go about it.
These instructions are described in some detail in the universal-ctags
install instructions on GitHub. But here’s what I ran:
% cd ~/src % hub clone universal-ctags/ctags universal-ctags && cd universal-ctags % ./autogen.sh % ./configure
I initially wanted to use --program-prefix=universal-
to result in the final code being installed into /usr/local/bin/universal-ctags/
instead of just as ctags
. But it turned out that breaks because of how universal-ctags
handles etags
compatibility: it must be called as ${PROGRAM_PREFIX}etags
. But via the alternatives system, it will actually be called as plain old etags
, so it needed to be built with no --program-prefix
argument.
Continuing the build:
% make
Simply:
% sudo make install
Here, we want to tell Ubuntu that it can use universal-ctags
as a ctags
variant. The update-alternatives
command is used for this. First, let’s have a look at what’s already been installed as known alternatives:
% update-alternatives --display ctags ctags - auto mode link best version is /usr/bin/ctags.emacs24 link currently points to /usr/bin/ctags.emacs24 link ctags is /usr/bin/ctags slave ctags.1.gz is /usr/share/man/man1/ctags.1.gz /usr/bin/ctags.emacs24 - priority 27 slave ctags.1.gz: /usr/share/man/man1/ctags.emacs24.1.gz
This may look complex, but it’s just telling us that a version of ctags has been automatically selected from the single known alternative — ctags.emacs24
, installed as part of Emacs.
As earlier mentioned, if you examine the manpage for universal-ctags
, you’ll note that to run in Emacs mode, it expects to be called as etags
. So let’s see what’s currently in use as etags
:
% update-alternatives --display etags etags - auto mode link best version is /usr/bin/etags.emacs24 link currently points to /usr/bin/etags.emacs24 link etags is /usr/bin/etags slave etags.1.gz is /usr/share/man/man1/etags.1.gz /usr/bin/etags.emacs24 - priority 27 slave etags.1.gz: /usr/share/man/man1/etags.emacs24.1.gz
Much the same thing.
So now, we have to inform Ubuntu’s alternatives system about the new command.
% sudo update-alternatives --install /usr/bin/ctags ctags /usr/local/bin/ctags 50 --slave /usr/share/man/man1/ctags.1.gz ctags.1.gz /usr/local/share/man/man1/ctags.1
Here, we tell it that /usr/local/bin/ctags
is an acceptable version of ctags
, and that its manpage can be found at /usr/local/share/man/man1/ctags.1.gz
. Note the 50
— that argument sets the “priority” when autoselecting an alternative. The above output told us that Emacs’ version was set to priority 27
, so 50
has been arbitrarily chosen as a higher priority, forcing universal-ctags
to be preferred.
We need to do the same with etags
, as so:
% sudo update-alternatives --install /usr/bin/etags etags /usr/local/bin/ctags 50 --slave /usr/share/man/man1/etags.1.gz etags.1.gz /usr/local/share/man/man1/ctags.1
Now we can see the links are right:
% echo =ctags =etags /usr/local/bin/ctags /usr/bin/etags % readlink -f =etags =ctags /usr/local/bin/ctags /usr/local/bin/ctags
- Note
- The syntax
=ctags
tells zsh to replace the string with the full path name to thectags
command. In bash,$(which ctags)
would be equivalent.
The most obvious difference between ordinary ctags
and etags
is where they put the tagfile: the former uses tags
, the latter TAGS
. So we can test this as so to ensure that universal-ctags
is being called correctly; if etags
creates a TAGS
file instead of a tags
file, we’re good:
% ls tags TAGS ls: cannot access 'tags': No such file or directory ls: cannot access 'TAGS': No such file or directory % ctags -R . % ls tags TAGS ls: cannot access 'TAGS': No such file or directory tags % etags -R . % ls tags TAGS TAGS tags
Now, all that’s required is to use your tags as normal.