Ctags: gtags not respecting .ctags file

Created on 8 Dec 2017  ·  25Comments  ·  Source: universal-ctags/ctags

I have built globals with universal-ctags. I could verify that when executing ctags --version i get the universal-ctags version and not any other.

I have created a .ctags file that contains:

-exclude=foo

When executing gtags I don't see it respecting the .ctags file. instead it just go ahead and extract tags for everything in the working directory.

What am I doing wrong?

All 25 comments

Universal-ctags doesn't read .ctags. See FILES section of ctags.1 man page.

Are you referring to this?

/ctags.cnf (on MSDOS, MSWindows only)
/etc/ctags.conf
/usr/local/etc/ctags.conf
$HOME/.ctags
$HOME/ctags.cnf (on MSDOS, MSWindows only)
.ctags
ctags.cnf (on MSDOS, MSWindows only)

If any of these configuration files exist, each will be expected to contain a set of default options which are read in the order listed when ctags starts, but before the CTAGS environment variable is read or any command line options are read. This makes it possible to set up site-wide, personal or project-level defaults. It is possible to compile ctags to read an additional configuration file before any of those shown above, which will be indicated if the output produced by the --version option lists the "custom-conf" feature. Options appearing in the CTAGS environment variable or on the command line will override options specified in these files. Only options will be read from these files. Note that the option files are read in line-oriented mode in which spaces are significant (since shell quoting is not possible). Each line of the file is read as one command line parameter (as if it were quoted with single quotes). Therefore, use new lines to indicate separate command-line arguments.

I do see .ctags as one of the possibilities!

Presumably, he meant the current man page.

Thanks codebrainz for responding. So I created this file:
/pathtorepo/ctags.d/.ctags

which includes the -R --excludes that I need.

When executing this command from the repos directory:

ctags --verbose

It tells me that it is expecting input.

When I do

ctags --vertbose --options=ctags.d/.ctags

it does the right thing and extract tags from all the repo except the excludes in the .ctags file.

What am I doing wrong?

I need ctags to respect ctags.d/.ctags (or any file it requires) when only executing "ctags".

The reason is I am using ggtags inside emacs and ggtags requires ggtags working side by side with ctags.

So basically I want to get to a state when I can just do "gtags" on the command prompt and it automatically:

  1. Use universal-ctags
  2. respects universal-ctags (ctags.d/.ctags) file

How can I do that?

How about /pathtorepo/.ctags.d/exclude.ctags ?
See the source tree of universal-ctags itself. You can find .ctags.d directory in it.
https://github.com/universal-ctags/ctags/tree/master/.ctags.d

Sorry for updating my comment repeated ly.

u-ctags must load /pathtorepo/.ctags.d/exclude.ctags when running u-ctags at /pathtorepo.
Feel free to reopen this if u-ctags doesn't load your exclude.ctags.

masatake, thanks for the response. It seems that the exclude file is being picked up but I have a couple of questions:

  1. this parses the non excluded files:
    ctags --verbose --options=.ctags
    but this does not:
    ctags --verbose
    although it says that it picked up exclude file, but I get this message:

ctags: No files specified. Try "ctags --help".

But why? Shouldn't it act like:
ctags --verbose --options=.ctags
and just parse everything in the current directory except the excludes?

  1. How to get gtags use universal-ctags and pick up it's exclude file?
    When I execute gtags it parses everything and ignores the exclude.ctags file although global is built --with-universal-ctags

About 1. I need the information about the environemnt to answer the questio.

I'm bad in English. I hope the following output may tell you everything you need.

Please, check you are really using u-ctags.

$ ./ctags --version | grep Universal
Universal Ctags 0.0.0(248cffc9), Copyright (C) 2015 Universal Ctags Team
Universal Ctags is derived from Exuberant Ctags.

u-ctags loads files having .ctags as suffix under ./.ctags.d.

$  ls -l .ctags.d
-rw-r--r--. 1 jet jet 104 Oct 14 02:46 exclusion.ctags

--verbose option tells you which files are loaded.

$ ./ctags --verbose 2>&1 | grep 'Considering option file'
Considering option file .ctags.d/exclusion.ctags: reading...

A directory or file can be specified with --options. If a directory is given,
files having .ctags as suffix under the directory are loaded.
However, the same file is not loaded twice.

