gopls/doc: document all of gopls' features

This CL enumerates and documents each LSP feature
supported by gopls so that users can find out:
- what the tool is capable of,
- how to use it,
- what settings affect the feature, and
- whether their LSP client supports a given feature.

We plan to provide Code Actions to open the relevant
section of the manual, e.g. "Refactor > Describe refactorings..."

To review the markdown, cherrypick this CL then
run this command from x/tools:

 $ go run rsc.io/cmd/mdweb@latest -a localhost:9876 &
   open http://localhost:9876/gopls/doc/features/README.md

The topic of completion is left for another day,
as is support for go.mod files.

Updates golang/go#54115

Change-Id: I8f7de7571bfe0355b3597487efbc0d7aae7a12d6
Reviewed-on: https://go-review.googlesource.com/c/tools/+/583316
Auto-Submit: Alan Donovan <adonovan@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Robert Findley <rfindley@google.com>
diff --git a/gopls/README.md b/gopls/README.md
index 962d80c..6602e0c 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.
 
 <!--TODO(rfindley): Add gifs here.-->
 
@@ -11,11 +13,16 @@
 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 @@
 
 ## 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 7159626..d66ce87 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 @@
 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 d3f7ba8..0410113 100644
--- a/gopls/doc/analyzers.md
+++ b/gopls/doc/analyzers.md
@@ -1,4 +1,4 @@
-# Analyzers
+# Gopls: Analyzers
 
 <!-- No Table of Contents: GitHub's Markdown renderer synthesizes it. -->
 
@@ -15,19 +15,20 @@
 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.
 
+<!-- When staticcheck=true, we currently use the {S SA ST QF} suites, sans {SA5009, SA5011} -->
+
 
 <!-- BEGIN Analyzers: DO NOT MANUALLY EDIT THIS SECTION -->
 <a id='appends'></a>
