@@ -308,6 +308,9 @@ find_completions(
308
308
% % Check for "-export(["
309
309
[{'[' , _ }, {'(' , _ }, {atom , _ , export }, {'-' , _ }] ->
310
310
unexported_definitions (Document , function );
311
+ % % Check for "-nifs(["
312
+ [{'[' , _ }, {'(' , _ }, {atom , _ , nifs }, {'-' , _ }] ->
313
+ definitions (Document , function , arity_only , false );
311
314
% % Check for "-export_type(["
312
315
[{'[' , _ }, {'(' , _ }, {atom , _ , export_type }, {'-' , _ }] ->
313
316
unexported_definitions (Document , type_definition );
@@ -353,8 +356,18 @@ find_completions(
353
356
{ItemFormat , POIKind } = completion_context (Document , Line , Column , Tokens ),
354
357
case ItemFormat of
355
358
arity_only ->
356
- % % Only complete unexported definitions when in export
357
- unexported_definitions (Document , POIKind );
359
+ #{text := Text } = Document ,
360
+ case
361
+ is_in (Document , Line , Column , [nifs ]) orelse
362
+ is_in_heuristic (Text , <<" nifs" >>, Line - 1 )
363
+ of
364
+ true ->
365
+ definitions (Document , POIKind , ItemFormat , false );
366
+ _ ->
367
+ % % Only complete unexported definitions when in
368
+ % % export
369
+ unexported_definitions (Document , POIKind )
370
+ end ;
358
371
_ ->
359
372
case complete_record_field (Opts , Tokens ) of
360
373
[] ->
@@ -495,6 +508,7 @@ attributes(Document, Line) ->
495
508
snippet (attribute_include ),
496
509
snippet (attribute_include_lib ),
497
510
snippet (attribute_on_load ),
511
+ snippet (attribute_nifs ),
498
512
snippet (attribute_opaque ),
499
513
snippet (attribute_record ),
500
514
snippet (attribute_type ),
@@ -579,6 +593,11 @@ snippet(attribute_on_load) ->
579
593
<<" -on_load()." >>,
580
594
<<" on_load(${1:Function})." >>
581
595
);
596
+ snippet (attribute_nifs ) ->
597
+ snippet (
598
+ <<" -nifs()." >>,
599
+ <<" nifs([${1:}])." >>
600
+ );
582
601
snippet (attribute_export_type ) ->
583
602
snippet (<<" -export_type()." >>, <<" export_type([${1:}])." >>);
584
603
snippet (attribute_feature ) ->
@@ -787,7 +806,7 @@ definitions(Document, POIKind, ItemFormat, ExportedOnly) ->
787
806
{item_format (), els_poi :poi_kind () | any }.
788
807
completion_context (#{text := Text } = Document , Line , Column , Tokens ) ->
789
808
ItemFormat =
790
- case is_in_export (Document , Line , Column ) of
809
+ case is_in_mfa_list_attr (Document , Line , Column ) of
791
810
true ->
792
811
arity_only ;
793
812
false ->
@@ -811,7 +830,7 @@ completion_context(#{text := Text} = Document, Line, Column, Tokens) ->
811
830
true ->
812
831
type_definition ;
813
832
false ->
814
- case is_in (Document , Line , Column , [export , function ]) of
833
+ case is_in (Document , Line , Column , [export , nifs , function ]) of
815
834
true ->
816
835
function ;
817
836
false ->
@@ -820,25 +839,30 @@ completion_context(#{text := Text} = Document, Line, Column, Tokens) ->
820
839
end ,
821
840
{ItemFormat , POIKind }.
822
841
823
- -spec is_in_export (els_dt_document :item (), line (), column ()) -> boolean ().
824
- is_in_export (#{text := Text } = Document , Line , Column ) ->
825
- % % Sometimes is_in will be confused because -export() failed to be parsed.
842
+ -spec is_in_mfa_list_attr (els_dt_document :item (), line (), column ()) -> boolean ().
843
+ is_in_mfa_list_attr (#{text := Text } = Document , Line , Column ) ->
844
+ % % Sometimes is_in will be confused because e.g. -export() failed to be parsed.
826
845
% % In such case we can use a heuristic to determine if we are inside
827
846
% % an export.
828
- is_in (Document , Line , Column , [export , export_type ]) orelse
829
- is_in_export_heuristic (Text , Line - 1 ).
847
+ is_in (Document , Line , Column , [export , export_type , nifs ]) orelse
848
+ is_in_mfa_list_attr_heuristic (Text , Line - 1 ).
849
+
850
+ -spec is_in_mfa_list_attr_heuristic (binary (), line ()) -> boolean ().
851
+ is_in_mfa_list_attr_heuristic (Text , Line ) ->
852
+ is_in_heuristic (Text , <<" export" >>, Line ) orelse
853
+ is_in_heuristic (Text , <<" nifs" >>, Line ).
830
854
831
- -spec is_in_export_heuristic (binary (), line ()) -> boolean ().
832
- is_in_export_heuristic (Text , Line ) ->
855
+ -spec is_in_heuristic (binary (), binary (), line ()) -> boolean ().
856
+ is_in_heuristic (Text , Attr , Line ) ->
857
+ Len = byte_size (Attr ),
833
858
case els_text :line (Text , Line ) of
834
- <<" -export " , _ /binary >> ->
835
- % % In export
859
+ <<" -" , Attr : Len / binary , _ /binary >> ->
860
+ % % In Attr
836
861
true ;
837
862
<<" " , _ /binary >> when Line > 1 ->
838
863
% % Indented line, continue to search previous line
839
- is_in_export_heuristic (Text , Line - 1 );
864
+ is_in_heuristic (Text , Attr , Line - 1 );
840
865
_ ->
841
- % % Not in export
842
866
false
843
867
end .
844
868
@@ -1409,12 +1433,12 @@ is_exported_heuristic_test_() ->
1409
1433
" -define(FOO, foo).\n "
1410
1434
>>,
1411
1435
[
1412
- ? _assertEqual (false , is_in_export_heuristic (Text , 0 )),
1413
- ? _assertEqual (true , is_in_export_heuristic (Text , 1 )),
1414
- ? _assertEqual (true , is_in_export_heuristic (Text , 2 )),
1415
- ? _assertEqual (true , is_in_export_heuristic (Text , 3 )),
1416
- ? _assertEqual (true , is_in_export_heuristic (Text , 4 )),
1417
- ? _assertEqual (false , is_in_export_heuristic (Text , 5 ))
1436
+ ? _assertEqual (false , is_in_mfa_list_attr_heuristic (Text , 0 )),
1437
+ ? _assertEqual (true , is_in_mfa_list_attr_heuristic (Text , 1 )),
1438
+ ? _assertEqual (true , is_in_mfa_list_attr_heuristic (Text , 2 )),
1439
+ ? _assertEqual (true , is_in_mfa_list_attr_heuristic (Text , 3 )),
1440
+ ? _assertEqual (true , is_in_mfa_list_attr_heuristic (Text , 4 )),
1441
+ ? _assertEqual (false , is_in_mfa_list_attr_heuristic (Text , 5 ))
1418
1442
].
1419
1443
1420
1444
-endif .
0 commit comments