ocaml
0
fork

Configure Feed

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

language server: add \date autocompletion

+85 -69
+85 -69
lib/language_server/Completion.ml
··· 21 21 | New_addr 22 22 | Assets 23 23 | Visible 24 + | Date 24 25 [@@deriving show] 25 26 26 27 module S = Set.Make(struct ··· 70 71 | Prev (Asai.Range.{value = Code.Ident ["route-asset"]; _}, _) 71 72 | Prev (_, Asai.Range.{value = Code.Ident ["route-asset"]; _}) -> 72 73 Some Assets 73 - | Prev (_, _) 74 - | Parent _ 75 - | Top _ -> 76 - None 74 + | Prev _ | Parent _ | Top _ -> None 77 75 in 78 76 let syn (context : Syn.node Range.located Analysis.Context.t) = 79 77 match context with 80 - | (Top {value = Route_asset; _}) -> Some Assets 81 - | (Prev (_, {value = Route_asset; _;})) -> Some Assets 78 + | Top {value = Route_asset; _} -> Some Assets 79 + | Prev (_, {value = Route_asset; _;}) -> Some Assets 82 80 | _ -> None 83 81 in 84 82 {text; code; syn} 85 83 84 + let date_completion : completion_kind = 85 + let text word_before = 86 + if Str.(string_match (regexp {|.*date.*|}) word_before 0) then 87 + Some Date 88 + else None 89 + in 90 + let code (context : _ Analysis.Context.t) = 91 + match context with 92 + | Prev (Asai.Range.{value = Code.Ident ["date"]; _}, _) 93 + | Prev (_, Asai.Range.{value = Code.Ident ["date"]; _}) -> 94 + Some Date 95 + | Prev _ | Parent _ | Top _ -> None 96 + in 97 + let syn (_context : Syn.node Range.located Analysis.Context.t) = None in 98 + {text; code; syn} 99 + 86 100 let uri_completion : completion_kind = 87 101 let text word_before = 88 102 if Str.(string_match (regexp {|.*]($|}) word_before 0) ··· 91 105 Some Addrs 92 106 else None 93 107 in 94 - let code (context : _ Analysis.Context.t) = 95 - match context with 96 - | Prev (_, _) 97 - | Parent _ 98 - | Top _ -> 99 - None 100 - in 101 - let syn (context : Syn.node Range.located Analysis.Context.t) = 102 - match context with 103 - | _ -> None 104 - in 108 + let code (_context : _ Analysis.Context.t) = None in 109 + let syn (_context : Syn.node Range.located Analysis.Context.t) = None in 105 110 {text; code; syn} 106 111 107 112 let new_uri_completion : completion_kind = ··· 119 124 asset_completion; 120 125 subtree_completion; 121 126 new_uri_completion; 127 + date_completion; 122 128 ] 123 129 in 124 130 let code_opt = Tree.to_code t in ··· 149 155 fun acc a -> 150 156 match a with 151 157 | None -> acc 152 - | Some compl -> 153 - S.add compl acc 158 + | Some compl -> S.add compl acc 154 159 end 155 160 S.empty 156 161 [ ··· 211 216 212 217 let insert_text path = String.concat "/" path 213 218 214 - let asset_completions ~(config : Config.t) () = 219 + let asset_completions ~(config : Config.t) = 215 220 let asset_dirs = config.assets in 216 221 let paths = List.of_seq @@ Hashtbl.to_seq_keys Asset_router.router in 217 222 let@ asset_path = List.filter_map @~ paths in ··· 307 312 ~label 308 313 () 309 314 315 + let addr_completions ~(forest : State.t) : L.CompletionItem.t list = 316 + List.of_seq @@ 317 + let@ uri, tree = Seq.map @~ URI.Tbl.to_seq forest.index in 318 + let frontmatter = Tree.get_frontmatter tree in 319 + let title = Option.map (State.get_expanded_title @~ forest) frontmatter in 320 + let render = Plain_text_client.string_of_content ~forest in 321 + let documentation = 322 + let taxon = Option.bind frontmatter (fun fm -> fm.taxon) in 323 + let content = 324 + Format.asprintf 325 + {|%s\n %s\n |} 326 + (Option.fold ~none: "" ~some: (fun s -> Format.asprintf "# %s" (render s)) title) 327 + (Option.fold ~none: "" ~some: (fun s -> Format.asprintf "taxon: %s" (render s)) taxon) 328 + in 329 + Some (`String content) 330 + in 331 + let insertText = URI_scheme.name uri in 332 + let title_text = Option.map render title in 333 + let filterText = Option.fold ~none: insertText ~some: (fun s -> insertText ^ " " ^ s) title_text in 334 + L.CompletionItem.create 335 + ?documentation 336 + ~label: (Format.(asprintf "%a (%s)" (pp_print_option pp_print_string) title_text (URI_scheme.name uri))) 337 + ~insertText 338 + ~filterText 339 + () 340 + 341 + let new_addr_completions ~(forest : State.t) : L.CompletionItem.t list = 342 + let next mode = URI_util.next_uri ~prefix: None ~mode ~forest in 343 + [ 344 + L.CompletionItem.create ~label: "random" ~insertText: (next `Random) (); 345 + L.CompletionItem.create ~label: "sequential" ~insertText: (next `Sequential) () 346 + ] 347 + 348 + let visible_completions ~(forest : State.t) ~(position : L.Position.t) : Tree.code option -> L.CompletionItem.t list = function 349 + | None -> 350 + List.append syntax_completions @@ 351 + let@ path, _ = List.map @~ List.of_seq @@ Trie.to_seq Expand.initial_visible_trie in 352 + L.CompletionItem.create 353 + ~insertText: "todo" 354 + ~label: (String.concat "/" path) 355 + () 356 + | Some {nodes; _} -> 357 + Analysis.get_visible ~position ~forest nodes 358 + |> Trie.to_seq 359 + |> List.of_seq 360 + |> List.filter_map make 361 + |> List.append syntax_completions 362 + 363 + let date_completions () : L.CompletionItem.t list = 364 + let now = Human_datetime.now () in 365 + let now_string = Format.asprintf "%a" Human_datetime.pp now in 366 + [ 367 + L.CompletionItem.create ~label: now_string ~insertText: now_string () 368 + ] 369 + 310 370 let compute ({context; position; textDocument = {uri}; _;}: L.CompletionParams.t) = 311 371 Logs.debug (fun m -> m "when computing completions for %s" (Lsp.Uri.to_string uri)); 312 372 let triggerCharacter = ··· 335 395 let items = 336 396 let@ completion = List.concat_map @~ S.to_list completion_types in 337 397 match completion with 338 - | Addrs -> 339 - List.of_seq @@ 340 - let@ uri, tree = Seq.map @~ URI.Tbl.to_seq forest.index in 341 - let frontmatter = Tree.get_frontmatter tree in 342 - let title = Option.map (State.get_expanded_title @~ forest) frontmatter in 343 - let render = Plain_text_client.string_of_content ~forest in 344 - let documentation = 345 - let taxon = Option.bind frontmatter (fun fm -> fm.taxon) in 346 - let content = 347 - Format.asprintf 348 - {|%s\n %s\n |} 349 - (Option.fold ~none: "" ~some: (fun s -> Format.asprintf "# %s" (render s)) title) 350 - (Option.fold ~none: "" ~some: (fun s -> Format.asprintf "taxon: %s" (render s)) taxon) 351 - in 352 - Some (`String content) 353 - in 354 - let insertText = URI_scheme.name uri in 355 - let title_text = Option.map render title in 356 - let filterText = Option.fold ~none: insertText ~some: (fun s -> insertText ^ " " ^ s) title_text in 357 - L.CompletionItem.create 358 - ?documentation 359 - ~label: (Format.(asprintf "%a (%s)" (pp_print_option pp_print_string) title_text (URI_scheme.name uri))) 360 - ~insertText 361 - ~filterText 362 - () 363 - | New_addr -> 364 - let next mode = URI_util.next_uri ~prefix: None ~mode ~forest in 365 - [ 366 - L.CompletionItem.create ~label: "random" ~insertText: (next `Random) (); 367 - L.CompletionItem.create ~label: "sequential" ~insertText: (next `Sequential) () 368 - ] 369 - | Assets -> asset_completions ~config () 370 - | Visible -> 371 - begin 372 - match code with 373 - | None -> 374 - List.append syntax_completions @@ 375 - let@ path, _ = List.map @~ List.of_seq @@ Trie.to_seq Expand.initial_visible_trie in 376 - L.CompletionItem.create 377 - ~insertText: "todo" 378 - ~label: (String.concat "/" path) 379 - () 380 - | Some {nodes; _} -> 381 - Analysis.get_visible ~position ~forest nodes 382 - |> Trie.to_seq 383 - |> List.of_seq 384 - |> List.filter_map make 385 - |> List.append syntax_completions 386 - end 398 + | Addrs -> addr_completions ~forest 399 + | New_addr -> new_addr_completions ~forest 400 + | Assets -> asset_completions ~config 401 + | Visible -> visible_completions ~forest ~position code 402 + | Date -> date_completions () 387 403 in 388 404 Logs.debug (fun m -> m "items: %d" (List.length items)); 389 405 Option.some @@ `CompletionList (L.CompletionList.create ~isIncomplete: false ~items ())