$ ./ctags --verbose --options=.ctags.d 2>&1 | grep 'Considering option file'
Considering option file .ctags.d/exclusion.ctags: reading...
Considering option file .ctags.d/exclusion.ctags: already considered

A file without the suffix is not loaded unless specifying the file with --options explicitly.

$ touch ./.ctags.d/please-load-me
$ ./ctags --verbose  2>&1 | grep 'Considering option file'
Considering option file .ctags.d/exclusion.ctags: reading...
$ mv ./.ctags.d/please-load-me ./.ctags.d/please-load-me.ctags
$ ./ctags --verbose  2>&1 | grep 'Considering option file'
Considering option file .ctags.d/exclusion.ctags: reading...
Considering option file .ctags.d/please-load-me.ctags: reading...

That's all. Please, see the man page. If the man page is not written well, please, consider to make a pull request and show me how we can improve it.

About 2, I'm sorry but I don't know well about gtags.

I think we will get this kind of question repeatedly. What can I do before getting the question?

If you still load $HOME/.ctags, you won't get this question. Compatibility is great, and I don't see why you stop loading that file. The commit ce0617a7be7a4d33a09ac60f21b8a9ce26690853 changed this without saying the reason.

Now I'll have to move my files and update my recordings about config files.

The commit is part of #1519, so the reason is described there.

Breaking compatibility is a bad idea. However, I will do it once, only once(I hope) when releasing the initial version of u-ctags. I think the last one is the tags file format. The most important thing is done by @b4n. What I have to do is assigning version 3 tags file format and making document for it.

I have the issue same issue as the original poster, using both ~/.ctags.d/*.ctags and (locally) ./.ctags.d/*.ctags.
I am using GNU Global 6.6.3, compiled with Universal Ctags support. GTAGSCONF points to the default gtags.conf installation path and GTAGSLABEL is new-ctags.

I also looked through the source code in Global's /plugin-factory/exuberant-ctags.c (used to call Universal Ctags; starting from line 193) but it seemed like Universal Ctags is called with no option that would disable the loading of .ctags.d/*.ctags.

If I should rather report this to the Global dev(s), please tell me and I will do so. :)

To reproduce:

git clone -b tests --single-branch https://github.com/janEbert/julia-ctags.git
cd julia-ctags
mkdir -p ~/.ctags.d
mkdir -p .ctags.d
ln -s $PWD/ctags ~/.ctags.d/julia.ctags  # or cp if you want to be safe
ln -s $PWD/ctags ./.ctags.d/julia.ctags
gtags
global greet  # returns nothing

How about calling ctags directly like:

$ new-ctags --version
$ new-ctags -o - JULIA-FILE

Do you get expecting result?

Yes, calling Universal Ctags (uctags on my machine; GTAGSLABEL is not the name of the binary) directly works perfectly, with or without the .ctags file specified via --options.
So Universal Ctags uses the ~/.ctags.d files but somehow this behaviour does not get transferred to Global.

Please, don't use --options. uctags should load ~/.ctags.d/julia.ctags and ./.ctags.d/julia.ctags without specifying --options.

So what I would like you to run is:

$ uctags --version
$ uctags -o - JULIA-FILE

I would like to see the command output.

BTW, do you use ctags on GNU/Linux?

Sorry, I wasn't clear. uctags uses the contents of ~/.ctags.d as desired, even if I do not give the --options flag. However, if I use gtags with uctags as the backend, ~/.ctags.d is _not_ used.

Yes, I am using it on GNU/Linux, specifically Ubuntu. The output is the following:

$ uctags --version
Universal Ctags 0.0.0(1a94658c), Copyright (C) 2015 Universal Ctags Team
Universal Ctags is derived from Exuberant Ctags.
Exuberant Ctags 5.8, Copyright (C) 1996-2009 Darren Hiebert
  Compiled: Jul 29 2019, 13:42:51
  URL: https://ctags.io/
  Optional compiled features: +wildcards, +regex, +iconv, +option-directory, +xpath, +packcc
$ uctags -o - testfile.jl
CtagsTest   testfile.jl /^module CtagsTest$/;"  f
ImmutablePoint  testfile.jl /^struct ImmutablePoint{T}$/;"  f
MutablePoint    testfile.jl /^mutable struct MutablePoint{T}$/;"    f
addcoment   testfile.jl /^addcoment(string::AbstractString, comment, spaces=1) = begin  # Maybe write without `begin`?$/;"  f
addone! testfile.jl /^function addone!(x::T) where {T <: Number}$/;"    f
deprecated_returnsquarepower    testfile.jl /^deprecated_returnsquarepower() = 2.0$/;"  f
multiply    testfile.jl /^multiply(x, y) = x * y$/;"    f
multiply    testfile.jl /^multiply(x, y...) = begin$/;" f
printgreeting   testfile.jl /^    function printgreeting(x)$/;" f
square  testfile.jl /^function square(x)$/;"    f

Edit: Compiled newer version of Universal Ctags, output stayed the same.

The output does not show the greet function that I used in the example to reproduce further above. This is due to an outdated parser in the branch I linked you to – just substitute global greet with global square and it will still give no output.

o.k. As a standing alone program, uctags woks well.

You are using GNU/Linux. Good! I can help you much more.

Please, install strace package. I don't know Ubuntu well but, apt-get may be the command to install strace.

Then run

$ strace -s 4096 -f -e execve,execveat gtags

I would like to see the output.

o.k. As a standing alone program, uctags woks well.

Yes, it works beautifully standalone!

You are using GNU/Linux. Good! I can help you much more.

Sorry I did not mention that earlier.

$ strace -s 4096 -f -e execve,execveat gtags
execve("/usr/local/bin/gtags", ["gtags"], 0x7ffe7e8d0fe8 /* 83 vars */) = 0
strace: Process 2210 attached
[pid  2210] execve("/usr/bin/sort", ["/usr/bin/sort", "-k", "1,1"], 0x562714c855b0 /* 84 vars */) = 0
strace: Process 2211 attached
[pid  2211] execve("/usr/bin/sort", ["/usr/bin/sort", "-k", "1,1"], 0x562714c97410 /* 84 vars */) = 0
[pid  2210] +++ exited with 0 +++
[pid  2209] --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=2210, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
[pid  2211] +++ exited with 0 +++
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=2211, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
+++ exited with 0 +++

