Wumpf / IncludeToolbox

Visual Studio extension to format, prune, and inspect include directives.
https://marketplace.visualstudio.com/items?itemName=Wumpf.IncludeToolbox
MIT License
51 stars 22 forks source link

Add search function to Include Graph #45

Open Wumpf opened 7 years ago

Wumpf commented 7 years ago

Reported by Fei here: https://wumpfblog.wordpress.com/about/#comment-20

Wumpf commented 6 years ago

Requested by Alexandre Azzalini as well. https://marketplace.visualstudio.com/items?itemName=Wumpf.IncludeToolbox#qna

Ext3h commented 6 years ago

"Reverse" search as well please.

Common use case, a header shows up in the "Solution explorer" as "External Dependency", but no clue which files included it, and what else that causes.

So a search should produce the full graph of all headers and sources which are either transient descendant or parent of a specific file.

Wumpf commented 6 years ago

What I had in mind was more a search over all (unique) elements in the graph of a single file. On success it would jump to the next hit starting from the selection in the graph. If I understand correctly what you would need is a full search over all potential include graphs in the entire project. Not sure if I want to do that any time soon, seems overly specific

Ext3h commented 6 years ago

Fair enough, I suppose a text search in the single file view has also it's uses. It answers the question "have I already included file X".

Even though this question is usually answered also by Intellisense providing auto completion with corresponding symbols (respectively a tool like VisualAssist also automatically adding the include on the fly).

Why would there be more than one hit though? You mean infix search of all matching filenames? Or glob/regex?

Is it really sufficient for all use cases to only traverse only a tree with unique elements, or are there use cases for which searching the tree with duplicates would be preferable?

Only jump from result to result, or thin out (+unfold) the graph while typing instead, making the result visually comprehensible without any need to jump in most use cases? (E.g. of there is less than 10 elements still showing, for all remaining edges of the tree, that easily fits a single view.)


Ok, that's entirely different from what I meant, I was talking about exploring all relations in the global include graph from a fully specified file.

What you had in mind would had been equivalent to another filter on the global graph with two files, where as the remaining graph contains all edges which would lead to A including B, including those currently masked by include guards.

Wumpf commented 6 years ago

In the manual parsing there is nothing that prevents "duplicated entries". If an an include was included several time in different places (maybe in the same file with different configurations) it is technically a different element each time and double clicking will jump to the corresponding place. Also, the manual parsing based include graph doesn't necessarily produce a tree, it can have cycles since it doesn't heed pragma once or include guards. The ui is created on demand and can expand infinitely in such a case.

Why would there be more than one hit though?

-> Graph with cycles, and yes anything that matches would be nice

Is it really sufficient for all use cases to only traverse only a tree with unique elements, or are there use cases for which searching the tree with duplicates would be preferable?

-> The way stuff is set up there are no unique elements :)

Only jump from result to result, or thin out (+unfold) the graph while typing instead, making the result visually comprehensible without any need to jump in most use cases?

I guess it's a matter of taste but I would prefer not to thin out the graph when searching since the context/parents of an include are usually what you're interested in. So I'd prefer just to jump to the first result and jump to the next on pressing enter. Or something like that. I'd figure the details out when I implement it (everybody else is welcome to try and PR)

Ok, that's entirely different from what I meant, I was talking about exploring all relations in the global include graph from a fully specified file.

Yeah that's how I understood it. My answer wasn't quite clear though. That global graph doesn't exist yet in IncludeToolbox and a few things are actually not clear cut with it:

#define DO_A
#include "doesAorB.h"
#define DO_B
#include "doesAorB.h"

Would such a graph collapse those two into a single edge or multiple? Well so far it would result into two different nodes and edges since that's useful if you want to explore stuff like a tree starting from a certain file. So can't necessarily recycle the old code 1:1. Etc... haven't put too much thought into all that. I mainly stopped because a dgml with a full graph gets ridiculously large and I haven't seen much use in it so far.

Ext3h commented 6 years ago

Interesting point about the alternating behavior depending on current set of defines.

I suppose the naive approach would be to only record one edge, and only one copy of each file. Still based on what is reachable at all though, so not the naive parsing but only based on preprocessor prior. Obviously, the real include tree couldn't be reconstructed from that.

Probably a more sensible approach would be to store each file together with two sets of sets of defines.

One set with sets significant defines, so that all textual variations of the file are covered.

One at of all seen set of defines, for reconstructing a specific tree.

For the later set, together with each set of defines, also a list of includes with the currently active full set at that point.

I'm not claiming this is the most efficient structure, but appears to be a sufficient data base to run all interesting queries against. From a "simplified" neighborhood exploration which treats all files as equal by name, distinction by effective file content for a detailed exploration or full set of defines for reconstructing the tree.

Sure, that's completely out of scope for the moment, but it's not impossible to solve that.

magol commented 5 years ago

A search function is something I have long been missing for myself. It doesn't have to be so advanced in a first iteration. A simple text search in the tree is enough.