microsoft / vscode-cpptools

Official repository for the Microsoft C/C++ extension for VS Code.
Other
5.52k stars 1.55k forks source link

Add ability to limit Find All References to scopes: current file, open files, workspace files #4102

Open sean-mcmanus opened 5 years ago

sean-mcmanus commented 5 years ago

Can "searching" for files containing references be limited to workspace folders, if possible as an option? Since, IMHO, it may reduce no. of files to be "confirmed". And mostly IMHO, only references within the workspace are required.

Originally posted by @harikrishnan94 in https://github.com/microsoft/vscode-cpptools/issues/4051#issuecomment-521874558

sean-mcmanus commented 5 years ago

@harikrishnan94 Yeah, VS supports this, although it has a dropdown to select the scope...not sure how we'd expose the setting. Maybe just a simple C_Cpp.findAllReferencesScope setting with values CurrentDocument, OpenDocuments, CurrentWorkspaceFolder, AllBrowsePaths

UPDATE: We could also add a Change References Scope command that could appear when the search icon is clicked.

Lennon925 commented 5 years ago

@harikrishnan94 Yeah, VS supports this, although it has a dropdown to select the scope...not sure how we'd expose the setting. Maybe just a simple C_Cpp.findAllReferencesScope setting with values CurrentDocument, OpenDocuments, CurrentWorkspaceFolder, AllBrowsePaths

I think it will be better if you can add ability to find all references by some certain folders. User can search references in these folders.

sean-mcmanus commented 5 years ago

@Lennon925 What do you mean by "certain folders"? How would the folders be chosen? Right now, the initial of files for potential references is the entire browse database (i.e. all files with parsed symbols), which can be made smaller via using "*" to remove recursiveness and/or adding folders to files.exclude.

Lennon925 commented 5 years ago

@Lennon925 What do you mean by "certain folders"? How would the folders be chosen? Right now, the initial of files for potential references is the entire browse database (i.e. all files with parsed symbols), which can be made smaller via using "*" to remove recursiveness and/or adding folders to files.exclude.

