ocaml
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

language server: correct computation of inlay hints

1. Inlay hints computation should descend into children of nodes

2. Inlay hints (e.g. for links) cannot be accurately computed on Code.t;
we must instead wait for Syn.t.

+37 -11
+37 -11
lib/language_server/Inlay_hint.ml
··· 15 15 module L = Lsp.Types 16 16 end 17 17 18 + let list_of_option = function 19 + | Some x -> [x] 20 + | None -> [] 21 + 22 + let consume_addr_for_inlay ~(config : Config.t) ~(forest : State.t) (node : Syn.node Range.located) : string option * Syn.t = 23 + match node.value with 24 + | Link {title = None; dest = [{value = Text addr; _}]} -> Some addr, [] 25 + | Subtree (addr, nodes) -> addr, nodes 26 + | _ -> None, Syn.children node 27 + 28 + let inlay_hint_for_addr ~(config : Config.t) ~(forest : State.t) ~(pos : Range.position) (addr : string) : L.InlayHint.t option = 29 + let uri = URI_scheme.named_uri ~base: config.url addr in 30 + let@ {frontmatter; _} = Option.bind @@ State.get_article uri forest in 31 + let@ title = Option.bind frontmatter.title in 32 + let content = " " ^ Plain_text_client.string_of_content ~forest title in 33 + Option.some @@ L.InlayHint.create ~position: (Lsp_shims.Loc.lsp_pos_of_pos pos) ~label: (`String content) () 34 + 35 + let pos_of_node (node : 'a Range.located) : Range.position option = 36 + let@ loc = Option.bind node.loc in 37 + match Range.view loc with 38 + | `End_of_file _ -> None 39 + | `Range (_, pos) -> Some pos 40 + 41 + let rec extract_inlayable_hints ~(config : Config.t) ~(forest : State.t) (nodes : Syn.t) : L.InlayHint.t list = 42 + let@ node = List.concat_map @~ nodes in 43 + let addr_opt, rest = consume_addr_for_inlay ~config ~forest node in 44 + let hint_opt = 45 + let@ addr = Option.bind addr_opt in 46 + let@ pos = Option.bind @@ pos_of_node node in 47 + inlay_hint_for_addr ~config ~forest ~pos addr 48 + in 49 + let hints = extract_inlayable_hints ~config ~forest rest in 50 + list_of_option hint_opt @ hints 51 + 52 + 18 53 let compute (params : L.InlayHintParams.t) : L.InlayHint.t list option = 19 54 let Lsp_state.{forest; _} = Lsp_state.get () in 20 55 let config = forest.config in 21 56 let uri = URI_scheme.lsp_uri_to_uri ~base: config.url params.textDocument.uri in 22 - let@ {nodes; _} = Option.map @~ Option.bind forest.={uri} Tree.to_code in 23 - let@ (Range.{loc; _} as node) = List.filter_map @~ Analysis.flatten nodes in 24 - match Option.map Range.view loc with 25 - | None | Some (`End_of_file _) -> None 26 - | Some (`Range (_, pos)) -> 27 - let@ {value = str; _} = Option.bind @@ Analysis.extract_addr node in 28 - let uri = URI_scheme.named_uri ~base: config.url str in 29 - let@ {frontmatter; _} = Option.bind @@ State.get_article uri forest in 30 - let@ title = Option.map @~ frontmatter.title in 31 - let content = " " ^ Plain_text_client.string_of_content ~forest title in 32 - L.InlayHint.create ~position: (Lsp_shims.Loc.lsp_pos_of_pos pos) ~label: (`String content) () 57 + let@ {nodes; _} = Option.map @~ Option.bind forest.={uri} Tree.to_syn in 58 + extract_inlayable_hints ~config ~forest nodes