The output of strace tells gtags didn't call uctags.

どうもありがとう。迷惑をかけてごめんなさい。
じゃあGLOBALの開発元に書きます!
またありがとう!Universal Ctagsは素晴らしいです。:)

Hey, I tried around a bit. I'm not sure if I should write you or Shigio.

GNU Global uses langmap settings in the GTAGSCONF file to filter the files gtags processes and also passes those settings to Universal Ctags.

At one point I had added the file extension for Julia (.jl) to the Global config, however, Universal Ctags stopped with the warning:
Unknown language "[list of langmaps]"

The problem arises because Universal Ctags first parses its arguments and then loads the options in .ctags.d. I modified Global to explicitly pass --options=[...].ctags _before_ it passes the --langmap option.
After that everything worked perfectly once again and I get the Global tables.

As I said, I'm not sure if this is something you want to change (so that the .ctags.d files are processed before the arguments to Universal Ctags) or if I should file a report to Global.

The problem arises because Universal Ctags first parses its arguments and then loads the options in .ctags.d.

I didn't implement so.
Only a few exceptions, Universal-ctags loads .ctags.d/*.ctags then parses the cmdline options.
As I wrote in ctags-optlib.7 man page, you can use --_echo=MSG option to understand and debug how u-ctags loads config files.

 [yamato@slave]~% ls ~/.ctags.d 
config.ctags
[yamato@slave]~% cat ~/.ctags.d/config.ctags
--_echo=hello from dot-ctags


[yamato@slave]~% u-ctags --_echo="hello from cmdline" --_force-quit
u-ctags: Notice: hello from dot-ctags
u-ctags: Notice: hello from cmdline

See ctags.1 man page. I don't understand why you want to pass --options to ctags.
Putting julia.ctags to ~/.ctags.d may be enough for your purpose. u-ctags loads julia.ctags automatically. So you don't have to specify --options explicitly.

Okay, I just tested again and I also do not get an error anymore. Sorry once again for troubling you.

Was this page helpful?
0 / 5 - 0 ratings