diff --git a/gopls/doc/assets/convert-string-interpreted.png b/gopls/doc/assets/convert-string-interpreted.png
new file mode 100644
index 0000000..6bb7f2a
--- /dev/null
+++ b/gopls/doc/assets/convert-string-interpreted.png
Binary files differ
diff --git a/gopls/doc/assets/convert-string-raw.png b/gopls/doc/assets/convert-string-raw.png
new file mode 100644
index 0000000..24dea62
--- /dev/null
+++ b/gopls/doc/assets/convert-string-raw.png
Binary files differ
diff --git a/gopls/doc/assets/diagnostic-analysis.png b/gopls/doc/assets/diagnostic-analysis.png
new file mode 100644
index 0000000..5a934d0
--- /dev/null
+++ b/gopls/doc/assets/diagnostic-analysis.png
Binary files differ
diff --git a/gopls/doc/assets/diagnostic-typeerror.png b/gopls/doc/assets/diagnostic-typeerror.png
new file mode 100644
index 0000000..8f78228
--- /dev/null
+++ b/gopls/doc/assets/diagnostic-typeerror.png
Binary files differ
diff --git a/gopls/doc/assets/document-highlight.png b/gopls/doc/assets/document-highlight.png
new file mode 100644
index 0000000..ded4564
--- /dev/null
+++ b/gopls/doc/assets/document-highlight.png
Binary files differ
diff --git a/gopls/doc/assets/documentlink.png b/gopls/doc/assets/documentlink.png
new file mode 100644
index 0000000..8bc5e3d
--- /dev/null
+++ b/gopls/doc/assets/documentlink.png
Binary files differ
diff --git a/gopls/doc/assets/extract-function-after.png b/gopls/doc/assets/extract-function-after.png
new file mode 100644
index 0000000..4599a82
--- /dev/null
+++ b/gopls/doc/assets/extract-function-after.png
Binary files differ
diff --git a/gopls/doc/assets/extract-function-before.png b/gopls/doc/assets/extract-function-before.png
new file mode 100644
index 0000000..9c2590b
--- /dev/null
+++ b/gopls/doc/assets/extract-function-before.png
Binary files 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 0000000..3f0aa85
--- /dev/null
+++ b/gopls/doc/assets/extract-to-new-file-after.png
Binary files 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 0000000..9c05ceb
--- /dev/null
+++ b/gopls/doc/assets/extract-to-new-file-before.png
Binary files differ
diff --git a/gopls/doc/assets/extract-var-after.png b/gopls/doc/assets/extract-var-after.png
new file mode 100644
index 0000000..db558d6
--- /dev/null
+++ b/gopls/doc/assets/extract-var-after.png
Binary files differ
diff --git a/gopls/doc/assets/extract-var-before.png b/gopls/doc/assets/extract-var-before.png
new file mode 100644
index 0000000..356a242
--- /dev/null
+++ b/gopls/doc/assets/extract-var-before.png
Binary files differ
diff --git a/gopls/doc/assets/fill-struct-after.png b/gopls/doc/assets/fill-struct-after.png
new file mode 100644
index 0000000..6166228
--- /dev/null
+++ b/gopls/doc/assets/fill-struct-after.png
Binary files differ
diff --git a/gopls/doc/assets/fill-struct-before.png b/gopls/doc/assets/fill-struct-before.png
new file mode 100644
index 0000000..fd54492
--- /dev/null
+++ b/gopls/doc/assets/fill-struct-before.png
Binary files differ
diff --git a/gopls/doc/assets/fill-switch-after.png b/gopls/doc/assets/fill-switch-after.png
new file mode 100644
index 0000000..33d1bd3
--- /dev/null
+++ b/gopls/doc/assets/fill-switch-after.png
Binary files differ
diff --git a/gopls/doc/assets/fill-switch-before.png b/gopls/doc/assets/fill-switch-before.png
new file mode 100644
index 0000000..f25af03
--- /dev/null
+++ b/gopls/doc/assets/fill-switch-before.png
Binary files 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 0000000..564be17
--- /dev/null
+++ b/gopls/doc/assets/fill-switch-enum-after.png
Binary files 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 0000000..8515034
--- /dev/null
+++ b/gopls/doc/assets/fill-switch-enum-before.png
Binary files differ
diff --git a/gopls/doc/assets/foldingrange.png b/gopls/doc/assets/foldingrange.png
new file mode 100644
index 0000000..19e7645
--- /dev/null
+++ b/gopls/doc/assets/foldingrange.png
Binary files differ
diff --git a/gopls/doc/assets/hover-basic.png b/gopls/doc/assets/hover-basic.png
new file mode 100644
index 0000000..687ff71
--- /dev/null
+++ b/gopls/doc/assets/hover-basic.png
Binary files differ
diff --git a/gopls/doc/assets/hover-embed.png b/gopls/doc/assets/hover-embed.png
new file mode 100644
index 0000000..4d877a2
--- /dev/null
+++ b/gopls/doc/assets/hover-embed.png
Binary files differ
diff --git a/gopls/doc/assets/hover-linkname.png b/gopls/doc/assets/hover-linkname.png
new file mode 100644
index 0000000..c547d52
--- /dev/null
+++ b/gopls/doc/assets/hover-linkname.png
Binary files differ
diff --git a/gopls/doc/assets/inlayhint-parameternames.png b/gopls/doc/assets/inlayhint-parameternames.png
new file mode 100644
index 0000000..83d934e
--- /dev/null
+++ b/gopls/doc/assets/inlayhint-parameternames.png
Binary files differ
diff --git a/gopls/doc/assets/invert-if-after.png b/gopls/doc/assets/invert-if-after.png
new file mode 100644
index 0000000..d66dc8e
--- /dev/null
+++ b/gopls/doc/assets/invert-if-after.png
Binary files differ
diff --git a/gopls/doc/assets/invert-if-before.png b/gopls/doc/assets/invert-if-before.png
new file mode 100644
index 0000000..48581d2
--- /dev/null
+++ b/gopls/doc/assets/invert-if-before.png
Binary files differ
diff --git a/gopls/doc/assets/outgoingcalls.png b/gopls/doc/assets/outgoingcalls.png
new file mode 100644
index 0000000..00ca4b1
--- /dev/null
+++ b/gopls/doc/assets/outgoingcalls.png
Binary files differ
diff --git a/gopls/doc/assets/remove-unusedparam-after.png b/gopls/doc/assets/remove-unusedparam-after.png
new file mode 100644
index 0000000..04193fd
--- /dev/null
+++ b/gopls/doc/assets/remove-unusedparam-after.png
Binary files differ
diff --git a/gopls/doc/assets/remove-unusedparam-before.png b/gopls/doc/assets/remove-unusedparam-before.png
new file mode 100644
index 0000000..4e49c42
--- /dev/null
+++ b/gopls/doc/assets/remove-unusedparam-before.png
Binary files differ
diff --git a/gopls/doc/assets/rename-conflict.png b/gopls/doc/assets/rename-conflict.png
new file mode 100644
index 0000000..105a6ee
--- /dev/null
+++ b/gopls/doc/assets/rename-conflict.png
Binary files differ
diff --git a/gopls/doc/assets/signature-help.png b/gopls/doc/assets/signature-help.png
new file mode 100644
index 0000000..ca53778
--- /dev/null
+++ b/gopls/doc/assets/signature-help.png
Binary files differ
diff --git a/gopls/doc/codelenses.md b/gopls/doc/codelenses.md
index 3477627..71425ce 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 @@
 [`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.
+
+
 <!-- This portion is generated by doc/generate from the ../internal/settings package. -->
 <!-- BEGIN Lenses: DO NOT MANUALLY EDIT THIS SECTION -->
 ## `gc_details`: Toggle display of Go compiler optimization decisions
diff --git a/gopls/doc/command-line.md b/gopls/doc/command-line.md
index 4659058..4f825e2 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:
 
-<!--TODO(rstambler): Generate this file.-->
+```
+$ 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
+```
+
+See golang/go#63693 for a discussion of its future.
 
 Learn about available commands and flags by running `gopls help`.
 
-Much of the functionality of `gopls` is available through a command line interface.
-
-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.
-
-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 90f70d3..8d0c870 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.
 
 <!-- BEGIN Commands: DO NOT MANUALLY EDIT THIS SECTION -->
+<a id='gopls.add_dependency'></a>
 ## `gopls.add_dependency`: **Add a dependency**
 
 Adds a dependency to the go.mod file for a module.
@@ -20,6 +35,7 @@
 }
 ```
 
+<a id='gopls.add_import'></a>
 ## `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 @@
 }
 ```
 
+<a id='gopls.add_telemetry_counters'></a>
 ## `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 @@
 }
 ```
 
+<a id='gopls.apply_fix'></a>
 ## `gopls.apply_fix`: **Apply a fix**
 
 Applies a fix to a region of source code.
@@ -140,6 +158,7 @@
 }
 ```
 
