diff --git a/gopls/README.md b/gopls/README.md
index 962d80c3ff8..6602e0c27a7 100644
--- a/gopls/README.md
+++ b/gopls/README.md
@@ -3,7 +3,9 @@
[![PkgGoDev](https://pkg.go.dev/badge/golang.org/x/tools/gopls)](https://pkg.go.dev/golang.org/x/tools/gopls)
`gopls` (pronounced "Go please") is the official Go [language server] developed
-by the Go team. It provides IDE features to any [LSP]-compatible editor.
+by the Go team.
+It provides a wide variety of [IDE features](doc/features/README.md)
+to any [LSP]-compatible editor.
@@ -11,11 +13,16 @@ You should not need to interact with `gopls` directly--it will be automatically
integrated into your editor. The specific features and settings vary slightly
by editor, so we recommend that you proceed to the
[documentation for your editor](#editors) below.
+Also, the gopls documentation for each feature describes whether it is
+supported in each client editor.
## Editors
To get started with `gopls`, install an LSP plugin in your editor of choice.
+TODO: ensure that each editor has a local page (and move these to doc/clients/$EDITOR.md).
+TODO: also, be more consistent about editor (e.g. Emacs) vs. client (e.g. eglot).
+
* [VS Code](https://github.com/golang/vscode-go/blob/master/README.md)
* [Vim / Neovim](doc/vim.md)
* [Emacs](doc/emacs.md)
@@ -137,8 +144,9 @@ If you are having issues with `gopls`, please follow the steps described in the
## Additional information
-* [Features](doc/features.md)
+* [Index of features](doc/features/README.md)
* [Command-line interface](doc/command-line.md)
+* [Configuration settings](doc/settings.md)
* [Advanced topics](doc/advanced.md)
* [Contributing to `gopls`](doc/contributing.md)
* [Integrating `gopls` with an editor](doc/design/integrating.md)
diff --git a/gopls/doc/advanced.md b/gopls/doc/advanced.md
index 7159626306d..d66ce8743a2 100644
--- a/gopls/doc/advanced.md
+++ b/gopls/doc/advanced.md
@@ -1,4 +1,4 @@
-# Advanced topics
+# Gopls: Advanced topics
This documentation is for advanced `gopls` users, who may want to test
unreleased versions or try out special features.
@@ -54,27 +54,4 @@ Note that you must work inside the `GOROOT/src` subdirectory, as the `go`
command does not recognize `go.work` files in a parent of `GOROOT/src`
(https://go.dev/issue/59429).
-## Working with generic code
-
-Gopls has support for editing generic Go code. To enable this support, you need
-to **install gopls using Go 1.18 or later**. The easiest way to do this is by
-[installing Go 1.18+](https://go.dev/dl) and then using this Go version to
-install gopls:
-
-```
-$ go install golang.org/x/tools/gopls@latest
-```
-
-It is strongly recommended that you install the latest version of `gopls`, or
-the latest **unstable** version as [described above](#installing-unreleased-versions).
-
-The `gopls` built with these instructions understands generic code. See the
-[generics tutorial](https://go.dev/doc/tutorial/generics) for more information
-on how to use generics in Go!
-
-### Known issues
-
- * [`staticcheck`](https://github.com/golang/tools/blob/master/gopls/doc/settings.md#staticcheck)
- on generic code is not supported yet.
-
[Go project]: https://go.googlesource.com/go
diff --git a/gopls/doc/analyzers.md b/gopls/doc/analyzers.md
index d3f7ba8eab3..04101131353 100644
--- a/gopls/doc/analyzers.md
+++ b/gopls/doc/analyzers.md
@@ -1,4 +1,4 @@
-# Analyzers
+# Gopls: Analyzers
@@ -15,19 +15,20 @@ before you run your tests, or even before you save your files.
This document describes the suite of analyzers available in gopls,
which aggregates analyzers from a variety of sources:
-- all the usual bug-finding analyzers from the `go vet` suite;
-- a number of analyzers with more substantial dependencies that prevent them from being used in `go vet`;
-- analyzers that augment compilation errors by suggesting quick fixes to common mistakes; and
-- a handful of analyzers that suggest possible style improvements.
+- all the usual bug-finding analyzers from the `go vet` suite (e.g. `printf`; run `go tool vet help` for the complete list);
+- a number of analyzers with more substantial dependencies that prevent them from being used in `go vet` (e.g. `nilness`);
+- analyzers that augment compilation errors by suggesting quick fixes to common mistakes (e.g. `fillreturns`); and
+- a handful of analyzers that suggest possible style improvements (e.g. `simplifyrange`).
-More details about how to enable and disable analyzers can be found
-[here](settings.md#analyses).
+To enable or disable analyzers, use the [analyses](settings.md#analyses) setting.
In addition, gopls includes the [`staticcheck` suite](https://staticcheck.dev/docs/checks),
though these analyzers are off by default.
Use the [`staticcheck`](settings.md#staticcheck`) setting to enable them,
and consult staticcheck's documentation for analyzer details.
+
+
diff --git a/gopls/doc/assets/convert-string-interpreted.png b/gopls/doc/assets/convert-string-interpreted.png
new file mode 100644
index 00000000000..6bb7f2a9b35
Binary files /dev/null and b/gopls/doc/assets/convert-string-interpreted.png differ
diff --git a/gopls/doc/assets/convert-string-raw.png b/gopls/doc/assets/convert-string-raw.png
new file mode 100644
index 00000000000..24dea626eb1
Binary files /dev/null and b/gopls/doc/assets/convert-string-raw.png differ
diff --git a/gopls/doc/assets/diagnostic-analysis.png b/gopls/doc/assets/diagnostic-analysis.png
new file mode 100644
index 00000000000..5a934d0d6e6
Binary files /dev/null and b/gopls/doc/assets/diagnostic-analysis.png differ
diff --git a/gopls/doc/assets/diagnostic-typeerror.png b/gopls/doc/assets/diagnostic-typeerror.png
new file mode 100644
index 00000000000..8f78228893c
Binary files /dev/null and b/gopls/doc/assets/diagnostic-typeerror.png differ
diff --git a/gopls/doc/assets/document-highlight.png b/gopls/doc/assets/document-highlight.png
new file mode 100644
index 00000000000..ded4564c027
Binary files /dev/null and b/gopls/doc/assets/document-highlight.png differ
diff --git a/gopls/doc/assets/documentlink.png b/gopls/doc/assets/documentlink.png
new file mode 100644
index 00000000000..8bc5e3d05e6
Binary files /dev/null and b/gopls/doc/assets/documentlink.png differ
diff --git a/gopls/doc/assets/extract-function-after.png b/gopls/doc/assets/extract-function-after.png
new file mode 100644
index 00000000000..4599a827a0e
Binary files /dev/null and b/gopls/doc/assets/extract-function-after.png differ
diff --git a/gopls/doc/assets/extract-function-before.png b/gopls/doc/assets/extract-function-before.png
new file mode 100644
index 00000000000..9c2590b41c3
Binary files /dev/null and b/gopls/doc/assets/extract-function-before.png differ
diff --git a/gopls/doc/assets/extract-to-new-file-after.png b/gopls/doc/assets/extract-to-new-file-after.png
new file mode 100644
index 00000000000..3f0aa856091
Binary files /dev/null and b/gopls/doc/assets/extract-to-new-file-after.png differ
diff --git a/gopls/doc/assets/extract-to-new-file-before.png b/gopls/doc/assets/extract-to-new-file-before.png
new file mode 100644
index 00000000000..9c05ceb9db1
Binary files /dev/null and b/gopls/doc/assets/extract-to-new-file-before.png differ
diff --git a/gopls/doc/assets/extract-var-after.png b/gopls/doc/assets/extract-var-after.png
new file mode 100644
index 00000000000..db558d6736a
Binary files /dev/null and b/gopls/doc/assets/extract-var-after.png differ
diff --git a/gopls/doc/assets/extract-var-before.png b/gopls/doc/assets/extract-var-before.png
new file mode 100644
index 00000000000..356a242db3c
Binary files /dev/null and b/gopls/doc/assets/extract-var-before.png differ
diff --git a/gopls/doc/assets/fill-struct-after.png b/gopls/doc/assets/fill-struct-after.png
new file mode 100644
index 00000000000..61662287e10
Binary files /dev/null and b/gopls/doc/assets/fill-struct-after.png differ
diff --git a/gopls/doc/assets/fill-struct-before.png b/gopls/doc/assets/fill-struct-before.png
new file mode 100644
index 00000000000..fd544921a6d
Binary files /dev/null and b/gopls/doc/assets/fill-struct-before.png differ
diff --git a/gopls/doc/assets/fill-switch-after.png b/gopls/doc/assets/fill-switch-after.png
new file mode 100644
index 00000000000..33d1bd34c4a
Binary files /dev/null and b/gopls/doc/assets/fill-switch-after.png differ
diff --git a/gopls/doc/assets/fill-switch-before.png b/gopls/doc/assets/fill-switch-before.png
new file mode 100644
index 00000000000..f25af03b9c8
Binary files /dev/null and b/gopls/doc/assets/fill-switch-before.png differ
diff --git a/gopls/doc/assets/fill-switch-enum-after.png b/gopls/doc/assets/fill-switch-enum-after.png
new file mode 100644
index 00000000000..564be177976
Binary files /dev/null and b/gopls/doc/assets/fill-switch-enum-after.png differ
diff --git a/gopls/doc/assets/fill-switch-enum-before.png b/gopls/doc/assets/fill-switch-enum-before.png
new file mode 100644
index 00000000000..85150347fb0
Binary files /dev/null and b/gopls/doc/assets/fill-switch-enum-before.png differ
diff --git a/gopls/doc/assets/foldingrange.png b/gopls/doc/assets/foldingrange.png
new file mode 100644
index 00000000000..19e7645b266
Binary files /dev/null and b/gopls/doc/assets/foldingrange.png differ
diff --git a/gopls/doc/assets/hover-basic.png b/gopls/doc/assets/hover-basic.png
new file mode 100644
index 00000000000..687ff71c162
Binary files /dev/null and b/gopls/doc/assets/hover-basic.png differ
diff --git a/gopls/doc/assets/hover-embed.png b/gopls/doc/assets/hover-embed.png
new file mode 100644
index 00000000000..4d877a283da
Binary files /dev/null and b/gopls/doc/assets/hover-embed.png differ
diff --git a/gopls/doc/assets/hover-linkname.png b/gopls/doc/assets/hover-linkname.png
new file mode 100644
index 00000000000..c547d52f7a4
Binary files /dev/null and b/gopls/doc/assets/hover-linkname.png differ
diff --git a/gopls/doc/assets/inlayhint-parameternames.png b/gopls/doc/assets/inlayhint-parameternames.png
new file mode 100644
index 00000000000..83d934e1ca6
Binary files /dev/null and b/gopls/doc/assets/inlayhint-parameternames.png differ
diff --git a/gopls/doc/assets/invert-if-after.png b/gopls/doc/assets/invert-if-after.png
new file mode 100644
index 00000000000..d66dc8e92f7
Binary files /dev/null and b/gopls/doc/assets/invert-if-after.png differ
diff --git a/gopls/doc/assets/invert-if-before.png b/gopls/doc/assets/invert-if-before.png
new file mode 100644
index 00000000000..48581d2f3d8
Binary files /dev/null and b/gopls/doc/assets/invert-if-before.png differ
diff --git a/gopls/doc/assets/outgoingcalls.png b/gopls/doc/assets/outgoingcalls.png
new file mode 100644
index 00000000000..00ca4b1a50a
Binary files /dev/null and b/gopls/doc/assets/outgoingcalls.png differ
diff --git a/gopls/doc/assets/remove-unusedparam-after.png b/gopls/doc/assets/remove-unusedparam-after.png
new file mode 100644
index 00000000000..04193fdcb18
Binary files /dev/null and b/gopls/doc/assets/remove-unusedparam-after.png differ
diff --git a/gopls/doc/assets/remove-unusedparam-before.png b/gopls/doc/assets/remove-unusedparam-before.png
new file mode 100644
index 00000000000..4e49c4294fb
Binary files /dev/null and b/gopls/doc/assets/remove-unusedparam-before.png differ
diff --git a/gopls/doc/assets/rename-conflict.png b/gopls/doc/assets/rename-conflict.png
new file mode 100644
index 00000000000..105a6ee15de
Binary files /dev/null and b/gopls/doc/assets/rename-conflict.png differ
diff --git a/gopls/doc/assets/signature-help.png b/gopls/doc/assets/signature-help.png
new file mode 100644
index 00000000000..ca537787475
Binary files /dev/null and b/gopls/doc/assets/signature-help.png differ
diff --git a/gopls/doc/codelenses.md b/gopls/doc/codelenses.md
index 34776273e29..71425ce09c6 100644
--- a/gopls/doc/codelenses.md
+++ b/gopls/doc/codelenses.md
@@ -1,4 +1,4 @@
-# Code Lenses
+# Gopls: Code lenses
A "code lens" is a command associated with a range of a source file.
The VS Code manual describes code lenses as
@@ -14,6 +14,13 @@ They can be enabled and disabled using the
[`codelenses`](settings.md#codelenses) setting.
Their features are subject to change.
+Client support:
+- **VS Code**: Code Lenses appear as small text links above a line of source code.
+- **Emacs + eglot**: Not supported, but prototype exists at https://github.joaotavora/eglot/pull/71.
+- **Vim + coc.nvim**: ??
+- **CLI**: `gopls codelens`. For example, `gopls codelens -exec file.go:123 "run test"` runs the test at the specified line.
+
+
## `gc_details`: Toggle display of Go compiler optimization decisions
diff --git a/gopls/doc/command-line.md b/gopls/doc/command-line.md
index 465905873c1..4f825e21b89 100644
--- a/gopls/doc/command-line.md
+++ b/gopls/doc/command-line.md
@@ -1,15 +1,35 @@
-# Command line
+# Gopls: Command-line interface
-**Note: The `gopls` command-line is still experimental and subject to change at any point.**
+The `gopls` command provides a number of subcommands that expose much
+of the server's functionality. However, the interface is currently
+**experimental** and **subject to change at any point.**
+It is not efficient, complete, flexible, or officially supported.
-`gopls` exposes some (but not all) features on the command-line. This can be useful for debugging `gopls` itself.
+Its primary use is as a debugging aid.
+For example, this command reports the location of references to the
+symbol at the specified file/line/column:
-
+```
+$ gopls references ./gopls/main.go:35:8
+Log: Loading packages...
+Info: Finished loading packages.
+/home/gopher/xtools/go/packages/gopackages/main.go:27:7-11
+/home/gopher/xtools/gopls/internal/cmd/integration_test.go:1062:7-11
+/home/gopher/xtools/gopls/internal/test/integration/bench/bench_test.go:59:8-12
+/home/gopher/xtools/gopls/internal/test/integration/regtest.go:140:8-12
+/home/gopher/xtools/gopls/main.go:35:7-11
+```
-Learn about available commands and flags by running `gopls help`.
-
-Much of the functionality of `gopls` is available through a command line interface.
+See golang/go#63693 for a discussion of its future.
-There are two main reasons for this. The first is that we do not want users to rely on separate command line tools when they wish to do some task outside of an editor. The second is that the CLI assists in debugging. It is easier to reproduce behavior via single command.
+Learn about available commands and flags by running `gopls help`.
-It is not a goal of `gopls` to be a high performance command line tool. Its command line is intended for single file/package user interaction speeds, not bulk processing.
+Positions within files are specified as `file.go:line:column` triples,
+where the line and column start at 1, and columns are measured in
+bytes of the UTF-8 encoding.
+Alternatively, positions may be specified by the byte offset within
+the UTF-8 encoding of the file, starting from zero, for example
+`file.go:#1234`.
+(When working in non-ASCII files, beware that your editor may report a
+position's offset within its file using a different measure such as
+UTF-16 codes, Unicode code points, or graphemes).
diff --git a/gopls/doc/commands.md b/gopls/doc/commands.md
index 90f70d3bb47..8d0c870747e 100644
--- a/gopls/doc/commands.md
+++ b/gopls/doc/commands.md
@@ -1,8 +1,23 @@
-# Commands
+# Gopls: Commands
-This document describes the LSP-level commands supported by `gopls`. They cannot be invoked directly by users, and all the details are subject to change, so nobody should rely on this information.
+The LSP's `workspace/executeCommand` RPC is an extension mechanism
+that allows clients to invoke ad hoc commands offered by servers.
+This document describes the commands supported by `gopls`.
+
+Most commands provide the implementations of features advertised
+through documented LSP mechanisms such as
+[Code Lenses](settings.md#code-lenses) and
+[Code Actions](features/transformation.md#code-actions).
+
+They are not intended to be invoked directly by clients,
+and typically editors do not make them directly accessible.
+
+We document them for completeness, but these interfaces
+are not stable and may change without notice.
+TODO(rfindley): unpublish and remove this page.
+
## `gopls.add_dependency`: **Add a dependency**
Adds a dependency to the go.mod file for a module.
@@ -20,6 +35,7 @@ Args:
}
```
+
## `gopls.add_import`: **Add an import**
Ask the server to add an import path to a given Go file. The method will
@@ -39,6 +55,7 @@ Args:
}
```
+
## `gopls.add_telemetry_counters`: **Update the given telemetry counters**
Gopls will prepend "fwd/" to all the counters updated using this command
@@ -54,6 +71,7 @@ Args:
}
```
+
## `gopls.apply_fix`: **Apply a fix**
Applies a fix to a region of source code.
@@ -140,6 +158,7 @@ Result:
}
```
+
## `gopls.assembly`: **Browse assembly listing of current function in a browser.**
This command opens a web-based disassembly listing of the
@@ -154,6 +173,7 @@ string,
string
```
+
## `gopls.change_signature`: **Perform a "change signature" refactoring**
This command is experimental, currently only supporting parameter removal.
@@ -226,6 +246,7 @@ Result:
}
```
+
## `gopls.check_upgrades`: **Check for upgrades**
Checks for module upgrades.
@@ -241,6 +262,7 @@ Args:
}
```
+
## `gopls.diagnose_files`: **Cause server to publish diagnostics for the specified files.**
This command is needed by the 'gopls {check,fix}' CLI subcommands.
@@ -253,6 +275,7 @@ Args:
}
```
+
## `gopls.doc`: **Browse package documentation.**
Opens the Go package documentation page for the current
@@ -276,6 +299,7 @@ Args:
}
```
+
## `gopls.edit_go_directive`: **Run go mod edit -go=version**
Runs `go mod edit -go=version` for a module.
@@ -291,6 +315,7 @@ Args:
}
```
+
## `gopls.extract_to_new_file`: **Move selected declarations to a new file**
Used by the code action of the same name.
@@ -313,6 +338,7 @@ Args:
}
```
+
## `gopls.fetch_vulncheck_result`: **Get known vulncheck result**
Fetch the result of latest vulnerability check (`govulncheck`).
@@ -332,6 +358,7 @@ Result:
map[golang.org/x/tools/gopls/internal/protocol.DocumentURI]*golang.org/x/tools/gopls/internal/vulncheck.Result
```
+
## `gopls.free_symbols`: **Browse free symbols referenced by the selection in a browser.**
This command is a query over a selected range of Go source
@@ -361,6 +388,7 @@ string,
}
```
+
## `gopls.gc_details`: **Toggle gc_details**
Toggle the calculation of gc annotations.
@@ -371,6 +399,7 @@ Args:
string
```
+
## `gopls.generate`: **Run go generate**
Runs `go generate` for a given directory.
@@ -386,6 +415,7 @@ Args:
}
```
+
## `gopls.go_get_package`: **'go get' a package**
Runs `go get` to fetch a package.
@@ -402,6 +432,7 @@ Args:
}
```
+
## `gopls.list_imports`: **List imports of a file and its package**
Retrieve a list of imports in the given Go file, and the package it
@@ -432,6 +463,7 @@ Result:
}
```
+
## `gopls.list_known_packages`: **List known packages**
Retrieve a list of packages that are importable from the given URI.
@@ -458,12 +490,14 @@ Result:
}
```
+
## `gopls.maybe_prompt_for_telemetry`: **Prompt user to enable telemetry**
Checks for the right conditions, and then prompts the user
to ask if they want to enable Go telemetry uploading. If
the user responds 'Yes', the telemetry mode is set to "on".
+
## `gopls.mem_stats`: **Fetch memory statistics**
Call runtime.GC multiple times and return memory statistics as reported by
@@ -481,6 +515,7 @@ Result:
}
```
+
## `gopls.regenerate_cgo`: **Regenerate cgo**
Regenerates cgo definitions.
@@ -494,6 +529,7 @@ Args:
}
```
+
## `gopls.remove_dependency`: **Remove a dependency**
Removes a dependency from the go.mod file of a module.
@@ -513,6 +549,7 @@ Args:
}
```
+
## `gopls.reset_go_mod_diagnostics`: **Reset go.mod diagnostics**
Reset diagnostics in the go.mod file of a module.
@@ -530,6 +567,7 @@ Args:
}
```
+
## `gopls.run_go_work_command`: **Run `go work [args...]`, and apply the resulting go.work**
edits to the current go.work file
@@ -544,6 +582,7 @@ Args:
}
```
+
## `gopls.run_govulncheck`: **Run vulncheck**
Run vulnerability check (`govulncheck`).
@@ -571,6 +610,7 @@ Result:
}
```
+
## `gopls.run_tests`: **Run test(s)**
Runs `go test` for a specific set of test or benchmark functions.
@@ -590,10 +630,12 @@ Args:
}
```
+
## `gopls.scan_imports`: **force a sychronous scan of the imports cache.**
This command is intended for use by gopls tests only.
+
## `gopls.start_debugging`: **Start the gopls debug server**
Start the gopls debug server if it isn't running, and return the debug
@@ -638,6 +680,7 @@ Result:
}
```
+
## `gopls.start_profile`: **Start capturing a profile of gopls' execution**
Start a new pprof profile. Before using the resulting file, profiling must
@@ -658,6 +701,7 @@ Result:
struct{}
```
+
## `gopls.stop_profile`: **Stop an ongoing profile**
This command is intended for internal use only, by the gopls benchmark
@@ -678,6 +722,7 @@ Result:
}
```
+
## `gopls.test`: **Run test(s) (legacy)**
Runs `go test` for a specific set of test or benchmark functions.
@@ -697,6 +742,7 @@ string,
[]string
```
+
## `gopls.tidy`: **Run go mod tidy**
Runs `go mod tidy` for a module.
@@ -710,6 +756,7 @@ Args:
}
```
+
## `gopls.toggle_gc_details`: **Toggle gc_details**
Toggle the calculation of gc annotations.
@@ -723,6 +770,7 @@ Args:
}
```
+
## `gopls.update_go_sum`: **Update go.sum**
Updates the go.sum file for a module.
@@ -736,6 +784,7 @@ Args:
}
```
+
## `gopls.upgrade_dependency`: **Upgrade a dependency**
Upgrades a dependency in the go.mod file for a module.
@@ -753,6 +802,7 @@ Args:
}
```
+
## `gopls.vendor`: **Run go mod vendor**
Runs `go mod vendor` for a module.
@@ -766,6 +816,7 @@ Args:
}
```
+
## `gopls.views`: **List current Views on the server.**
This command is intended for use by gopls tests only.
@@ -782,6 +833,7 @@ Result:
}
```
+
## `gopls.workspace_stats`: **Fetch workspace statistics**
Query statistics about workspace builds, modules, packages, and files.
diff --git a/gopls/doc/contributing.md b/gopls/doc/contributing.md
index a2f987b63c9..594bcd4f32a 100644
--- a/gopls/doc/contributing.md
+++ b/gopls/doc/contributing.md
@@ -1,4 +1,4 @@
-# Documentation for contributors
+# Gopls: Documentation for contributors
This documentation augments the general documentation for contributing to the
x/tools repository, described at the [repository root](../../CONTRIBUTING.md).
diff --git a/gopls/doc/daemon.md b/gopls/doc/daemon.md
index 86356daf236..0844bc062e7 100644
--- a/gopls/doc/daemon.md
+++ b/gopls/doc/daemon.md
@@ -1,4 +1,4 @@
-# Running gopls as a daemon
+# Gopls: Running as a daemon
**Note: this feature is new. If you encounter bugs, please [file an
issue](troubleshooting.md#file-an-issue).**
diff --git a/gopls/doc/emacs.md b/gopls/doc/emacs.md
index d5e3ba28803..3b6ee80d05a 100644
--- a/gopls/doc/emacs.md
+++ b/gopls/doc/emacs.md
@@ -1,4 +1,4 @@
-# Emacs
+# Gopls: Using Emacs
## Installing `gopls`
@@ -116,6 +116,9 @@ project root.
(add-hook 'go-mode-hook #'eglot-format-buffer-before-save)
```
+Use `M-x eglot-upgrade-eglot` to upgrade to the latest version of
+Eglot.
+
### Configuring `gopls` via Eglot
See [settings] for information about available gopls settings.
diff --git a/gopls/doc/features.md b/gopls/doc/features.md
deleted file mode 100644
index 70a734eadc3..00000000000
--- a/gopls/doc/features.md
+++ /dev/null
@@ -1,55 +0,0 @@
-# Features
-
-This document describes some of the features supported by `gopls`. It is
-currently under construction, so, for a comprehensive list, see the
-[Language Server Protocol](https://microsoft.github.io/language-server-protocol/).
-
-## Special features
-
-Here, only special features outside of the LSP are described.
-
-### Symbol Queries
-
-Gopls supports some extended syntax for `workspace/symbol` requests, when using
-the `fuzzy` symbol matcher (the default). Inspired by the popular fuzzy matcher
-[FZF](https://github.com/junegunn/fzf), the following special characters are
-supported within symbol queries:
-
-| Character | Usage | Match |
-| --------- | --------- | ------------ |
-| `'` | `'abc` | exact |
-| `^` | `^printf` | exact prefix |
-| `$` | `printf$` | exact suffix |
-
-## Template Files
-
-Gopls provides some support for Go template files, that is, files that
-are parsed by `text/template` or `html/template`.
-Gopls recognizes template files based on their file extension, which may be
-configured by the
-[`templateExtensions`](https://github.com/golang/tools/blob/master/gopls/doc/settings.md#templateextensions) setting.
-Making this list empty turns off template support.
-
-In template files, template support works inside
-the default `{{` delimiters. (Go template parsing
-allows the user to specify other delimiters, but
-gopls does not know how to do that.)
-
-Gopls template support includes the following features:
-+ **Diagnostics**: if template parsing returns an error,
-it is presented as a diagnostic. (Missing functions do not produce errors.)
-+ **Syntax Highlighting**: syntax highlighting is provided for template files.
-+ **Definitions**: gopls provides jump-to-definition inside templates, though it does not understand scoping (all templates are considered to be in one global scope).
-+ **References**: gopls provides find-references, with the same scoping limitation as definitions.
-+ **Completions**: gopls will attempt to suggest completions inside templates.
-
-### Configuring your editor
-
-In addition to configuring `templateExtensions`, you may need to configure your
-editor or LSP client to activate `gopls` for template files. For example, in
-`VS Code` you will need to configure both
-[`files.associations`](https://code.visualstudio.com/docs/languages/identifiers)
-and `build.templateExtensions` (the gopls setting).
-
-
-
diff --git a/gopls/doc/features/README.md b/gopls/doc/features/README.md
new file mode 100644
index 00000000000..6c93b0339c6
--- /dev/null
+++ b/gopls/doc/features/README.md
@@ -0,0 +1,59 @@
+# Gopls: Index of features
+
+This page provides an index of all supported features of gopls that
+are accessible through the [language server protocol](https://microsoft.github.io/language-server-protocol/) (LSP).
+It is intended for:
+- **users of gopls** learning its capabilities so that they get the most out of their editor;
+- **editor maintainers** adding or improving Go support in an LSP-capable editor; and
+- **contributors to gopls** trying to understand how it works.
+
+In an ideal world, Go users would not need to know that gopls or even
+LSP exists, as their LSP-enabled editors would implement every facet
+of the protocol and expose each feature in a natural and discoverable
+way. In reality, editors vary widely in their support for LSP, so
+unfortunately these documents necessarily involve many details of the
+protocol.
+
+We also list [settings](../settings.md) that affect each feature.
+
+Most features are illustrated with reference to VS Code, but we will
+briefly mention whether each feature is supported in other popular
+clients, and if so, how to find it. We welcome contributions, edits,
+and updates from users of any editor.
+
+- [Passive](passive.md): features that are always on and require no special action
+ - [Hover](passive.md#Hover): information about the symbol under the cursor
+ - [SignatureHelp](passive.md#SignatureHelp): type information about the enclosing function call
+ - [DocumentHighlight](passive.md#DocumentHighlight): highlight identifiers referring to the same symbol
+ - [InlayHint](passive.md#InlayHint): show implicit names of struct fields and parameter names
+ - [SemanticTokens](passive.md#SemanticTokens): report syntax information used by editors to color the text
+ - [FoldingRange](passive.md#FoldingRange): report text regions that can be "folded" (expanded/collapsed) in an editor
+ - [DocumentLink](passive.md#DocumentLink): extracts URLs from doc comments, strings in current file so client can linkify
+- [Diagnostics](diagnostics.md): compile errors and static analysis findings
+ - TODO: expand subindex
+- [Navigation](navigation.md): navigation of cross-references, types, and symbols
+ - [Definition](navigation.md#Definition): go to definition of selected symbol
+ - [TypeDefinition](navigation.md#TypeDefinition): go to definition of type of selected symbol
+ - [References](navigation.md#References): list references to selected symbol
+ - [Implementation](navigation.md#Implementation): show "implements" relationships of selected type
+ - [DocumentSymbol](passive.md#DocumentSymbol): outline of symbols defined in current file
+ - [Symbol](navigation.md#Symbol): fuzzy search for symbol by name
+ - [SelectionRange](navigation.md#SelectionRange): select enclosing unit of syntax
+ - [CallHierarchy](navigation.md#CallHierarchy): show outgoing/incoming calls to the current function
+- [Completion](completion.md): context-aware completion of identifiers, statements
+- [Code transformation](transformation.md): fixes and refactorings
+ - [Formatting](transformation.md#Formatting): format the source code
+ - [Rename](transformation.md#Rename): rename a symbol or package
+ - [Organize imports](transformation.md#OrganizeImports): organize the import declaration
+ - [Extract](transformation.md#Extract): extract selection to a new file/function/variable
+ - [Inline](transformation.md#Inline): inline a call to a function or method
+ - [Miscellaneous rewrites](transformation.md#Rewrite): various Go-specific refactorings
+- [Web-based queries](web.md): commands that open a browser page
+ - [Package documentation](web.md#doc): browse documentation for current Go package
+ - [Free symbols](web.md#freesymbols): show symbols used by a selected block of code
+ - [Assembly](web.md#assembly): show listing of assembly code for selected function
+- Support for non-Go files:
+ - [Template files](templates.md): files parsed by `text/template` and `html/template`
+ - [go.mod and go.work files](modfiles.md): Go module and workspace manifests
+- [Command-line interface](../command-line.md): CLI for debugging and scripting (unstable)
+- [Non-standard commands](../commands.md): gopls-specific RPC protocol extensions (unstable)
diff --git a/gopls/doc/features/completion.md b/gopls/doc/features/completion.md
new file mode 100644
index 00000000000..46991aab05e
--- /dev/null
+++ b/gopls/doc/features/completion.md
@@ -0,0 +1,3 @@
+# Gopls: Completion
+
+TODO(golang/go#62022): document
diff --git a/gopls/doc/features/diagnostics.md b/gopls/doc/features/diagnostics.md
new file mode 100644
index 00000000000..4bf1138af6c
--- /dev/null
+++ b/gopls/doc/features/diagnostics.md
@@ -0,0 +1,170 @@
+# Gopls: Diagnostics
+
+Gopls continuously annotates all your open files of source code with a
+variety of diagnostics. Every time you edit a file or make a
+configuration change, gopls asynchronously recomputes these
+diagnostics and sends them to the client using the LSP
+[`publishDiagnostics`](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification#textDocument_publishDiagnostics)
+notification, giving you real-time feedback that reduces the cost of
+common mistakes.
+
+Diagnostics come from two main sources: build errors and analysis findings.
+
+- **Build errors** are those that you would obtain from running `go
+ build`. Gopls doesn't actually run the compiler; that would be too
+ slow. Instead it runs `go list` (when needed) to compute the
+ metadata of the build, then processes those packages in a similar
+ manner to the compiler front-end: reading, scanning, and parsing the
+ source files, then type-checking them. Each of these steps can
+ produce errors that gopls will surface as a diagnostic.
+
+ The `source` field of the LSP `Diagnostic` record indicates where
+ the diagnostic came from: those with source `"go list"` come from
+ the `go list` command, and those with source `"compiler"` come from
+ gopls' parsing or type checking phases, which are similar to those
+ used in the Go compiler.
+
+ ![A diagnostic due to a type error](../assets/diagnostic-typeerror.png)
+
+ The example above shows a `string + int` addition, causes the type
+ checker to report a `MismatchedTypes` error. The diagnostic contains
+ a link to the documentation about this class of type error.
+
+- **Analysis findings** come from the [**Go analysis
+ framework**](https://golang.org/x/tools/go/analysis), the system
+ used by `go vet` to apply a variety of additional static checks to
+ your Go code. The best-known example is the [`printf`
+ analyzer](https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/printf),
+ which reports calls to [`fmt.Printf`](https://pkg.go.dev/fmt#Printf)
+ where the format "verb" doesn't match the argument, such as
+ `fmt.Printf("%d", "three")`.
+
+ Gopls provides dozens of analyzers aggregated from a variety of
+ suites. See [Analyzers](../analyzers.md) for the complete list. The
+ `source` field of each diagnostic produced by an analyzer records
+ the name of the analyzer that produced it.
+
+ ![A diagnostic due to an analysis finding](../assets/diagnostic-analysis.png)
+
+ The example above shows a `printf` formatting mistake. The diagnostic contains
+ a link to the documentation for the `printf` analyzer.
+
+## Recomputation of diagnostics
+
+Diagnostics are automatically recomputed each time the source files
+are edited.
+
+Build errors are updated immediately after each file is edited,
+potentially after every keystroke. This ensures rapid feedback of
+syntax and type errors while editing.
+
+Analysis diagnostics can be more expensive to compute than type
+checking, so they are usually recomputed after a short idle period
+following an edit.
+The [`diagnosticsDelay`](../settings.md#diagnosticsDelay) setting determines
+this period.
+Alternatively, diagnostics may be triggered only after an edited file
+is saved, using the
+[`diagnosticsTrigger`](../settings.md#diagnosticsTrigger) setting.
+
+Gopls does not currently support "pull-based" diagnostics, which are
+computed synchronously when requested by the client; see golang/go#53275.
+
+
+## Quick fixes
+
+Each analyzer diagnostic may suggest one or more alternative
+ways to fix the problem by editing the code.
+For example, when a `return` statement has too few operands,
+the [`fillreturns`](../analyzers.md#fillreturns) analyzer
+suggests a fix that heuristically fills in the missing ones
+with suitable values. Applying the fix eliminates the build error.
+
+![An analyzer diagnostic with two alternative fixes](../assets/remove-unusedparam-before.png)
+
+The screenshot above shows VS Code's Quick Fix menu for an "unused
+parameter" analysis diagnostic with two alternative fixes.
+(See [Remove unused parameter](transformation.md#remove-unused-parameter) for more detail.)
+
+Suggested fixes that are indisputably safe are [code
+actions](transformation.md#code-actions) whose kind is
+`"source.fixAll"`. Many client editors have a shortcut to apply all
+such fixes.
+
+TODO(adonovan): audit all the analyzers to ensure that their
+documentation is up-to-date w.r.t. any fixes they suggest.
+
+Settings:
+
+- The [`diagnosticsDelay`](../settings.md#diagnosticsDelay) setting determines
+ the idle period after an edit before diagnostics are recomputed.
+- The [`diagnosticsTriggerr`](../settings.md#diagnosticsTrigger) setting determines
+ what events cause recomputation of diagnostics.
+- The [`linkTarget`](../settings.md#linkTarget) setting specifies
+ the base URI for Go package links in the Diagnostic.CodeDescription field.
+
+Client support:
+- **VS Code**: Diagnostics appear as a red squiggly underline.
+ Hovering reveals the details, along with any suggested fixes.
+- **Emacs + eglot**: Diagnostics appear as a red squiggly underline.
+ Hovering reveals the details. Use `M-x eglot-code-action-quickfix`
+ to apply available fixes; it will prompt if there are more than one.
+- **Vim + coc.nvim**: ??
+- **CLI**: `gopls check file.go`
+
+
diff --git a/gopls/doc/features/modfiles.md b/gopls/doc/features/modfiles.md
new file mode 100644
index 00000000000..775be987ade
--- /dev/null
+++ b/gopls/doc/features/modfiles.md
@@ -0,0 +1,9 @@
+# Gopls: Support for go.mod and go.work files
+
+TODO: document these features for go.{mod,work} files:
+- hover
+- vulncheck
+- add dependency
+- update dependency
+- diagnostics
+
diff --git a/gopls/doc/features/navigation.md b/gopls/doc/features/navigation.md
new file mode 100644
index 00000000000..2bf4411d292
--- /dev/null
+++ b/gopls/doc/features/navigation.md
@@ -0,0 +1,251 @@
+# Gopls: Navigation features
+
+This page documents gopls features for navigating your source code.
+
+## Definition
+
+The LSP [`textDocument/definition`](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_definition)
+request returns the location of the declaration of the symbol under the cursor.
+Most editors provide a command to navigate directly to that location.
+
+A definition query also works in these unexpected places:
+
+- On an **import path**, it returns the list of locations, of
+ each package declaration in the files of the imported package.
+- On a **package declaration**, it returns the location of
+ the package declaration that provides the documentation of that package.
+- On a symbol in a **[`go:linkname` directive](https://pkg.go.dev/cmd/compile)**,
+ it returns the location of that symbol's declaration.
+- On a **[doc link](https://tip.golang.org/doc/comment#doclinks)**, it returns
+ (like [`hover`](passive.md#Hover)) the location of the linked symbol.
+- On a file name in a **[`go:embed` directive](https://pkg.go.dev/embed)**,
+ it returns the location of the embedded file.
+
+
+
+Client support:
+- **VS Code**: Use [Go to Definition](https://code.visualstudio.com/docs/editor/editingevolved#_go-to-definition) (`F12` or `⌘`-click).
+ If the cursor is already at the declaration, the request is instead interpreted as "Go to References".
+- **Emacs + eglot**: use [`M-x xref-find-definitions`](https://www.gnu.org/software/emacs/manual/html_node/emacs/Xref.html).
+- **Vim + coc.nvim**: ??
+- **CLI**: `gopls definition file.go:#offset`
+
+## References
+
+The LSP [`textDocument/references`](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_references)
+request returns the locations of all identifiers that refers to the symbol under the cursor.
+
+The references algorithm handles various parts of syntax as follows:
+
+- The references to a **symbol** report all uses of that symbol.
+ In the case of exported this may include locations in other packages.
+- The references to a **package declaration** are all the
+ direct imports of the package, along with all the other package
+ declarations in the same package.
+- It is an error to request the references to a **built-in symbol**
+ such as `int` or `append`,
+ as they are presumed too numerous to be of interest.
+- The references to an **interface method** include references to
+ concrete types that implement the interface. Similarly, the
+ references to a **method of a concrete type** include references to
+ corresponding interface methods.
+- An **embedded field** `T` in a struct type such as `struct{T}` is
+ unique in Go in that it is both a reference (to a type) and a
+ definition (of a field).
+ The `references` operation reports only the references to it [as a field](golang/go#63521).
+ To find references to the type, jump to the type declararation first.
+
+Be aware that a references query returns information only about the
+build configuration used to analyze the selected file, so if you ask
+for the references to a symbol defined in `foo_windows.go`, the result
+will never include the file `bar_linux.go`, even if that file refers
+to a symbol of the same name; see golang/go#65755.
+
+Clients can request that the the declaration be included among the
+references; most do.
+
+Client support:
+- **VS Code**: Use [`Go to References`](https://code.visualstudio.com/docs/editor/editingevolved#_peek) to quickly "peek" at the references,
+ or `Find all References` to open the references panel.
+- **Emacs + eglot**: Via [`xref` package](https://www.gnu.org/software/emacs/manual/html_node/emacs/Xref.html): use `M-x xref-find-references`.
+- **Vim + coc.nvim**: ??
+- **CLI**: `gopls references file.go:#offset`
+
+## Implementation
+
+The LSP
+[`textDocument/implementation`](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_implementation)
+request queries the "implements" relation between interfaces and concrete types:
+
+- When invoked on a reference to an **interface type**, it returns the
+ location of the declaration of each type that implements
+ the interface.
+- When invoked on a **concrete type**,
+ it returns the locations of the matching interface types.
+- When invoked on an **interface method**, it returns the corresponding
+ methods of the types that satisfy the interface.
+- When invoked on a **concrete method**,
+ it returns the locations of the matching interface methods.
+
+Only non-trivial interfaces are considered; no implementations are
+reported for type `any`.
+
+Within the same package, all matching types/methods are reported.
+However, across packages, only exported package-level types and their
+methods are reported, so local types (whether interfaces, or struct
+types with methods due to embedding) may be missing from the results.
+
+
+Generic types are currently not fully supported; see golang/go#59224.
+
+Client support:
+- **VS Code**: Use [Go to Implementations](https://code.visualstudio.com/docs/editor/editingevolved#_go-to-implementation) (`⌘F12`).
+- **Emacs + eglot**: Use `M-x eglot-find-implementation`.
+- **Vim + coc.nvim**: ??
+- **CLI**: `gopls implementation file.go:#offset`
+
+
+## TypeDefinition
+
+The LSP
+[`textDocument/typeDefinition`](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_typeDefinition)
+request returns the location of the type of the selected symbol.
+
+For example, if the selection is the name `buf` of a local variable of
+type `*bytes.Buffer`, a `typeDefinition` query will return the
+location of the type `bytes.Buffer`.
+Clients typically navigate to that location.
+
+Type constructors such as pointer, array, slice, channel, and map are
+stripped off the selected type in the search for a named type. For
+example, if x is of type `chan []*T`, the reported type definition
+will be that of `T`.
+Similarly, if the symbol's type is a function with one "interesting"
+(named, non-`error`) result type, the function's result type is used.
+
+Gopls currently requires that a `typeDefinition` query be applied to a
+symbol, not to an arbitrary expression; see golang/go#67890 for
+potential extensions of this functionality.
+
+
+Client support:
+- **VS Code**: Use [Go to Type Definition](https://code.visualstudio.com/docs/editor/editingevolved#_go-to-implementation).
+- **Emacs + eglot**: Use `M-x eglot-find-typeDefinition`.
+- **Vim + coc.nvim**: ??
+- **CLI**: not supported
+
+## DocumentSymbol
+
+The `textDocument/documentSymbol` LSP query reports the list of
+top-level declarations in this file. Clients may use this information
+to present an overview of the file, and an index for faster navigation.
+
+Gopls responds with the newer
+[`DocumentSymbol`](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification#documentSymbol)
+type if the client indicates
+[`hierarchicalDocumentSymbolSupport`](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification#documentSymbolClientCapabilities);
+otherwise it returns the older
+[`SymbolInformation`](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification#symbolInformation).
+
+Client support:
+- **VS Code**: Use the [Outline view](https://code.visualstudio.com/docs/getstarted/userinterface#_outline-view) for navigation.
+- **Emacs + eglot**: Use [`M-x imenu`](https://www.gnu.org/software/emacs/manual/html_node/emacs/Imenu.html#Imenu) to jump to a symbol.
+- **Vim + coc.nvim**: ??
+- **CLI**: `gopls links file.go`
+
+
+## Symbol
+
+The
+[`workspace/symbol`](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification#workspace_symbol)
+LSP query searches an index of all the symbols in the workspace.
+
+The default symbol matching algorithm (`fastFuzzy`), inspired by the
+popular fuzzy matcher [FZF](https://github.com/junegunn/fzf), attempts
+a variety of inexact matches to correct for misspellings in your
+query. For example, it considers `DocSym` a match for `DocumentSymbol`.
+
+
+
+TODO: screenshot
+
+Settings:
+- The [`symbolMatcher`](../settings.md#symbolMatcher) setting controls the algorithm used for symbol matching.
+- The [`symbolStyle`](../settings.md#symbolStyle) setting controls how symbols are qualified in symbol responses.
+- The [`symbolScope`](../settings.md#symbolScope) setting determines the scope of the query.
+- The [`directoryFilters`](../settings.md#directoryFilters) setting specifies directories to be excluded from the search.
+
+Client support:
+- **VS Code**: Use ⌘T to open [Go to Symbol](https://code.visualstudio.com/docs/editor/editingevolved#_go-to-symbol) with workspace scope. (Alternatively, use Ctrl-Shift-O, and add a `@` prefix to search within the file or a `#` prefix to search throughout the workspace.)
+- **Emacs + eglot**: Use [`M-x xref-find-apropos`](https://www.gnu.org/software/emacs/manual/html_node/emacs/Looking-Up-Identifiers.html) to show symbols that match a search term.
+- **Vim + coc.nvim**: ??
+- **CLI**: `gopls links file.go`
+
+
+## SelectionRange
+
+The
+[`textDocument/selectionRange`](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification#textDocument_selectionRange)
+LSP query returns information about the lexical extent of each piece
+of syntax enclosing the current selection.
+Clients may use it to provide an operation to expand the selection
+to successively larger expressions.
+
+Client support:
+- **VSCode**: Use `⌘⇧^→` to expand the selection or `⌘⇧^←` to contract it again; watch this [video](https://www.youtube.com/watch?v=dO4SGAMl7uQ).
+- **Emacs + eglot**: Not standard. Use `M-x eglot-expand-selection` defined in [this configuration snippet](https://github.com/joaotavora/eglot/discussions/1220#discussioncomment-9321061).
+- **Vim + coc.nvim**: ??
+- **CLI**: not supported
+
+## CallHierarchy
+
+The LSP CallHierarchy mechanism consists of three queries that
+together enable clients to present a hierarchical view of a portion of
+the static call graph:
+
+- [`textDocument/prepareCallHierarchy`](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification#textDocument_prepareCallHierarchy) returns a list of [items](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification#callHierarchyItem) for a given position, each representing a named function or method enclosing the position;
+- [`callHierarchyItem/incomingCalls`](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification#callHierarchy_incomingCalls) returns the set of call sites that call the selected item; and
+- [`callHierarchy/outgoingCalls`](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification#callHierarchy_incomingCalls) returns the set of functions called by the selected item.
+
+Invoke the command while selecting the name in a function declaration.
+
+Dynamic calls are not included, because it is not analytically
+practical to detect them. So, beware that the results may not be
+exhaustive, and perform a [References](#references) query if necessary.
+
+The hierarchy does not consider a nested function distinct from its
+enclosing named function. (Without the ability to detect dynamic
+calls, it would make little sense do so.)
+
+The screenshot below shows the outgoing call tree rooted at `f`. The
+tree has been expanded to show a path from `f` to the `String` method
+of `fmt.Stringer` through the guts of `fmt.Sprint:`
+
+
+
+Caveats:
+- In some cases dynamic function calls are (erroneously) included in
+ the output; see golang/go#68153.
+
+Client support:
+- **VS Code**: `Show Call Hierarchy` menu item (`⌥⇧H`) opens [Call hierarchy view](https://code.visualstudio.com/docs/cpp/cpp-ide#_call-hierarchy) (note: docs refer to C++ but the idea is the same for Go).
+- **Emacs + eglot**: Not standard; install with `(package-vc-install "https://github.com/dolmens/eglot-hierarchy")`. Use `M-x eglot-hierarchy-call-hierarchy` to show the direct incoming calls to the selected function; use a prefix argument (`C-u`) to show the direct outgoing calls. There is no way to expand the tree.
+- **CLI**: `gopls call_hierarchy file.go:#offset` shows outgoing and incoming calls.
diff --git a/gopls/doc/features/passive.md b/gopls/doc/features/passive.md
new file mode 100644
index 00000000000..39c0ba6bd0e
--- /dev/null
+++ b/gopls/doc/features/passive.md
@@ -0,0 +1,266 @@
+# Gopls: Passive features
+
+This page documents the fundamental LSP features of gopls that may be
+described as "passive", since many editors use them to continuously
+provide information about your source files without requiring any
+special action.
+
+See also [Code Lenses](../codelenses.md), some of which annotate your
+source code with additional information and may thus also be
+considered passive features.
+
+
+## Hover
+
+The LSP [`textDocument/hover`](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_hover)
+query returns description of the code currently under the cursor, such
+as its name, kind, type, value (for a constant), abbreviated
+declaration (for a type), its doc comment, if any, and a link to the
+symbol's documentation on `pkg.go.dev`. The client may request either
+plain text or Markdown.
+
+
+
+Depending on the selection, it may include additional information.
+For example, hovering over a type shows its declared methods,
+plus any methods promoted from embedded fields.
+
+**Doc links**: A doc comment may refer to another symbol using square
+brackets, for example `[fmt.Printf]`. Hovering over one of these
+[doc links](https://tip.golang.org/doc/comment#doclinks) reveals
+information about the referenced symbol.
+
+
+
+**Struct size/offset info**: for declarations of struct types,
+hovering over the name reveals the struct's size in bytes:
+
+
+
+And hovering over each field name shows the size and offset of that field:
+
+
+
+This information may be useful when optimizing the layout of your data
+structures, or when reading assembly files or stack traces that refer
+to each field by its cryptic byte offset.
+
+In addition, Hover reports the percentage of wasted space due to
+suboptimal ordering of struct fields, if this figure is 20% or higher:
+
+
+
+In the struct above, alignment rules require each of the two boolean
+fields (1 byte) to occupy a complete word (8 bytes), leading to (7 +
+7) / (3 * 8) = 58% waste.
+Placing the two booleans together would save a word.
+(In most structures clarity is more important than compactness, so you
+should reorder fields to save space only in data structures that have
+been shown by profiling to be very frequently allocated.)
+
+**Embed directives**: hovering over the file name pattern in
+[`//go:embed` directive](https://pkg.go.dev/embed), for example
+`*.html`, reveals the list of file names to which the wildcard
+expands.
+
+
+
+
+**Linkname directives**: a [`//go:linkname` directive](https://pkg.go.dev/cmd/compile#hdr-Compiler_Directives) creates a linker-level alias for another symbol.
+Hovering over the directive shows information about the other symbol.
+
+
+
+Settings:
+- The [`hoverKind`](../settings.md#hoverKind) setting controls the verbosity of documentation.
+- The [`linkTarget`](../settings.md#linkTarget) setting specifies
+ the base URI for Go package links
+
+Caveats:
+- It is an unfortunate limitation of the LSP that a `Hover` request
+ currently includes only a position but not a selection, as this
+ means it is impossible to request information about the type and
+ methods of, say, the `f(x)` portion of the larger expression
+ `f(x).y`. Please upvote microsoft/language-server-protocol#1466 if
+ you would like to see this addressed.
+
+Client support:
+- **VS Code**: enabled by default. Displays rendered Markdown in a panel near the cursor.
+- **Emacs + eglot**: enabled by default. Displays a one-line summary in the echo area.
+- **Vim + coc.nvim**: ??
+- **CLI**: `gopls definition file.go:#start-#end` includes information from a Hover query.
+
+
+## SignatureHelp
+
+The LSP [`textDocument/signatureHelp`](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_signatureHelp)
+query returns information about the innermost function call enclosing
+the cursor or selection, including the signature of the function and
+the names, types, and documentation of each parameter.
+
+Clients may provide this information to help remind the user of the
+purpose of each parameter and their order, while reading or editing a
+function call.
+
+
+
+Client support:
+- **VS Code**: enabled by default. Displays signature and doc comment alongside Hover information.
+- **Emacs + eglot**: enabled by default. Displays signature in the echo area.
+- **Vim + coc.nvim**: ??
+- **CLI**: `gopls signature file.go:#start-#end`
+
+
+## DocumentHighlight
+
+The LSP [`textDocument/documentHighlight`](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_documentHighlight)
+query reports a set of source ranges that should be highlighted based
+on the current cursor position or selection, to emphasize the
+relationship between them.
+
+Each of the following parts of syntax forms a set so that if you
+select any one member, gopls will highlight the complete set:
+
+- each identifier that refers to the same symbol (as in the screenshot below);
+- a named result variable and all its corresponding operands of `return` statements;
+- the `for`, `break`, and `continue` tokens of the same loop;
+- the `switch` and `break` tokens of the same switch statement;
+- the `func` keyword of a function and all of its `return` statements.
+
+More than one of these rules may be activated by the same selection,
+for example, an identifier that is also a return operand.
+
+
+
+Client support:
+- **VS Code**: enabled by default. Triggered by cursor motion, or single click.
+ (Note: double clicking activates a simple syntax-oblivious textual match.)
+- **Emacs + eglot**: enabled by default. Triggered by cursor motion or selection.
+- **Vim + coc.nvim**: ??
+- **CLI**: `gopls signature file.go:#start-#end`
+
+
+## InlayHint
+
+The LSP [`textDocument/inlayHint`](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_inlayHint)
+query returns a set of annotations to be spliced into the current file
+that reveal implicit information.
+
+
+
+Examples:
+
+- In a function call `f(1, 2)`, gopls will provide hints for the
+ names of the parameters (`parameterNames`), as in the screenshot above.
+- In a call to a generic function, hints provide the type arguments
+ (`functionTypeParameters`).
+- In an assignment `x, y = 1, 2`, hints provide the types of the
+ variables (`assignVariableTypes`).
+- In a struct literal such as `Point2D{1, 2}`, hints provide the field
+ names (`compositeLiteralFields`).
+- In a nested composite literal `T{{...}}`, a hint provides the type of
+ the inner literal, `{...}` (`compositeLiteralTypes`).
+- In a `for k, v := range x {}` loop, hints provide the types of the
+ variables k and v (`rangeVariableTypes`).
+- For a constant expression (perhaps using `iota`), a hint provides
+ its computed value (`constantValues`).
+
+See [Inlay hints](../inlayHints.md) for a complete list with examples.
+
+TODO: Do we really need that separate doc? We could put all the
+ information here with much less fuss. It changes so rarely that a
+ culture of "update the tests and docs in every CL" should be sufficient.
+ IIUC, VS Code needs only the api-json representation.
+
+Settings:
+- The [`hints`](../settings.md#hints) setting indicates the desired set of hints.
+ To reduce distractions, its default value is empty.
+ To enable hints, add one or more of the identifiers above to the hints
+ map. For example:
+ ```json5
+ "hints": {"parameterNames": true}
+ ```
+
+Client support:
+- **VS Code**: in addition to the `hints` configuration value, VS Code provides a graphical
+ configuration menu ("Preferences: Open Settings (UI)" the search for "Go Inlay Hints")
+ for each supported kind of inlay hint.
+- **Emacs + eglot**: disabled by default. Needs `M-x eglot-inlay-hints-mode` plus the configuration [described here](https://www.reddit.com/r/emacs/comments/11bqzvk/emacs29_and_eglot_inlay_hints/)
+- **Vim + coc.nvim**: ??
+- **CLI**: not supported
+
+## SemanticTokens
+
+The LSP [`textDocument/semanticTokens`](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_semanticTokens)
+query reports information about all the tokens in the current file, or
+a portion of it.
+The client may use this information to provide syntax highlighting
+that conveys semantic distinctions between, for example, functions and
+types, constants and variables, or library functions and built-ins.
+The client specifies the sets of types and modifiers they are interested in.
+
+Settings:
+- The [`semanticTokens`](../settings.md#semanticTokens) setting determines whether
+ gopls responds to semantic token requests. This option allows users to disable
+ semantic tokens even when their client provides no client-side control over the
+ feature. Because gopls' semantic-tokens algorithm depends on type checking,
+ which adds a tangible latency, this feature is currently disabled by default
+ to avoid any delay in syntax highlighting; see golang/go#45313, golang/go#47465.
+- The experimental [`noSemanticString`](../settings.md#noSemanticString) and
+ [`noSemanticNumber`](../settings.md#noSemanticNumber) settings cause the server
+ to exclude the `string` and `number` kinds from the response, as some clients
+ may do a more colorful job highlighting these tokens; see golang/go#45753.
+
+Client Support:
+- **VS Code**: See [Semantic Highlighting Guide](https://code.visualstudio.com/api/language-extensions/semantic-highlight-guide).
+- **Emacs + eglot**: Not supported; see joaotavora/eglot#615.
+- **Vim + coc.nvim**: ??
+- **CLI**: `gopls semtok file.go`
+
+For internal details of gopls' implementation of semantic tokens,
+see [semantic tokens](../semantictokens.md).
+
+## FoldingRange
+
+The LSP [`textDocument/foldingRange`](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_foldingRange)
+query reports the list of regions in the current file that may be
+independently collapsed or expanded. For example, it may be convenient
+to collapse large comments or functions when studying some code so
+that more of it fits in a single screen.
+
+
+
+The protocol [allows](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#foldingRangeClientCapabilities) clients to indicate whether they prefer
+fine-grained ranges such as matched pairs of brackets, or only ranges
+consisting of complete lines.
+
+Client support:
+- **VS Code**: displayed in left margin. Toggle the chevrons (`∨` and `>`) to collapse or expand.
+- **Emacs + eglot**: not supported.
+- **Vim + coc.nvim**: ??
+- **CLI**: `gopls folding_ranges file.go`
+
+## DocumentLink
+
+The LSP [`textDocument/documentLink`](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_documentLink)
+query uses heuristics to extracts URLs from doc comments and string
+literals in the current file so that client can present them as
+clickable links.
+
+
+
+In addition to explicit URLs, gopls also turns string literals in
+import declarations into links to the pkg.go.dev documentation for the
+imported package.
+
+Settings:
+- The [`importShortcut`](../settings.md#importShortcut) setting determines
+ what kind of link is returned for an `import` declaration.
+- The [`linkTarget`](../settings.md#linkTarget) setting specifies
+ the base URI for Go package links.
+
+Client support:
+- **VS Code**: Hovering over a link displays a "Follow link (cmd+click)" popup.
+- **Emacs + eglot**: not currently used.
+- **Vim + coc.nvim**: ??
+- **CLI**: `gopls links file.go`
diff --git a/gopls/doc/features/templates.md b/gopls/doc/features/templates.md
new file mode 100644
index 00000000000..a71a2ea181c
--- /dev/null
+++ b/gopls/doc/features/templates.md
@@ -0,0 +1,49 @@
+# Gopls: Support for template files
+
+Gopls provides some support for Go template files, that is, files that
+are parsed by [`text/template`](https://pkg.go.dev/text/template) or
+[`html/template`](https://pkg.go.dev/html/template).
+
+## Enabling template support
+
+Gopls recognizes template files based on their file extension, which
+may be configured by the
+[`templateExtensions`](../settings.md#templateExtensions) setting. If
+this list is empty, template support is disabled. (This is the default
+value, since Go templates don't have a canonical file extension.)
+
+Additional configuration may be necessary to ensure that your client
+chooses the correct language kind when opening template files.
+Gopls recogizes both `"tmpl"` and `"gotmpl"` for template files.
+For example, in `VS Code` you will also need to add an
+entry to the
+[`files.associations`](https://code.visualstudio.com/docs/languages/identifiers)
+mapping:
+```json
+"files.associations": {
+ ".mytemplate": "gotmpl"
+},
+```
+
+
+## Features
+In template files, template support works inside
+the default `{{` delimiters. (Go template parsing
+allows the user to specify other delimiters, but
+gopls does not know how to do that.)
+
+Gopls template support includes the following features:
++ **Diagnostics**: if template parsing returns an error,
+it is presented as a diagnostic. (Missing functions do not produce errors.)
++ **Syntax Highlighting**: syntax highlighting is provided for template files.
++ **Definitions**: gopls provides jump-to-definition inside templates, though it does not understand scoping (all templates are considered to be in one global scope).
++ **References**: gopls provides find-references, with the same scoping limitation as definitions.
++ **Completions**: gopls will attempt to suggest completions inside templates.
+
+TODO: also
++ Hover
++ SemanticTokens
++ Symbol search
++ DocumentHighlight
+
+
diff --git a/gopls/doc/features/transformation.md b/gopls/doc/features/transformation.md
new file mode 100644
index 00000000000..615a59a3093
--- /dev/null
+++ b/gopls/doc/features/transformation.md
@@ -0,0 +1,659 @@
+# Gopls: Code transformation features
+
+This document describes gopls' features for code transformation, which
+include a range of behavior-preserving changes (refactorings,
+formatting, simplifications), code repair (fixes), and editing support
+(filling in struct literals, switch statements).
+
+Code transformations are not a single category in the LSP:
+- a few, such as Formatting and Rename, are primary operations in the
+ protocol;
+- some are [commands](../commands.md) exposed through [Code
+ Lenses](../codelenses.md) (though none of these are transformations of Go syntax);
+
+- most are defined as *code actions*.
+
+
+## Code Actions
+
+A **code action** is an action associated with a portion of the file.
+Each time the selection changes, a typical client makes a
+[`textDocument/codeAction`](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_codeAction)
+request for the set of available actions, then updates its UI
+elements (menus, icons, tooltips) to reflect them.
+The VS Code manual describes code actions as
+"[Quick fixes + Refactorings](https://code.visualstudio.com/docs/editor/refactoring#_code-actions-quick-fixes-and-refactorings)".
+
+A `codeAction` request delivers the menu, so to speak, but it does
+not order the meal. When an action is chosen, one of two things happens.
+In trivial cases, the action itself contains an edit that the
+client can directly apply to the file.
+But in most cases, the action contains a [command](../commands.md)
+to be sent back to the server for its side effects,
+just as with the command associated with a Code Lens.
+This allows the work of computing the patch to be done lazily, only
+when actually needed. (Most aren't.)
+The server may then compute the edit and send the client a
+[`workspace/applyEdit`](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#workspace_applyEdit)
+request to patch the files.
+Not all code actions' commands have an `applyEdit` side effect: some
+may change the state of the server, for example, to toggle a
+variable, or cause the server to send other requests to the client,
+such as as a `showDocument` request to open a report in a web browser.
+
+The main difference between code lenses and code actions is this:
+- `codeLens` requests commands for the entire file.
+ Each command specifies its applicable source range,
+ and typically appears as an annotation on that source range.
+- `codeAction` requests commands only for a particular range: the current selection.
+ All the commands are presented together in a menu at that location.
+
+Each action has a _kind_,
+which is a hierarchical identifier such as `refactor.inline`.
+Clients may filter actions based on their kind.
+For example, VS Code has two menus, "Refactor..." and "Source action...",
+each populated by different kinds of code actions (`refactor.*` and `source.*`),
+plus a lightbulb icon that triggers a menu of "quick fixes" (of kind `quickfix.*`),
+which are commands deemed unambiguously safe to apply.
+
+
+
+Many transformations are computed by [analyzers](../analyzers.md)
+that, in the course of reporting a diagnostic about a problem,
+also suggest a fix.
+A `codeActions` request will return any fixes accompanying diagnostics
+for the current selection.
+
+
+Caveats:
+- Many of gopls code transformations are limited by Go's syntax tree
+ representation, which currently records comments not in the tree,
+ but in a side table; consequently, transformations such as Extract
+ and Inline are prone to losing comments. This is issue
+ golang/go#20744, and it is a priority for us to fix in 2024.
+
+- Generated files, as identified by the conventional
+ [DO NOT EDIT](https://go.dev/s/generatedcode) comment,
+ are not offered code actions for transformations.
+
+
+Client support for code actions:
+
+- **VS Code**: Depending on their kind, code actions are found in
+ the "Refactor..." menu (`^⇧R`),
+ the "Source action..." menu,
+ the 💡 (light bulb) icon's menu, or
+ the "Quick fix" (`⌘.`) menu.
+- **Emacs + eglot**: Code actions are invisible.
+ Use `M-x eglot-code-actions` to select one from those that are
+ available (if there are multiple) and execute it.
+ Some action kinds have filtering shortcuts,
+ e.g. [`M-x eglot-code-action-{inline,extract,rewrite}`](https://joaotavora.github.io/eglot/#index-M_002dx-eglot_002dcode_002daction_002dinline).
+- **CLI**: `gopls fix -a file.go:#123-#456 kinds...` executes code actions of the specified
+ kinds (e.g. `refactor.inline`) on the selected range, specified using zero-based byte offsets.
+
+## Formatting
+
+The LSP
+[`textDocument/formatting`](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_formatting)
+request returns edits that format a file.
+Gopls applies Go's canonical formatting algorithm,
+[`go fmt`](https://pkg.go.dev/cmd/gofmt).
+LSP formatting options are ignored.
+
+Most clients are configured to format files and organize imports
+whenever a file is saved.
+
+Settings:
+- The [`gofumpt`](../settings.md#gofumpt) setting causes gopls to use an
+ alternative formatter, [`github.com/mvdan/gofumpt`](https://pkg.go.dev/mvdan.cc/gofumpt).
+
+Client support:
+- **VS Code**: Formats on save by default. Use `Format document` menu item (`⌥⇧F`) to invoke manually.
+- **Emacs + eglot**: Use `M-x eglot-format-buffer` to format. Attach it to `before-save-hook` to format on save. For formatting combined with organize-imports, many users take the legacy approach of setting `"goimports"` as their `gofmt-command` using [go-mode](https://github.com/dominikh/go-mode.el), and adding `gofmt-before-save` to `before-save-hook`. An LSP-based solution requires code such as https://github.com/joaotavora/eglot/discussions/1409.
+- **CLI**: `gopls format file.go`
+
+## Organize imports
+
+A `codeActions` request in a file whose imports are not organized will
+return an action of the standard kind `source.organizeImports`.
+Its command has the effect of organizing the imports:
+deleting existing imports that are duplicate or unused,
+adding new ones for undefined symbols,
+and sorting them into the conventional order.
+
+The addition of new imports is based on heuristics that depends on
+your workspace and the contents of your GOMODCACHE directory; it may
+sometimes make surprising choices.
+
+Many editors automatically organize imports and format the code before
+saving any edited file.
+
+Some users dislike the automatic removal of imports that are
+unreferenced because, for example, the sole line that refers to the
+import is temporarily commented out for debugging; see golang/go#54362.
+
+Settings:
+
+- The [`local`](../settings.md#local) setting is a comma-separated list of
+ prefixes of import paths that are "local" to the current file and
+ should appear after standard and third-party packages in the sort order.
+
+Client support:
+- **VS Code**: automatically invokes `source.organizeImports` before save.
+ To disable it, use the snippet below, and invoke the "Organize Imports" command manually as needed.
+ ```
+ "[go]": {
+ "editor.codeActionsOnSave": { "source.organizeImports": false }
+ }
+ ```
+- **Emacs + eglot**: Use `M-x eglot-code-action-organize-imports` to invoke manually.
+ Many users of [go-mode](https://github.com/dominikh/go-mode.el) use these lines to
+ organize imports and reformat each modified file before saving it, but this
+ approach is based on the legacy
+ [`goimports`](https://pkg.go.dev/golang.org/x/tools/cmd/goimports) tool, not gopls:
+ ```lisp
+ (setq gofmt-command "goimports")
+ (add-hook 'before-save-hook 'gofmt-before-save)
+ ```
+- **CLI**: `gopls fix -a file.go:#offset source.organizeImports`
+
+
+## Rename
+
+The LSP
+[`textDocument/rename`](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_rename)
+request renames a symbol.
+
+Renaming is a two-stage process. The first step, a
+[`prepareRename`](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_prepareRename) query, returns the current
+name of the identifier under the cursor (if indeed there is one).
+The client then displays a dialog prompting the user to choose a new
+name by editing the old one. The second step, `rename` proper, applies
+the changes. (This simple dialog support is unique among LSP
+refactoring operations; see microsoft/language-server-protocol#1164.)
+
+Gopls' renaming algorithm takes great care to detect situations in
+which renaming might introduce a compilation error.
+For example, changing a name may cause a symbol to become "shadowed",
+so that some existing references are no longer in scope. Gopls will
+report an error, stating the pair of symbols and the shadowed reference:
+
+
+
+As another example, consider renaming a method of a concrete type.
+Renaming may cause the type to no longer satisfy the same interfaces
+as before, which could cause the program to fail to compile.
+To avoid this, gopls inspects each conversion (explicit or implicit)
+from the affected type to an interface type, and checks whether it
+would remain valid after the renaming. If not, it aborts the renaming
+with an error.
+
+If you intend to rename both the original method and the corresponding
+methods of any matching interface types (as well as any methods of
+types matching them in turn), you can indicate this by invoking the
+rename operation on the interface method.
+
+Similarly, gopls will report an error if you rename a field of a
+struct that happens to be an "anonymous" field that embeds a type,
+since that would require a larger renaming involving the type as well.
+If that is what you intend, you can again indicate this by
+invoking the rename operation on the type.
+
+Renaming should never introduce a compilation error, but it may
+introduce dynamic errors. For example, in a method renaming, if there
+is no direct conversion of the affected type to the interface type,
+but there is an intermediate conversion to `interface{}` followed by a
+type assertion to the interface type, then gopls may proceed to rename
+the method, causing the type assertion to fail at run time.
+Similar problems may arise with packages that use reflection, such as
+`encoding/json` or `text/template`. There is no substitute for good
+judgment and testing.
+
+Some tips for best results:
+- There is currently no special support for renaming all receivers of
+ a family of methods at once, so you will need to rename one receiver
+ one at a time (golang/go#41892).
+- The safety checks performed by the Rename algorithm require type
+ information. If the program is grossly malformed, there may be
+ insufficient information for it to run (golang/go#41870),
+ and renaming cannot generally be used to fix a type error (golang/go#41851).
+ When refactoring, we recommend working in small steps, repairing any
+ problems as you go, so that as much as possible of the program
+ compiles at each step.
+- Sometimes it may be desirable for a renaming operation to change the
+ reference structure of the program, for example to intentionally
+ combine two variables x and y by renaming y to x.
+ The renaming tool is too strict to help in this case (golang/go#41852).
+
+
+
+For the gory details of gopls' rename algorithm, you may be interested
+in the latter half of this 2015 GothamGo talk:
+[Using go/types for Code Comprehension and Refactoring Tools](https://www.youtube.com/watch?v=p_cz7AxVdfg).
+
+Client support:
+- **VS Code**: Use "[Rename symbol](https://code.visualstudio.com/docs/editor/editingevolved#_rename-symbol)" menu item (`F2`).
+- **Emacs + eglot**: Use `M-x eglot-rename`, or `M-x go-rename` from [go-mode](https://github.com/dominikh/go-mode.el).
+- **CLI**: `gopls rename file.go:#offset newname`
+
+
+
+## Extract function/method/variable
+
+The `refactor.extract` family of code actions all return commands that
+replace the selected expression or statements with a reference to a
+newly created declaration that contains the selected code:
+
+
+
+- **Extract function** replaces one or more complete statements by a
+ call to a new function named `newFunction` whose body contains the
+ statements. The selection must enclose fewer statements than the
+ entire body of the existing function.
+
+ ![Before extracting a function](../assets/extract-function-before.png)
+ ![After extracting a function](../assets/extract-function-after.png)
+
+- **Extract method** is a variant of "Extract function" offered when
+ the selected statements belong to a method. The newly created function
+ will be a method of the same receiver type.
+
+- **Extract variable** replaces an expression by a reference to a new
+ local variable named `x` initialized by the expression:
+
+ ![Before extracting a var](../assets/extract-var-before.png)
+ ![After extracting a var](../assets/extract-var-after.png)
+
+If the default name for the new declaration is already in use, gopls
+generates a fresh name.
+
+Extraction is a challenging problem requiring consideration of a
+variety of aspects such as identifier scope and shadowing, control
+flow such as `break`/`continue` in a loop or `return` in a
+function, cardinality of variables, and even subtle issues of style.
+In each case, the tool will try to update the extracted statements
+as needed to avoid build breakage or behavior changes.
+Unfortunately, gopls' Extract algorithms are considerably less
+rigorous than the Rename and Inline operations, and we are aware of a
+number of cases where it falls short, including:
+
+- https://github.com/golang/go/issues/66289
+- https://github.com/golang/go/issues/65944
+- https://github.com/golang/go/issues/64821
+- https://github.com/golang/go/issues/63394
+- https://github.com/golang/go/issues/61496
+- https://github.com/golang/go/issues/50851
+
+The following Extract features are planned for 2024 but not yet supported:
+
+- **Extract constant** is a variant of "Extract variable" to be
+ offered when the expression is constant; see golang/go#37170.
+- **Extract to new file** will extract one or more top-level
+ declarations into a new file in the same package; see golang/go#65707.
+
+- **Extract parameter struct** will replace two or more parameters of a
+ function by a struct type with one field per parameter; see golang/go#65552.
+
+
+- **Extract interface for type** will create a declaration of an
+ interface type with all the methods of the selected concrete type;
+ see golang/go#65721 and golang/go#46665.
+
+
+
+## Extract declarations to new file
+
+If you select one or more top-level declarations, gopls will offer an
+"Extract declarations to new file" code action that moves the selected
+declarations into a new file whose name is based on the first declared
+symbol.
+Gopls also offers this code action when the selection is just the
+first token of the declaration, such as `func` or `type`.
+Import declarations are created as needed.
+
+![Before: select the declarations to move](../assets/extract-to-new-file-before.png)
+![After: the new file is based on the first symbol name](../assets/extract-to-new-file-after.png)
+
+
+
+## Inline call to function
+
+For a `codeActions` request where the selection is (or is within) a
+call of a function or method, gopls will return a command of kind
+`refactor.inline`, whose effect is to inline the function call.
+
+The screenshots below show a call to `sum` before and after inlining:
+
+![Before: select Refactor... Inline call to sum](../inline-before.png)
+![After: the call has been replaced by the sum logic](../inline-after.png)
+
+Inlining replaces the call expression by a copy of the function body,
+with parameters replaced by arguments.
+Inlining is useful for a number of reasons.
+Perhaps you want to eliminate a call to a deprecated
+function such as `ioutil.ReadFile` by replacing it with a call to the
+newer `os.ReadFile`; inlining will do that for you.
+Or perhaps you want to copy and modify an existing function in some
+way; inlining can provide a starting point.
+The inlining logic also provides a building block for
+other refactorings, such as "change signature".
+
+Not every call can be inlined.
+Of course, the tool needs to know which function is being called, so
+you can't inline a dynamic call through a function value or interface
+method; but static calls to methods are fine.
+Nor can you inline a call if the callee is declared in another package
+and refers to non-exported parts of that package, or to [internal
+packages](https://go.dev/doc/go1.4#internalpackages) that are
+inaccessible to the caller.
+Calls to generic functions are not yet supported
+(golang/go#63352), though we plan to fix that.
+
+When inlining is possible, it's critical that the tool preserve
+the original behavior of the program.
+We don't want refactoring to break the build, or, worse, to introduce
+subtle latent bugs.
+This is especially important when inlining tools are used to perform
+automated clean-ups in large code bases;
+we must be able to trust the tool.
+Our inliner is very careful not to make guesses or unsound
+assumptions about the behavior of the code.
+However, that does mean it sometimes produces a change that differs
+from what someone with expert knowledge of the same code might have
+written by hand.
+
+In the most difficult cases, especially with complex control flow, it
+may not be safe to eliminate the function call at all.
+For example, the behavior of a `defer` statement is intimately tied to
+its enclosing function call, and `defer` is the only control
+construct that can be used to handle panics, so it cannot be reduced
+into simpler constructs.
+So, for example, given a function f defined as:
+
+```go
+func f(s string) {
+ defer fmt.Println("goodbye")
+ fmt.Println(s)
+}
+```
+a call `f("hello")` will be inlined to:
+```go
+ func() {
+ defer fmt.Println("goodbye")
+ fmt.Println("hello")
+ }()
+```
+Although the parameter was eliminated, the function call remains.
+
+An inliner is a bit like an optimizing compiler.
+A compiler is considered "correct" if it doesn't change the meaning of
+the program in translation from source language to target language.
+An _optimizing_ compiler exploits the particulars of the input to
+generate better code, where "better" usually means more efficient.
+As users report inputs that cause the compiler to emit suboptimal
+code, the compiler is improved to recognize more cases, or more rules,
+and more exceptions to rules---but this process has no end.
+Inlining is similar, except that "better" code means tidier code.
+The most conservative translation provides a simple but (hopefully!)
+correct foundation, on top of which endless rules, and exceptions to
+rules, can embellish and improve the quality of the output.
+
+Here are some of the technical challenges involved in sound inlining:
+
+- **Effects:** When replacing a parameter by its argument expression,
+ we must be careful not to change the effects of the call. For
+ example, if we call a function `func twice(x int) int { return x + x }`
+ with `twice(g())`, we do not want to see `g() + g()`, which would
+ cause g's effects to occur twice, and potentially each call might
+ return a different value. All effects must occur the same number of
+ times, and in the same order. This requires analyzing both the
+ arguments and the callee function to determine whether they are
+ "pure", whether they read variables, or whether (and when) they
+ update them too. The inliner will introduce a declaration such as
+ `var x int = g()` when it cannot prove that it is safe to substitute
+ the argument throughout.
+
+- **Constants:** If inlining always replaced a parameter by its argument
+ when the value is constant, some programs would no longer build
+ because checks previously done at run time would happen at compile time.
+ For example `func index(s string, i int) byte { return s[i] }`
+ is a valid function, but if inlining were to replace the call `index("abc", 3)`
+ by the expression `"abc"[3]`, the compiler will report that the
+ index `3` is out of bounds for the string `"abc"`.
+ The inliner will prevent substitution of parameters by problematic
+ constant arguments, again introducing a `var` declaration instead.
+
+- **Referential integrity:** When a parameter variable is replaced by
+ its argument expression, we must ensure that any names in the
+ argument expression continue to refer to the same thing---not to a
+ different declaration in the callee function body that happens to
+ use the same name! The inliner must replace local references such as
+ `Printf` by qualified references such as `fmt.Printf`, and add an
+ import of package `fmt` as needed.
+
+- **Implicit conversions:** When passing an argument to a function, it
+ is implicitly converted to the parameter type.
+ If we eliminate the parameter variable, we don't want to
+ lose the conversion as it may be important.
+ For example, in `func f(x any) { y := x; fmt.Printf("%T", &y) }` the
+ type of variable y is `any`, so the program prints `"*interface{}"`.
+ But if inlining the call `f(1)` were to produce the statement `y :=
+ 1`, then the type of y would have changed to `int`, which could
+ cause a compile error or, as in this case, a bug, as the program
+ now prints `"*int"`. When the inliner substitutes a parameter variable
+ by its argument value, it may need to introduce explicit conversions
+ of each value to the original parameter type, such as `y := any(1)`.
+
+- **Last reference:** When an argument expression has no effects
+ and its corresponding parameter is never used, the expression
+ may be eliminated. However, if the expression contains the last
+ reference to a local variable at the caller, this may cause a compile
+ error because the variable is now unused! So the inliner must be
+ cautious about eliminating references to local variables.
+
+This is just a taste of the problem domain. If you're curious, the
+documentation for [golang.org/x/tools/internal/refactor/inline](https://pkg.go.dev/golang.org/x/tools/internal/refactor/inline) has
+more detail. All of this is to say, it's a complex problem, and we aim
+for correctness first of all. We've already implemented a number of
+important "tidiness optimizations" and we expect more to follow.
+
+
+## Miscellaneous rewrites
+
+This section covers a number of transformations that are accessible as
+code actions of kind `refactor.rewrite`.
+
+
+
+
+### Remove unused parameter
+
+The [`unusedparams` analyzer](../analyzers.md#unusedparams) reports a
+diagnostic for each parameter that is not used within the function body.
+For example:
+```go
+func f(x, y int) { // "unused parameter: x"
+ fmt.Println(y)
+}
+```
+
+It does _not_ report diagnostics for address-taken functions, which
+may need all their parameters, even unused ones, in order to conform
+to a particular function signature.
+Nor does it report diagnostics for exported functions,
+which may be address-taken by another package.
+(A function is _address-taken_ if it is used other than in call position, `f(...)`.)
+
+In addition to the diagnostic, it suggests two possible fixes:
+
+1. rename the parameter to `_` to emphasize that it is unreferenced (an immediate edit); or
+2. delete the parameter altogether, using a `ChangeSignature` command, updating all callers.
+
+Fix \#2 uses the same machinery as "Inline function call" (see above)
+to ensure that the behavior of all existing calls is preserved, even
+when the argument expression for the deleted parameter has side
+effects, as in the example below.
+
+![The parameter x is unused](../assets/remove-unusedparam-before.png)
+![The parameter x has been deleted](../assets/remove-unusedparam-after.png)
+
+Observe that in the first call, the argument `chargeCreditCard()` was
+not deleted because of potential side effects, whereas in the second
+call, the argument 2, a constant, was safely deleted.
+
+### Convert string literal between raw and interpreted
+
+When the selection is a string literal, gopls offers a code action
+to convert the string between raw form (`` `abc` ``) and interpreted
+form (`"abc"`):
+
+![Convert to interpreted](../assets/convert-string-interpreted.png)
+![Convert to raw](../assets/convert-string-raw.png)
+
+Apply the code action a second time to revert back to the original
+form.
+
+### Invert 'if' condition
+
+When the selection is within an `if`/`else` statement that is not
+followed by `else if`, gopls offers a code action to invert the
+statement, negating the condition and swapping the `if` and and `else`
+blocks.
+
+![Before "Invert if condition"](../assets/invert-if-before.png)
+![After "Invert if condition"](../assets/invert-if-after.png)
+
+
+
+### Split elements into separate lines
+
+When the selection is within a bracketed list such as:
+
+- the **elements** of a composite literal, `[]T{a, b, c}`,
+- the **arguments** of a function call, `f(a, b, c)`,
+- the **groups of parameters** of a function signature, `func(a, b, c int, d, e bool)`, or
+- its **groups of results**, `func() (x, y string, z rune)`,
+
+gopls will offer the "Split [items] into separate lines" code
+action, which would transform the forms above into these forms:
+
+```go
+[]T{
+ a,
+ b,
+ c,
+}
+
+f(
+ a,
+ b,
+ c,
+)
+
+func(
+ a, b, c int,
+ d, e bool,
+)
+
+func() (
+ x, y string,
+ z rune,
+)
+```
+Observe that in the last two cases, each
+[group](https://pkg.go.dev/go/ast#Field) of parameters or results is
+treated as a single item.
+
+The opposite code action, "Join [items] into one line", undoes the operation.
+Neither action is offered if the list is already full split or joined,
+respectively, or trivial (fewer than two items).
+
+These code actions are not offered for lists containing `//`-style
+comments, which run to the end of the line.
+
+
+
+### Fill struct literal
+
+When the cursor is within a struct literal `S{}`, gopls offers the
+"Fill S" code action, which populates each missing field of the
+literal that is accessible.
+
+It uses the following heuristic to choose the value assigned to each
+field: it finds candidate variables, constants, and functions that are
+assignable to the field, and picks the one whose name is the closest
+match to the field name.
+If there are none, it uses the zero value (such as `0`, `""`, or
+`nil`) of the field's type.
+
+In the example below, a
+[`slog.HandlerOptions`](https://pkg.go.dev/golang.org/x/exp/slog#HandlerOptions)
+struct literal is filled in using two local variables (`level` and
+`add`) and a function (`replace`):
+
+![Before "Fill slog.HandlerOptions"](../assets/fill-struct-before.png)
+![After "Fill slog.HandlerOptions"](../assets/fill-struct-after.png)
+
+Caveats:
+
+- This code action requires type information for the struct type, so
+ if it is defined in another package that is not yet imported, you
+ may need to "organize imports" first, for example by saving the
+ file.
+- Candidate declarations are sought only in the current file, and only
+ above the current point. Symbols declared beneath the current point,
+ or in other files in the package, are not considered; see
+ golang/go#68224.
+
+### Fill switch
+
+When the cursor is within a switch statement whose operand type is an
+_enum_ (a finite set of named constants), or within a type switch,
+gopls offers the "Add cases for T" code action, which populates the
+switch statement by adding a case for each accessible named constant
+of the enum type, or, for a type switch, by adding a case for each
+accessible named non-interface type that implements the interface.
+Only missing cases are added.
+
+The screenshots below show a type switch whose operand has the
+[`net.Addr`](https://pkg.go.dev/net#Addr) interface type. The code
+action adds one case per concrete network address type, plus a default
+case that panics with an informative message if an unexpected operand
+is encountered.
+
+![Before "Add cases for Addr"](../assets/fill-switch-before.png)
+![After "Add cases for Addr"](../assets/fill-switch-after.png)
+
+And these screenshots illustrate the code action adding cases for each
+value of the
+[`html.TokenType`](https://pkg.go.dev/golang.org/x/net/html#TokenType)
+enum type, which represents the various types of token from
+which HTML documents are composed:
+
+![Before "Add cases for Addr"](../assets/fill-switch-enum-before.png)
+![After "Add cases for Addr"](../assets/fill-switch-enum-after.png)
diff --git a/gopls/doc/features/web.md b/gopls/doc/features/web.md
new file mode 100644
index 00000000000..682d8e517d3
--- /dev/null
+++ b/gopls/doc/features/web.md
@@ -0,0 +1,152 @@
+# Gopls: Web-based features
+
+The LSP
+[`window.showDocument`](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#window_showDocument) request
+allows the server to instruct the client to open a file in the editor
+or a web page in a browser. It is the basis for a number of gopls
+features that report information about your program through a web
+interface.
+
+We recognize that a web interface is not ideal for everyone: some
+users prefer a full-screen editor layout and dislike switching
+windows; others may work in a text-only terminal without a window
+system, perhaps over remote ssh or on the Linux console.
+Unfortunately, the LSP lacks several natural kinds of extensibility,
+including the ability for servers to define:
+
+- queries that [generalize a References
+ query](https://github.com/microsoft/language-server-protocol/issues/1911),
+ displaying results using similar UI elements;
+- commands that [produce a stream of
+ text](https://github.com/joaotavora/eglot/discussions/1402), like a
+ typical shell command or compiler, that the client can redirect to
+ the editor's usual terminal-like UI element; or
+- refactoring operations that, like Rename, [prompt the
+ user](https://github.com/microsoft/language-server-protocol/issues/1164)
+ for additional information.
+
+The web-based UI can help fill these gaps until such time as the LSP
+provides standard ways of implementing these features.
+
+Gopls' web server listens on a `localhost` port. For security, all its
+endpoints include a random string that serves as an authentication
+token. The client, provided authenticated URLs by the server, will be
+able to access your source code, but arbitrary processes running on
+your machine will not.
+Restarting the gopls process causes this secret to change, rendering
+all existing previous URLs invalid; existing pages will display a banner
+indicating that they have become disconnected.
+
+TODO: combine the web server and the debug server; see golang/go#68229.
+
+Gopls supports two-way communication between the web browser and the
+client editor. All of the web-based reports contains links to
+declarations in your source code. Clicking on one of these links
+causes gopls to send a `showDocument` request to your editor to open
+the relevant source file at the appropriate line. This works even when
+your source code has been modified but not saved.
+(VS Code users: please upvote microsoft/vscode#208093 if you would
+like your editor to raise its window when handling this event.)
+
+
+## View package documentation
+
+In any Go source file, a code action request returns a command to
+"View package documentation". This command opens a browser window
+showing the documentation for the current Go package, presented using
+a similar design to https://pkg.go.dev.
+
+This allows you to preview the documentation for your packages, even
+internal ones that may be unpublished externally. Reloading the page
+updates the documentation to reflect your changes. It is not necessary
+to save modified Go source files.
+
+
+
+Clicking on the link for a package-level symbol or method, which in
+`pkg.go.dev` would ordinarily take you to a source-code viewer such as
+GitHub or Google Code Search, causes your editor to navigate to the
+relevant source file and line.
+
+Client support:
+- **VS Code**: Use the "Source Action... > View package documentation" menu.
+- **Emacs + eglot**: Use `M-x go-browse-doc` in [go-mode](https://github.com/dominikh/go-mode.el).
+- **Vim + coc.nvim**: ??
+
+
+
+## View free symbols
+
+When studying code, either to understand it or to evaluate a different
+organization or factoring, it is common to need to know what the
+"inputs" are to a given chunk of code, either because you are
+considering extracting it into its own function and want to know what
+parameters it would take, or just to understand how one piece of a long
+function relates to the preceding pieces.
+
+If you select a chunk of code, and apply the "[View free
+symbols](../commands.md#gopls.free_symbols)" command, your editor will
+open a browser displaying a report on the free symbols of the
+selection. A symbol is "free" if it is referenced from within the
+selection but defined outside of it. In essence, these are the inputs
+to the selected chunk.
+
+
+
+The report classifies the symbols into imported, local, and
+package-level symbols. The imported symbols are grouped by package,
+and link to the documentation for the package, as described above.
+Each of the remaining symbols is presented as a link that causes your
+editor to navigate to its declaration.
+
+TODO: explain dotted paths.
+
+Client support:
+- **VS Code**: Use the "Source Action... > View free symbols" menu.
+- **Emacs + eglot**: Use `M-x go-browse-freesymbols` in [go-mode](https://github.com/dominikh/go-mode.el).
+- **Vim + coc.nvim**: ??
+
+
+
+## View assembly
+
+When you're optimizing the performance of your code or investigating
+an unexpected crash, it may sometimes be helpful to inspect the
+assembly code produced by the compiler for a given Go function.
+
+If you position the cursor or selection within a function f, a code
+action will offer the "[View assembly for
+f](../commands.md#gopls.assembly)" command. This opens a web-based
+listing of the assembly for the function, plus any functions nested
+within it.
+
+Each time you edit your source and reload the page, the current
+package is recompiled and the listing is updated. It is not necessary
+to save your modified files.
+
+The compiler's target architecture is the same as the one gopls uses
+when analyzing the file: typically, this is your machine's GOARCH, but
+when viewing a file with a build tag, such as one named `foo_amd64.go`
+or containing the comment `//go:build amd64`, the tags determine the
+architecture.
+
+Each instruction is displayed with a link that causes your editor to
+navigate to the source line responsible for the instruction, according
+to the debug information.
+
+
+
+The example above shows the arm64 assembly listing of
+[`time.NewTimer`](https://pkg.go.dev/time#NewTimer).
+Observe that the indicated instruction links to a source location
+inside a different function, `syncTimer`, because the compiler
+inlined the call from `NewTimer` to `syncTimer`.
+
+Viewing assembly is not yet supported for generic functions, package
+initializers (`func init`), or functions in test packages.
+(Contributions welcome!)
+
+Client support:
+- **VS Code**: Use the "Source Action... > View GOARCH assembly for f" menu.
+- **Emacs + eglot**: Use `M-x go-browse-assembly` in [go-mode](https://github.com/dominikh/go-mode.el).
+- **Vim + coc.nvim**: ??
diff --git a/gopls/doc/generate/generate.go b/gopls/doc/generate/generate.go
index 7a3e4afdbf8..524dc178d55 100644
--- a/gopls/doc/generate/generate.go
+++ b/gopls/doc/generate/generate.go
@@ -13,6 +13,8 @@
// Run it with this command:
//
// $ cd gopls/internal/doc && go generate
+//
+// TODO(adonovan): move this package to gopls/internal/doc/generate.
package main
import (
@@ -204,7 +206,7 @@ func loadOptions(category reflect.Value, optsType types.Object, pkg *packages.Pa
return nil, err
}
- enums, err := loadEnums(pkg)
+ enums, err := loadEnums(pkg) // TODO(adonovan): do this only once at toplevel.
if err != nil {
return nil, err
}
@@ -694,7 +696,7 @@ func rewriteSettings(prevContent []byte, api *doc.API) ([]byte, error) {
//
// We do not display the undocumented dotted-path alias
// (h.title + "." + opt.Name) used by VS Code only.
- fmt.Fprintf(&buf, "### `%s` *%v*\n\n", opt.Name, opt.Type)
+ fmt.Fprintf(&buf, "### `%s %s`\n\n", opt.Name, opt.Type)
// status
switch opt.Status {
@@ -829,6 +831,9 @@ func rewriteCodeLenses(prevContent []byte, api *doc.API) ([]byte, error) {
func rewriteCommands(prevContent []byte, api *doc.API) ([]byte, error) {
var buf bytes.Buffer
for _, command := range api.Commands {
+ // Emit HTML anchor as GitHub markdown doesn't support
+ // "# Heading {#anchor}" syntax.
+ fmt.Fprintf(&buf, "\n", command.Command)
fmt.Fprintf(&buf, "## `%s`: **%s**\n\n%v\n\n", command.Command, command.Title, command.Doc)
if command.ArgDoc != "" {
fmt.Fprintf(&buf, "Args:\n\n```\n%s\n```\n\n", command.ArgDoc)
diff --git a/gopls/doc/helix.md b/gopls/doc/helix.md
index 83f923de923..209ffdaaa81 100644
--- a/gopls/doc/helix.md
+++ b/gopls/doc/helix.md
@@ -1,4 +1,4 @@
-# Helix
+# Gopls: Using Helix
Configuring `gopls` to work with Helix is rather straightforward. Install `gopls`, and then add it to the `PATH` variable. If it is in the `PATH` variable, Helix will be able to detect it automatically.
diff --git a/gopls/doc/inlayHints.md b/gopls/doc/inlayHints.md
index 0358bf6e161..3d693baeae1 100644
--- a/gopls/doc/inlayHints.md
+++ b/gopls/doc/inlayHints.md
@@ -1,7 +1,11 @@
-# Hints
+# Gopls: Inlay hints
-This document describes the inlay hints that `gopls` uses inside the editor.
+Inlay Hints are helpful annotations that the editor can optionally
+display in-line in the source code, such as the names of parameters in
+a function call. This document describes the inlay hints available
+from `gopls`.
+
## **assignVariableTypes**
diff --git a/gopls/doc/refactor-inline.md b/gopls/doc/refactor-inline.md
index dd857f874dd..cdddeb29e6e 100644
--- a/gopls/doc/refactor-inline.md
+++ b/gopls/doc/refactor-inline.md
@@ -1,4 +1,6 @@
+
+
Gopls v0.14 supports a new refactoring operation:
inlining of function calls.
diff --git a/gopls/doc/releases.md b/gopls/doc/releases.md
index befb92c3966..c4220e41116 100644
--- a/gopls/doc/releases.md
+++ b/gopls/doc/releases.md
@@ -1,4 +1,4 @@
-# Gopls release policy
+# Gopls: Release policy
Gopls releases follow [semver](http://semver.org), with major changes and new
features introduced only in new minor versions (i.e. versions of the form
diff --git a/gopls/doc/semantictokens.md b/gopls/doc/semantictokens.md
index a1e140d29ec..761d94a02d1 100644
--- a/gopls/doc/semantictokens.md
+++ b/gopls/doc/semantictokens.md
@@ -1,4 +1,7 @@
-# Semantic Tokens
+# Gopls: Semantic Tokens
+
+TODO(adonovan): this doc is internal, not for end users.
+Move it closer to the code in golang or protocol/semtok.
The [LSP](https://microsoft.github.io/language-server-protocol/specifications/specification-3-17/#textDocument_semanticTokens)
specifies semantic tokens as a way of telling clients about language-specific
diff --git a/gopls/doc/settings.md b/gopls/doc/settings.md
index 684e9169849..d64be6370ef 100644
--- a/gopls/doc/settings.md
+++ b/gopls/doc/settings.md
@@ -1,8 +1,8 @@
-# Settings
+# Gopls: Settings
This document describes gopls' configuration settings.
-Gopls settings are defined by an JSON object whose valid fields are
+Gopls settings are defined by a JSON object whose valid fields are
described below. These fields are gopls-specific, and generic LSP
clients have no knowledge of them.
@@ -17,9 +17,7 @@ Some clients also permit settings to be configured differently for
each workspace folder.
Any settings that are experimental or for debugging purposes are
-marked as such. To enable all experimental features, use
-**allExperiments: `true`**. You will still be able to independently
-override specific experimental features.
+marked as such.