1

I'm trying to learn about ctags in emacs. I have built a TAGS file as per the instructions here: https://www.emacswiki.org/emacs/EmacsTags. I think I'm using exuberent-ctags, but I'm not sure.

I have a large code base around statistical models. Many classes have data members of the form

MySmartPointer<SomeModelType> model_;

This would be in a header file. In the associated .cpp file I'll see code like

model_->do_something();

I'd like to press M-. and have emacs take me to the definition of model_. Instead, I'm getting a long list of all the data members everywhere named model_, which is a very long list.

My questions are these:

  1. Are my expectations realistic? I.e does the ctags system contain enough information to know that the model_ I'm clicking on belongs to the class whose member function I'm editing?

  2. Is there an obvious configuration step that I have missed? I create the TAGS file using ctags -e -R --extra=+a. (I've tried with and without the --extra flag).

  3. (Added later) If making TAGS work this way is hard, what should I be looking at instead? I assume I'm not the first person to need this functionality.

Thanks.

1

Are my expectations realistic? I.e does the ctags system contain enough information to know that the model_ I'm clicking on belongs to the class whose member function I'm editing?

No, a TAGS file is just a list of names and where to find them. If you have duplicate names, you need to specify which one you want.

i.e. TAGS are poorly-suited to object-oriented programming or other name-spacing techniques.

1

Ctags by itself only list tag name, file path and line number.

But you can still use Emacs Lisp code to get more precise result (https://github.com/redguardtoo/counsel-etags):

  • Use negative file path pattern to exclude some candidates manually through ivy's filter UI (counsel-etags uses ivy)

  • Write lisp rules to exclude noise automatically. For example, find model_'s type in current file by search from top of the file to find SomeModelType and expect the class SomeModelType is defined in a file SomeModelType.cpp.

  • When there are multiple candidates, sort the candidate using string distance algorithm. For example do_something is defined in both ParentModelType.cpp and ParentViewType.cpp, Candidate from ParentModelType.cpp is placed at the top because it's closer to SomeModelType.cpp.

0

At least, universal-ctags knows types of fields in C and C++ input. However, the TAGS file format doesn't allow ctags to record them. As a result, Emacs cannot do more.

[jet@localhost]/tmp% cat /tmp/foo.c
cat /tmp/foo.c
struct A {
  char member;
};

struct B {
  float member;
};
[jet@localhost]/tmp% u-ctags  --fields=+tZ -o - /tmp/foo.c 
u-ctags  --fields=+tZ -o - /tmp/foo.c 
A   /tmp/foo.c  /^struct A {$/;"    s   file:
B   /tmp/foo.c  /^struct B {$/;"    s   file:
member  /tmp/foo.c  /^  char member;$/;"    m   scope:struct:A  typeref:typename:char   file:
member  /tmp/foo.c  /^  float member;$/;"   m   scope:struct:B  typeref:typename:float  file:

See "typedef:" fields of output.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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