diff options
Diffstat (limited to 'crates/ra_ide/src/completion/presentation.rs')
-rw-r--r-- | crates/ra_ide/src/completion/presentation.rs | 466 |
1 files changed, 136 insertions, 330 deletions
diff --git a/crates/ra_ide/src/completion/presentation.rs b/crates/ra_ide/src/completion/presentation.rs index f472b9529..fd12673b2 100644 --- a/crates/ra_ide/src/completion/presentation.rs +++ b/crates/ra_ide/src/completion/presentation.rs | |||
@@ -383,12 +383,14 @@ impl Builder { | |||
383 | return self; | 383 | return self; |
384 | } | 384 | } |
385 | if ctx.use_item_syntax.is_some() || ctx.is_call { | 385 | if ctx.use_item_syntax.is_some() || ctx.is_call { |
386 | mark::hit!(no_parens_in_use_item); | ||
386 | return self; | 387 | return self; |
387 | } | 388 | } |
388 | 389 | ||
389 | // Don't add parentheses if the expected type is some function reference. | 390 | // Don't add parentheses if the expected type is some function reference. |
390 | if let Some(ty) = &ctx.expected_type { | 391 | if let Some(ty) = &ctx.expected_type { |
391 | if ty.is_fn() { | 392 | if ty.is_fn() { |
393 | mark::hit!(no_call_parens_if_fn_ptr_needed); | ||
392 | return self; | 394 | return self; |
393 | } | 395 | } |
394 | } | 396 | } |
@@ -413,7 +415,10 @@ impl Builder { | |||
413 | .sep_by(", "); | 415 | .sep_by(", "); |
414 | format!("{}({})$0", name, function_params_snippet) | 416 | format!("{}({})$0", name, function_params_snippet) |
415 | } | 417 | } |
416 | _ => format!("{}($0)", name), | 418 | _ => { |
419 | mark::hit!(suppress_arg_snippets); | ||
420 | format!("{}($0)", name) | ||
421 | } | ||
417 | }; | 422 | }; |
418 | 423 | ||
419 | (snippet, format!("{}(…)", name)) | 424 | (snippet, format!("{}(…)", name)) |
@@ -460,7 +465,7 @@ mod tests { | |||
460 | use test_utils::mark; | 465 | use test_utils::mark; |
461 | 466 | ||
462 | use crate::completion::{ | 467 | use crate::completion::{ |
463 | test_utils::{check_edit, do_completion, do_completion_with_options}, | 468 | test_utils::{check_edit, check_edit_with_config, do_completion}, |
464 | CompletionConfig, CompletionItem, CompletionKind, | 469 | CompletionConfig, CompletionItem, CompletionKind, |
465 | }; | 470 | }; |
466 | 471 | ||
@@ -468,13 +473,6 @@ mod tests { | |||
468 | do_completion(ra_fixture, CompletionKind::Reference) | 473 | do_completion(ra_fixture, CompletionKind::Reference) |
469 | } | 474 | } |
470 | 475 | ||
471 | fn do_reference_completion_with_options( | ||
472 | ra_fixture: &str, | ||
473 | options: CompletionConfig, | ||
474 | ) -> Vec<CompletionItem> { | ||
475 | do_completion_with_options(ra_fixture, CompletionKind::Reference, &options) | ||
476 | } | ||
477 | |||
478 | #[test] | 476 | #[test] |
479 | fn enum_detail_includes_names_for_record() { | 477 | fn enum_detail_includes_names_for_record() { |
480 | assert_debug_snapshot!( | 478 | assert_debug_snapshot!( |
@@ -647,6 +645,7 @@ fn no_args() {} | |||
647 | fn main() { no_args()$0 } | 645 | fn main() { no_args()$0 } |
648 | "#, | 646 | "#, |
649 | ); | 647 | ); |
648 | |||
650 | check_edit( | 649 | check_edit( |
651 | "with_args", | 650 | "with_args", |
652 | r#" | 651 | r#" |
@@ -658,6 +657,7 @@ fn with_args(x: i32, y: String) {} | |||
658 | fn main() { with_args(${1:x}, ${2:y})$0 } | 657 | fn main() { with_args(${1:x}, ${2:y})$0 } |
659 | "#, | 658 | "#, |
660 | ); | 659 | ); |
660 | |||
661 | check_edit( | 661 | check_edit( |
662 | "foo", | 662 | "foo", |
663 | r#" | 663 | r#" |
@@ -675,6 +675,45 @@ impl S { | |||
675 | fn bar(s: &S) { s.foo()$0 } | 675 | fn bar(s: &S) { s.foo()$0 } |
676 | "#, | 676 | "#, |
677 | ); | 677 | ); |
678 | |||
679 | check_edit( | ||
680 | "foo", | ||
681 | r#" | ||
682 | struct S {} | ||
683 | impl S { | ||
684 | fn foo(&self, x: i32) {} | ||
685 | } | ||
686 | fn bar(s: &S) { | ||
687 | s.f<|> | ||
688 | } | ||
689 | "#, | ||
690 | r#" | ||
691 | struct S {} | ||
692 | impl S { | ||
693 | fn foo(&self, x: i32) {} | ||
694 | } | ||
695 | fn bar(s: &S) { | ||
696 | s.foo(${1:x})$0 | ||
697 | } | ||
698 | "#, | ||
699 | ); | ||
700 | } | ||
701 | |||
702 | #[test] | ||
703 | fn suppress_arg_snippets() { | ||
704 | mark::check!(suppress_arg_snippets); | ||
705 | check_edit_with_config( | ||
706 | "with_args", | ||
707 | r#" | ||
708 | fn with_args(x: i32, y: String) {} | ||
709 | fn main() { with_<|> } | ||
710 | "#, | ||
711 | r#" | ||
712 | fn with_args(x: i32, y: String) {} | ||
713 | fn main() { with_args($0) } | ||
714 | "#, | ||
715 | &CompletionConfig { add_call_argument_snippets: false, ..CompletionConfig::default() }, | ||
716 | ); | ||
678 | } | 717 | } |
679 | 718 | ||
680 | #[test] | 719 | #[test] |
@@ -694,294 +733,111 @@ fn main() { foo(${1:foo}, ${2:bar}, ${3:ho_ge_})$0 } | |||
694 | 733 | ||
695 | #[test] | 734 | #[test] |
696 | fn inserts_parens_for_tuple_enums() { | 735 | fn inserts_parens_for_tuple_enums() { |
697 | assert_debug_snapshot!( | 736 | check_edit( |
698 | do_reference_completion( | 737 | "Some", |
699 | r" | 738 | r#" |
700 | enum Option<T> { Some(T), None } | 739 | enum Option<T> { Some(T), None } |
701 | use Option::*; | 740 | use Option::*; |
702 | fn main() -> Option<i32> { | 741 | fn main() -> Option<i32> { |
703 | Som<|> | 742 | Som<|> |
704 | } | 743 | } |
705 | " | 744 | "#, |
706 | ), | 745 | r#" |
707 | @r###" | 746 | enum Option<T> { Some(T), None } |
708 | [ | 747 | use Option::*; |
709 | CompletionItem { | 748 | fn main() -> Option<i32> { |
710 | label: "None", | 749 | Some($0) |
711 | source_range: 79..82, | 750 | } |
712 | delete: 79..82, | 751 | "#, |
713 | insert: "None", | ||
714 | kind: EnumVariant, | ||
715 | detail: "()", | ||
716 | }, | ||
717 | CompletionItem { | ||
718 | label: "Option", | ||
719 | source_range: 79..82, | ||
720 | delete: 79..82, | ||
721 | insert: "Option", | ||
722 | kind: Enum, | ||
723 | }, | ||
724 | CompletionItem { | ||
725 | label: "Some(…)", | ||
726 | source_range: 79..82, | ||
727 | delete: 79..82, | ||
728 | insert: "Some($0)", | ||
729 | kind: EnumVariant, | ||
730 | lookup: "Some", | ||
731 | detail: "(T)", | ||
732 | trigger_call_info: true, | ||
733 | }, | ||
734 | CompletionItem { | ||
735 | label: "main()", | ||
736 | source_range: 79..82, | ||
737 | delete: 79..82, | ||
738 | insert: "main()$0", | ||
739 | kind: Function, | ||
740 | lookup: "main", | ||
741 | detail: "fn main() -> Option<i32>", | ||
742 | }, | ||
743 | ] | ||
744 | "### | ||
745 | ); | 752 | ); |
746 | assert_debug_snapshot!( | 753 | check_edit( |
747 | do_reference_completion( | 754 | "Some", |
748 | r" | 755 | r#" |
749 | enum Option<T> { Some(T), None } | 756 | enum Option<T> { Some(T), None } |
750 | use Option::*; | 757 | use Option::*; |
751 | fn main(value: Option<i32>) { | 758 | fn main(value: Option<i32>) { |
752 | match value { | 759 | match value { |
753 | Som<|> | 760 | Som<|> |
754 | } | 761 | } |
755 | } | 762 | } |
756 | " | 763 | "#, |
757 | ), | 764 | r#" |
758 | @r###" | 765 | enum Option<T> { Some(T), None } |
759 | [ | 766 | use Option::*; |
760 | CompletionItem { | 767 | fn main(value: Option<i32>) { |
761 | label: "None", | 768 | match value { |
762 | source_range: 104..107, | 769 | Some($0) |
763 | delete: 104..107, | 770 | } |
764 | insert: "None", | 771 | } |
765 | kind: EnumVariant, | 772 | "#, |
766 | detail: "()", | ||
767 | }, | ||
768 | CompletionItem { | ||
769 | label: "Option", | ||
770 | source_range: 104..107, | ||
771 | delete: 104..107, | ||
772 | insert: "Option", | ||
773 | kind: Enum, | ||
774 | }, | ||
775 | CompletionItem { | ||
776 | label: "Some(…)", | ||
777 | source_range: 104..107, | ||
778 | delete: 104..107, | ||
779 | insert: "Some($0)", | ||
780 | kind: EnumVariant, | ||
781 | lookup: "Some", | ||
782 | detail: "(T)", | ||
783 | trigger_call_info: true, | ||
784 | }, | ||
785 | ] | ||
786 | "### | ||
787 | ); | 773 | ); |
788 | } | 774 | } |
789 | 775 | ||
790 | #[test] | 776 | #[test] |
791 | fn no_call_parens_if_fn_ptr_needed() { | 777 | fn no_call_parens_if_fn_ptr_needed() { |
792 | assert_debug_snapshot!( | 778 | mark::check!(no_call_parens_if_fn_ptr_needed); |
793 | do_reference_completion( | 779 | check_edit( |
794 | r" | 780 | "foo", |
795 | fn somefn(with: u8, a: u8, lot: u8, of: u8, args: u8) {} | 781 | r#" |
782 | fn foo(foo: u8, bar: u8) {} | ||
783 | struct ManualVtable { f: fn(u8, u8) } | ||
796 | 784 | ||
797 | struct ManualVtable { | 785 | fn main() -> ManualVtable { |
798 | method: fn(u8, u8, u8, u8, u8), | 786 | ManualVtable { f: f<|> } |
799 | } | 787 | } |
788 | "#, | ||
789 | r#" | ||
790 | fn foo(foo: u8, bar: u8) {} | ||
791 | struct ManualVtable { f: fn(u8, u8) } | ||
800 | 792 | ||
801 | fn main() -> ManualVtable { | 793 | fn main() -> ManualVtable { |
802 | ManualVtable { | 794 | ManualVtable { f: foo } |
803 | method: some<|> | 795 | } |
804 | } | 796 | "#, |
805 | } | ||
806 | " | ||
807 | ), | ||
808 | @r###" | ||
809 | [ | ||
810 | CompletionItem { | ||
811 | label: "ManualVtable", | ||
812 | source_range: 182..186, | ||
813 | delete: 182..186, | ||
814 | insert: "ManualVtable", | ||
815 | kind: Struct, | ||
816 | }, | ||
817 | CompletionItem { | ||
818 | label: "main", | ||
819 | source_range: 182..186, | ||
820 | delete: 182..186, | ||
821 | insert: "main", | ||
822 | kind: Function, | ||
823 | detail: "fn main() -> ManualVtable", | ||
824 | }, | ||
825 | CompletionItem { | ||
826 | label: "somefn", | ||
827 | source_range: 182..186, | ||
828 | delete: 182..186, | ||
829 | insert: "somefn", | ||
830 | kind: Function, | ||
831 | detail: "fn somefn(with: u8, a: u8, lot: u8, of: u8, args: u8)", | ||
832 | }, | ||
833 | ] | ||
834 | "### | ||
835 | ); | 797 | ); |
836 | } | 798 | } |
837 | 799 | ||
838 | #[test] | 800 | #[test] |
839 | fn arg_snippets_for_method_call() { | 801 | fn no_parens_in_use_item() { |
840 | assert_debug_snapshot!( | 802 | mark::check!(no_parens_in_use_item); |
841 | do_reference_completion( | 803 | check_edit( |
842 | r" | 804 | "foo", |
843 | struct S {} | 805 | r#" |
844 | impl S { | 806 | mod m { pub fn foo() {} } |
845 | fn foo(&self, x: i32) {} | 807 | use crate::m::f<|>; |
846 | } | 808 | "#, |
847 | fn bar(s: &S) { | 809 | r#" |
848 | s.f<|> | 810 | mod m { pub fn foo() {} } |
849 | } | 811 | use crate::m::foo; |
850 | " | 812 | "#, |
851 | ), | ||
852 | @r###" | ||
853 | [ | ||
854 | CompletionItem { | ||
855 | label: "foo(…)", | ||
856 | source_range: 74..75, | ||
857 | delete: 74..75, | ||
858 | insert: "foo(${1:x})$0", | ||
859 | kind: Method, | ||
860 | lookup: "foo", | ||
861 | detail: "fn foo(&self, x: i32)", | ||
862 | trigger_call_info: true, | ||
863 | }, | ||
864 | ] | ||
865 | "### | ||
866 | ) | ||
867 | } | ||
868 | |||
869 | #[test] | ||
870 | fn no_arg_snippets_for_method_call() { | ||
871 | assert_debug_snapshot!( | ||
872 | do_reference_completion_with_options( | ||
873 | r" | ||
874 | struct S {} | ||
875 | impl S { | ||
876 | fn foo(&self, x: i32) {} | ||
877 | } | ||
878 | fn bar(s: &S) { | ||
879 | s.f<|> | ||
880 | } | ||
881 | ", | ||
882 | CompletionConfig { | ||
883 | add_call_argument_snippets: false, | ||
884 | .. Default::default() | ||
885 | } | ||
886 | ), | ||
887 | @r###" | ||
888 | [ | ||
889 | CompletionItem { | ||
890 | label: "foo(…)", | ||
891 | source_range: 74..75, | ||
892 | delete: 74..75, | ||
893 | insert: "foo($0)", | ||
894 | kind: Method, | ||
895 | lookup: "foo", | ||
896 | detail: "fn foo(&self, x: i32)", | ||
897 | trigger_call_info: true, | ||
898 | }, | ||
899 | ] | ||
900 | "### | ||
901 | ) | ||
902 | } | ||
903 | |||
904 | #[test] | ||
905 | fn dont_render_function_parens_in_use_item() { | ||
906 | assert_debug_snapshot!( | ||
907 | do_reference_completion( | ||
908 | " | ||
909 | //- /lib.rs | ||
910 | mod m { pub fn foo() {} } | ||
911 | use crate::m::f<|>; | ||
912 | " | ||
913 | ), | ||
914 | @r###" | ||
915 | [ | ||
916 | CompletionItem { | ||
917 | label: "foo", | ||
918 | source_range: 40..41, | ||
919 | delete: 40..41, | ||
920 | insert: "foo", | ||
921 | kind: Function, | ||
922 | detail: "pub fn foo()", | ||
923 | }, | ||
924 | ] | ||
925 | "### | ||
926 | ); | 813 | ); |
927 | } | 814 | } |
928 | 815 | ||
929 | #[test] | 816 | #[test] |
930 | fn dont_render_function_parens_if_already_call() { | 817 | fn no_parens_in_call() { |
931 | assert_debug_snapshot!( | 818 | check_edit( |
932 | do_reference_completion( | 819 | "foo", |
933 | " | 820 | r#" |
934 | //- /lib.rs | 821 | fn foo(x: i32) {} |
935 | fn frobnicate() {} | 822 | fn main() { f<|>(); } |
936 | fn main() { | 823 | "#, |
937 | frob<|>(); | 824 | r#" |
938 | } | 825 | fn foo(x: i32) {} |
939 | " | 826 | fn main() { foo(); } |
940 | ), | 827 | "#, |
941 | @r###" | ||
942 | [ | ||
943 | CompletionItem { | ||
944 | label: "frobnicate", | ||
945 | source_range: 35..39, | ||
946 | delete: 35..39, | ||
947 | insert: "frobnicate", | ||
948 | kind: Function, | ||
949 | detail: "fn frobnicate()", | ||
950 | }, | ||
951 | CompletionItem { | ||
952 | label: "main", | ||
953 | source_range: 35..39, | ||
954 | delete: 35..39, | ||
955 | insert: "main", | ||
956 | kind: Function, | ||
957 | detail: "fn main()", | ||
958 | }, | ||
959 | ] | ||
960 | "### | ||
961 | ); | 828 | ); |
962 | assert_debug_snapshot!( | 829 | check_edit( |
963 | do_reference_completion( | 830 | "foo", |
964 | " | 831 | r#" |
965 | //- /lib.rs | 832 | struct Foo; |
966 | struct Foo {} | 833 | impl Foo { fn foo(&self){} } |
967 | impl Foo { fn new() -> Foo {} } | 834 | fn f(foo: &Foo) { foo.f<|>(); } |
968 | fn main() { | 835 | "#, |
969 | Foo::ne<|>(); | 836 | r#" |
970 | } | 837 | struct Foo; |
971 | " | 838 | impl Foo { fn foo(&self){} } |
972 | ), | 839 | fn f(foo: &Foo) { foo.foo(); } |
973 | @r###" | 840 | "#, |
974 | [ | ||
975 | CompletionItem { | ||
976 | label: "new", | ||
977 | source_range: 67..69, | ||
978 | delete: 67..69, | ||
979 | insert: "new", | ||
980 | kind: Function, | ||
981 | detail: "fn new() -> Foo", | ||
982 | }, | ||
983 | ] | ||
984 | "### | ||
985 | ); | 841 | ); |
986 | } | 842 | } |
987 | 843 | ||
@@ -1450,54 +1306,4 @@ fn main() { foo(${1:foo}, ${2:bar}, ${3:ho_ge_})$0 } | |||
1450 | "### | 1306 | "### |
1451 | ); | 1307 | ); |
1452 | } | 1308 | } |
1453 | |||
1454 | #[test] | ||
1455 | fn no_keyword_autocompletion_on_line_comments() { | ||
1456 | assert_debug_snapshot!( | ||
1457 | do_completion( | ||
1458 | r" | ||
1459 | fn test() { | ||
1460 | let x = 2; // A comment<|> | ||
1461 | } | ||
1462 | ", | ||
1463 | CompletionKind::Keyword | ||
1464 | ), | ||
1465 | @r###" | ||
1466 | [] | ||
1467 | "### | ||
1468 | ); | ||
1469 | } | ||
1470 | |||
1471 | #[test] | ||
1472 | fn no_keyword_autocompletion_on_multi_line_comments() { | ||
1473 | assert_debug_snapshot!( | ||
1474 | do_completion( | ||
1475 | r" | ||
1476 | /* | ||
1477 | Some multi-line comment<|> | ||
1478 | */ | ||
1479 | ", | ||
1480 | CompletionKind::Keyword | ||
1481 | ), | ||
1482 | @r###" | ||
1483 | [] | ||
1484 | "### | ||
1485 | ); | ||
1486 | } | ||
1487 | |||
1488 | #[test] | ||
1489 | fn no_keyword_autocompletion_on_doc_comments() { | ||
1490 | assert_debug_snapshot!( | ||
1491 | do_completion( | ||
1492 | r" | ||
1493 | /// Some doc comment | ||
1494 | /// let test<|> = 1 | ||
1495 | ", | ||
1496 | CompletionKind::Keyword | ||
1497 | ), | ||
1498 | @r###" | ||
1499 | [] | ||
1500 | "### | ||
1501 | ); | ||
1502 | } | ||
1503 | } | 1309 | } |