|
@@ -11,6 +11,13 @@ type hover_result = {
|
|
hexpected : WithType.t option;
|
|
hexpected : WithType.t option;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+type fields_result = {
|
|
|
|
+ fitems : CompletionItem.t list;
|
|
|
|
+ fkind : CompletionResultKind.t;
|
|
|
|
+ finsert_pos : pos option;
|
|
|
|
+ fsubject : placed_name option;
|
|
|
|
+}
|
|
|
|
+
|
|
type signature_kind =
|
|
type signature_kind =
|
|
| SKCall
|
|
| SKCall
|
|
| SKArrayAccess
|
|
| SKArrayAccess
|
|
@@ -23,7 +30,7 @@ type kind =
|
|
| DisplaySignatures of (((tsignature * CompletionType.ct_function) * documentation) list * int * int * signature_kind) option
|
|
| DisplaySignatures of (((tsignature * CompletionType.ct_function) * documentation) list * int * int * signature_kind) option
|
|
| DisplayHover of hover_result option
|
|
| DisplayHover of hover_result option
|
|
| DisplayPositions of pos list
|
|
| DisplayPositions of pos list
|
|
- | DisplayFields of (CompletionItem.t list * CompletionResultKind.t * pos option (* insert pos *)) option
|
|
|
|
|
|
+ | DisplayFields of fields_result option
|
|
| DisplayPackage of string list
|
|
| DisplayPackage of string list
|
|
|
|
|
|
exception DisplayException of kind
|
|
exception DisplayException of kind
|
|
@@ -35,17 +42,78 @@ let raise_metadata s = raise (DisplayException(Metadata s))
|
|
let raise_signatures l isig iarg kind = raise (DisplayException(DisplaySignatures(Some(l,isig,iarg,kind))))
|
|
let raise_signatures l isig iarg kind = raise (DisplayException(DisplaySignatures(Some(l,isig,iarg,kind))))
|
|
let raise_hover item expected p = raise (DisplayException(DisplayHover(Some {hitem = item;hpos = p;hexpected = expected})))
|
|
let raise_hover item expected p = raise (DisplayException(DisplayHover(Some {hitem = item;hpos = p;hexpected = expected})))
|
|
let raise_positions pl = raise (DisplayException(DisplayPositions pl))
|
|
let raise_positions pl = raise (DisplayException(DisplayPositions pl))
|
|
-let raise_fields ckl cr po = raise (DisplayException(DisplayFields(Some(ckl,cr,po))))
|
|
|
|
|
|
+let raise_fields ckl cr po = raise (DisplayException(DisplayFields(Some({fitems = ckl;fkind = cr;finsert_pos = po;fsubject = None}))))
|
|
|
|
+let raise_fields2 ckl cr po subject = raise (DisplayException(DisplayFields(Some({fitems = ckl;fkind = cr;finsert_pos = po;fsubject = Some subject}))))
|
|
let raise_package sl = raise (DisplayException(DisplayPackage sl))
|
|
let raise_package sl = raise (DisplayException(DisplayPackage sl))
|
|
|
|
|
|
(* global state *)
|
|
(* global state *)
|
|
let last_completion_result = ref (Array.make 0 (CompletionItem.make (ITModule ([],"")) None))
|
|
let last_completion_result = ref (Array.make 0 (CompletionItem.make (ITModule ([],"")) None))
|
|
|
|
+let last_completion_pos = ref None
|
|
|
|
+let max_completion_items = ref 0
|
|
|
|
+
|
|
|
|
+let filter_somehow ctx items subject kind po =
|
|
|
|
+ let ret = DynArray.create () in
|
|
|
|
+ let acc_types = DynArray.create () in
|
|
|
|
+ let subject = match subject with
|
|
|
|
+ | None -> ""
|
|
|
|
+ | Some(subject,_) -> String.lowercase subject
|
|
|
|
+ in
|
|
|
|
+ let subject_matches subject s =
|
|
|
|
+ let rec loop i =
|
|
|
|
+ if i < String.length subject then begin
|
|
|
|
+ ignore(String.index_from s i subject.[i]);
|
|
|
|
+ loop (i + 1)
|
|
|
|
+ end
|
|
|
|
+ in
|
|
|
|
+ try
|
|
|
|
+ loop 0;
|
|
|
|
+ true
|
|
|
|
+ with Not_found ->
|
|
|
|
+ false
|
|
|
|
+ in
|
|
|
|
+ let rec loop items index =
|
|
|
|
+ match items with
|
|
|
|
+ | _ when DynArray.length ret > !max_completion_items ->
|
|
|
|
+ ()
|
|
|
|
+ | item :: items ->
|
|
|
|
+ let name = String.lowercase (get_filter_name item) in
|
|
|
|
+ if subject_matches subject name then begin
|
|
|
|
+ (* Treat types with lowest priority. The assumption is that they are the only kind
|
|
|
|
+ which actually causes the limit to be hit, so we show everything else and then
|
|
|
|
+ fill in types. *)
|
|
|
|
+ match item.ci_kind with
|
|
|
|
+ | ITType _ ->
|
|
|
|
+ if DynArray.length ret + DynArray.length acc_types < !max_completion_items then
|
|
|
|
+ DynArray.add acc_types (item,index);
|
|
|
|
+ | _ ->
|
|
|
|
+ DynArray.add ret (CompletionItem.to_json ctx (Some index) item);
|
|
|
|
+ end;
|
|
|
|
+ loop items (index + 1)
|
|
|
|
+ | [] ->
|
|
|
|
+ ()
|
|
|
|
+ in
|
|
|
|
+ loop items 0;
|
|
|
|
+ DynArray.iter (fun (item,index) ->
|
|
|
|
+ if DynArray.length ret < !max_completion_items then
|
|
|
|
+ DynArray.add ret (CompletionItem.to_json ctx (Some index) item);
|
|
|
|
+ ) acc_types;
|
|
|
|
+ DynArray.to_list ret,DynArray.length ret = !max_completion_items
|
|
|
|
|
|
-let fields_to_json ctx fields kind po =
|
|
|
|
- let ja = List.map (CompletionItem.to_json ctx) fields in
|
|
|
|
|
|
+let fields_to_json ctx fields kind po subject =
|
|
last_completion_result := Array.of_list fields;
|
|
last_completion_result := Array.of_list fields;
|
|
|
|
+ let needs_filtering = !max_completion_items > 0 && Array.length !last_completion_result > !max_completion_items in
|
|
|
|
+ let ja,did_filter = if needs_filtering then
|
|
|
|
+ filter_somehow ctx fields subject kind po
|
|
|
|
+ else
|
|
|
|
+ List.mapi (fun i item -> CompletionItem.to_json ctx (Some i) item) fields,false
|
|
|
|
+ in
|
|
|
|
+ if did_filter then begin match subject with
|
|
|
|
+ | Some(_,p) -> last_completion_pos := Some p;
|
|
|
|
+ | None -> last_completion_pos := None
|
|
|
|
+ end;
|
|
let fl =
|
|
let fl =
|
|
("items",jarray ja) ::
|
|
("items",jarray ja) ::
|
|
|
|
+ ("isIncomplete",jbool did_filter) ::
|
|
("mode",CompletionResultKind.to_json ctx kind) ::
|
|
("mode",CompletionResultKind.to_json ctx kind) ::
|
|
(match po with None -> [] | Some p -> ["replaceRange",generate_pos_as_range (Parser.cut_pos_at_display p)]) in
|
|
(match po with None -> [] | Some p -> ["replaceRange",generate_pos_as_range (Parser.cut_pos_at_display p)]) in
|
|
jobject fl
|
|
jobject fl
|
|
@@ -107,14 +175,14 @@ let to_json ctx de =
|
|
jobject [
|
|
jobject [
|
|
"documentation",jopt jstring (CompletionItem.get_documentation hover.hitem);
|
|
"documentation",jopt jstring (CompletionItem.get_documentation hover.hitem);
|
|
"range",generate_pos_as_range hover.hpos;
|
|
"range",generate_pos_as_range hover.hpos;
|
|
- "item",CompletionItem.to_json ctx hover.hitem;
|
|
|
|
|
|
+ "item",CompletionItem.to_json ctx None hover.hitem;
|
|
"expected",expected;
|
|
"expected",expected;
|
|
]
|
|
]
|
|
| DisplayPositions pl ->
|
|
| DisplayPositions pl ->
|
|
jarray (List.map generate_pos_as_location pl)
|
|
jarray (List.map generate_pos_as_location pl)
|
|
| DisplayFields None ->
|
|
| DisplayFields None ->
|
|
jnull
|
|
jnull
|
|
- | DisplayFields Some(fields,kind,po) ->
|
|
|
|
- fields_to_json ctx fields kind po
|
|
|
|
|
|
+ | DisplayFields Some r ->
|
|
|
|
+ fields_to_json ctx r.fitems r.fkind r.finsert_pos r.fsubject
|
|
| DisplayPackage pack ->
|
|
| DisplayPackage pack ->
|
|
jarray (List.map jstring pack)
|
|
jarray (List.map jstring pack)
|