Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C/C++ Sort definitions before prototypes #4015

Closed
terminatorul opened this issue Jun 6, 2024 · 3 comments
Closed

C/C++ Sort definitions before prototypes #4015

terminatorul opened this issue Jun 6, 2024 · 3 comments

Comments

@terminatorul
Copy link

terminatorul commented Jun 6, 2024

Hello

If I enable prototypes, I can get many tags generated for the same function, but only one of them (mostly) will be a definition.

For multiple tags of the same name (like declarations of the same function), can ctags please sort them so the definition always shows up before the prototypes and other references ?

To be clear, ctags currently outputs definition tags (with roles:def) for prototypes, which is not actually correct. At least in C and C++, but also other languages. So let me say implementing #1796 (introduce prototype role) would be great.

But prototypes are not exactly references either, not in the proper sense. The function declared in a prototype does not have to exist, and the program is still correct, as long as the function remains unused (never called; the function type can still be used, for example in a sizeof() expression or with decltype()). So there is nothing to be referenced.

However when no definition is available or desired (for external libraries for example), then the prototype from the library header is the next best thing.

So what I really need as an user is to get the function definition first, if there one, or the prototype otherwise.

Can ctags add sort order for tags of the same name, and sort them with the definition first, and the prototypes after ? Because most code editors would show the first tag first ...

@masatake
Copy link
Member

masatake commented Jun 6, 2024

Well understandable. But Soriting is not the job of ctags.
It is the job of client tools.

Hereafter, I will write about general sorting, not only definition v.s. prototype.

citre (https://github.com/universal-ctags/citre), an extension for Emacs editor, does this.
See https://github.com/universal-ctags/citre/blob/master/citre-lang-c.el#L132. Citre has various rules for sorting. I'm a user. It is really useful.
universal-ctags/citre#42 was the issue we (ctags maintainer and citre maintainer ) discussed about sorting.

citre uses readtags command internally. With readtags, you can specify the order of listing with sort expressions. See https://docs.ctags.io/en/latest/man/readtags.1.html#sorting .

If the readtags command doesn't fit your purpose, you can write your tool or library with libreadtags (https://github.com/universal-ctags/libreadtags) or https://github.com/universal-ctags/python-ctags3.

@terminatorul
Copy link
Author

This works for a client like gVim, where I could do this in less then 20 lines of Vim script in the latest version (which I plan to, some day...)

But how about less -t ?

Wikipedia lists 25 clients using ctags, I am sure there are more.

Are you sure ctags shouldn't have a good default for the sort order ?

@masatake
Copy link
Member

Are you sure ctags shouldn't have a good default for the sort order ?

Yes. Currently, I think ctags should not do too much in the area.
It is a part of post-processing, the area of client tools.
I have improved readtags for this purpose.

$ cat /tmp/foo.c
void foo(void) {}
$ cat /tmp/bar.c
void bar(void);
void bar(void) {}
$ cat /tmp/decl.h
void foo(void);
$ ./ctags  --extras=+p --kinds-C=+p -o - /tmp/foo.c /tmp/bar.c /tmp/decl.h | ./readtags -e -t - --sorter '(if (eq? $name &name) (cond ((and (eq? $kind "p") (eq? &kind "f")) 1) ((and (eq? $name &name) (eq? $kind "f") (eq? &kind "p")) -1) (#t 0)) (<> $name &name))' -l | tee tags
...
bar	/tmp/bar.c	/^void bar(void) {}$/;"	kind:f	typeref:typename:void
bar	/tmp/bar.c	/^void bar(void);$/;"	kind:p	file:	typeref:typename:void
foo	/tmp/foo.c	/^void foo(void) {}$/;"	kind:f	typeref:typename:void
foo	/tmp/decl.h	/^void foo(void);$/;"	kind:p	typeref:typename:void

The client tools may be able to use the post-processed tags file.

Embedding readtags into ctags is a way to implement the idea you proposed.
I plan to embed libreadtags into ctags. However, it is not for sorting.

@terminatorul terminatorul closed this as not planned Won't fix, can't repro, duplicate, stale Jun 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants