Skip to content

Commit 3b745b7

Browse files
committed
docs: explain multi-entry-point project mapping
1 parent c47cae7 commit 3b745b7

1 file changed

Lines changed: 66 additions & 2 deletions

File tree

book/src/lsp.md

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,72 @@ LSP configuration is supplied by the client/editor via `nim.*` settings.
148148

149149
When inside a Nimble project, `nimble` drives the entry points for `nimsuggest` automatically.
150150

151+
### Multi-entry-point projects
152+
153+
Some Nim packages have several independent entry points. For example, [Chronos](https://github.com/status-im/nim-chronos) has a main module `chronos.nim`, while also providing separate application modules that import only a subset of the package. [Constantine](https://github.com/mratsim/constantine) has a similar layout, with several public API modules rather than one module that reaches all of the package.
154+
155+
For these projects, the file being edited is not always the right `nimsuggest` project root. Without a mapping, `nimlangserver` falls back to the opened file, i.e. every opened file is a project root. Nimsuggest will then analyse that file and its imports, but it will not see independent entry points that use the file. This is especially important for generic code: the exact overload may only be known from a concrete instantiation in another entry point.
156+
157+
Use `nim.projectMapping` to select the entry point whose compilation context matches the files being edited:
158+
159+
```json
160+
{
161+
"nim.projectMapping": [
162+
{
163+
"projectFile": "chronos/apps/http/httpclient.nim",
164+
"fileRegex": "^chronos/apps/http/.*\\.nim$"
165+
},
166+
{
167+
"projectFile": "chronos.nim",
168+
"fileRegex": "^chronos/.*\\.nim$"
169+
}
170+
]
171+
}
172+
```
173+
174+
Mappings are checked in order, so put more specific patterns first. Paths in `projectFile` and `fileRegex` are relative to the workspace root. The mapped file must exist and be a compilable Nim entry point; a mapping does not import modules or create generic instantiations by itself.
175+
176+
#### Chronos
177+
178+
The core entry point is `chronos.nim`, but the HTTP application modules are independent entry points. Mapping HTTP sources to `httpclient.nim` gives nimsuggest the context of the HTTP implementation, while other Chronos files use the core entry point.
179+
180+
#### Constantine
181+
182+
Map each source area to an existing public API module that actually exercises the code being edited. For example, elliptic-curve sources can use a suitable elliptic-curve API entry point:
183+
184+
```json
185+
{
186+
"nim.projectMapping": [
187+
{
188+
"projectFile": "constantine/ethereum_bls_signatures.nim",
189+
"fileRegex": "^constantine/math/elliptic/.*\\.nim$"
190+
},
191+
{
192+
"projectFile": "constantine/ethereum_bls_signatures.nim",
193+
"fileRegex": "^constantine/.*\\.nim$"
194+
}
195+
]
196+
}
197+
```
198+
199+
The best root depends on the API area. If no existing entry point exercises the required combinations, create a project-local analysis root that imports representative public APIs and, where necessary, contains representative concrete uses. Keep that file as tooling infrastructure rather than treating it as a public package entry point.
200+
201+
#### Project-local editor configuration
202+
203+
The setting is supplied by the editor's LSP client. For Helix, a project-local `.helix/languages.toml` can contain:
204+
205+
```toml
206+
[language-server.nimlangserver.config.nim]
207+
projectMapping = [
208+
{ projectFile = "chronos/apps/http/httpclient.nim", fileRegex = "^chronos/apps/http/.*\\.nim$" },
209+
{ projectFile = "chronos.nim", fileRegex = "^chronos/.*\\.nim$" },
210+
]
211+
```
212+
213+
For VS Code, put the equivalent JSON setting in the project's `.vscode/settings.json`. Other editors expose the same `nim.projectMapping` setting through their LSP client configuration.
214+
215+
Project mapping is not required for ordinary definitions or every generic lookup. It is needed when precise results depend on a concrete instantiation reachable only from another entry point. Nimsuggest can perform conservative speculative analysis when no instantiation is available, but it cannot infer uses that are outside the selected compilation context.
216+
151217
## Inlay hints
152218

153219
Inlay hints are visual snippets displayed inline by the editor to provide context without cluttering the source.
@@ -275,5 +341,3 @@ Result: {
275341
"content": " block:\n template field1(): untyped =\n a.field1\n\n template field2(): untyped =\n a.field2\n\n field1 = field2"
276342
}
277343
```
278-
279-

0 commit comments

Comments
 (0)