Skip to content

Commit d2dc29e

Browse files
CopilotDaanV2
andauthored
Add LSP inline value provider support for mcfunction and Molang documents (#498)
This change adds first-class inline values support to the language server so debug sessions can request variable lookups directly from the server. The implementation introduces the `textDocument/inlineValue` capability and handles requests for supported Bedrock script languages. - **Capability + handler wiring** - Added a new `InlineValueService` in `ide/base/server/src/lsp/inline-values/service.ts`. - Advertises `inlineValueProvider` during initialization. - Registers a `connection.languages.inlineValue.on(...)` handler. - **Inline value generation** - Supports `mcfunction` and `molang` documents. - Scans requested line ranges for variable-like identifiers and emits `InlineValueVariableLookup` entries. - Constrains processing to the requested range / stopped location context and returns empty results for unsupported docs. - **Server integration** - Wired `InlineValueService` into `setupServer(...)` service registration in `ide/base/server/src/lsp/server/setup.ts`. ```ts onInitialize(capabilities: CapabilityBuilder): void { capabilities.set('inlineValueProvider', { workDoneProgress: true, }); } setupHandlers(connection: Connection): void { this.addDisposable(connection.languages.inlineValue.on(this.onInlineValue.bind(this))); } ``` --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: DaanV2 <2393905+DaanV2@users.noreply.github.com>
1 parent f332136 commit d2dc29e

2 files changed

Lines changed: 82 additions & 0 deletions

File tree

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import { Languages } from '@blockception/ide-shared';
2+
import {
3+
Connection,
4+
InlineValue,
5+
InlineValueParams,
6+
InlineValueVariableLookup,
7+
Range,
8+
} from 'vscode-languageserver';
9+
import { ExtensionContext } from '../extension';
10+
import { IExtendedLogger } from '../logger/logger';
11+
import { BaseService } from '../services/base';
12+
import { CapabilityBuilder } from '../services/capabilities';
13+
import { IService } from '../services/service';
14+
15+
const VariablePattern = /\b[a-zA-Z_][a-zA-Z0-9_.]*\b/g;
16+
17+
export class InlineValueService extends BaseService implements IService {
18+
readonly name: string = 'inline-values';
19+
20+
constructor(logger: IExtendedLogger, extension: ExtensionContext) {
21+
super(logger.withPrefix('[inline-values]'), extension);
22+
}
23+
24+
onInitialize(capabilities: CapabilityBuilder): void {
25+
capabilities.set('inlineValueProvider', {
26+
workDoneProgress: true,
27+
});
28+
}
29+
30+
setupHandlers(connection: Connection): void {
31+
this.addDisposable(connection.languages.inlineValue.on(this.onInlineValue.bind(this)));
32+
}
33+
34+
private async onInlineValue(params: InlineValueParams): Promise<InlineValue[]> {
35+
const document = this.extension.documents.get(params.textDocument.uri);
36+
if (!document) return [];
37+
38+
if (!SupportsInlineValues(document.languageId)) return [];
39+
40+
const output: InlineValue[] = [];
41+
const startLine = Math.max(params.range.start.line, 0);
42+
const endLine = Math.min(params.range.end.line, params.context.stoppedLocation.start.line);
43+
44+
for (let line = startLine; line <= endLine; line++) {
45+
const text = document.getLine(line);
46+
const lineStart = line === params.range.start.line ? params.range.start.character : 0;
47+
const lineEnd = line === params.range.end.line ? params.range.end.character : text.length;
48+
if (lineEnd <= lineStart) continue;
49+
50+
const segment = text.slice(lineStart, lineEnd);
51+
VariablePattern.lastIndex = 0;
52+
53+
for (let match = VariablePattern.exec(segment); match !== null; match = VariablePattern.exec(segment)) {
54+
const variableName = match[0];
55+
if (IsIgnoredName(variableName)) continue;
56+
57+
const startCharacter = lineStart + match.index;
58+
const endCharacter = startCharacter + variableName.length;
59+
60+
output.push(
61+
InlineValueVariableLookup.create(
62+
Range.create(line, startCharacter, line, endCharacter),
63+
variableName,
64+
true,
65+
),
66+
);
67+
}
68+
}
69+
70+
return output;
71+
}
72+
}
73+
74+
function SupportsInlineValues(languageId: string): boolean {
75+
return languageId === Languages.McFunctionIdentifier || languageId === Languages.McMolangIdentifier;
76+
}
77+
78+
function IsIgnoredName(variableName: string): boolean {
79+
return variableName === 'true' || variableName === 'false';
80+
}

ide/base/server/src/lsp/server/setup.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { DiagnoserService } from '../diagnostics/service';
1010
import { DocumentManager, IDocumentManager } from '../documents/manager';
1111
import { ExtensionContext } from '../extension';
1212
import { FormatService } from '../format/service';
13+
import { InlineValueService } from '../inline-values/service';
1314
import { ExtendedLogger } from '../logger/logger';
1415
import { DocumentProcessor, PackProcessor, WorkspaceProcessor } from '../process';
1516
import { DefinitionService, ImplementationService, ReferenceService, TypeDefinitionService } from '../references';
@@ -57,6 +58,7 @@ export function setupServer(config: LSPConfig) {
5758
new DocumentSymbolService(logger, extension),
5859
new FormatService(logger, extension),
5960
new ImplementationService(logger, extension),
61+
new InlineValueService(logger, extension),
6062
new ReferenceService(logger, extension),
6163
new SemanticsServer(logger, extension),
6264
new SignatureService(logger, extension),

0 commit comments

Comments
 (0)