+<a id='gopls.assembly'></a>
 ## `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
 ```
 
+<a id='gopls.change_signature'></a>
 ## `gopls.change_signature`: **Perform a "change signature" refactoring**
 
 This command is experimental, currently only supporting parameter removal.
@@ -226,6 +246,7 @@
 }
 ```
 
+<a id='gopls.check_upgrades'></a>
 ## `gopls.check_upgrades`: **Check for upgrades**
 
 Checks for module upgrades.
@@ -241,6 +262,7 @@
 }
 ```
 
+<a id='gopls.diagnose_files'></a>
 ## `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 @@
 }
 ```
 
+<a id='gopls.doc'></a>
 ## `gopls.doc`: **Browse package documentation.**
 
 Opens the Go package documentation page for the current
@@ -276,6 +299,7 @@
 }
 ```
 
+<a id='gopls.edit_go_directive'></a>
 ## `gopls.edit_go_directive`: **Run go mod edit -go=version**
 
 Runs `go mod edit -go=version` for a module.
@@ -291,6 +315,7 @@
 }
 ```
 
+<a id='gopls.extract_to_new_file'></a>
 ## `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 @@
 }
 ```
 
+<a id='gopls.fetch_vulncheck_result'></a>
 ## `gopls.fetch_vulncheck_result`: **Get known vulncheck result**
 
 Fetch the result of latest vulnerability check (`govulncheck`).
@@ -332,6 +358,7 @@
 map[golang.org/x/tools/gopls/internal/protocol.DocumentURI]*golang.org/x/tools/gopls/internal/vulncheck.Result
 ```
 
+<a id='gopls.free_symbols'></a>
 ## `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 @@
 }
 ```
 
+<a id='gopls.gc_details'></a>
 ## `gopls.gc_details`: **Toggle gc_details**
 
 Toggle the calculation of gc annotations.
@@ -371,6 +399,7 @@
 string
 ```
 
+<a id='gopls.generate'></a>
 ## `gopls.generate`: **Run go generate**
 
 Runs `go generate` for a given directory.
@@ -386,6 +415,7 @@
 }
 ```
 
+<a id='gopls.go_get_package'></a>
 ## `gopls.go_get_package`: **'go get' a package**
 
 Runs `go get` to fetch a package.
@@ -402,6 +432,7 @@
 }
 ```
 
+<a id='gopls.list_imports'></a>
 ## `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 @@
 }
 ```
 
+<a id='gopls.list_known_packages'></a>
 ## `gopls.list_known_packages`: **List known packages**
 
 Retrieve a list of packages that are importable from the given URI.
@@ -458,12 +490,14 @@
 }
 ```
 
+<a id='gopls.maybe_prompt_for_telemetry'></a>
 ## `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".
 
+<a id='gopls.mem_stats'></a>
 ## `gopls.mem_stats`: **Fetch memory statistics**
 
 Call runtime.GC multiple times and return memory statistics as reported by
@@ -481,6 +515,7 @@
 }
 ```
 
+<a id='gopls.regenerate_cgo'></a>
 ## `gopls.regenerate_cgo`: **Regenerate cgo**
 
 Regenerates cgo definitions.
@@ -494,6 +529,7 @@
 }
 ```
 
+<a id='gopls.remove_dependency'></a>
 ## `gopls.remove_dependency`: **Remove a dependency**
 
 Removes a dependency from the go.mod file of a module.
@@ -513,6 +549,7 @@
 }
 ```
 
+<a id='gopls.reset_go_mod_diagnostics'></a>
 ## `gopls.reset_go_mod_diagnostics`: **Reset go.mod diagnostics**
 
 Reset diagnostics in the go.mod file of a module.
@@ -530,6 +567,7 @@
 }
 ```
 
+<a id='gopls.run_go_work_command'></a>
 ## `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 @@
 }
 ```
 
+<a id='gopls.run_govulncheck'></a>
 ## `gopls.run_govulncheck`: **Run vulncheck**
 
 Run vulnerability check (`govulncheck`).
@@ -571,6 +610,7 @@
 }
 ```
 
+<a id='gopls.run_tests'></a>
 ## `gopls.run_tests`: **Run test(s)**
 
 Runs `go test` for a specific set of test or benchmark functions.
@@ -590,10 +630,12 @@
 }
 ```
 
+<a id='gopls.scan_imports'></a>
 ## `gopls.scan_imports`: **force a sychronous scan of the imports cache.**
 
 This command is intended for use by gopls tests only.
 
+<a id='gopls.start_debugging'></a>
 ## `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 @@
 }
 ```
 
+<a id='gopls.start_profile'></a>
 ## `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 @@
 struct{}
 ```
 
+<a id='gopls.stop_profile'></a>
 ## `gopls.stop_profile`: **Stop an ongoing profile**
 
 This command is intended for internal use only, by the gopls benchmark
@@ -678,6 +722,7 @@
 }
 ```
 
+<a id='gopls.test'></a>
 ## `gopls.test`: **Run test(s) (legacy)**
 
 Runs `go test` for a specific set of test or benchmark functions.
@@ -697,6 +742,7 @@
 []string
 ```
 
+<a id='gopls.tidy'></a>
 ## `gopls.tidy`: **Run go mod tidy**
 
 Runs `go mod tidy` for a module.
@@ -710,6 +756,7 @@
 }
 ```
 
