From 815ccffe9cb7d48e617ab7ba0f9047f15f62be55 Mon Sep 17 00:00:00 2001 From: Shulhi Sapli <913103+shulhi@users.noreply.github.com> Date: Sun, 15 Feb 2026 21:47:11 +0800 Subject: [PATCH 1/4] Read from current buffer for position --- analysis/bin/main.ml | 6 +++++- analysis/src/Commands.ml | 6 +++--- analysis/src/Hint.ml | 5 +++-- server/src/server.ts | 7 ++++++- 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/analysis/bin/main.ml b/analysis/bin/main.ml index 259b1a300..505ac6902 100644 --- a/analysis/bin/main.ml +++ b/analysis/bin/main.ml @@ -161,10 +161,14 @@ let main () = (match allowForConstructorPayloads with | "true" -> true | _ -> false) + | [_; "inlayHint"; path; line_start; line_end; maxLength; currentFile] -> + Commands.inlayhint ~path + ~pos:(int_of_string line_start, int_of_string line_end) + ~maxLength ~currentFile:(Some currentFile) ~debug | [_; "inlayHint"; path; line_start; line_end; maxLength] -> Commands.inlayhint ~path ~pos:(int_of_string line_start, int_of_string line_end) - ~maxLength ~debug + ~maxLength ~currentFile:None ~debug | [_; "codeLens"; path] -> Commands.codeLens ~path ~debug | [_; "codeAction"; path; startLine; startCol; endLine; endCol; currentFile] -> diff --git a/analysis/src/Commands.ml b/analysis/src/Commands.ml index 32bfe08ff..943810954 100644 --- a/analysis/src/Commands.ml +++ b/analysis/src/Commands.ml @@ -41,9 +41,9 @@ let completionResolve ~path ~modulePath = in print_endline docstring -let inlayhint ~path ~pos ~maxLength ~debug = +let inlayhint ~path ~pos ~maxLength ~currentFile ~debug = let result = - match Hint.inlay ~path ~pos ~maxLength ~debug with + match Hint.inlay ~path ~pos ~maxLength ~currentFile ~debug with | Some hints -> hints |> Protocol.array | None -> Protocol.null in @@ -491,7 +491,7 @@ let test ~path = ("Inlay Hint " ^ path ^ " " ^ string_of_int line_start ^ ":" ^ string_of_int line_end); inlayhint ~path ~pos:(line_start, line_end) ~maxLength:"25" - ~debug:false + ~currentFile:None ~debug:false | "cle" -> print_endline ("Code Lens " ^ path); codeLens ~path ~debug:false diff --git a/analysis/src/Hint.ml b/analysis/src/Hint.ml index 9f553d063..9dec35c3d 100644 --- a/analysis/src/Hint.ml +++ b/analysis/src/Hint.ml @@ -31,7 +31,7 @@ let locItemToTypeHint ~full:{file; package} locItem = | `Field -> fromType t)) | _ -> None -let inlay ~path ~pos ~maxLength ~debug = +let inlay ~path ~pos ~maxLength ~currentFile ~debug = let maxlen = try Some (int_of_string maxLength) with Failure _ -> None in let hints = ref [] in let start_line, end_line = pos in @@ -70,11 +70,12 @@ let inlay ~path ~pos ~maxLength ~debug = Ast_iterator.default_iterator.value_binding iterator vb in let iterator = {Ast_iterator.default_iterator with value_binding} in + let sourceFile = match currentFile with Some f -> f | None -> path in (if Files.classifySourceFile path = Res then let parser = Res_driver.parsing_engine.parse_implementation ~for_printer:false in - let {Res_driver.parsetree = structure} = parser ~filename:path in + let {Res_driver.parsetree = structure} = parser ~filename:sourceFile in iterator.structure iterator structure |> ignore); match Cmt.loadFullCmtFromPath ~path with | None -> None diff --git a/server/src/server.ts b/server/src/server.ts index f4829dd0e..f3db1e31a 100644 --- a/server/src/server.ts +++ b/server/src/server.ts @@ -646,7 +646,10 @@ async function inlayHint(msg: p.RequestMessage) { const filePath = utils.uriToNormalizedPath( params.textDocument.uri as utils.FileURI, ); - + let code = getOpenedFileContent(params.textDocument.uri as utils.FileURI); + let extension = path.extname(params.textDocument.uri); + let tmpname = utils.createFileInTempDir(extension); + fs.writeFileSync(tmpname, code, { encoding: "utf-8" }); const response = await utils.runAnalysisCommand( filePath, [ @@ -655,9 +658,11 @@ async function inlayHint(msg: p.RequestMessage) { params.range.start.line, params.range.end.line, config.extensionConfiguration.inlayHints?.maxLength, + tmpname, ], msg, ); + fs.unlink(tmpname, () => null); return response; } From f5be5fa57f251a6ddcd31503a78c6017ccd26ec5 Mon Sep 17 00:00:00 2001 From: Shulhi Sapli <913103+shulhi@users.noreply.github.com> Date: Sun, 15 Feb 2026 22:11:14 +0800 Subject: [PATCH 2/4] Debounce codeLens and inlayHint refresh requests from incremental typechecking --- server/src/server.ts | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/server/src/server.ts b/server/src/server.ts index f3db1e31a..e6e443af4 100644 --- a/server/src/server.ts +++ b/server/src/server.ts @@ -572,6 +572,7 @@ let closedFile = async (fileUri: utils.FileURI) => { } }; +let refreshTimeout: ReturnType | null = null; let updateOpenedFile = (fileUri: utils.FileURI, fileContent: string) => { getLogger().info( `Updating opened file ${fileUri}, incremental TC enabled: ${config.extensionConfiguration.incrementalTypechecking?.enable}`, @@ -581,12 +582,18 @@ let updateOpenedFile = (fileUri: utils.FileURI, fileContent: string) => { stupidFileContentCache.set(filePath, fileContent); if (config.extensionConfiguration.incrementalTypechecking?.enable) { ic.handleUpdateOpenedFile(filePath, fileContent, send, () => { - if (config.extensionConfiguration.codeLens) { - sendCodeLensRefresh(); - } - if (config.extensionConfiguration.inlayHints) { - sendInlayHintsRefresh(); + if (refreshTimeout != null) { + clearTimeout(refreshTimeout); } + refreshTimeout = setTimeout(() => { + refreshTimeout = null; + if (config.extensionConfiguration.codeLens) { + sendCodeLensRefresh(); + } + if (config.extensionConfiguration.inlayHints) { + sendInlayHintsRefresh(); + } + }, 200); }); } }; From 228685d821189a5e5b5c8ee6a3be34de8cc5dd29 Mon Sep 17 00:00:00 2001 From: Shulhi Sapli <913103+shulhi@users.noreply.github.com> Date: Sun, 15 Feb 2026 22:55:51 +0800 Subject: [PATCH 3/4] Only pass currentFile to analysis binary for ReScript >= 12.0.0-alpha.5 --- server/src/server.ts | 46 +++++++++++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/server/src/server.ts b/server/src/server.ts index e6e443af4..d55321855 100644 --- a/server/src/server.ts +++ b/server/src/server.ts @@ -653,23 +653,37 @@ async function inlayHint(msg: p.RequestMessage) { const filePath = utils.uriToNormalizedPath( params.textDocument.uri as utils.FileURI, ); - let code = getOpenedFileContent(params.textDocument.uri as utils.FileURI); - let extension = path.extname(params.textDocument.uri); - let tmpname = utils.createFileInTempDir(extension); - fs.writeFileSync(tmpname, code, { encoding: "utf-8" }); - const response = await utils.runAnalysisCommand( + let args: Array = [ + "inlayHint", filePath, - [ - "inlayHint", - filePath, - params.range.start.line, - params.range.end.line, - config.extensionConfiguration.inlayHints?.maxLength, - tmpname, - ], - msg, - ); - fs.unlink(tmpname, () => null); + params.range.start.line, + params.range.end.line, + config.extensionConfiguration.inlayHints?.maxLength, + ]; + let tmpname: string | null = null; + let projectRootPath = utils.findProjectRootOfFile(filePath); + let rescriptVersion = projectRootPath + ? projectsFiles.get(projectRootPath)?.rescriptVersion + : null; + let supportsCurrentFile = + rescriptVersion != null && + semver.valid(rescriptVersion) != null && + semver.gte(rescriptVersion, "12.0.0-alpha.5"); + // The currentFile argument (passing unsaved buffer content via a temp file) + // is only supported by the analysis binary that ships with the compiler + // starting from 12.0.0-alpha.5. Older versions don't recognize the extra + // argument and would fail to match the CLI pattern. + if (supportsCurrentFile) { + let code = getOpenedFileContent(params.textDocument.uri as utils.FileURI); + let extension = path.extname(params.textDocument.uri); + tmpname = utils.createFileInTempDir(extension); + fs.writeFileSync(tmpname, code, { encoding: "utf-8" }); + args.push(tmpname); + } + const response = await utils.runAnalysisCommand(filePath, args, msg); + if (tmpname != null) { + fs.unlink(tmpname, () => null); + } return response; } From 3111a8319b199338c42447478d1c828131ff1571 Mon Sep 17 00:00:00 2001 From: Shulhi Sapli <913103+shulhi@users.noreply.github.com> Date: Sun, 22 Feb 2026 11:29:31 +0800 Subject: [PATCH 4/4] Run formatter --- analysis/src/Hint.ml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/analysis/src/Hint.ml b/analysis/src/Hint.ml index 9dec35c3d..3650ddd8c 100644 --- a/analysis/src/Hint.ml +++ b/analysis/src/Hint.ml @@ -70,7 +70,11 @@ let inlay ~path ~pos ~maxLength ~currentFile ~debug = Ast_iterator.default_iterator.value_binding iterator vb in let iterator = {Ast_iterator.default_iterator with value_binding} in - let sourceFile = match currentFile with Some f -> f | None -> path in + let sourceFile = + match currentFile with + | Some f -> f + | None -> path + in (if Files.classifySourceFile path = Res then let parser = Res_driver.parsing_engine.parse_implementation ~for_printer:false