Skip to content
This repository has been archived by the owner on Jul 15, 2023. It is now read-only.

Show completion for newly created package. #1191

Merged
merged 42 commits into from
Sep 12, 2017
Merged

Show completion for newly created package. #1191

merged 42 commits into from
Sep 12, 2017

Conversation

uudashr
Copy link
Contributor

@uudashr uudashr commented Sep 4, 2017

Previously the goListAll() cache the packages, resulting completion for newly created package not shown because the outdated cache and it quite irritating.

To takeout cache, we need to invoke go list all on demand. But the execution time is unacceptable, it will try to load packages from GOROOT, GOPATH and also user home directory. That is why cp.spawn('go', [], { env: process.env }) took so long, and by not providing the env will execute faster.

Better implementation package listing tools https://github.com/haya14busa/gopkgs. It search the packages from golang src. So I replace the go list all using gopkgs.

go list all took 4.87s
gopkgs took 0.08s

  • No more cache on goListAll() and it fast.
  • Browse package also can lookup non-installed package (based on src, not the binary)
  • The extension will check if the gopkgs is not the expected one and prompt as missing tool

@msftclas
Copy link

msftclas commented Sep 4, 2017

@uudashr,
Thanks for having already signed the Contribution License Agreement. Your agreement was validated by Microsoft. We will now review your pull request.
Thanks,
Microsoft Pull Request Bot

@uudashr
Copy link
Contributor Author

uudashr commented Sep 4, 2017

@ramya-rao-a check please

let pkgs = new Map<string, string>();
chunks.join('').split('\n').forEach((pkgPath) => {
if (!pkgPath) return;
const lastIndex = pkgPath.lastIndexOf('/');
Copy link
Contributor

@ramya-rao-a ramya-rao-a Sep 5, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main reason I used go list all instead of gopkgs initially was to get the package name and not rely on the import path of the package to determine the package name like you are doing here.

Because package names need not necessarily be the last part of the package path. See #647

And we use the package names to provide completion for unimported packages.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see... make sense, because it completion, not import package

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, and later on I added the Go: Browse Packages feature because then I had all the packages in hand, so it seemed like a good feature to add

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can strip off the version part from "pkgname.v1" , it works when people always using standard way on naming package related to the package path, but that doesn't guarantee

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's exactly what I did in cb0d2bc :)

Copy link
Contributor Author

@uudashr uudashr Sep 5, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cb0d2bc no longer in master?

Here are some example, can't guarantee consistent pattern:

  • speech;google.golang.org/api/speech/v1beta1
  • spectrum;google.golang.org/api/spectrum/v1explorer
  • speech;google.golang.org/api/speech/v1
  • prediction;google.golang.org/api/prediction/v1.2
  • tilde;gopkg.in/mattes/go-expand-tilde.v1

So using go list -f '{{.Name}};{{.ImportPath}}' all is the proper way, it just need to make it faster.

Case

  1. Autocomplete un-imported will suggest only packages on cache, no way to suggest new package since it need invalidation. Need to listen some events to invalidates, haven't figure out which one.
  2. Go: Browse Packages use https://github.com/tpng/gopkgs which looks in $GOPATH/pkg, new package will not exists in $GOPATH/pkg, so browse package will not help. Except we change it, use https://github.com/haya14busa/gopkgs which search in $GOPATH/src. This is workaround, but still completion still stale.

Btw, why not change to https://github.com/haya14busa/gopkgs for Browse Packages? It seems good improvement, solve one problem.

Copy link
Contributor

@ramya-rao-a ramya-rao-a Sep 6, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I replaced cb0d2bc with using go list -f '{{.Name}};{{.ImportPath}}' all

I am fine with auto complete using cache as it does today.

I didnt use https://github.com/tpng/gopkgs for the Browse Packages feature as it will not have the "main" packages as in the ones that are executable

I am fine with using https://github.com/haya14busa/gopkgs for just the Browse Packages feature as well as long as it lists the "main" packages as well

@uudashr
Copy link
Contributor Author

uudashr commented Sep 7, 2017

@ramya-rao-a latest changes should be able to show correct package name

@uudashr uudashr closed this Sep 7, 2017
@uudashr uudashr reopened this Sep 7, 2017
@uudashr uudashr closed this Sep 7, 2017
@uudashr uudashr reopened this Sep 7, 2017
@uudashr
Copy link
Contributor Author

uudashr commented Sep 11, 2017

@ramya-rao-a please check

@uudashr uudashr closed this Sep 11, 2017
@uudashr uudashr reopened this Sep 11, 2017
@msftclas
Copy link

@uudashr,
Thanks for having already signed the Contribution License Agreement. Your agreement was validated by Microsoft. We will now review your pull request.
Thanks,
Microsoft Pull Request Bot

function getMissingTools(goVersion: SemVersion): Promise<string[]> {
let keys = Object.keys(getTools(goVersion));
return Promise.all<string>(keys.map(tool => new Promise<string>((resolve, reject) => {
if (tool === 'gopkgs') {
gopkgsMissing().then((missing) => {
Copy link
Contributor

@ramya-rao-a ramya-rao-a Sep 12, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line will be reached only when there is no gopkgs tool in the user's machine.
Whereas you are expecting to reach here to make a decision on whether the gopkgs present in the user machine is the old one or the new one

What do you think of this instead?
ramya-rao-a@2119ec1

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahhh... I see your point. Agree with that. We can remove the gopkgsMissing() then

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I have pushed my change to your branch

@ramya-rao-a
Copy link
Contributor

@uudashr The below assert is failing when vendor is not supported. Any idea why?

https://github.com/uudashr/vscode-go/blob/faster-go-list-all/test/go.test.ts#L590

@uudashr
Copy link
Contributor Author

uudashr commented Sep 12, 2017

@ramya-rao-a Not sure, still investigating...
For sure because now listPackages() use getImportablePackages().
Logic from old listPackages() not compatible with getImportablePackages()
And it happens only on Go 1.5 and 1.6

@ramya-rao-a
Copy link
Contributor

@uudashr Tests are fixed now

@ramya-rao-a ramya-rao-a merged commit e5aa763 into microsoft:master Sep 12, 2017
@ramya-rao-a
Copy link
Contributor

ramya-rao-a commented Sep 12, 2017

@uudashr First off, thanks for all your work in getting this together

There are a few things I still want to discuss

  1. If gopkgs for any reason runs more than 5 seconds, then every word typed after 5 seconds will end up creating a new process. We should safeguard against this. Something like "if a current gopkgs process is running, don't start a new one"
  2. Completions are usually expected to show up under a second. How do we ensure this when gopkgs takes more than a second? One way is to decouple the calls to gopkgs and gocode. This way even if you don't get completion for new pkg on first attempt, you will most likely get it in the second attempt.

@uudashr
Copy link
Contributor Author

uudashr commented Sep 12, 2017

You are welcome... thanks for fixing the test

  1. Cool
  2. Have something in my mind.. something like create subscription to the currently running process if any
  3. Something like Promise.race([goAllPackagesNoCache(), timeout(1000).then(() => cache)])

@uudashr
Copy link
Contributor Author

uudashr commented Sep 12, 2017

@ramya-rao-a for point number 2, roughly will be going to be like https://gist.github.com/uudashr/8fbacf975cb8140b962fc7fd3122ff22

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants