microsoft / microsoft/language-server-protocol
Introduce specification for namespace-level symbol resolution
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 13k
- Forks
- 1k
- Avg merge
- 6d 1h
- Merged PRs (30d)
- 10
Description
⚠️: Throughout this proposal I'll use namespace generically to represent a language's ability to scope symbols. The usage is synonymous with package (go), module (python), and namespace (C++), which have different mechanics, but are similar from a scoping standpoint.
Proposal
Add to the specification NamespaceSymbols, which is a way to resolve all symbols in a namespace. This is in addition to the existing DocumentSymbols and WorkspaceSymbols.
NamespaceSymbols would return all symbols in a namespace, which may span multiple files. By giving language servers a consistent way to represent this, we'll have a consistent means for navigating large code bases. This is helpful since, in large code bases, listing all symbols for a project (ie WorkspaceSymbols) can be way too much information to process. At the same time, showing symbols for just the current file (ie DocumentSymbols) is too limiting as the files can be entirely arbitrary based on the developer's brain and mean the individual navigating the code base must spelunk around looking for a class, function, etc.
Below is a concrete example of this.
Example and implications
In this example, I'll demonstrate the implications of this on a Go project in vscode and neovim. In both cases, their language-related information is sourced from gopls.
In this example, I'll look at go-git
git clone https://github.com/go-git/go-git
The storage/filesystem package (namespace) consists of 8 non-test source files. All of these files are in the namespace filesystem.
When navigating this code-base, vscode leverages the DocumentSymbols call. Which is helpful, but I'd argue not as helpful as looking up all the symbols in the package, since as someone reading or working on the code, I'm actually not that interested in which file something lives in, but more so, what the package contains.

In neovim, you can see the difference between a workspace and document symbol call from the same file, below. Similarly, you end up with a lookup that is either too limited (document) or too broad (workspace).

With this proposal, we could easily wire up editors to do this at a package-level, similar to how its done in goland:

Hopefully this show can example/implication/benefit for editors.
Parting thoughts
- I felt this might be possible by doing workspace symbol lookup with some filtering. But the more I thought about it, it felt like this is a common "scoping" mechanic in many languages and deserves its own, clear, way to resolve this.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading the linked LSP DocumentSymbols and WorkspaceSymbols specification sections and compare how the proposal distinguishes file, workspace, and namespace scopes. Review the Go, VS Code, and Neovim examples for the intended use case. Done means the NamespaceSymbols proposal has an agreed protocol shape and semantics in the specification.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, go, neovim, python, vscode
- Domain
- api, developer-experience, devtools
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100