citre
citre copied to clipboard
Accurate inspection on C struct members
Several Citre users talked about this idea to me.
If we are at:
foo.bar|
(|
is the cursor), we could:
- Find the definitons of
foo
(we could assume it's a variable, function parameter, or member (maybe more?)). - Find the
typeref
fields of these definitions. They should betyperef:struct:structName
(if there are more than 1 definitons, multiplestructName
is possible. - Sort the definitions of
bar
so those withstruct:structName
scope field are on the top.
I need to learn more on how a C file is tagged:
- For
foo->bar
, foo is a pointer. What does its typeref field look like?
Also, some users want struct member completion in this situation:
foo.|
We could do 1 and 2 the same as above, then:
- Filter all tags and find those with appropriate scope info. This can be slow.
- Or, assume qualified tags are enabled, then we could look for tags start with
structName.
. This should be fast.
I'd like to take the latter approach. The infrastructure of Citre needs some mild modify to support it, though.
If we could solve this, the design can be used for other static type languages, too. If we could also find the way of dealing with inheritance, I'd say Citre will have the potential of becoming the best tool for static type languages with class/subtype or even other fancy type systems.
If everything can be done in ctags/readtags, it is nice.
If we don't seek the above ideal, there are more choices.
which-function-mode
tells us the current scope.
You can call readtags to find foo
with (eq? $scope-name (the-scope-information-getting-from-which-mode))
.
Using https://github.com/universal-ctags/python-ctags3 is just another choice.
-
which-function-mode
actually usesimenu
, AFAIK.imenu
doesn't know where does a scope end, so it can't tell you the current scope accurately. -
I didn't see connection between the question I described and the current scope.
What I want is:
- find the symbol before
.
- find the tags of the symbol (it should be a struct instance)
- find the type of those tags (some kind of a struct)
- now we know the symbol after
.
should be a member of that struct. We can sort those results above others.
- find the symbol before
- find the tags of the symbol (it should be a struct instance) (B)
(B) can be done in readtags. However, readtags may provide multiple candidates.
struct port {
uint16_t num;
enum protocol proto;
};
extern struct port p;
void print_point(struct point p)
{
printf("%d %d\n", p.|
}
How can we know the type of p? readtags may report:
p foo.c /^extern struct port p;$/;" x typeref:struct:port
p foo.c /^void print_point(struct point p)$/;" z function:print_point typeref:struct:point file:
If we know the cursor is in print_point, citre can choose the latter one.
a tag entry of C language can have line: and end: fields. So we can implement (B) only with readtags. However, it will need a linear search that we don't want to do.
BTW we cannot forget typedef.
struct point;
typedef struct point Point;
Point p;
In that case, citre must run readtags repeatedly.
readtags may provide multiple candidates... If we know the cursor is in print_point, citre can choose the latter one.
I see.
a tag entry of C language can have line: and end: fields. So we can implement (B) only with readtags. However, it will need a linear search that we don't want to do.
Also, this won't work if the file has been edited, so the line length of the function is no longer (- end-field line-field)
.
What we could do is do some parsing in Citre to find the current function.
Using which-function-mode
is not a choice because it uses imenu, and when citre-mode
is on, imenu does a linear search on the tags file.
Also, when we couldn't do better, we can just use all definitons of p
. The point is not to do a complete semantic analysis, but trying to be accurate when guessing things.
BTW we cannot forget typedef. In that case, citre must run readtags repeatedly.
Thanks, I didn't thought about typedef. I'm prepared to running readtags multiple times, though.
Using which-function-mode is not a choice because it uses imenu, and when citre-mode is on, imenu does a linear search on the tags file.
In such a case, you can turn off citre-mode temporarily.
As discussed in the developer manual, we've decided to not take the approach to filter accurately as this may throw away actually useful tags. So I'll close this.