I mean maybe you can add 4 scopes like this:

  1. CurrentDocument
  2. OpenDocuments
  3. CurrentWorkspaceFolder (at the same time you can add a folder array so that we can find references from these folders of workspace. Because sometime it's not necessary to search from the whole workspace.)
  4. AllBrowsePaths
sean-mcmanus commented 5 years ago

How would "folder array" be specified? Generally, it's expected that if the workspace has folders that shouldn't be searched for symbols/references, the users would set the browse.path to something like ["${workspaceFolder}/*", "${workspaceFolder/subFolder1WithSymbols", "${workspaceFolder/subFolder2WithSymbols], which would have the same effect as a folder array. Is there a reason, that solution is not sufficient?

We could maybe add a CurrentDocumentFolder scope too.

Lennon925 commented 5 years ago

How would "folder array" be specified? Generally, it's expected that if the workspace has folders that shouldn't be searched for symbols/references, the users would set the browse.path to something like ["${workspaceFolder}/*", "${workspaceFolder/subFolder1WithSymbols", "${workspaceFolder/subFolder2WithSymbols], which would have the same effect as a folder array. Is there a reason, that solution is not sufficient?

We could maybe add a CurrentDocumentFolder scope too.

It's OK. I will try as your suggestion.

bryceschober commented 4 years ago

@sean-mcmanus: Can you clarify how symbol search is supposed to work?

Our use-case is a fairly common one, I think: We have a repository that includes a bunch of other repositories as third-party libraries. For this use-case we really want to be able to clearly declare a distinction between:

  1. First-party sources:
    • These symbols are most important for resolution and references
    • These symbols will frequently be subject to refactoring
  2. Third-party sources that are essentially "read-only":
    • These symbols are interesting for search & usages, but not quite as high a "priority"
    • These symbols should never (at least by default) be included as candidates when refactoring

My current experience is that I:

  1. have configured my includePath for every include path used by our build setup, and
  2. have included none of the platform include paths in my includePath, and
  3. have let all platform paths be discovered by the correctly-configured compilerPath,
  4. and am frequently offered "cannot confirm reference" results that are clearly declared & defined in platform paths

Ideally, these scopes would be configurable in two ways:

  1. Any include paths discovered via the configured compiler should be treated as third-party symbols
  2. ??? We don't currently have any other way to distinguish between 1st- and 3rd-party symbols that are included in the workspace, and I feel like the intellisense logic really needs one. Unless that's what your reference to "browse paths" was supposed to mean...
sean-mcmanus commented 4 years ago

Yeah, if we had the concept of a "workspace folder" scope, then the third part symbols in the other workspace folders would be excluded, although you would have to open the 3rd party folders in a different workspace folder -- we're in the process of re-writing our multi-root folder support. A "workspace" scope would exclude the symbols from the compiler or other external symbols.

The "Cannot confirm reference" means there was some problem locating IntelliSense info for that particular file (i.e. it could be from a crash, or picking the wrong TU). You may be able to find more info in the debug logs.

The browse.path is for tag parsing (global symbols), but it will affect Find All References symbols too, so if you removed the 3rd party folders from the browse.path (such as via using a files.exclude or making it non-recursive and excluding the folders manually), then the results will be excluded from the Find All References results.

Our current Rename doesn't have the concept of excluding things that are "read-only" and returns the same results as Find All References. We could potentially add some workspaceFolder setting that excludes results from that folder from Rename.

jandyman commented 4 years ago

I cannot get any of the exclusion techniques to work for a project I'm dealing with. Inside the build folder(s), there are .i files generated, which I do not wish to scan. I've tried this in settings.json:

{ "files.exclude": { "*/Build/": true }, "search.exclude": { "*/Build/": true, }

and this in c_cpp_properties.json:

"browse": { "path": [ "${workspaceFolder}/include/" ], "limitSymbolsToIncludedHeaders": true }

But I still see results from these build generated files. Also, is there any way to suppress the "Other References" section, which is almost always worthless to me?

sean-mcmanus commented 4 years ago

Can you change your files.exclude to "*/Build"? I don't think the "/Build/" regex is correct. We also disable "file-based" exclusions due to performance issues, so folder-based regex's are preferred (the C_Cpp.exclusionPolicy can enable file-based exclusions).

There is no way to suppress the "Other references", but they're not expected to decrease performance to compute.

jandyman commented 4 years ago

The "/Build/*" regex does work in terms of excluding files from the browser, so I figured it would also work for the references, but I will try again.

sean-mcmanus commented 4 years ago

Hmm, that is odd. "/Build/*" isn't working for me, but I see "*/Build/" applying a file exclusion (i.e. requires C_Cpp.exclusionPolicy set to "checkFilesAndFolders").

jandyman commented 4 years ago

I just wanted to let you know that I tried the prescription above, and I'm now getting good performance from Find All References in most cases. Thanks so much for your help.

Having said that, I'll say that sorting through things to get to this point has been painful. It seems there are ten different places to set up the filtering options for various features, and I'm still not sure I understand it all. One well written webpage to sort it all out and explain how it all works would be invaluable. I spent hours over several days getting things to work, and I'm no idiot.

Jimbo99 commented 4 years ago

Agreed - There are many places to set up file filters it seems and I've not yet found a straightforward guide to how it should be configured for optimising the finding of references. In my case I have a small C project comprising 20 or so source files plus compiler library. I only want to find references in my source files. When I do a Find All References it says searching 225 files. I've tried various exclude settings but this number stays at 225 (and takes around 10 seconds to complete). During that time my PC's fans noticeably spin up so it seems the computing is non-trivial.

Is there a way to see which files (225 in this case) it is searching in? That would be useful to know and help zone in on what isn't being excluded.

Find In Files works instantly on the other hand so I'm tending to use that for now instead but obviously not ideal.

sean-mcmanus commented 4 years ago

@Jimbo99 Are you seeing the message for "searching" or "confirming"? You can see all the files in the "Other References" section. Using files.exclude should work, but it'll affect other systems, which may not be desiried (i.e. go to def won't find results in those files).

Jimbo99 commented 4 years ago

Hi Sean. Thanks for the reply. I tried the same project again this morning and now Find All References is working pretty much instantly. (So I wasn't able to check if it showed "searching" or "confirming" as that box no longer appears.) Perhaps it needed a restart to invoke the exclude list. It's a game changer when it works that fast, really is. Appreciate your hard work, Sean.

positron96 commented 3 years ago

Hello guys! Is there a way to limit scope of reference search (and refactoring) in case of cpptools+platformio? To each project platformio attaches a framework (e.g. arduino or stm32 or esp32) with a couple of hundreeds of files, all of which are included into search. The framework resides somewhere in OS user directory, not inside project itself.

sean-mcmanus commented 3 years ago

@positron96 The only way currently, is to use files.exclude or remove the paths from browse.path.

positron96 commented 3 years ago

@positron96 The only way currently, is to use files.exclude or remove the paths from browse.path.

Thanks! But is there a way to write paths outside of project without their full paths (i.e. make my settings file portable between machines)?

sean-mcmanus commented 3 years ago

I'm not familiar with a way to make external paths portable between machines (in the settings.json or .code-workspace files). You could try asking at https://stackoverflow.com/questions/tagged/visual-studio-code or filing (or searching for) a feature request at https://github.com/microsoft/vscode/issues .

starball5 commented 1 year ago

Related Stack Overflow question: How to I limit the scope of "Find All References" searches in Visual Studio Code?

toniESAT commented 4 weeks ago

Any chance we get this feature? Every time I want to rename a variable using F2 I get a list of all the variables with the same name in all the external headers, it's pretty inconvenient.