+<a id='gopls.toggle_gc_details'></a>
 ## `gopls.toggle_gc_details`: **Toggle gc_details**
 
 Toggle the calculation of gc annotations.
@@ -723,6 +770,7 @@
 }
 ```
 
+<a id='gopls.update_go_sum'></a>
 ## `gopls.update_go_sum`: **Update go.sum**
 
 Updates the go.sum file for a module.
@@ -736,6 +784,7 @@
 }
 ```
 
+<a id='gopls.upgrade_dependency'></a>
 ## `gopls.upgrade_dependency`: **Upgrade a dependency**
 
 Upgrades a dependency in the go.mod file for a module.
@@ -753,6 +802,7 @@
 }
 ```
 
+<a id='gopls.vendor'></a>
 ## `gopls.vendor`: **Run go mod vendor**
 
 Runs `go mod vendor` for a module.
@@ -766,6 +816,7 @@
 }
 ```
 
+<a id='gopls.views'></a>
 ## `gopls.views`: **List current Views on the server.**
 
 This command is intended for use by gopls tests only.
@@ -782,6 +833,7 @@
 }
 ```
 
+<a id='gopls.workspace_stats'></a>
 ## `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 a2f987b..594bcd4 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 86356da..0844bc0 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 d5e3ba2..3b6ee80 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 @@
 (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 70a734e..0000000
--- 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).
-
-<!--TODO(rstambler): Automatically generate a list of supported features.-->
-
diff --git a/gopls/doc/features/README.md b/gopls/doc/features/README.md
new file mode 100644
index 0000000..6c93b03
--- /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 0000000..46991aa
--- /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 0000000..4bf1138
--- /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`
+
+<!--
+
+dorky details and deletia:
+
+- The **vet suite**, of about thirty analyzers
+  designed to catch likely mistakes in your code.
+ 
+- **Type-error fixers**. These are gopls-specific analyzers that
+  enrich diagnostics from the type checker by suggesting fixes for
+  simple problems.
+
+  For example, when a return statement has too few operands, the
+  [fillreturns](https://pkg.go.dev/golang.org/x/tools/gopls/internal/analysis/fillreturns) analyzer can heuristically fill in the missing ones
+  with suitable values.
+
+  The actual diagnostics are produced by the type checker,
+  so these analyzers won't cause you to see any new diagnostics;
+  but they add fixes to existing ones.
+  (The user needs to know this because the settings expose it.)
+
+  currently: fillreturns nonewvars noresultvalues stubmethods undeclaredname unusedvariable
+
+- **Simplifiers**. These are gopls-specific analyzers that
+  suggest ways to rewrite your code more simply.
+  They do not indicate a mistake in your code,
+  which is why they are not part of `go vet`.
+
+  For example, the `simplifyrange` analyzer will eliminate the
+  unnecessary blank variable in `for _ = range v {...}`.
+
+  currently: simplifycompositelit simplifyrange simplifyslice unusedparams infertypeargs
+
+- **Bug detectors**. Gopls has a suite of bug-detecting analyzers that
+    can't be part of vet for some reason. That might be because they
+    have dependencies that vet cannot have (e.g. nilness and
+    unusedwrite, which construct SSA), or because they are tightly
+    integrated with gopls (e.g. embeddirective, which produces lazy
+    fixes through the code action mechanism
+    [But others do that too:  undeclaredname embeddirective unusedparams stubmethods]
+
+  currently: atomicalign deepequalerrors nilness sortslice unusedwrite embeddirective
+
+- **staticcheck**: four suites:
+
+	add(simple.Analyzers, nil)
+	add(staticcheck.Analyzers - SA5009, SA5011
+	add(stylecheck.Analyzers, nil)
+	add(quickfix.Analyzers, nil)
+
+- **Experimental analyzers**. Gopls has some analyzers that are not
+  enabled by default, because they produce too high a rate of false
+  positives. For example, fieldalignment, shadow, useany.
+
+Note: fillstruct is not a real analyzer.
+
+-->
diff --git a/gopls/doc/features/modfiles.md b/gopls/doc/features/modfiles.md
new file mode 100644
index 0000000..775be98
--- /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 0000000..2bf4411
--- /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.
+
+<!-- On a built-in symbol such as `append` or `unsafe.Pointer`, `definition` reports
+the location of the declaration in the builtin or unsafe pseudo-packages,
+which are just documentation. -->
+
+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.
+<!-- Reason: assignability of local types such as I and J defined thus:
+     package p; func P() {type I interface {...}}
+     package q; func Q() {type J struct {...}}
+     depends on them both being in the same types.Importer "realm",
+     but that is not consistent with the "scalable" gopls design.
+-->
+
+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.
+<!-- e.g. selecting a struct field, package name, or other piece of syntax. -->
+
+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`.
+
+<!--
+It also supports the following special characters within queries:
+
+| Character | Usage     | Match        |
+| --------- | --------- | ------------ |
+| `'`       | `'abc`    | exact        |
+| `^`       | `^printf` | exact prefix |
+| `$`       | `printf$` | exact suffix |
+
+However, VS Code does its own fuzzy matching afterward, so these
+aren't effective in that client.
+-->
+
+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:`
+
+<img title="Outgoing calls of f" src="../assets/outgoingcalls.png" width="640">
+
+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 0000000..39c0ba6
--- /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.
+
+<img src='../assets/hover-basic.png'>
+
+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.
+
+<img src='../assets/hover-doclink.png'>
+
+**Struct size/offset info**: for declarations of struct types,
+hovering over the name reveals the struct's size in bytes:
+
+<img title="struct size info" src="../assets/hover-size-struct.png">
+
+And hovering over each field name shows the size and offset of that field:
+
+<img title="field size/offset info" src="../assets/hover-size-field.png">
+
+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:
+
+<img title="a struct with wasted space" src="../assets/hover-size-wasteful.png">
+
+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.
+
+<img src='../assets/hover-embed.png'>
+<!-- NB: Emacs+eglot displays only the first line of markdown, not the useful part! -->
+
+**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.
+
+<img src='../assets/hover-linkname.png'>
+
+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.
+
+<img src='../assets/signature-help.png'>
+
+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.
+
+<img src='../assets/document-highlight.png'>
+
+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.
+
+<img src='../assets/inlayhint-parameternames.png'>
+
+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.
+
+<img title="A function FoldingRange, collapsed, in VS Code" src="../assets/foldingrange.png" width="640">
+
+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.
+
+<img src='../assets/documentlink.png'>
+
+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 0000000..a71a2ea
--- /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 0000000..615a59a
--- /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);
+  <!-- Generate, RegenerateCgo (Go); Tidy, UpgradeDependency, Vendor (go.mod) -->
+- most are defined as *code actions*.
+
+<a id='code-actions'></a>
+## 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.
+
+<!-- In principle the filter may include the trigger event
+     e.g. auto (cursor motion) vs. invoked (open a menu)
+     but gopls currently ignores it. -->
+
+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.
+<!-- Some gopls-internal analyzers compute fixes lazily by
+     reporting an empty list of TextEdits and a Diagnostic.Category
+     recognized by gopls that enables corresponding logic in the
+     server's ApplyFix command handler. -->
+
+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.
+  <!-- TODO: this is frankly a nuisance. It is often convenient to modify generated files -->
+
+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:
+
+<img title="Renamed failed due to a shadowing conflict" src="../assets/rename-conflict.png">
+
+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).
+
+<!-- known issue: when renaming an interface method, gopls doesn't properly
+     traverse W-shaped import graphs looking for matching types; see golang/go#58461. -->
+
+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`
+
+
+<a id='Extract'></a>
+## 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:
+
+<!-- See TODO comments in settings/codeactionkind.go about splitting
+     up "refactor.extract" into finer grained categories. -->
+
+- **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.
+  <!-- TODO(adonovan): update when https://go.dev/cl/565895 lands. -->
+- **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.
+  <!-- TODO(adonovan): review and land https://go.dev/cl/563235. -->
+  <!-- Should this operation update all callers? That's more of a Change Signature. -->
+- **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.
+
+
+<a id='extract-to-new-file'></a>
+## 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)
+
+
+<a id='Inline'></a>
+## 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:
+<!-- source code used for images:
+
+func six() int {
+	return sum(1, 2, 3)
+}
+
+func sum(values ...int) int {
+	total := 0
+	for _, v := range values {
+		total += v
+	}
+	return total
+}
+-->
+![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.
+
+<a id='Rewrite'></a>
+## Miscellaneous rewrites
+
+This section covers a number of transformations that are accessible as
+code actions of kind `refactor.rewrite`.
+
+<!-- See TODO comments in settings/codeactionkind.go about splitting
+     up "refactor.extract" into finer grained categories. -->
+
+<a id='remove-unused-parameter'></a>
+### 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)
+
+<!-- The output of this transformation is often stylistically poor.
+     For example, it will drop the "else" and outdent an if/else
+     if the else block ends with a return statement; and thus applying
+     the operation twice does not get you back to where you started. -->
+
+### 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.
+<!-- Strictly, line comments make only "join" (but not "split") infeasible. -->
+
+
+### 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 0000000..682d8e5
--- /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.)
+
+<a id='doc'></a>
+## 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.
+
+<img title="View package documentation" src="../assets/browse-pkg-doc.png" width='80%'>
+
+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**: ??
+
+
+<a id='freesymbols'></a>
+## 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.
+
+<img title="View free symbols" src="../assets/browse-free-symbols.png" width='80%'>
+
+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**: ??
+
+
+<a id='assembly'></a>
+## 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.
+
+<img title="View assembly" src="../assets/browse-assembly.png" width="80%">
+
+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 7a3e4af..524dc17 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 @@
 		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 @@
 				//
 				// 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 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, "<a id='%s'></a>\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 83f923d..209ffda 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 0358bf6..3d693ba 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`.
 
+<!-- This portion is generated by doc/generate from golang.AllInlayHints. -->
 <!-- BEGIN Hints: DO NOT MANUALLY EDIT THIS SECTION -->
 ## **assignVariableTypes**
 
diff --git a/gopls/doc/refactor-inline.md b/gopls/doc/refactor-inline.md
index dd857f8..cdddeb2 100644
--- a/gopls/doc/refactor-inline.md
+++ b/gopls/doc/refactor-inline.md
@@ -1,4 +1,6 @@
 
+<!-- this doc has been incorporated into features/transformation.md#Rename -->
+
 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 befb92c..c4220e4 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 a1e140d..761d94a 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 684e916..d64be63 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 @@
 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.
 
 <!--
 All settings are uniquely identified by name such as `semanticTokens`
@@ -48,7 +46,7 @@
 ## Build
 
 <a id='buildFlags'></a>
-### `buildFlags` *[]string*
+### `buildFlags []string`
 
 buildFlags is the set of flags passed on to the build system when invoked.
 It is applied to queries like `go list`, which is used when discovering files.
@@ -57,14 +55,14 @@
 Default: `[]`.
 
 <a id='env'></a>
-### `env` *map[string]string*
+### `env map[string]string`
 
 env adds environment variables to external commands run by `gopls`, most notably `go list`.
 
 Default: `{}`.
 
 <a id='directoryFilters'></a>
