-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
gopls/doc: update workspace documentation for zero-config gopls
Rewrite the now-obsolete documentation. Notably, remove the section on experimental workspace mode, as it is long unsupported. For golang/go#57979 Change-Id: I8ba77d626d0b24b0ab34a78103985a5a881def21 Reviewed-on: https://go-review.googlesource.com/c/tools/+/566936 Reviewed-by: Hyang-Ah Hana Kim <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Auto-Submit: Robert Findley <[email protected]>
- Loading branch information
Showing
2 changed files
with
112 additions
and
83 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,101 +1,130 @@ | ||
# Setting up your workspace | ||
|
||
`gopls` supports both Go module and GOPATH modes. However, it needs a defined | ||
scope in which language features like references, rename, and implementation | ||
should operate. | ||
|
||
The following options are available for configuring this scope: | ||
|
||
## Module mode | ||
|
||
### One module | ||
|
||
If you are working with a single module, you can open the module root (the | ||
directory containing the `go.mod` file), a subdirectory within the module, | ||
or a parent directory containing the module. | ||
**In general, `gopls` should work when you open a Go file contained in your | ||
workspace folder**. If it isn't working for you, or if you want to better | ||
understand how gopls models your workspace, please read on. | ||
|
||
**Note**: If you open a parent directory containing a module, it must **only** | ||
contain that single module. Otherwise, you are working with multiple modules. | ||
## Workspace builds | ||
|
||
### Multiple modules | ||
|
||
Gopls has several alternatives for working on multiple modules simultaneously, | ||
described below. Starting with Go 1.18, Go workspaces are the preferred solution. | ||
|
||
#### Go workspaces (Go 1.18+) | ||
`gopls` supports both Go module and GOPATH modes. However, it needs a defined | ||
scope in which language features like references, rename, and implementation | ||
should operate. Put differently, gopls needs to infer which `go build` | ||
invocations you would use to build your workspace, including the working | ||
directory, environment, and build flags. | ||
|
||
Starting with `[email protected]`, gopls will try to guess the builds you are | ||
working on based on the set of open files. When you open a file in a workspace | ||
folder, gopls will check whether the file is contained in a module, `go.work` | ||
workspace, or GOPATH directory, and configure the build accordingly. | ||
Additionally, if you open a file that is constrained to a different operating | ||
system or architecture, for example opening `foo_windows.go` when working on | ||
Linux, gopls will create a scope with `GOOS` and `GOARCH` set to a value that | ||
matches the file. | ||
|
||
For example, suppose we had a repository with three modules: `moda`, `modb`, | ||
and `modc`, and a `go.work` file using modules `moda` and `modb`. If we open | ||
the files `moda/a.go`, `modb/b.go`, `moda/a_windows.go`, and `modc/c.go`, gopls | ||
will automatically create three builds: | ||
|
||
![Zero Config gopls](zeroconfig.png) | ||
|
||
This allows `gopls` to _just work_ when you open a Go file, but it does come with | ||
several caveats: | ||
|
||
- This causes gopls to do more work, since it is now tracking three builds | ||
instead of one. However, the recent | ||
[scalability redesign](https://go.dev/blog/gopls-scalability) | ||
allows much of this work to be avoided through efficient caching. | ||
- In some cases this may cause gopls to do more work, since gopls is now | ||
tracking three builds instead of one. However, the recent | ||
[scalability redesign](https://go.dev/blog/gopls-scalability) allows us | ||
to avoid most of this work by efficient caching. | ||
- For operations originating from a given file, including finding references | ||
and implementations, gopls executes the operation in | ||
_the default build for that file_. For example, finding references to | ||
a symbol `S` from `foo_linux.go` will return references from the Linux build, | ||
and finding references to the same symbol `S` from `foo_windows.go` will | ||
return references from the Windows build. This is done for performance | ||
reasons, as in the common case one build is sufficient, but may lead to | ||
surprising results. Issues [#65757](https://go.dev/issue/65757) and | ||
[#65755](https://go.dev/issue/65755) propose improvements to this behavior. | ||
- When selecting a `GOOS/GOARCH` combination to match a build-constrained file, | ||
`gopls` will choose the first matching combination from | ||
[this list](https://cs.opensource.google/go/x/tools/+/master:gopls/internal/cache/port.go;l=30;drc=f872b3d6f05822d290bc7bdd29db090fd9d89f5c). | ||
In some cases, that may be surprising. | ||
- When working in a `GOOS/GOARCH` constrained file that does not match your | ||
default toolchain, `CGO_ENABLED=0` is implicitly set. This means that `gopls` | ||
will not work in files including `import "C"`. Issue | ||
[#65758](https://go.dev/issue/65758) may lead to improvements in this | ||
behavior. | ||
- `gopls` is not able to guess build flags that include arbitrary user-defined | ||
build constraints. For example, if you are trying to work on a file that is | ||
constrained by the build directive `//go:build special`, gopls will not guess | ||
that it needs to create a build with `"buildFlags": ["-tags=special"]`. Issue | ||
[#65089](https://go.dev/issue/65089) proposes a heuristic by which gopls | ||
could handle this automatically. | ||
|
||
We hope that you provide feedback on this behavior by upvoting or commenting | ||
the issues mentioned above, or opening a [new issue](https://go.dev/issue/new) | ||
for other improvements you'd like to see. | ||
|
||
## When to use a `go.work` file for development | ||
|
||
Starting with Go 1.18, the `go` command has native support for multi-module | ||
workspaces, via [`go.work`](https://go.dev/ref/mod#workspaces) files. These | ||
files are recognized by gopls starting with `[email protected]`. | ||
|
||
The easiest way to work on multiple modules in Go 1.18 and later is therefore | ||
to create a `go.work` file containing the modules you wish to work on, and set | ||
your workspace root to the directory containing the `go.work` file. | ||
|
||
For example, suppose this repo is checked out into the `$WORK/tools` directory. | ||
We can work on both `golang.org/x/tools` and `golang.org/x/tools/gopls` | ||
simultaneously by creating a `go.work` file using `go work init`, followed by | ||
`go work use MODULE_DIRECTORIES...` to add directories containing `go.mod` files to the | ||
workspace: | ||
workspaces, via [`go.work`](https://go.dev/ref/mod#workspaces) files. `gopls` | ||
will recognize these files if they are present in your workspace. | ||
|
||
Use a `go.work` file when: | ||
|
||
- You want to work on multiple modules simultaneously in a single logical | ||
build, for example if you want changes to one module to be reflected in | ||
another. | ||
- You want to improve `gopls'` memory usage or performance by reducing the number | ||
of builds it must track. | ||
- You want `gopls` to know which modules you are working on in a multi-module | ||
workspace, without opening any files. For example, if you want to use | ||
`workspace/symbol` queries before any files are open. | ||
- You are using `[email protected]` or earlier, and want to work on multiple | ||
modules. | ||
|
||
For example, suppose this repo is checked out into the `$WORK/tools` directory, | ||
and [`x/mod`](https://pkg.go.dev/golang.org/x/mod) is checked out into | ||
`$WORK/mod`, and you are working on a new `x/mod` API for editing `go.mod` | ||
files that you want to simultaneously integrate into `gopls`. | ||
|
||
You can work on both `golang.org/x/tools/gopls` and `golang.org/x/mod` | ||
simultaneously by creating a `go.work` file: | ||
|
||
```sh | ||
cd $WORK | ||
go work init | ||
go work use ./tools/ ./tools/gopls/ | ||
go work use tools/gopls mod | ||
``` | ||
|
||
...followed by opening the `$WORK` directory in our editor. | ||
|
||
#### DEPRECATED: Experimental workspace module (Go 1.17 and earlier) | ||
|
||
**This feature is deprecated and will be removed in future versions of gopls. | ||
Please see [issue #52897](https://go.dev/issue/52897) for additional | ||
information.** | ||
|
||
With earlier versions of Go, `gopls` can simulate multi-module workspaces by | ||
creating a synthetic module requiring the modules in the workspace root. | ||
See [the design document](https://github.com/golang/proposal/blob/master/design/37720-gopls-workspaces.md) | ||
for more information. | ||
|
||
This feature is experimental, and will eventually be removed once `go.work` | ||
files are accepted by all supported Go versions. | ||
|
||
You can enable this feature by configuring the | ||
[experimentalWorkspaceModule](settings.md#experimentalworkspacemodule-bool) | ||
setting. | ||
|
||
#### Multiple workspace folders | ||
|
||
If neither of the above solutions work, and your editor allows configuring the | ||
set of | ||
["workspace folders"](https://microsoft.github.io/language-server-protocol/specifications/specification-3-17/#workspaceFolder) | ||
used during your LSP session, you can still work on multiple modules by adding | ||
a workspace folder at each module root (the locations of `go.mod` files). This | ||
means that each module has its own scope, and features will not work across | ||
modules. | ||
|
||
In VS Code, you can create a workspace folder by setting up a | ||
[multi-root workspace](https://code.visualstudio.com/docs/editor/multi-root-workspaces). | ||
View the [documentation for your editor plugin](../README.md#editor) to learn how to | ||
configure a workspace folder in your editor. | ||
|
||
### GOPATH mode | ||
...followed by opening the `$WORK` directory in your editor. | ||
|
||
When opening a directory within your GOPATH, the workspace scope will be just | ||
that directory. | ||
## When to manually configure `GOOS`, `GOARCH`, or `-tags` | ||
|
||
### At your own risk | ||
As described in the first section, `[email protected]` and later will try to | ||
configure a new build scope automatically when you open a file that doesn't | ||
match the system default operating system (`GOOS`) or architecture (`GOARCH`). | ||
|
||
Some users or companies may have projects that encompass one `$GOPATH`. If you | ||
open your entire `$GOPATH` or `$GOPATH/src` folder, the workspace scope will be | ||
your entire `GOPATH`. If your GOPATH is large, `gopls` to be very slow to start | ||
because it will try to find all of the Go files in the directory you have | ||
opened. It will then load all of the files it has found. | ||
However, per the caveats listed in that section, this automatic behavior comes | ||
with limitations. Customize your `gopls` environment by setting `GOOS` or | ||
`GOARCH` in your | ||
[`"build.env"`](https://github.com/golang/tools/blob/master/gopls/doc/settings.md#env-mapstringstring) | ||
or `-tags=...` in your" | ||
["build.buildFlags"](https://github.com/golang/tools/blob/master/gopls/doc/settings.md#buildflags-string) | ||
when: | ||
|
||
To work around this case, you can create a new `$GOPATH` that contains only the | ||
packages you want to work on. | ||
- You want to modify the default build environment. | ||
- `gopls` is not guessing the `GOOS/GOARCH` combination you want to use for | ||
cross platform development. | ||
- You need to work on a file that is constrained by a user-defined build tags, | ||
such as the build directive `//go:build special`. | ||
|
||
--- | ||
## GOPATH mode | ||
|
||
If you have additional use cases that are not mentioned above, please | ||
[file a new issue](https://github.com/golang/go/issues/new). | ||
When opening a directory within your `GOPATH`, the workspace scope will be just | ||
that directory and all directories contained within it. Note that opening | ||
a large GOPATH directory can make gopls very slow to start. |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.