ctags icon indicating copy to clipboard operation
ctags copied to clipboard

[Question] Defining new regex-based tags with scope defined by built-in `ctags` kinds

Open pidgeon777 opened this issue 3 years ago • 5 comments

Actually, to add scope to regex-based tags, it is needed to do something as follows:

--regex-LANG=/(top)/\1/t,top/{scope=set}
--regex-LANG=/(sub)/\1/s,sub/{scope=ref}

so that scope field will be added to all found sub tags (top tags will be considered as their parent scope).

Question is, what if for LANG a built-in tag kind for top is already defined? How could I use the already available kind instead of redefining it via regex + {scope=set}?

For example, I would like to define some tags for the case XXX statement inside of C functions. Each case tag should belong to the function, used as scope kind. But I have not idea on how to define the scope, without having to re-define the function kind.

pidgeon777 avatar Feb 02 '23 16:02 pidgeon777

There is no way to look up scopes recorded by a built-in code from a regex code NOW.

As usual, I have an idea of integrating the two worlds: {scope=intervalTree}.

$ cat /tmp/input.c
int f(void)
{
  return 0;
}
$ ./ctags --fields=+'{line}{end}' -o - /tmp/input.c
f	/tmp/input.c	/^int f(void)$/;"	f	line:1	typeref:typename:int	end:4

In some languages, ctags has the ability to record "line:" and "end:". ctags has a red-black tree (rbtree) implementation derived from Linux. The interval tree (https://en.wikipedia.org/wiki/Interval_tree) can be implemented based on the rbtree. (https://www.youtube.com/watch?v=LRLHBxMFpHM).

We can put all tags extracted by built-in code into the interval tree. The interval tree can answer a question like "the narrowest tag includes line N".

masatake avatar Feb 03 '23 15:02 masatake

We can use https://github.com/markfasheh/interval-tree/tree/master.

masatake avatar Mar 22 '23 05:03 masatake

The initial implementation of the flag {scope=interval} works.

$ cat -n case.c
     1	int
     2	main(void)
     3	{
     4		switch (x) {
     5		case A:
     6			break;
     7		case B:
     8			break;
     9		}
    10		return 0;
    11	}
    12	
    13	int
    14	foo(void)
    15	{
    16	
    17		/* NO switch/case here */
    18	
    19	}
    20	
    21	int
    22	bar(void)
    23	{
    24		switch (x) {
    25		case C:
    26			break;
    27		case D:
    28			break;
    29		}
    30		return 0;
    31	}
$ cat case.ctags
--kinddef-C=L,caseLabel,case labels
--_tabledef-C=init
--_mtable-regex-C=init/case +([a-zA-Z0-9]+)[^\n]*/\1/L/{scope=interval}
--_mtable-regex-C=init/.//
$ ./ctags --quiet --options=NONE --sort=no --options=case.ctags -o - ./case.c
main	./case.c	/^main(void)$/;"	f	typeref:typename:int
foo	./case.c	/^foo(void)$/;"	f	typeref:typename:int
bar	./case.c	/^bar(void)$/;"	f	typeref:typename:int
A	./case.c	/^	case A:$/;"	T	function:main
B	./case.c	/^	case B:$/;"	T	function:main
C	./case.c	/^	case C:$/;"	T	function:bar
D	./case.c	/^	case D:$/;"	T	function:bar

The scopes for case labels are extracted well.

masatake avatar Mar 23 '23 20:03 masatake

Superb. Adding scope information for a custom regex-based tag, referencing the tag kinds already internally parsed by ctags, would be a great addition in my opinion.

Has this feature already been added in the latest ctags binary, or there is a way to try it?

pidgeon777 avatar Mar 26 '23 00:03 pidgeon777

Superb. Adding scope information for a custom regex-based tag, referencing the tag kinds already internally parsed by ctags, would be a great addition in my opinion.

Yes. This is a great addition. I myself need this feature.

Has this feature already been added in the latest ctags binary, or there is a way to try it?

See #3678. You must specify {scope=_intervaltab} and {postrun}. The flags work with only C/C++/CUDA parsers.

I will NOT merge the branch in soon. I must reconsider the consistency between {scope=_intervaltab} and the other {scope=...} flags. I have to update ctags-optlib(7) man page. When updating the man page, I may need your help.

masatake avatar Mar 26 '23 08:03 masatake