microsoft / microsoft/language-server-protocol

Introduce specification for namespace-level symbol resolution

Open
#1,607 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

feature-request new request
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.

image

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).

image

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

image

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

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.