-### `directoryFilters` *[]string*
+### `directoryFilters []string`
 
 directoryFilters can be used to exclude unwanted directories from the
 workspace. By default, all directories are included. Filters are an
@@ -88,7 +86,7 @@
 Default: `["-**/node_modules"]`.
 
 <a id='templateExtensions'></a>
-### `templateExtensions` *[]string*
+### `templateExtensions []string`
 
 templateExtensions gives the extensions of file names that are treateed
 as template files. (The extension
@@ -97,7 +95,7 @@
 Default: `[]`.
 
 <a id='memoryMode'></a>
-### `memoryMode` *string*
+### `memoryMode string`
 
 **This setting is experimental and may be deleted.**
 
@@ -106,7 +104,7 @@
 Default: `""`.
 
 <a id='expandWorkspaceToModule'></a>
-### `expandWorkspaceToModule` *bool*
+### `expandWorkspaceToModule bool`
 
 **This setting is experimental and may be deleted.**
 
@@ -122,7 +120,7 @@
 Default: `true`.
 
 <a id='allowImplicitNetworkAccess'></a>
-### `allowImplicitNetworkAccess` *bool*
+### `allowImplicitNetworkAccess bool`
 
 **This setting is experimental and may be deleted.**
 
@@ -133,7 +131,7 @@
 Default: `false`.
 
 <a id='standaloneTags'></a>
-### `standaloneTags` *[]string*
+### `standaloneTags []string`
 
 standaloneTags specifies a set of build constraints that identify
 individual Go source files that make up the entire main package of an
@@ -160,17 +158,22 @@
 ## Formatting
 
 <a id='local'></a>
-### `local` *string*
+### `local string`
 
 local is the equivalent of the `goimports -local` flag, which puts
 imports beginning with this string after third-party packages. It should
 be the prefix of the import path whose imports should be grouped
 separately.
 
+It is used when tidying imports (during an LSP Organize
+Imports request) or when inserting new ones (for example,
+during completion); an LSP Formatting request merely sorts the
+existing imports.
+
 Default: `""`.
 
 <a id='gofumpt'></a>
-### `gofumpt` *bool*
+### `gofumpt bool`
 
 gofumpt indicates if we should run gofumpt formatting.
 
@@ -180,7 +183,7 @@
 ## UI
 
 <a id='codelenses'></a>
-### `codelenses` *map[enum]bool*
+### `codelenses map[enum]bool`
 
 codelenses overrides the enabled/disabled state of each of gopls'
 sources of [Code Lenses](codelenses.md).
@@ -201,7 +204,7 @@
 Default: `{"gc_details":false,"generate":true,"regenerate_cgo":true,"run_govulncheck":false,"tidy":true,"upgrade_dependency":true,"vendor":true}`.
 
 <a id='semanticTokens'></a>
-### `semanticTokens` *bool*
+### `semanticTokens bool`
 
 **This setting is experimental and may be deleted.**
 
@@ -211,7 +214,7 @@
 Default: `false`.
 
 <a id='noSemanticString'></a>
-### `noSemanticString` *bool*
+### `noSemanticString bool`
 
 **This setting is experimental and may be deleted.**
 
@@ -220,7 +223,7 @@
 Default: `false`.
 
 <a id='noSemanticNumber'></a>
-### `noSemanticNumber` *bool*
+### `noSemanticNumber bool`
 
 **This setting is experimental and may be deleted.**
 
@@ -232,7 +235,7 @@
 ## Completion
 
 <a id='usePlaceholders'></a>
-### `usePlaceholders` *bool*
+### `usePlaceholders bool`
 
 placeholders enables placeholders for function parameters or struct
 fields in completion responses.
@@ -240,7 +243,7 @@
 Default: `false`.
 
 <a id='completionBudget'></a>
-### `completionBudget` *time.Duration*
+### `completionBudget time.Duration`
 
 **This setting is for debugging purposes only.**
 
@@ -253,7 +256,7 @@
 Default: `"100ms"`.
 
 <a id='matcher'></a>
-### `matcher` *enum*
+### `matcher enum`
 
 **This is an advanced setting and should not be configured by most `gopls` users.**
 
@@ -269,7 +272,7 @@
 Default: `"Fuzzy"`.
 
 <a id='experimentalPostfixCompletions'></a>
-### `experimentalPostfixCompletions` *bool*
+### `experimentalPostfixCompletions bool`
 
 **This setting is experimental and may be deleted.**
 
@@ -279,7 +282,7 @@
 Default: `true`.
 
 <a id='completeFunctionCalls'></a>
-### `completeFunctionCalls` *bool*
+### `completeFunctionCalls bool`
 
 completeFunctionCalls enables function call completion.
 
@@ -293,7 +296,7 @@
 ## Diagnostic
 
 <a id='analyses'></a>
-### `analyses` *map[string]bool*
+### `analyses map[string]bool`
 
 analyses specify analyses that the user would like to enable or disable.
 A map of the names of analysis passes that should be enabled/disabled.
@@ -314,7 +317,7 @@
 Default: `{}`.
 
 <a id='staticcheck'></a>
-### `staticcheck` *bool*
+### `staticcheck bool`
 
 **This setting is experimental and may be deleted.**
 
@@ -325,7 +328,7 @@
 Default: `false`.
 
 <a id='annotations'></a>
-### `annotations` *map[enum]bool*
+### `annotations map[enum]bool`
 
 **This setting is experimental and may be deleted.**
 
@@ -342,7 +345,7 @@
 Default: `{"bounds":true,"escape":true,"inline":true,"nil":true}`.
 
 <a id='vulncheck'></a>
-### `vulncheck` *enum*
+### `vulncheck enum`
 
 **This setting is experimental and may be deleted.**
 
@@ -357,7 +360,7 @@
 Default: `"Off"`.
 
 <a id='diagnosticsDelay'></a>
-### `diagnosticsDelay` *time.Duration*
+### `diagnosticsDelay time.Duration`
 
 **This is an advanced setting and should not be configured by most `gopls` users.**
 
@@ -371,7 +374,7 @@
 Default: `"1s"`.
 
 <a id='diagnosticsTrigger'></a>
-### `diagnosticsTrigger` *enum*
+### `diagnosticsTrigger enum`
 
 **This setting is experimental and may be deleted.**
 
@@ -386,7 +389,7 @@
 Default: `"Edit"`.
 
 <a id='analysisProgressReporting'></a>
-### `analysisProgressReporting` *bool*
+### `analysisProgressReporting bool`
 
 analysisProgressReporting controls whether gopls sends progress
 notifications when construction of its index of analysis facts is taking a
@@ -404,7 +407,7 @@
 ## Documentation
 
 <a id='hoverKind'></a>
-### `hoverKind` *enum*
+### `hoverKind enum`
 
 hoverKind controls the information that appears in the hover text.
 SingleLine and Structured are intended for use only by authors of editor plugins.
@@ -423,9 +426,13 @@
 Default: `"FullDocumentation"`.
 
 <a id='linkTarget'></a>
-### `linkTarget` *string*
+### `linkTarget string`
 
-linkTarget controls where documentation links go.
+linkTarget is the base URL for links to Go package
+documentation returned by LSP operations such as Hover and
+DocumentLinks and in the CodeDescription field of each
+Diagnostic.
+
 It might be one of:
 
 * `"godoc.org"`
@@ -439,7 +446,7 @@
 Default: `"pkg.go.dev"`.
 
 <a id='linksInHover'></a>
-### `linksInHover` *enum*
+### `linksInHover enum`
 
 linksInHover controls the presence of documentation links in hover markdown.
 
@@ -455,7 +462,7 @@
 ## Inlayhint
 
 <a id='hints'></a>
-### `hints` *map[enum]bool*
+### `hints map[enum]bool`
 
 **This setting is experimental and may be deleted.**
 
@@ -469,7 +476,7 @@
 ## Navigation
 
 <a id='importShortcut'></a>
-### `importShortcut` *enum*
+### `importShortcut enum`
 
 importShortcut specifies whether import statements should link to
 documentation or go to definitions.
@@ -483,7 +490,7 @@
 Default: `"Both"`.
 
 <a id='symbolMatcher'></a>
-### `symbolMatcher` *enum*
+### `symbolMatcher enum`
 
 **This is an advanced setting and should not be configured by most `gopls` users.**
 
@@ -499,7 +506,7 @@
 Default: `"FastFuzzy"`.
 
 <a id='symbolStyle'></a>
-### `symbolStyle` *enum*
+### `symbolStyle enum`
 
 **This is an advanced setting and should not be configured by most `gopls` users.**
 
@@ -529,7 +536,7 @@
 Default: `"Dynamic"`.
 
 <a id='symbolScope'></a>
-### `symbolScope` *enum*
+### `symbolScope enum`
 
 symbolScope controls which packages are searched for workspace/symbol
 requests. When the scope is "workspace", gopls searches only workspace
@@ -545,7 +552,7 @@
 Default: `"all"`.
 
 <a id='verboseOutput'></a>
-### `verboseOutput` *bool*
+### `verboseOutput bool`
 
 **This setting is for debugging purposes only.**
 
diff --git a/gopls/doc/subl.md b/gopls/doc/subl.md
index a2b1585..37ddf9f 100644
--- a/gopls/doc/subl.md
+++ b/gopls/doc/subl.md
@@ -1,4 +1,4 @@
-# Sublime Text
+# Gopls: Using Sublime Text
 
 Use the [LSP] package. After installing it using Package Control, do the following:
 
diff --git a/gopls/doc/troubleshooting.md b/gopls/doc/troubleshooting.md
index 121dd86..5c064fd 100644
--- a/gopls/doc/troubleshooting.md
+++ b/gopls/doc/troubleshooting.md
@@ -1,4 +1,4 @@
-# Troubleshooting
+# Gopls: Troubleshooting
 
 If you suspect that `gopls` is crashing or not working correctly, please follow the troubleshooting steps below.
 
diff --git a/gopls/doc/vim.md b/gopls/doc/vim.md
index ac040fb..e714821 100644
--- a/gopls/doc/vim.md
+++ b/gopls/doc/vim.md
@@ -1,4 +1,4 @@
-# Vim / Neovim
+# Gopls: Using Vim or Neovim
 
 * [vim-go](#vimgo)
 * [LanguageClient-neovim](#lcneovim)
diff --git a/gopls/doc/workspace.md b/gopls/doc/workspace.md
index 94f83fb..766175d 100644
--- a/gopls/doc/workspace.md
+++ b/gopls/doc/workspace.md
@@ -1,4 +1,4 @@
-# Setting up your workspace
+# Gopls: Setting up your workspace
 
 In the language server protocol, a "workspace" consists of a folder along with
 per-folder configuration. Some LSP clients such as VS Code allow configuring
diff --git a/gopls/internal/doc/api.go b/gopls/internal/doc/api.go
index 826beca..a78127a 100644
--- a/gopls/internal/doc/api.go
+++ b/gopls/internal/doc/api.go
@@ -10,7 +10,7 @@
 
 import _ "embed"
 
-// API is a JSON value of type API.
+// JSON is a JSON encoding of value of type API.
 // The 'gopls api-json' command prints it.
 //
 //go:embed api.json
diff --git a/gopls/internal/doc/api.json b/gopls/internal/doc/api.json
index ffe9e33..9034b62 100644
--- a/gopls/internal/doc/api.json
+++ b/gopls/internal/doc/api.json
@@ -142,7 +142,7 @@
 			{
 				"Name": "linkTarget",
 				"Type": "string",
-				"Doc": "linkTarget controls where documentation links go.\nIt might be one of:\n\n* `\"godoc.org\"`\n* `\"pkg.go.dev\"`\n\nIf company chooses to use its own `godoc.org`, its address can be used as well.\n\nModules matching the GOPRIVATE environment variable will not have\ndocumentation links in hover.\n",
+				"Doc": "linkTarget is the base URL for links to Go package\ndocumentation returned by LSP operations such as Hover and\nDocumentLinks and in the CodeDescription field of each\nDiagnostic.\n\nIt might be one of:\n\n* `\"godoc.org\"`\n* `\"pkg.go.dev\"`\n\nIf company chooses to use its own `godoc.org`, its address can be used as well.\n\nModules matching the GOPRIVATE environment variable will not have\ndocumentation links in hover.\n",
 				"EnumKeys": {
 					"ValueType": "",
 					"Keys": null
@@ -901,7 +901,7 @@
 			{
 				"Name": "local",
 				"Type": "string",
-				"Doc": "local is the equivalent of the `goimports -local` flag, which puts\nimports beginning with this string after third-party packages. It should\nbe the prefix of the import path whose imports should be grouped\nseparately.\n",
+				"Doc": "local is the equivalent of the `goimports -local` flag, which puts\nimports beginning with this string after third-party packages. It should\nbe the prefix of the import path whose imports should be grouped\nseparately.\n\nIt is used when tidying imports (during an LSP Organize\nImports request) or when inserting new ones (for example,\nduring completion); an LSP Formatting request merely sorts the\nexisting imports.\n",
 				"EnumKeys": {
 					"ValueType": "",
 					"Keys": null
diff --git a/gopls/internal/server/code_action.go b/gopls/internal/server/code_action.go
index 5c71be8..dd6abe0 100644
--- a/gopls/internal/server/code_action.go
+++ b/gopls/internal/server/code_action.go
@@ -190,7 +190,6 @@
 		}
 		edit, err := command.Dispatch(ctx, params, handler)
 		if err != nil {
-
 			return nil, err
 		}
 		var ok bool
diff --git a/gopls/internal/settings/default.go b/gopls/internal/settings/default.go
index 29d49ae..8d5eb6b 100644
--- a/gopls/internal/settings/default.go
+++ b/gopls/internal/settings/default.go
@@ -52,6 +52,7 @@
 						GoAssembly:                     true,
 						GoDoc:                          true,
 						GoFreeSymbols:                  true,
+						// Not GoTest: it must be explicit in CodeActionParams.Context.Only
 					},
 					file.Mod: {
 						protocol.SourceOrganizeImports: true,
diff --git a/gopls/internal/settings/settings.go b/gopls/internal/settings/settings.go
index ca0bf6a..935eb10 100644
--- a/gopls/internal/settings/settings.go
+++ b/gopls/internal/settings/settings.go
@@ -343,7 +343,11 @@
 	// SingleLine and Structured are intended for use only by authors of editor plugins.
 	HoverKind HoverKind
 
-	// LinkTarget controls where documentation links go.
+	// LinkTarget is the base URL for links to Go package
+	// documentation returned by LSP operations such as Hover and
+	// DocumentLinks and in the CodeDescription field of each
+	// Diagnostic.
+	//
 	// It might be one of:
 	//
 	// * `"godoc.org"`
@@ -375,6 +379,11 @@
 	// imports beginning with this string after third-party packages. It should
 	// be the prefix of the import path whose imports should be grouped
 	// separately.
+	//
+	// It is used when tidying imports (during an LSP Organize
+	// Imports request) or when inserting new ones (for example,
+	// during completion); an LSP Formatting request merely sorts the
+	// existing imports.
 	Local string
 
 	// Gofumpt indicates if we should run gofumpt formatting.
@@ -790,7 +799,7 @@
 		seen := make(map[string]struct{})
 		for name, value := range value {
 			if err := o.set(name, value, seen); err != nil {
-				err := fmt.Errorf("setting option %v: %w", name, err)
+				err := fmt.Errorf("setting option %q: %w", name, err)
 				errors = append(errors, err)
 			}
 		}