@venn-lang/lsp 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +167 -0
  3. package/dist/bin/venn-lsp.d.mts +1 -0
  4. package/dist/bin/venn-lsp.mjs +17 -0
  5. package/dist/bin/venn-lsp.mjs.map +1 -0
  6. package/dist/index.d.mts +722 -0
  7. package/dist/index.d.mts.map +1 -0
  8. package/dist/index.mjs +2 -0
  9. package/dist/server-BET60xwK.mjs +5376 -0
  10. package/dist/server-BET60xwK.mjs.map +1 -0
  11. package/package.json +65 -0
  12. package/src/bin/venn-lsp.ts +17 -0
  13. package/src/catalog/build-catalog.ts +72 -0
  14. package/src/catalog/catalog.types.ts +44 -0
  15. package/src/catalog/index.ts +2 -0
  16. package/src/code-actions/anchor.ts +49 -0
  17. package/src/code-actions/code-actions.ts +139 -0
  18. package/src/code-actions/exporting-modules.ts +73 -0
  19. package/src/code-actions/index.ts +5 -0
  20. package/src/completion/argument-items.ts +81 -0
  21. package/src/completion/completion.ts +416 -0
  22. package/src/completion/completion.types.ts +38 -0
  23. package/src/completion/context.ts +144 -0
  24. package/src/completion/icons.ts +83 -0
  25. package/src/completion/index.ts +4 -0
  26. package/src/completion/items.ts +232 -0
  27. package/src/completion/member-items.ts +147 -0
  28. package/src/completion/module-paths.ts +63 -0
  29. package/src/completion/options-map-items.ts +47 -0
  30. package/src/completion/read-from.ts +77 -0
  31. package/src/completion/type-name-items.ts +62 -0
  32. package/src/deco/builtin-decos.ts +35 -0
  33. package/src/deco/builtin-docs.ts +26 -0
  34. package/src/deco/declared-deco.ts +56 -0
  35. package/src/deco/deco.types.ts +23 -0
  36. package/src/deco/decos-in-scope.ts +63 -0
  37. package/src/deco/imported-decos.ts +49 -0
  38. package/src/deco/index.ts +9 -0
  39. package/src/deco/kind-of.ts +15 -0
  40. package/src/deco/render-deco.ts +44 -0
  41. package/src/definition/definition.ts +93 -0
  42. package/src/definition/index.ts +1 -0
  43. package/src/docs/doc.types.ts +17 -0
  44. package/src/docs/index.ts +4 -0
  45. package/src/docs/parse-doc.ts +42 -0
  46. package/src/docs/read-doc.ts +45 -0
  47. package/src/docs/render-doc.ts +42 -0
  48. package/src/document/exported-names.ts +30 -0
  49. package/src/document/expression-path.ts +43 -0
  50. package/src/document/find-binding.ts +82 -0
  51. package/src/document/host-at.ts +61 -0
  52. package/src/document/imported-modules.ts +91 -0
  53. package/src/document/imported-names.ts +15 -0
  54. package/src/document/index.ts +19 -0
  55. package/src/document/interpolation-at.ts +134 -0
  56. package/src/document/names-in-scope.ts +126 -0
  57. package/src/document/resolve-fragment.ts +38 -0
  58. package/src/document/resolve-imported.ts +35 -0
  59. package/src/effects/index.ts +1 -0
  60. package/src/effects/waiting-fns.ts +83 -0
  61. package/src/env/env-vars.ts +88 -0
  62. package/src/env/env.types.ts +9 -0
  63. package/src/env/index.ts +3 -0
  64. package/src/env/render-env.ts +25 -0
  65. package/src/formatting/formatter.ts +68 -0
  66. package/src/formatting/index.ts +1 -0
  67. package/src/hover/hover.ts +322 -0
  68. package/src/hover/index.ts +1 -0
  69. package/src/hover/keywords.ts +168 -0
  70. package/src/hover/render-action.ts +94 -0
  71. package/src/hover/render-decl.ts +155 -0
  72. package/src/hover/render-imported.ts +49 -0
  73. package/src/hover/render-symbol.ts +108 -0
  74. package/src/hover/render-type-name.ts +78 -0
  75. package/src/hover/resolve-symbol.ts +77 -0
  76. package/src/hover/type-hover.ts +62 -0
  77. package/src/index.ts +38 -0
  78. package/src/markdown/index.ts +1 -0
  79. package/src/markdown/markdown.ts +38 -0
  80. package/src/references/document-highlight.ts +45 -0
  81. package/src/references/find-occurrences.ts +49 -0
  82. package/src/references/index.ts +13 -0
  83. package/src/references/name-property.ts +14 -0
  84. package/src/references/occurrence-range.ts +23 -0
  85. package/src/references/occurrences.ts +124 -0
  86. package/src/references/references.ts +38 -0
  87. package/src/references/symbol-at.ts +114 -0
  88. package/src/references/symbol.types.ts +38 -0
  89. package/src/rename/declares-deco.ts +15 -0
  90. package/src/rename/index.ts +1 -0
  91. package/src/rename/rename.ts +73 -0
  92. package/src/semantic/highlight-calls.ts +56 -0
  93. package/src/semantic/highlight-interpolation.ts +135 -0
  94. package/src/semantic/highlight-keywords.ts +115 -0
  95. package/src/semantic/highlight-literals.ts +38 -0
  96. package/src/semantic/highlight-module.ts +36 -0
  97. package/src/semantic/highlight-names.ts +97 -0
  98. package/src/semantic/highlight-paths.ts +80 -0
  99. package/src/semantic/highlight.types.ts +10 -0
  100. package/src/semantic/index.ts +1 -0
  101. package/src/semantic/semantic-tokens.ts +32 -0
  102. package/src/server/index.ts +1 -0
  103. package/src/server/start-server.ts +15 -0
  104. package/src/services/index.ts +2 -0
  105. package/src/services/lsp.types.ts +14 -0
  106. package/src/services/venn-lsp-module.ts +65 -0
  107. package/src/signature/action-call.ts +82 -0
  108. package/src/signature/bare-call.ts +55 -0
  109. package/src/signature/call-shape.ts +90 -0
  110. package/src/signature/call-shape.types.ts +34 -0
  111. package/src/signature/declared-shape.ts +52 -0
  112. package/src/signature/index.ts +11 -0
  113. package/src/signature/paren-call.ts +77 -0
  114. package/src/signature/render-shape.ts +92 -0
  115. package/src/signature/shape-at.ts +35 -0
  116. package/src/signature/signature-help.ts +98 -0
  117. package/src/symbols/document-symbols.ts +68 -0
  118. package/src/symbols/index.ts +1 -0
  119. package/src/testing/fixtures/alias-import.vn +16 -0
  120. package/src/testing/fixtures/shared/auth.vn +33 -0
  121. package/src/testing/fixtures/venn.toml +8 -0
  122. package/src/testing/lsp-fixture.ts +77 -0
  123. package/src/types/index.ts +3 -0
  124. package/src/types/type-service.ts +144 -0
  125. package/src/types/warm-types.ts +30 -0
  126. package/src/validation/check-validator.ts +111 -0
  127. package/src/validation/index.ts +1 -0
  128. package/src/workspace/import-resolver.ts +187 -0
  129. package/src/workspace/index.ts +1 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Vinicius Borges
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,167 @@
1
+ # @venn-lang/lsp
2
+
3
+ > The Venn language server: diagnostics, hover, completion, definition, references, rename, signature help, semantic tokens, formatting, document highlight and quick fixes for `.vn` files.
4
+
5
+ Venn's grammar is deliberately tiny, so the parser alone cannot tell `http.get` from `myHelper.foo`. This package puts the missing knowledge back: it loads the whole stdlib, indexes every action, matcher and published type into a catalog, and serves that catalog to an editor over LSP. It is built on Langium and ships a standalone `venn-lsp` binary that any client can spawn.
6
+
7
+ ## Usage
8
+
9
+ Run the server from a shell. With no transport flag it defaults to stdio, so a bare invocation works.
10
+
11
+ ```bash
12
+ pnpm --filter @venn-lang/lsp build
13
+ node packages/lsp/dist/bin/venn-lsp.mjs --stdio
14
+ ```
15
+
16
+ To host it yourself, hand `startVennServer` a connection. This is the whole server entry point of the VS Code extension:
17
+
18
+ ```ts
19
+ import { startVennServer } from "@venn-lang/lsp";
20
+ import { createConnection, ProposedFeatures } from "vscode-languageserver/node";
21
+
22
+ startVennServer(createConnection(ProposedFeatures.all));
23
+ ```
24
+
25
+ To drive the providers directly (tests, a custom editor, a node graph UI), build the services and call them:
26
+
27
+ ```ts
28
+ import { createVennLspServices } from "@venn-lang/lsp";
29
+ import { EmptyFileSystem } from "langium";
30
+
31
+ const { shared, Venn } = createVennLspServices(EmptyFileSystem);
32
+ const hover = await Venn.lsp.HoverProvider?.getHoverContent(document, params);
33
+ ```
34
+
35
+ `Venn` is a `VennServices`: Langium's own services plus `catalog`, `imports` and `types`.
36
+
37
+ ## API
38
+
39
+ ### Server and services
40
+
41
+ | Export | What it does |
42
+ | --- | --- |
43
+ | `startVennServer(connection)` | Builds the services on the node filesystem and starts the Langium language server. |
44
+ | `createVennLspServices(context)` | Returns `{ shared, Venn }`. Registers the Venn checks and keeps workspace types warm. |
45
+ | `VennServices`, `VennAddedServices` | The service types. `VennAddedServices` is `catalog`, `imports` and `types`. |
46
+ | `registerVennChecks(services)` | Wires the runtime's static check and type inference into Langium's validation registry. |
47
+
48
+ ### Providers
49
+
50
+ Each is registered by `createVennLspServices`; export them for direct use or for a client that assembles its own module.
51
+
52
+ | Export | LSP request |
53
+ | --- | --- |
54
+ | `VennHoverProvider` | `textDocument/hover` |
55
+ | `VennCompletionProvider` | `textDocument/completion` |
56
+ | `VennDefinitionProvider` | `textDocument/definition` |
57
+ | `VennReferencesProvider` | `textDocument/references` |
58
+ | `VennDocumentHighlightProvider` | `textDocument/documentHighlight` |
59
+ | `VennRenameProvider` | `textDocument/rename`, `prepareRename` |
60
+ | `VennSignatureHelpProvider` | `textDocument/signatureHelp` |
61
+ | `VennSemanticTokenProvider` | `textDocument/semanticTokens` |
62
+ | `VennDocumentSymbolProvider` | `textDocument/documentSymbol` |
63
+ | `VennFormatter` | `formatting`, `rangeFormatting`, `onTypeFormatting` |
64
+
65
+ ### Catalog
66
+
67
+ | Export | What it does |
68
+ | --- | --- |
69
+ | `buildCatalog(plugins)` | Indexes plugin definitions into a `SymbolCatalog`. |
70
+ | `SymbolCatalog` | Lookup and listing: `namespaces()`, `hasNamespace()`, `actionsIn()`, `action()`, `typesIn()`, `matchers()`, `matcher()`, `packagesFor()`, `namespaceOfPackage()`. |
71
+ | `ActionEntry`, `MatcherEntry` | One action or matcher, with the package that contributes it. |
72
+
73
+ ### Documents and workspace
74
+
75
+ | Export | What it does |
76
+ | --- | --- |
77
+ | `createImportResolver()`, `ImportResolver` | Reads the nearest `venn.toml`: resolves a specifier, lists `[paths]` aliases, returns `[format]` settings, declared env vars and derived package types. |
78
+ | `resolveFragment(args)`, `FragmentLocation` | Finds a fragment in this file or through the `import` naming it. |
79
+ | `findFragment(document, name)` | The fragment a parsed document declares under that name. |
80
+ | `findBinding(from, name)` | The node that binds a name, searched outwards to the document. |
81
+ | `exportedNames(document)` | The names a module marks `pub`, each with its kind (`fragment`, `fn`, `deco`). |
82
+ | `importedNames(document)` | The names a document pulls in through `import { … }`. |
83
+
84
+ ### Completion, decorators, docs, references
85
+
86
+ | Export | What it does |
87
+ | --- | --- |
88
+ | `contextAt(text)`, `CompletionContext` | Classifies the cursor from the text before it: `package`, `modulePath`, `importName`, `action`, `member`, `annotation`, `fragment`, `matcher`, `optionKey`, `argument`, `typeName`, `statement`. |
89
+ | `modulePaths(args)` | What may follow `from "`: sibling `.vn` files, or a `#alias/…` path from `venn.toml`. |
90
+ | `decosInScope(scope)`, `decoNamed(name, scope)`, `builtinDecos()` | Every decorator a `@name` could mean here: built-ins, imported `pub deco`s, and the file's own. Later wins. |
91
+ | `DecoInfo`, `DecoScope` | A decorator's name, signature, what it decorates, and where it is declared. |
92
+ | `parseDoc(lines)`, `readDoc(document, node)`, `renderDoc(doc)` | Read and render a documentation block. |
93
+ | `DocBlock`, `DocParam` | Summary, params, returns, examples, deprecated. |
94
+ | `symbolAt(document, position)` | What a position names: a `fragment`, `deco`, `fn`, `type`, `binding` or `external` name. |
95
+ | `occurrencesIn(args)` | Every place one symbol appears in one document. |
96
+ | `findOccurrences(args)` | The same across the workspace, but only for symbols that cross files. |
97
+
98
+ ## What the server answers
99
+
100
+ | Feature | Behaviour |
101
+ | --- | --- |
102
+ | **Diagnostics** | Syntax errors (`VN1xxx`), then the same static check `venn check` runs: `VN2003` unknown action, `VN2004` unknown matcher, `VN2005` unknown fragment, `VN2006` an `env` var no `venn.toml` declares, `VN2007` a namespace used without a `use`, `VN2008` a verb read as a value, `VN2009` a name the imported module does not publish, plus type errors (`VN3xxx`) and lint (`VN5xxx`). |
103
+ | **Hover** | Action signature, docs, options and owning package; matchers; fragment signatures; what a `let` or a parameter binds; what a package contributes; what an annotation means; what an `env` variable holds. Inside `"${…}"` the name hovers as code, not as text. |
104
+ | **Completion** | Verbs and published types after `namespace.`, members after any other dot, matchers once `expect` has a subject, fragments after `run`, decorators after `@`, packages inside `use "…"`, module paths after `from "`, published names inside `import { … }`, option keys inside a call's `{ … }`, type names after a `:`, and the names in scope anywhere else. |
105
+ | **Go to definition** | `run <fragment>` lands on the declaration, following an `import` into another file; a name lands on the statement that binds it; a `@deco` lands on the `deco` that declares it; an import specifier opens the file. |
106
+ | **References and highlight** | Both read one occurrence walk, so they agree with rename. A `fragment`, `fn` or `deco` is searched across the workspace; a `binding` or a `type` stays in its file, because a `const` of the same name next door is a different name. Highlight marks the declaration as a write and each use as a read. |
107
+ | **Rename** | Rewrites exactly what "find all references" reports, including the names inside `import { … }`. A built-in decorator has no source to rewrite, so rename declines it. |
108
+ | **Signature help** | Space is a trigger character alongside `(` and `,`, because a Venn call needs no brackets: `http.on ` already has an argument due. The options map counts as the last parameter. |
109
+ | **Semantic tokens** | The namespace of `http.get` is coloured apart from the verb, a matcher is a `method`, an annotation is a `decorator`, a `run` target is a `macro`, and anything the catalog knows carries the `defaultLibrary` modifier. |
110
+ | **Outline** | Flows with their nested steps and groups, plus fragments and `deco` declarations. |
111
+ | **Formatting** | Runs through `formatText` in `@venn-lang/core`, so the editor and `venn fmt` produce byte-identical output. `[format]` in `venn.toml` wins; the editor's indent settings fill in the rest. On-type formatting triggers on `}` and newline. |
112
+ | **Quick fixes** | `VN2007` offers `Add use "<pkg>"` for every package providing the namespace, inserted above the imports. `VN2005` offers `Import <name> from "…"` for every module that publishes it. `VN5001` replaces `capture` with `let`. |
113
+
114
+ ## Documenting a declaration
115
+
116
+ A run of `##` lines directly above a declaration is its documentation. The body is markdown, and four tags are understood: `@param`, `@returns`, `@example`, `@deprecated`.
117
+
118
+ ```ruby
119
+ ## Signs a user in through the API and asserts the session is live.
120
+ ##
121
+ ## @param user The account name to sign in as.
122
+ ## @returns The HTTP response of the sign-in call.
123
+ ## @example
124
+ ## run login("alice")
125
+ pub fragment login(user) {
126
+ step "in" { expect true }
127
+ }
128
+ ```
129
+
130
+ A single `#` stays an ordinary comment. The `@doc("…")` annotation works too and is used when no `##` block is present. Hovering `run login(…)` shows the block even when the fragment lives in another file: the server follows the `import`, `#alias/…` paths included.
131
+
132
+ ## Editors
133
+
134
+ **VS Code.** The client extension is in [`packages/vscode`](../vscode). It bundles this server and spawns it over IPC. From the repo root:
135
+
136
+ ```bash
137
+ pnpm vscode:install # build, package a .vsix, install it
138
+ pnpm vscode:uninstall
139
+ ```
140
+
141
+ Reload the window afterwards. This needs the `code` CLI on your PATH.
142
+
143
+ **Any other client.** Point it at the binary and claim the `.vn` extension. For Neovim:
144
+
145
+ ```lua
146
+ vim.filetype.add({ extension = { vn = "venn" } })
147
+ vim.lsp.config.venn = {
148
+ cmd = { "node", "/abs/path/packages/lsp/dist/bin/venn-lsp.mjs", "--stdio" },
149
+ filetypes = { "venn" },
150
+ root_markers = { "venn.toml", ".git" },
151
+ }
152
+ vim.lsp.enable("venn")
153
+ ```
154
+
155
+ ## Notes
156
+
157
+ - Every namespace resolves regardless of which `use` lines a file has, because the server loads the whole stdlib. A missing `use` is reported as `VN2007` rather than as an unknown action.
158
+ - Type inference is cached per parse in a shared `TypeService`, so diagnostics and hover read the same result and a keystroke re-checks only the edited file.
159
+ - Import specifiers resolve like the CLI's: relative paths against the importing file, `#alias/…` through `[paths]` in the nearest `venn.toml`, searched upwards and cached per directory.
160
+ - Cross-file rename reaches every document the server has indexed. A file it has never opened or scanned is not rewritten.
161
+
162
+ ## See also
163
+
164
+ - [`@venn-lang/core`](../core) for the grammar, the AST, type inference and the formatter.
165
+ - [`@venn-lang/runtime`](../runtime) for the static check and the plugin registry the diagnostics use.
166
+ - [`@venn-lang/stdlib`](../stdlib) for the plugins the catalog indexes.
167
+ - [`packages/vscode`](../vscode) for the client that ships this server.
@@ -0,0 +1 @@
1
+ export {}
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env node
2
+ import { t as startVennServer } from "../server-BET60xwK.mjs";
3
+ import { ProposedFeatures, createConnection } from "vscode-languageserver/node";
4
+ //#region src/bin/venn-lsp.ts
5
+ const TRANSPORT_FLAGS = [
6
+ "--stdio",
7
+ "--node-ipc",
8
+ "--socket"
9
+ ];
10
+ function connect() {
11
+ return process.argv.some((arg) => TRANSPORT_FLAGS.some((flag) => arg.startsWith(flag))) ? createConnection(ProposedFeatures.all) : createConnection(ProposedFeatures.all, process.stdin, process.stdout);
12
+ }
13
+ startVennServer(connect());
14
+ //#endregion
15
+ export {};
16
+
17
+ //# sourceMappingURL=venn-lsp.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"venn-lsp.mjs","names":[],"sources":["../../src/bin/venn-lsp.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { type Connection, createConnection, ProposedFeatures } from \"vscode-languageserver/node\";\nimport { startVennServer } from \"../server/index.js\";\n\nconst TRANSPORT_FLAGS = [\"--stdio\", \"--node-ipc\", \"--socket\"];\n\n// Editors pass a transport flag; with none given, default to stdio so the server\n// is usable straight from a shell.\nfunction connect(): Connection {\n const flagged = process.argv.some((arg) => TRANSPORT_FLAGS.some((flag) => arg.startsWith(flag)));\n const connection = flagged\n ? createConnection(ProposedFeatures.all)\n : createConnection(ProposedFeatures.all, process.stdin, process.stdout);\n return connection as Connection;\n}\n\nstartVennServer(connect());\n"],"mappings":";;;;AAIA,MAAM,kBAAkB;CAAC;CAAW;CAAc;AAAU;AAI5D,SAAS,UAAsB;CAK7B,OAJgB,QAAQ,KAAK,MAAM,QAAQ,gBAAgB,MAAM,SAAS,IAAI,WAAW,IAAI,CAAC,CACrE,IACrB,iBAAiB,iBAAiB,GAAG,IACrC,iBAAiB,iBAAiB,KAAK,QAAQ,OAAO,QAAQ,MAAM;AAE1E;AAEA,gBAAgB,QAAQ,CAAC"}