@@ -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
[] ->
@@ -476,6 +489,7 @@ attributes(Document, Line) ->
476
489
snippet (attribute_include ),
477
490
snippet (attribute_include_lib ),
478
491
snippet (attribute_on_load ),
492
+ snippet (attribute_nifs ),
479
493
snippet (attribute_opaque ),
480
494
snippet (attribute_record ),
481
495
snippet (attribute_type ),
@@ -562,6 +576,11 @@ snippet(attribute_on_load) ->
562
576
<<" -on_load()." >>,
563
577
<<" on_load(${1:Function})." >>
564
578
);
579
+ snippet (attribute_nifs ) ->
580
+ snippet (
581
+ <<" -nifs()." >>,
582
+ <<" nifs([${1:}])." >>
583
+ );
565
584
snippet (attribute_export_type ) ->
566
585
snippet (<<" -export_type()." >>, <<" export_type([${1:}])." >>);
567
586
snippet (attribute_feature ) ->
@@ -770,7 +789,7 @@ definitions(Document, POIKind, ItemFormat, ExportedOnly) ->
770
789
{item_format (), els_poi :poi_kind () | any }.
771
790
completion_context (#{text := Text } = Document , Line , Column , Tokens ) ->
772
791
ItemFormat =
773
- case is_in_export (Document , Line , Column ) of
792
+ case is_in_mfa_list_attr (Document , Line , Column ) of
774
793
true ->
775
794
arity_only ;
776
795
false ->
@@ -794,7 +813,7 @@ completion_context(#{text := Text} = Document, Line, Column, Tokens) ->
794
813
true ->
795
814
type_definition ;
796
815
false ->
797
- case is_in (Document , Line , Column , [export , function ]) of
816
+ case is_in (Document , Line , Column , [export , nifs , function ]) of
798
817
true ->
799
818
function ;
800
819
false ->
@@ -803,25 +822,30 @@ completion_context(#{text := Text} = Document, Line, Column, Tokens) ->
803
822
end ,
804
823
{ItemFormat , POIKind }.
805
824
806
- -spec is_in_export (els_dt_document :item (), line (), column ()) -> boolean ().
807
- is_in_export (#{text := Text } = Document , Line , Column ) ->
808
- % % Sometimes is_in will be confused because -export() failed to be parsed.
825
+ -spec is_in_mfa_list_attr (els_dt_document :item (), line (), column ()) -> boolean ().
826
+ is_in_mfa_list_attr (#{text := Text } = Document , Line , Column ) ->
827
+ % % Sometimes is_in will be confused because e.g. -export() failed to be parsed.
809
828
% % In such case we can use a heuristic to determine if we are inside
810
829
% % an export.
811
- is_in (Document , Line , Column , [export , export_type ]) orelse
812
- is_in_export_heuristic (Text , Line - 1 ).
830
+ is_in (Document , Line , Column , [export , export_type , nifs ]) orelse
831
+ is_in_mfa_list_attr_heuristic (Text , Line - 1 ).
832
+
833
+ -spec is_in_mfa_list_attr_heuristic (binary (), line ()) -> boolean ().
834
+ is_in_mfa_list_attr_heuristic (Text , Line ) ->
835
+ is_in_heuristic (Text , <<" export" >>, Line ) orelse
836
+ is_in_heuristic (Text , <<" nifs" >>, Line ).
813
837
814
- -spec is_in_export_heuristic (binary (), line ()) -> boolean ().
815
- is_in_export_heuristic (Text , Line ) ->
838
+ -spec is_in_heuristic (binary (), binary (), line ()) -> boolean ().
839
+ is_in_heuristic (Text , Attr , Line ) ->
840
+ Len = byte_size (Attr ),
816
841
case els_text :line (Text , Line ) of
817
- <<" -export " , _ /binary >> ->
818
- % % In export
842
+ <<" -" , Attr : Len / binary , _ /binary >> ->
843
+ % % In Attr
819
844
true ;
820
845
<<" " , _ /binary >> when Line > 1 ->
821
846
% % Indented line, continue to search previous line
822
- is_in_export_heuristic (Text , Line - 1 );
847
+ is_in_heuristic (Text , Attr , Line - 1 );
823
848
_ ->
824
- % % Not in export
825
849
false
826
850
end .
827
851
@@ -1392,12 +1416,12 @@ is_exported_heuristic_test_() ->
1392
1416
" -define(FOO, foo).\n "
1393
1417
>>,
1394
1418
[
1395
- ? _assertEqual (false , is_in_export_heuristic (Text , 0 )),
1396
- ? _assertEqual (true , is_in_export_heuristic (Text , 1 )),
1397
- ? _assertEqual (true , is_in_export_heuristic (Text , 2 )),
1398
- ? _assertEqual (true , is_in_export_heuristic (Text , 3 )),
1399
- ? _assertEqual (true , is_in_export_heuristic (Text , 4 )),
1400
- ? _assertEqual (false , is_in_export_heuristic (Text , 5 ))
1419
+ ? _assertEqual (false , is_in_mfa_list_attr_heuristic (Text , 0 )),
1420
+ ? _assertEqual (true , is_in_mfa_list_attr_heuristic (Text , 1 )),
1421
+ ? _assertEqual (true , is_in_mfa_list_attr_heuristic (Text , 2 )),
1422
+ ? _assertEqual (true , is_in_mfa_list_attr_heuristic (Text , 3 )),
1423
+ ? _assertEqual (true , is_in_mfa_list_attr_heuristic (Text , 4 )),
1424
+ ? _assertEqual (false , is_in_mfa_list_attr_heuristic (Text , 5 ))
1401
1425
].
1402
1426
1403
1427
-endif .
0 commit comments