mirror of
https://github.com/c-cube/linol.git
synced 2025-12-06 03:05:31 -05:00
98 lines
3.1 KiB
OCaml
98 lines
3.1 KiB
OCaml
let document = "let mem = ListLabels.mem\n\nlet _ = mem ~se" |> Merlin_kernel.Msource.make
|
|
|
|
let long_document_text =
|
|
{|let prefix_of_position ~short_path source position =
|
|
let open Prefix_parser in
|
|
match Msource.text source with
|
|
| "" -> ""
|
|
| text ->
|
|
let end_of_prefix =
|
|
let (`Offset index) = Msource.get_offset source position in
|
|
min (String.length text - 1) (index - 1)
|
|
in
|
|
let prefix_text =
|
|
let pos =
|
|
(*clamp the length of a line to process at 500 chars, this is just a
|
|
reasonable limit for regex performance*)
|
|
max 0 (end_of_prefix - 500)
|
|
in
|
|
String.sub text ~pos ~len:(end_of_prefix + 1 - pos)
|
|
(*because all whitespace is semantically the same we convert it all to
|
|
spaces for easier regex matching*)
|
|
|> String.rev_map ~f:(fun x -> if x = '\n' || x = '\t' then ' ' else x)
|
|
in
|
|
|
|
let reconstructed_prefix =
|
|
try_parse_with_regex prefix_text
|
|
|> Option.value ~default:""
|
|
|> String.rev_filter ~f:(fun x -> x <> ' ')
|
|
in
|
|
|
|
if short_path then
|
|
match String.split_on_char reconstructed_prefix ~sep:'.' |> List.last with
|
|
| Some s -> s
|
|
| None -> reconstructed_prefix
|
|
else reconstructed_prefix
|
|
|
|
let suffix_of_position source position =
|
|
match Msource.text source with
|
|
| "" -> ""
|
|
| text ->
|
|
let (`Offset index) = Msource.get_offset source position in
|
|
let len = String.length text in
|
|
if index >= len then ""
|
|
else
|
|
let from = index in
|
|
let len =
|
|
let ident_char = function
|
|
| 'a' .. 'z' | 'A' .. 'Z' | '0' .. '9' | '\'' | '_' -> true
|
|
| _ -> false
|
|
in
|
|
let until =
|
|
String.findi ~from text ~f:(fun c -> not (ident_char c))
|
|
|> Option.value ~default:len
|
|
in
|
|
until - from
|
|
in
|
|
String.sub text ~pos:from ~len
|
|
|
|
let reconstruct_ident source position =
|
|
let prefix = prefix_of_position ~short_path:false source position in
|
|
let suffix = suffix_of_position source position in
|
|
let ident = prefix ^ suffix in
|
|
Option.some_if (ident <> "") ident
|
|
|
|
let range_prefix (lsp_position : Position.t) prefix : Range.t =
|
|
let start =
|
|
let len = String.length prefix in
|
|
let character = lsp_position.character - len in
|
|
{ lsp_position with character }
|
|
in
|
|
{ Range.start; end_ = lsp_position }
|
|
|
|
let sortText_of_index idx = Printf.sprintf "%04d" idx
|
|
|
|
module Complete_by_prefix = struct
|
|
let completionItem_of_completion_entry idx
|
|
(entry : Query_protocol.Compl.entry) ~compl_params ~range ~deprecated =
|
|
let kind = completion_kind entry.kind in
|
|
let textEdit = `TextEdit { TextEdit.range; newText = entry.name } in
|
|
CompletionItem.create
|
|
~label:entry.name
|
|
?kind
|
|
~detail:entry.desc
|
|
?deprecated:(Option.some_if deprecated entry.deprecated)
|
|
(* Without this field the client is not forced to respect the order
|
|
provided by merlin. *)
|
|
~sortText:(sortText_of_index idx)
|
|
?data:compl_params
|
|
~textEdit
|
|
()
|
|
|
|
let dispatch_cmd ~prefix position pipeline =
|
|
let complete =
|
|
Query_protocol.Complete_prefix (prefix, position, [], false, true)
|
|
in
|
|
Query_commands.dispatch pipeline comp
|
|
|}
|
|
;;
|