Mercurial > vim
comparison src/testdir/test_ins_complete.vim @ 26518:13ba00ef7687 v8.2.3788
patch 8.2.3788: lambda for option that is a function may be freed
Commit: https://github.com/vim/vim/commit/6ae8fae8696623b527c7fb22567f6a3705b2f0dd
Author: Yegappan Lakshmanan <yegappan@yahoo.com>
Date: Sun Dec 12 16:26:44 2021 +0000
patch 8.2.3788: lambda for option that is a function may be freed
Problem: Lambda for option that is a function may be garbage collected.
Solution: Set a reference in the funcref. (Yegappan Lakshmanan,
closes #9330)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sun, 12 Dec 2021 17:30:04 +0100 |
parents | 7eaf61a67d18 |
children | 33d680d372aa |
comparison
equal
deleted
inserted
replaced
26517:7dfc4c45f698 | 26518:13ba00ef7687 |
---|---|
873 func MycompleteFunc1(val, findstart, base) | 873 func MycompleteFunc1(val, findstart, base) |
874 call add(g:MycompleteFunc1_args, [a:val, a:findstart, a:base]) | 874 call add(g:MycompleteFunc1_args, [a:val, a:findstart, a:base]) |
875 return a:findstart ? 0 : [] | 875 return a:findstart ? 0 : [] |
876 endfunc | 876 endfunc |
877 | 877 |
878 " Test for using a function() | 878 let lines =<< trim END |
879 set completefunc=function('MycompleteFunc1',[10]) | 879 #" Test for using a function() |
880 new | only | 880 set completefunc=function('g:MycompleteFunc1',\ [10]) |
881 call setline(1, 'one') | 881 new | only |
882 let g:MycompleteFunc1_args = [] | 882 call setline(1, 'one') |
883 call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x') | 883 LET g:MycompleteFunc1_args = [] |
884 call assert_equal([[10, 1, ''], [10, 0, 'one']], g:MycompleteFunc1_args) | 884 call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x') |
885 bw! | 885 call assert_equal([[10, 1, ''], [10, 0, 'one']], g:MycompleteFunc1_args) |
886 | 886 bw! |
887 " Using a funcref variable to set 'completefunc' | 887 |
888 let Fn = function('MycompleteFunc1', [11]) | 888 #" Using a funcref variable to set 'completefunc' |
889 let &completefunc = Fn | 889 VAR Fn = function('g:MycompleteFunc1', [11]) |
890 new | only | 890 LET &completefunc = Fn |
891 call setline(1, 'two') | 891 new | only |
892 let g:MycompleteFunc1_args = [] | 892 call setline(1, 'two') |
893 call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x') | 893 LET g:MycompleteFunc1_args = [] |
894 call assert_equal([[11, 1, ''], [11, 0, 'two']], g:MycompleteFunc1_args) | 894 call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x') |
895 bw! | 895 call assert_equal([[11, 1, ''], [11, 0, 'two']], g:MycompleteFunc1_args) |
896 | 896 bw! |
897 " Using string(funcref_variable) to set 'completefunc' | 897 |
898 let Fn = function('MycompleteFunc1', [12]) | 898 #" Using string(funcref_variable) to set 'completefunc' |
899 let &completefunc = string(Fn) | 899 LET Fn = function('g:MycompleteFunc1', [12]) |
900 new | only | 900 LET &completefunc = string(Fn) |
901 call setline(1, 'two') | 901 new | only |
902 let g:MycompleteFunc1_args = [] | 902 call setline(1, 'two') |
903 call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x') | 903 LET g:MycompleteFunc1_args = [] |
904 call assert_equal([[12, 1, ''], [12, 0, 'two']], g:MycompleteFunc1_args) | 904 call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x') |
905 bw! | 905 call assert_equal([[12, 1, ''], [12, 0, 'two']], g:MycompleteFunc1_args) |
906 | 906 bw! |
907 " Test for using a funcref() | 907 |
908 set completefunc=funcref('MycompleteFunc1',\ [13]) | 908 #" Test for using a funcref() |
909 new | only | 909 set completefunc=funcref('g:MycompleteFunc1',\ [13]) |
910 call setline(1, 'three') | 910 new | only |
911 let g:MycompleteFunc1_args = [] | 911 call setline(1, 'three') |
912 call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x') | 912 LET g:MycompleteFunc1_args = [] |
913 call assert_equal([[13, 1, ''], [13, 0, 'three']], g:MycompleteFunc1_args) | 913 call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x') |
914 bw! | 914 call assert_equal([[13, 1, ''], [13, 0, 'three']], g:MycompleteFunc1_args) |
915 | 915 bw! |
916 " Using a funcref variable to set 'completefunc' | 916 |
917 let Fn = funcref('MycompleteFunc1', [14]) | 917 #" Using a funcref variable to set 'completefunc' |
918 let &completefunc = Fn | 918 LET Fn = funcref('g:MycompleteFunc1', [14]) |
919 new | only | 919 LET &completefunc = Fn |
920 call setline(1, 'four') | 920 new | only |
921 let g:MycompleteFunc1_args = [] | 921 call setline(1, 'four') |
922 call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x') | 922 LET g:MycompleteFunc1_args = [] |
923 call assert_equal([[14, 1, ''], [14, 0, 'four']], g:MycompleteFunc1_args) | 923 call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x') |
924 bw! | 924 call assert_equal([[14, 1, ''], [14, 0, 'four']], g:MycompleteFunc1_args) |
925 | 925 bw! |
926 " Using a string(funcref_variable) to set 'completefunc' | 926 |
927 let Fn = funcref('MycompleteFunc1', [15]) | 927 #" Using a string(funcref_variable) to set 'completefunc' |
928 let &completefunc = string(Fn) | 928 LET Fn = funcref('g:MycompleteFunc1', [15]) |
929 new | only | 929 LET &completefunc = string(Fn) |
930 call setline(1, 'four') | 930 new | only |
931 let g:MycompleteFunc1_args = [] | 931 call setline(1, 'four') |
932 call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x') | 932 LET g:MycompleteFunc1_args = [] |
933 call assert_equal([[15, 1, ''], [15, 0, 'four']], g:MycompleteFunc1_args) | 933 call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x') |
934 bw! | 934 call assert_equal([[15, 1, ''], [15, 0, 'four']], g:MycompleteFunc1_args) |
935 | 935 bw! |
936 " Test for using a lambda function | 936 |
937 set completefunc={a,\ b\ ->\ MycompleteFunc1(16,\ a,\ b)} | 937 #" Test for using a lambda function with set |
938 new | only | 938 VAR optval = "LSTART a, b LMIDDLE MycompleteFunc1(16, a, b) LEND" |
939 call setline(1, 'five') | 939 LET optval = substitute(optval, ' ', '\\ ', 'g') |
940 let g:MycompleteFunc1_args = [] | 940 exe "set completefunc=" .. optval |
941 call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x') | 941 new | only |
942 call assert_equal([[16, 1, ''], [16, 0, 'five']], g:MycompleteFunc1_args) | 942 call setline(1, 'five') |
943 bw! | 943 LET g:MycompleteFunc1_args = [] |
944 | 944 call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x') |
945 " Set 'completefunc' to a lambda expression | 945 call assert_equal([[16, 1, ''], [16, 0, 'five']], g:MycompleteFunc1_args) |
946 let &completefunc = {a, b -> MycompleteFunc1(17, a, b)} | 946 bw! |
947 new | only | 947 |
948 call setline(1, 'six') | 948 #" Set 'completefunc' to a lambda expression |
949 let g:MycompleteFunc1_args = [] | 949 LET &completefunc = LSTART a, b LMIDDLE MycompleteFunc1(17, a, b) LEND |
950 call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x') | 950 new | only |
951 call assert_equal([[17, 1, ''], [17, 0, 'six']], g:MycompleteFunc1_args) | 951 call setline(1, 'six') |
952 bw! | 952 LET g:MycompleteFunc1_args = [] |
953 | 953 call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x') |
954 " Set 'completefunc' to string(lambda_expression) | 954 call assert_equal([[17, 1, ''], [17, 0, 'six']], g:MycompleteFunc1_args) |
955 let &completefunc = '{a, b -> MycompleteFunc1(18, a, b)}' | 955 bw! |
956 new | only | 956 |
957 call setline(1, 'six') | 957 #" Set 'completefunc' to string(lambda_expression) |
958 let g:MycompleteFunc1_args = [] | 958 LET &completefunc = 'LSTART a, b LMIDDLE MycompleteFunc1(18, a, b) LEND' |
959 call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x') | 959 new | only |
960 call assert_equal([[18, 1, ''], [18, 0, 'six']], g:MycompleteFunc1_args) | 960 call setline(1, 'six') |
961 bw! | 961 LET g:MycompleteFunc1_args = [] |
962 | 962 call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x') |
963 " Set 'completefunc' to a variable with a lambda expression | 963 call assert_equal([[18, 1, ''], [18, 0, 'six']], g:MycompleteFunc1_args) |
964 let Lambda = {a, b -> MycompleteFunc1(19, a, b)} | 964 bw! |
965 let &completefunc = Lambda | 965 |
966 new | only | 966 #" Set 'completefunc' to a variable with a lambda expression |
967 call setline(1, 'seven') | 967 VAR Lambda = LSTART a, b LMIDDLE MycompleteFunc1(19, a, b) LEND |
968 let g:MycompleteFunc1_args = [] | 968 LET &completefunc = Lambda |
969 call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x') | 969 new | only |
970 call assert_equal([[19, 1, ''], [19, 0, 'seven']], g:MycompleteFunc1_args) | 970 call setline(1, 'seven') |
971 bw! | 971 LET g:MycompleteFunc1_args = [] |
972 | 972 call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x') |
973 " Set 'completefunc' to a string(variable with a lambda expression) | 973 call assert_equal([[19, 1, ''], [19, 0, 'seven']], g:MycompleteFunc1_args) |
974 let Lambda = {a, b -> MycompleteFunc1(20, a, b)} | 974 bw! |
975 let &completefunc = string(Lambda) | 975 |
976 new | only | 976 #" Set 'completefunc' to a string(variable with a lambda expression) |
977 call setline(1, 'seven') | 977 LET Lambda = LSTART a, b LMIDDLE MycompleteFunc1(20, a, b) LEND |
978 let g:MycompleteFunc1_args = [] | 978 LET &completefunc = string(Lambda) |
979 call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x') | 979 new | only |
980 call assert_equal([[20, 1, ''], [20, 0, 'seven']], g:MycompleteFunc1_args) | 980 call setline(1, 'seven') |
981 bw! | 981 LET g:MycompleteFunc1_args = [] |
982 | 982 call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x') |
983 " Test for using a lambda function with incorrect return value | 983 call assert_equal([[20, 1, ''], [20, 0, 'seven']], g:MycompleteFunc1_args) |
984 let Lambda = {s -> strlen(s)} | 984 bw! |
985 let &completefunc = Lambda | 985 |
986 new | only | 986 #" Test for using a lambda function with incorrect return value |
987 call setline(1, 'eight') | 987 LET Lambda = LSTART a, b LMIDDLE strlen(a) LEND |
988 call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x') | 988 LET &completefunc = Lambda |
989 bw! | 989 new | only |
990 | 990 call setline(1, 'eight') |
991 " Test for clearing the 'completefunc' option | 991 call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x') |
992 set completefunc='' | 992 bw! |
993 set completefunc& | 993 |
994 | 994 #" Test for clearing the 'completefunc' option |
995 call assert_fails("set completefunc=function('abc')", "E700:") | 995 set completefunc='' |
996 call assert_fails("set completefunc=funcref('abc')", "E700:") | 996 set completefunc& |
997 call assert_fails("set completefunc=function('abc')", "E700:") | |
998 call assert_fails("set completefunc=funcref('abc')", "E700:") | |
999 | |
1000 #" set 'completefunc' to a non-existing function | |
1001 func MycompleteFunc2(findstart, base) | |
1002 call add(g:MycompleteFunc2_args, [a:findstart, a:base]) | |
1003 return a:findstart ? 0 : [] | |
1004 endfunc | |
1005 set completefunc=MycompleteFunc2 | |
1006 call setline(1, 'five') | |
1007 call assert_fails("set completefunc=function('NonExistingFunc')", 'E700:') | |
1008 call assert_fails("LET &completefunc = function('NonExistingFunc')", 'E700:') | |
1009 LET g:MycompleteFunc2_args = [] | |
1010 call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x') | |
1011 call assert_equal([[1, ''], [0, 'five']], g:MycompleteFunc2_args) | |
1012 bw! | |
1013 END | |
1014 call CheckLegacyAndVim9Success(lines) | |
1015 | |
997 let &completefunc = {a -> 'abc'} | 1016 let &completefunc = {a -> 'abc'} |
998 call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x') | 1017 call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x') |
999 | 1018 |
1000 " Using Vim9 lambda expression in legacy context should fail | 1019 " Using Vim9 lambda expression in legacy context should fail |
1001 set completefunc=(a,\ b)\ =>\ g:MycompleteFunc1(21,\ a,\ b) | 1020 set completefunc=(a,\ b)\ =>\ MycompleteFunc1(21,\ a,\ b) |
1002 new | only | 1021 new | only |
1003 let g:MycompleteFunc1_args = [] | 1022 let g:MycompleteFunc1_args = [] |
1004 call assert_fails('call feedkeys("A\<C-X>\<C-U>\<Esc>", "x")', 'E117:') | 1023 call assert_fails('call feedkeys("A\<C-X>\<C-U>\<Esc>", "x")', 'E117:') |
1005 call assert_equal([], g:MycompleteFunc1_args) | 1024 call assert_equal([], g:MycompleteFunc1_args) |
1006 | 1025 |
1007 " set 'completefunc' to a non-existing function | 1026 " set 'completefunc' to a partial with dict. This used to cause a crash. |
1008 func MycompleteFunc2(findstart, base) | 1027 func SetCompleteFunc() |
1009 call add(g:MycompleteFunc2_args, [a:findstart, a:base]) | 1028 let params = {'complete': function('g:DictCompleteFunc')} |
1010 return a:findstart ? 0 : [] | 1029 let &completefunc = params.complete |
1011 endfunc | 1030 endfunc |
1012 set completefunc=MycompleteFunc2 | 1031 func g:DictCompleteFunc(_) dict |
1013 call setline(1, 'five') | 1032 endfunc |
1014 call assert_fails("set completefunc=function('NonExistingFunc')", 'E700:') | 1033 call SetCompleteFunc() |
1015 call assert_fails("let &completefunc = function('NonExistingFunc')", 'E700:') | 1034 new |
1016 let g:MycompleteFunc2_args = [] | 1035 call SetCompleteFunc() |
1017 call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x') | 1036 bw |
1018 call assert_equal([[1, ''], [0, 'five']], g:MycompleteFunc2_args) | 1037 call test_garbagecollect_now() |
1019 bw! | 1038 new |
1039 set completefunc= | |
1040 wincmd w | |
1041 set completefunc= | |
1042 %bw! | |
1043 delfunc g:DictCompleteFunc | |
1044 delfunc SetCompleteFunc | |
1020 | 1045 |
1021 " Vim9 tests | 1046 " Vim9 tests |
1022 let lines =<< trim END | 1047 let lines =<< trim END |
1023 vim9script | 1048 vim9script |
1024 | 1049 |
1025 # Test for using function() | 1050 # Test for using a def function with completefunc |
1026 def Vim9CompleteFunc(val: number, findstart: number, base: string): any | 1051 def Vim9CompleteFunc(val: number, findstart: number, base: string): any |
1027 add(g:Vim9completeFuncArgs, [val, findstart, base]) | 1052 add(g:Vim9completeFuncArgs, [val, findstart, base]) |
1028 return findstart ? 0 : [] | 1053 return findstart ? 0 : [] |
1029 enddef | 1054 enddef |
1030 set completefunc=function('Vim9CompleteFunc',\ [60]) | 1055 set completefunc=function('Vim9CompleteFunc',\ [60]) |
1032 setline(1, 'one') | 1057 setline(1, 'one') |
1033 g:Vim9completeFuncArgs = [] | 1058 g:Vim9completeFuncArgs = [] |
1034 feedkeys("A\<C-X>\<C-U>\<Esc>", 'x') | 1059 feedkeys("A\<C-X>\<C-U>\<Esc>", 'x') |
1035 assert_equal([[60, 1, ''], [60, 0, 'one']], g:Vim9completeFuncArgs) | 1060 assert_equal([[60, 1, ''], [60, 0, 'one']], g:Vim9completeFuncArgs) |
1036 bw! | 1061 bw! |
1037 | |
1038 # Test for using a lambda | |
1039 &completefunc = (a, b) => Vim9CompleteFunc(61, a, b) | |
1040 new | only | |
1041 setline(1, 'two') | |
1042 g:Vim9completeFuncArgs = [] | |
1043 feedkeys("A\<C-X>\<C-U>\<Esc>", 'x') | |
1044 assert_equal([[61, 1, ''], [61, 0, 'two']], g:Vim9completeFuncArgs) | |
1045 bw! | |
1046 | |
1047 # Test for using a string(lambda) | |
1048 &completefunc = '(a, b) => Vim9CompleteFunc(62, a, b)' | |
1049 new | only | |
1050 setline(1, 'two') | |
1051 g:Vim9completeFuncArgs = [] | |
1052 feedkeys("A\<C-X>\<C-U>\<Esc>", 'x') | |
1053 assert_equal([[62, 1, ''], [62, 0, 'two']], g:Vim9completeFuncArgs) | |
1054 bw! | |
1055 | |
1056 # Test for using a variable with a lambda expression | |
1057 var Fn: func = (a, b) => Vim9CompleteFunc(63, a, b) | |
1058 &completefunc = Fn | |
1059 new | only | |
1060 setline(1, 'three') | |
1061 g:Vim9completeFuncArgs = [] | |
1062 feedkeys("A\<C-X>\<C-U>\<Esc>", 'x') | |
1063 assert_equal([[63, 1, ''], [63, 0, 'three']], g:Vim9completeFuncArgs) | |
1064 bw! | |
1065 | |
1066 # Test for using a string(variable with a lambda expression) | |
1067 Fn = (a, b) => Vim9CompleteFunc(64, a, b) | |
1068 &completefunc = string(Fn) | |
1069 new | only | |
1070 setline(1, 'three') | |
1071 g:Vim9completeFuncArgs = [] | |
1072 feedkeys("A\<C-X>\<C-U>\<Esc>", 'x') | |
1073 assert_equal([[64, 1, ''], [64, 0, 'three']], g:Vim9completeFuncArgs) | |
1074 bw! | |
1075 END | 1062 END |
1076 call CheckScriptSuccess(lines) | 1063 call CheckScriptSuccess(lines) |
1077 | 1064 |
1078 " cleanup | 1065 " cleanup |
1079 delfunc MycompleteFunc1 | 1066 delfunc MycompleteFunc1 |
1087 func MyomniFunc1(val, findstart, base) | 1074 func MyomniFunc1(val, findstart, base) |
1088 call add(g:MyomniFunc1_args, [a:val, a:findstart, a:base]) | 1075 call add(g:MyomniFunc1_args, [a:val, a:findstart, a:base]) |
1089 return a:findstart ? 0 : [] | 1076 return a:findstart ? 0 : [] |
1090 endfunc | 1077 endfunc |
1091 | 1078 |
1092 " Test for using a function() | 1079 let lines =<< trim END |
1093 set omnifunc=function('MyomniFunc1',[10]) | 1080 #" Test for using a function() |
1094 new | only | 1081 set omnifunc=function('g:MyomniFunc1',\ [10]) |
1095 call setline(1, 'one') | 1082 new | only |
1096 let g:MyomniFunc1_args = [] | 1083 call setline(1, 'one') |
1097 call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x') | 1084 LET g:MyomniFunc1_args = [] |
1098 call assert_equal([[10, 1, ''], [10, 0, 'one']], g:MyomniFunc1_args) | 1085 call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x') |
1099 bw! | 1086 call assert_equal([[10, 1, ''], [10, 0, 'one']], g:MyomniFunc1_args) |
1100 | 1087 bw! |
1101 " Using a funcref variable to set 'omnifunc' | 1088 |
1102 let Fn = function('MyomniFunc1', [11]) | 1089 #" Using a funcref variable to set 'omnifunc' |
1103 let &omnifunc = Fn | 1090 VAR Fn = function('g:MyomniFunc1', [11]) |
1104 new | only | 1091 LET &omnifunc = Fn |
1105 call setline(1, 'two') | 1092 new | only |
1106 let g:MyomniFunc1_args = [] | 1093 call setline(1, 'two') |
1107 call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x') | 1094 LET g:MyomniFunc1_args = [] |
1108 call assert_equal([[11, 1, ''], [11, 0, 'two']], g:MyomniFunc1_args) | 1095 call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x') |
1109 bw! | 1096 call assert_equal([[11, 1, ''], [11, 0, 'two']], g:MyomniFunc1_args) |
1110 | 1097 bw! |
1111 " Using a string(funcref_variable) to set 'omnifunc' | 1098 |
1112 let Fn = function('MyomniFunc1', [12]) | 1099 #" Using a string(funcref_variable) to set 'omnifunc' |
1113 let &omnifunc = string(Fn) | 1100 LET Fn = function('g:MyomniFunc1', [12]) |
1114 new | only | 1101 LET &omnifunc = string(Fn) |
1115 call setline(1, 'two') | 1102 new | only |
1116 let g:MyomniFunc1_args = [] | 1103 call setline(1, 'two') |
1117 call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x') | 1104 LET g:MyomniFunc1_args = [] |
1118 call assert_equal([[12, 1, ''], [12, 0, 'two']], g:MyomniFunc1_args) | 1105 call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x') |
1119 bw! | 1106 call assert_equal([[12, 1, ''], [12, 0, 'two']], g:MyomniFunc1_args) |
1120 | 1107 bw! |
1121 " Test for using a funcref() | 1108 |
1122 set omnifunc=funcref('MyomniFunc1',\ [13]) | 1109 #" Test for using a funcref() |
1123 new | only | 1110 set omnifunc=funcref('g:MyomniFunc1',\ [13]) |
1124 call setline(1, 'three') | 1111 new | only |
1125 let g:MyomniFunc1_args = [] | 1112 call setline(1, 'three') |
1126 call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x') | 1113 LET g:MyomniFunc1_args = [] |
1127 call assert_equal([[13, 1, ''], [13, 0, 'three']], g:MyomniFunc1_args) | 1114 call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x') |
1128 bw! | 1115 call assert_equal([[13, 1, ''], [13, 0, 'three']], g:MyomniFunc1_args) |
1129 | 1116 bw! |
1130 " Using a funcref variable to set 'omnifunc' | 1117 |
1131 let Fn = funcref('MyomniFunc1', [14]) | 1118 #" Use let to set 'omnifunc' to a funcref |
1132 let &omnifunc = Fn | 1119 LET Fn = funcref('g:MyomniFunc1', [14]) |
1133 new | only | 1120 LET &omnifunc = Fn |
1134 call setline(1, 'four') | 1121 new | only |
1135 let g:MyomniFunc1_args = [] | 1122 call setline(1, 'four') |
1136 call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x') | 1123 LET g:MyomniFunc1_args = [] |
1137 call assert_equal([[14, 1, ''], [14, 0, 'four']], g:MyomniFunc1_args) | 1124 call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x') |
1138 bw! | 1125 call assert_equal([[14, 1, ''], [14, 0, 'four']], g:MyomniFunc1_args) |
1139 | 1126 bw! |
1140 " Using a string(funcref_variable) to set 'omnifunc' | 1127 |
1141 let Fn = funcref('MyomniFunc1', [15]) | 1128 #" Using a string(funcref) to set 'omnifunc' |
1142 let &omnifunc = string(Fn) | 1129 LET Fn = funcref("g:MyomniFunc1", [15]) |
1143 new | only | 1130 LET &omnifunc = string(Fn) |
1144 call setline(1, 'four') | 1131 new | only |
1145 let g:MyomniFunc1_args = [] | 1132 call setline(1, 'four') |
1146 call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x') | 1133 LET g:MyomniFunc1_args = [] |
1147 call assert_equal([[15, 1, ''], [15, 0, 'four']], g:MyomniFunc1_args) | 1134 call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x') |
1148 bw! | 1135 call assert_equal([[15, 1, ''], [15, 0, 'four']], g:MyomniFunc1_args) |
1149 | 1136 bw! |
1150 " Test for using a lambda function | 1137 |
1151 set omnifunc={a,\ b\ ->\ MyomniFunc1(16,\ a,\ b)} | 1138 #" Test for using a lambda function with set |
1152 new | only | 1139 VAR optval = "LSTART a, b LMIDDLE MyomniFunc1(16, a, b) LEND" |
1153 call setline(1, 'five') | 1140 LET optval = substitute(optval, ' ', '\\ ', 'g') |
1154 let g:MyomniFunc1_args = [] | 1141 exe "set omnifunc=" .. optval |
1155 call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x') | 1142 new | only |
1156 call assert_equal([[16, 1, ''], [16, 0, 'five']], g:MyomniFunc1_args) | 1143 call setline(1, 'five') |
1157 bw! | 1144 LET g:MyomniFunc1_args = [] |
1158 | 1145 call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x') |
1159 " Set 'omnifunc' to a lambda expression | 1146 call assert_equal([[16, 1, ''], [16, 0, 'five']], g:MyomniFunc1_args) |
1160 let &omnifunc = {a, b -> MyomniFunc1(17, a, b)} | 1147 bw! |
1161 new | only | 1148 |
1162 call setline(1, 'six') | 1149 #" Set 'omnifunc' to a lambda expression |
1163 let g:MyomniFunc1_args = [] | 1150 LET &omnifunc = LSTART a, b LMIDDLE MyomniFunc1(17, a, b) LEND |
1164 call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x') | 1151 new | only |
1165 call assert_equal([[17, 1, ''], [17, 0, 'six']], g:MyomniFunc1_args) | 1152 call setline(1, 'six') |
1166 bw! | 1153 LET g:MyomniFunc1_args = [] |
1167 | 1154 call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x') |
1168 " Set 'omnifunc' to a string(lambda_expression) | 1155 call assert_equal([[17, 1, ''], [17, 0, 'six']], g:MyomniFunc1_args) |
1169 let &omnifunc = '{a, b -> MyomniFunc1(18, a, b)}' | 1156 bw! |
1170 new | only | 1157 |
1171 call setline(1, 'six') | 1158 #" Set 'omnifunc' to a string(lambda_expression) |
1172 let g:MyomniFunc1_args = [] | 1159 LET &omnifunc = 'LSTART a, b LMIDDLE MyomniFunc1(18, a, b) LEND' |
1173 call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x') | 1160 new | only |
1174 call assert_equal([[18, 1, ''], [18, 0, 'six']], g:MyomniFunc1_args) | 1161 call setline(1, 'six') |
1175 bw! | 1162 LET g:MyomniFunc1_args = [] |
1176 | 1163 call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x') |
1177 " Set 'omnifunc' to a variable with a lambda expression | 1164 call assert_equal([[18, 1, ''], [18, 0, 'six']], g:MyomniFunc1_args) |
1178 let Lambda = {a, b -> MyomniFunc1(19, a, b)} | 1165 bw! |
1179 let &omnifunc = Lambda | 1166 |
1180 new | only | 1167 #" Set 'omnifunc' to a variable with a lambda expression |
1181 call setline(1, 'seven') | 1168 VAR Lambda = LSTART a, b LMIDDLE MyomniFunc1(19, a, b) LEND |
1182 let g:MyomniFunc1_args = [] | 1169 LET &omnifunc = Lambda |
1183 call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x') | 1170 new | only |
1184 call assert_equal([[19, 1, ''], [19, 0, 'seven']], g:MyomniFunc1_args) | 1171 call setline(1, 'seven') |
1185 bw! | 1172 LET g:MyomniFunc1_args = [] |
1186 | 1173 call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x') |
1187 " Set 'omnifunc' to a string(variable with a lambda expression) | 1174 call assert_equal([[19, 1, ''], [19, 0, 'seven']], g:MyomniFunc1_args) |
1188 let Lambda = {a, b -> MyomniFunc1(20, a, b)} | 1175 bw! |
1189 let &omnifunc = string(Lambda) | 1176 |
1190 new | only | 1177 #" Set 'omnifunc' to a string(variable with a lambda expression) |
1191 call setline(1, 'seven') | 1178 LET Lambda = LSTART a, b LMIDDLE MyomniFunc1(20, a, b) LEND |
1192 let g:MyomniFunc1_args = [] | 1179 LET &omnifunc = string(Lambda) |
1193 call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x') | 1180 new | only |
1194 call assert_equal([[20, 1, ''], [20, 0, 'seven']], g:MyomniFunc1_args) | 1181 call setline(1, 'seven') |
1195 bw! | 1182 LET g:MyomniFunc1_args = [] |
1196 | 1183 call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x') |
1197 " Test for using a lambda function with incorrect return value | 1184 call assert_equal([[20, 1, ''], [20, 0, 'seven']], g:MyomniFunc1_args) |
1198 let Lambda = {s -> strlen(s)} | 1185 bw! |
1199 let &omnifunc = Lambda | 1186 |
1200 new | only | 1187 #" Test for using a lambda function with incorrect return value |
1201 call setline(1, 'eight') | 1188 LET Lambda = LSTART a, b LMIDDLE strlen(a) LEND |
1202 call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x') | 1189 LET &omnifunc = Lambda |
1203 bw! | 1190 new | only |
1204 | 1191 call setline(1, 'eight') |
1205 " Test for clearing the 'omnifunc' option | 1192 call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x') |
1206 set omnifunc='' | 1193 bw! |
1207 set omnifunc& | 1194 |
1208 | 1195 #" Test for clearing the 'omnifunc' option |
1209 call assert_fails("set omnifunc=function('abc')", "E700:") | 1196 set omnifunc='' |
1210 call assert_fails("set omnifunc=funcref('abc')", "E700:") | 1197 set omnifunc& |
1198 call assert_fails("set omnifunc=function('abc')", "E700:") | |
1199 call assert_fails("set omnifunc=funcref('abc')", "E700:") | |
1200 | |
1201 #" set 'omnifunc' to a non-existing function | |
1202 func MyomniFunc2(findstart, base) | |
1203 call add(g:MyomniFunc2_args, [a:findstart, a:base]) | |
1204 return a:findstart ? 0 : [] | |
1205 endfunc | |
1206 set omnifunc=MyomniFunc2 | |
1207 call setline(1, 'nine') | |
1208 call assert_fails("set omnifunc=function('NonExistingFunc')", 'E700:') | |
1209 call assert_fails("LET &omnifunc = function('NonExistingFunc')", 'E700:') | |
1210 LET g:MyomniFunc2_args = [] | |
1211 call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x') | |
1212 call assert_equal([[1, ''], [0, 'nine']], g:MyomniFunc2_args) | |
1213 bw! | |
1214 END | |
1215 call CheckLegacyAndVim9Success(lines) | |
1216 | |
1211 let &omnifunc = {a -> 'abc'} | 1217 let &omnifunc = {a -> 'abc'} |
1212 call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x') | 1218 call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x') |
1213 | 1219 |
1214 " Using Vim9 lambda expression in legacy context should fail | 1220 " Using Vim9 lambda expression in legacy context should fail |
1215 set omnifunc=(a,\ b)\ =>\ g:MyomniFunc1(21,\ a,\ b) | 1221 set omnifunc=(a,\ b)\ =>\ MyomniFunc1(21,\ a,\ b) |
1216 new | only | 1222 new | only |
1217 let g:MyomniFunc1_args = [] | 1223 let g:MyomniFunc1_args = [] |
1218 call assert_fails('call feedkeys("A\<C-X>\<C-O>\<Esc>", "x")', 'E117:') | 1224 call assert_fails('call feedkeys("A\<C-X>\<C-O>\<Esc>", "x")', 'E117:') |
1219 call assert_equal([], g:MyomniFunc1_args) | 1225 call assert_equal([], g:MyomniFunc1_args) |
1220 | 1226 |
1221 " set 'omnifunc' to a non-existing function | 1227 " set 'omnifunc' to a partial with dict. This used to cause a crash. |
1222 func MyomniFunc2(findstart, base) | 1228 func SetOmniFunc() |
1223 call add(g:MyomniFunc2_args, [a:findstart, a:base]) | 1229 let params = {'omni': function('g:DictOmniFunc')} |
1224 return a:findstart ? 0 : [] | 1230 let &omnifunc = params.omni |
1225 endfunc | 1231 endfunc |
1226 set omnifunc=MyomniFunc2 | 1232 func g:DictOmniFunc(_) dict |
1227 call setline(1, 'nine') | 1233 endfunc |
1228 call assert_fails("set omnifunc=function('NonExistingFunc')", 'E700:') | 1234 call SetOmniFunc() |
1229 call assert_fails("let &omnifunc = function('NonExistingFunc')", 'E700:') | 1235 new |
1230 let g:MyomniFunc2_args = [] | 1236 call SetOmniFunc() |
1231 call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x') | 1237 bw |
1232 call assert_equal([[1, ''], [0, 'nine']], g:MyomniFunc2_args) | 1238 call test_garbagecollect_now() |
1233 bw! | 1239 new |
1240 set omnifunc= | |
1241 wincmd w | |
1242 set omnifunc= | |
1243 %bw! | |
1244 delfunc g:DictOmniFunc | |
1245 delfunc SetOmniFunc | |
1234 | 1246 |
1235 " Vim9 tests | 1247 " Vim9 tests |
1236 let lines =<< trim END | 1248 let lines =<< trim END |
1237 vim9script | 1249 vim9script |
1238 | 1250 |
1239 # Test for using function() | 1251 # Test for using a def function with omnifunc |
1240 def Vim9omniFunc(val: number, findstart: number, base: string): any | 1252 def Vim9omniFunc(val: number, findstart: number, base: string): any |
1241 add(g:Vim9omniFunc_Args, [val, findstart, base]) | 1253 add(g:Vim9omniFunc_Args, [val, findstart, base]) |
1242 return findstart ? 0 : [] | 1254 return findstart ? 0 : [] |
1243 enddef | 1255 enddef |
1244 set omnifunc=function('Vim9omniFunc',\ [60]) | 1256 set omnifunc=function('Vim9omniFunc',\ [60]) |
1246 setline(1, 'one') | 1258 setline(1, 'one') |
1247 g:Vim9omniFunc_Args = [] | 1259 g:Vim9omniFunc_Args = [] |
1248 feedkeys("A\<C-X>\<C-O>\<Esc>", 'x') | 1260 feedkeys("A\<C-X>\<C-O>\<Esc>", 'x') |
1249 assert_equal([[60, 1, ''], [60, 0, 'one']], g:Vim9omniFunc_Args) | 1261 assert_equal([[60, 1, ''], [60, 0, 'one']], g:Vim9omniFunc_Args) |
1250 bw! | 1262 bw! |
1251 | |
1252 # Test for using a lambda | |
1253 &omnifunc = (a, b) => Vim9omniFunc(61, a, b) | |
1254 new | only | |
1255 setline(1, 'two') | |
1256 g:Vim9omniFunc_Args = [] | |
1257 feedkeys("A\<C-X>\<C-O>\<Esc>", 'x') | |
1258 assert_equal([[61, 1, ''], [61, 0, 'two']], g:Vim9omniFunc_Args) | |
1259 bw! | |
1260 | |
1261 # Test for using a string(lambda) | |
1262 &omnifunc = '(a, b) => Vim9omniFunc(62, a, b)' | |
1263 new | only | |
1264 setline(1, 'two') | |
1265 g:Vim9omniFunc_Args = [] | |
1266 feedkeys("A\<C-X>\<C-O>\<Esc>", 'x') | |
1267 assert_equal([[62, 1, ''], [62, 0, 'two']], g:Vim9omniFunc_Args) | |
1268 bw! | |
1269 | |
1270 # Test for using a variable with a lambda expression | |
1271 var Fn: func = (a, b) => Vim9omniFunc(63, a, b) | |
1272 &omnifunc = Fn | |
1273 new | only | |
1274 setline(1, 'three') | |
1275 g:Vim9omniFunc_Args = [] | |
1276 feedkeys("A\<C-X>\<C-O>\<Esc>", 'x') | |
1277 assert_equal([[63, 1, ''], [63, 0, 'three']], g:Vim9omniFunc_Args) | |
1278 bw! | |
1279 | |
1280 # Test for using a string(variable with a lambda expression) | |
1281 Fn = (a, b) => Vim9omniFunc(64, a, b) | |
1282 &omnifunc = string(Fn) | |
1283 new | only | |
1284 setline(1, 'three') | |
1285 g:Vim9omniFunc_Args = [] | |
1286 feedkeys("A\<C-X>\<C-O>\<Esc>", 'x') | |
1287 assert_equal([[64, 1, ''], [64, 0, 'three']], g:Vim9omniFunc_Args) | |
1288 bw! | |
1289 END | 1263 END |
1290 call CheckScriptSuccess(lines) | 1264 call CheckScriptSuccess(lines) |
1291 | 1265 |
1292 " cleanup | 1266 " cleanup |
1293 delfunc MyomniFunc1 | 1267 delfunc MyomniFunc1 |
1301 func MytsrFunc1(val, findstart, base) | 1275 func MytsrFunc1(val, findstart, base) |
1302 call add(g:MytsrFunc1_args, [a:val, a:findstart, a:base]) | 1276 call add(g:MytsrFunc1_args, [a:val, a:findstart, a:base]) |
1303 return a:findstart ? 0 : [] | 1277 return a:findstart ? 0 : [] |
1304 endfunc | 1278 endfunc |
1305 | 1279 |
1306 " Test for using a function() | 1280 let lines =<< trim END |
1307 set thesaurusfunc=function('MytsrFunc1',[10]) | 1281 #" Test for using a function() |
1308 new | only | 1282 set thesaurusfunc=function('g:MytsrFunc1',\ [10]) |
1309 call setline(1, 'one') | 1283 new | only |
1310 let g:MytsrFunc1_args = [] | 1284 call setline(1, 'one') |
1311 call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x') | 1285 LET g:MytsrFunc1_args = [] |
1312 call assert_equal([[10, 1, ''], [10, 0, 'one']], g:MytsrFunc1_args) | 1286 call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x') |
1313 bw! | 1287 call assert_equal([[10, 1, ''], [10, 0, 'one']], g:MytsrFunc1_args) |
1314 | 1288 bw! |
1315 " Using a funcref variable to set 'thesaurusfunc' | 1289 |
1316 let Fn = function('MytsrFunc1', [11]) | 1290 #" Using a funcref variable to set 'thesaurusfunc' |
1317 let &thesaurusfunc = Fn | 1291 VAR Fn = function('g:MytsrFunc1', [11]) |
1318 new | only | 1292 LET &thesaurusfunc = Fn |
1319 call setline(1, 'two') | 1293 new | only |
1320 let g:MytsrFunc1_args = [] | 1294 call setline(1, 'two') |
1321 call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x') | 1295 LET g:MytsrFunc1_args = [] |
1322 call assert_equal([[11, 1, ''], [11, 0, 'two']], g:MytsrFunc1_args) | 1296 call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x') |
1323 bw! | 1297 call assert_equal([[11, 1, ''], [11, 0, 'two']], g:MytsrFunc1_args) |
1324 | 1298 bw! |
1325 " Using a string(funcref_variable) to set 'thesaurusfunc' | 1299 |
1326 let Fn = function('MytsrFunc1', [12]) | 1300 #" Using a string(funcref_variable) to set 'thesaurusfunc' |
1327 let &thesaurusfunc = string(Fn) | 1301 LET Fn = function('g:MytsrFunc1', [12]) |
1328 new | only | 1302 LET &thesaurusfunc = string(Fn) |
1329 call setline(1, 'two') | 1303 new | only |
1330 let g:MytsrFunc1_args = [] | 1304 call setline(1, 'two') |
1331 call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x') | 1305 LET g:MytsrFunc1_args = [] |
1332 call assert_equal([[12, 1, ''], [12, 0, 'two']], g:MytsrFunc1_args) | 1306 call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x') |
1333 bw! | 1307 call assert_equal([[12, 1, ''], [12, 0, 'two']], g:MytsrFunc1_args) |
1334 | 1308 bw! |
1335 " Test for using a funcref() | 1309 |
1336 set thesaurusfunc=funcref('MytsrFunc1',[13]) | 1310 #" Test for using a funcref() |
1337 new | only | 1311 set thesaurusfunc=funcref('g:MytsrFunc1',\ [13]) |
1338 call setline(1, 'three') | 1312 new | only |
1339 let g:MytsrFunc1_args = [] | 1313 call setline(1, 'three') |
1340 call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x') | 1314 LET g:MytsrFunc1_args = [] |
1341 call assert_equal([[13, 1, ''], [13, 0, 'three']], g:MytsrFunc1_args) | 1315 call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x') |
1342 bw! | 1316 call assert_equal([[13, 1, ''], [13, 0, 'three']], g:MytsrFunc1_args) |
1343 | 1317 bw! |
1344 " Using a funcref variable to set 'thesaurusfunc' | 1318 |
1345 let Fn = funcref('MytsrFunc1', [14]) | 1319 #" Using a funcref variable to set 'thesaurusfunc' |
1346 let &thesaurusfunc = Fn | 1320 LET Fn = funcref('g:MytsrFunc1', [14]) |
1347 new | only | 1321 LET &thesaurusfunc = Fn |
1348 call setline(1, 'four') | 1322 new | only |
1349 let g:MytsrFunc1_args = [] | 1323 call setline(1, 'four') |
1350 call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x') | 1324 LET g:MytsrFunc1_args = [] |
1351 call assert_equal([[14, 1, ''], [14, 0, 'four']], g:MytsrFunc1_args) | 1325 call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x') |
1352 bw! | 1326 call assert_equal([[14, 1, ''], [14, 0, 'four']], g:MytsrFunc1_args) |
1353 | 1327 bw! |
1354 " Using a string(funcref_variable) to set 'thesaurusfunc' | 1328 |
1355 let Fn = funcref('MytsrFunc1', [15]) | 1329 #" Using a string(funcref_variable) to set 'thesaurusfunc' |
1356 let &thesaurusfunc = string(Fn) | 1330 LET Fn = funcref('g:MytsrFunc1', [15]) |
1357 new | only | 1331 LET &thesaurusfunc = string(Fn) |
1358 call setline(1, 'four') | 1332 new | only |
1359 let g:MytsrFunc1_args = [] | 1333 call setline(1, 'four') |
1360 call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x') | 1334 LET g:MytsrFunc1_args = [] |
1361 call assert_equal([[15, 1, ''], [15, 0, 'four']], g:MytsrFunc1_args) | 1335 call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x') |
1362 bw! | 1336 call assert_equal([[15, 1, ''], [15, 0, 'four']], g:MytsrFunc1_args) |
1363 | 1337 bw! |
1364 " Test for using a lambda function | 1338 |
1365 set thesaurusfunc={a,\ b\ ->\ MytsrFunc1(16,\ a,\ b)} | 1339 #" Test for using a lambda function |
1366 new | only | 1340 VAR optval = "LSTART a, b LMIDDLE MytsrFunc1(16, a, b) LEND" |
1367 call setline(1, 'five') | 1341 LET optval = substitute(optval, ' ', '\\ ', 'g') |
1368 let g:MytsrFunc1_args = [] | 1342 exe "set thesaurusfunc=" .. optval |
1369 call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x') | 1343 new | only |
1370 call assert_equal([[16, 1, ''], [16, 0, 'five']], g:MytsrFunc1_args) | 1344 call setline(1, 'five') |
1371 bw! | 1345 LET g:MytsrFunc1_args = [] |
1372 | 1346 call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x') |
1373 " Set 'thesaurusfunc' to a lambda expression | 1347 call assert_equal([[16, 1, ''], [16, 0, 'five']], g:MytsrFunc1_args) |
1374 let &thesaurusfunc = {a, b -> MytsrFunc1(17, a, b)} | 1348 bw! |
1375 new | only | 1349 |
1376 call setline(1, 'six') | 1350 #" Test for using a lambda function with set |
1377 let g:MytsrFunc1_args = [] | 1351 LET &thesaurusfunc = LSTART a, b LMIDDLE MytsrFunc1(17, a, b) LEND |
1378 call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x') | 1352 new | only |
1379 call assert_equal([[17, 1, ''], [17, 0, 'six']], g:MytsrFunc1_args) | 1353 call setline(1, 'six') |
1380 bw! | 1354 LET g:MytsrFunc1_args = [] |
1381 | 1355 call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x') |
1382 " Set 'thesaurusfunc' to a string(lambda expression) | 1356 call assert_equal([[17, 1, ''], [17, 0, 'six']], g:MytsrFunc1_args) |
1383 let &thesaurusfunc = '{a, b -> MytsrFunc1(18, a, b)}' | 1357 bw! |
1384 new | only | 1358 |
1385 call setline(1, 'six') | 1359 #" Set 'thesaurusfunc' to a string(lambda expression) |
1386 let g:MytsrFunc1_args = [] | 1360 LET &thesaurusfunc = 'LSTART a, b LMIDDLE MytsrFunc1(18, a, b) LEND' |
1387 call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x') | 1361 new | only |
1388 call assert_equal([[18, 1, ''], [18, 0, 'six']], g:MytsrFunc1_args) | 1362 call setline(1, 'six') |
1389 bw! | 1363 LET g:MytsrFunc1_args = [] |
1390 | 1364 call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x') |
1391 " Set 'thesaurusfunc' to a variable with a lambda expression | 1365 call assert_equal([[18, 1, ''], [18, 0, 'six']], g:MytsrFunc1_args) |
1392 let Lambda = {a, b -> MytsrFunc1(19, a, b)} | 1366 bw! |
1393 let &thesaurusfunc = Lambda | 1367 |
1394 new | only | 1368 #" Set 'thesaurusfunc' to a variable with a lambda expression |
1395 call setline(1, 'seven') | 1369 VAR Lambda = LSTART a, b LMIDDLE MytsrFunc1(19, a, b) LEND |
1396 let g:MytsrFunc1_args = [] | 1370 LET &thesaurusfunc = Lambda |
1397 call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x') | 1371 new | only |
1398 call assert_equal([[19, 1, ''], [19, 0, 'seven']], g:MytsrFunc1_args) | 1372 call setline(1, 'seven') |
1399 bw! | 1373 LET g:MytsrFunc1_args = [] |
1400 | 1374 call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x') |
1401 " Set 'thesaurusfunc' to a string(variable with a lambda expression) | 1375 call assert_equal([[19, 1, ''], [19, 0, 'seven']], g:MytsrFunc1_args) |
1402 let Lambda = {a, b -> MytsrFunc1(20, a, b)} | 1376 bw! |
1403 let &thesaurusfunc = string(Lambda) | 1377 |
1404 new | only | 1378 #" Set 'thesaurusfunc' to a string(variable with a lambda expression) |
1405 call setline(1, 'seven') | 1379 LET Lambda = LSTART a, b LMIDDLE MytsrFunc1(20, a, b) LEND |
1406 let g:MytsrFunc1_args = [] | 1380 LET &thesaurusfunc = string(Lambda) |
1407 call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x') | 1381 new | only |
1408 call assert_equal([[20, 1, ''], [20, 0, 'seven']], g:MytsrFunc1_args) | 1382 call setline(1, 'seven') |
1409 bw! | 1383 LET g:MytsrFunc1_args = [] |
1410 | 1384 call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x') |
1411 " Test for using a lambda function with incorrect return value | 1385 call assert_equal([[20, 1, ''], [20, 0, 'seven']], g:MytsrFunc1_args) |
1412 let Lambda = {s -> strlen(s)} | 1386 bw! |
1413 let &thesaurusfunc = Lambda | 1387 |
1414 new | only | 1388 #" Test for using a lambda function with incorrect return value |
1415 call setline(1, 'eight') | 1389 LET Lambda = LSTART a, b LMIDDLE strlen(a) LEND |
1416 call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x') | 1390 LET &thesaurusfunc = Lambda |
1417 bw! | 1391 new | only |
1418 | 1392 call setline(1, 'eight') |
1419 " Test for clearing the 'thesaurusfunc' option | 1393 call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x') |
1420 set thesaurusfunc='' | 1394 bw! |
1421 set thesaurusfunc& | 1395 |
1422 | 1396 #" Test for clearing the 'thesaurusfunc' option |
1423 call assert_fails("set thesaurusfunc=function('abc')", "E700:") | 1397 set thesaurusfunc='' |
1424 call assert_fails("set thesaurusfunc=funcref('abc')", "E700:") | 1398 set thesaurusfunc& |
1399 call assert_fails("set thesaurusfunc=function('abc')", "E700:") | |
1400 call assert_fails("set thesaurusfunc=funcref('abc')", "E700:") | |
1401 | |
1402 #" set 'thesaurusfunc' to a non-existing function | |
1403 func MytsrFunc2(findstart, base) | |
1404 call add(g:MytsrFunc2_args, [a:findstart, a:base]) | |
1405 return a:findstart ? 0 : ['sunday'] | |
1406 endfunc | |
1407 set thesaurusfunc=MytsrFunc2 | |
1408 call setline(1, 'ten') | |
1409 call assert_fails("set thesaurusfunc=function('NonExistingFunc')", 'E700:') | |
1410 call assert_fails("LET &thesaurusfunc = function('NonExistingFunc')", 'E700:') | |
1411 LET g:MytsrFunc2_args = [] | |
1412 call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x') | |
1413 call assert_equal([[1, ''], [0, 'ten']], g:MytsrFunc2_args) | |
1414 bw! | |
1415 | |
1416 #" Use a buffer-local value and a global value | |
1417 set thesaurusfunc& | |
1418 setlocal thesaurusfunc=function('g:MytsrFunc1',\ [22]) | |
1419 call setline(1, 'sun') | |
1420 LET g:MytsrFunc1_args = [] | |
1421 call feedkeys("A\<C-X>\<C-T>\<Esc>", "x") | |
1422 call assert_equal('sun', getline(1)) | |
1423 call assert_equal([[22, 1, ''], [22, 0, 'sun']], g:MytsrFunc1_args) | |
1424 new | |
1425 call setline(1, 'sun') | |
1426 LET g:MytsrFunc1_args = [] | |
1427 call feedkeys("A\<C-X>\<C-T>\<Esc>", "x") | |
1428 call assert_equal('sun', getline(1)) | |
1429 call assert_equal([], g:MytsrFunc1_args) | |
1430 set thesaurusfunc=function('g:MytsrFunc1',\ [23]) | |
1431 wincmd w | |
1432 call setline(1, 'sun') | |
1433 LET g:MytsrFunc1_args = [] | |
1434 call feedkeys("A\<C-X>\<C-T>\<Esc>", "x") | |
1435 call assert_equal('sun', getline(1)) | |
1436 call assert_equal([[22, 1, ''], [22, 0, 'sun']], g:MytsrFunc1_args) | |
1437 :%bw! | |
1438 END | |
1439 call CheckLegacyAndVim9Success(lines) | |
1440 | |
1425 let &thesaurusfunc = {a -> 'abc'} | 1441 let &thesaurusfunc = {a -> 'abc'} |
1426 call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x') | 1442 call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x') |
1427 | 1443 |
1428 " Using Vim9 lambda expression in legacy context should fail | 1444 " Using Vim9 lambda expression in legacy context should fail |
1429 set thesaurusfunc=(a,\ b)\ =>\ g:MytsrFunc1(21,\ a,\ b) | 1445 set thesaurusfunc=(a,\ b)\ =>\ MytsrFunc1(21,\ a,\ b) |
1430 new | only | 1446 new | only |
1431 let g:MytsrFunc1_args = [] | 1447 let g:MytsrFunc1_args = [] |
1432 call assert_fails('call feedkeys("A\<C-X>\<C-T>\<Esc>", "x")', 'E117:') | 1448 call assert_fails('call feedkeys("A\<C-X>\<C-T>\<Esc>", "x")', 'E117:') |
1433 call assert_equal([], g:MytsrFunc1_args) | 1449 call assert_equal([], g:MytsrFunc1_args) |
1434 bw! | 1450 bw! |
1435 | 1451 |
1436 " Use a buffer-local value and a global value | 1452 " set 'thesaurusfunc' to a partial with dict. This used to cause a crash. |
1437 set thesaurusfunc& | 1453 func SetTsrFunc() |
1438 setlocal thesaurusfunc=function('MytsrFunc1',[22]) | 1454 let params = {'thesaurus': function('g:DictTsrFunc')} |
1439 call setline(1, 'sun') | 1455 let &thesaurusfunc = params.thesaurus |
1440 let g:MytsrFunc1_args = [] | 1456 endfunc |
1441 call feedkeys("A\<C-X>\<C-T>\<Esc>", "x") | 1457 func g:DictTsrFunc(_) dict |
1442 call assert_equal('sun', getline(1)) | 1458 endfunc |
1443 call assert_equal([[22, 1, ''], [22, 0, 'sun']], g:MytsrFunc1_args) | 1459 call SetTsrFunc() |
1444 new | 1460 new |
1445 call setline(1, 'sun') | 1461 call SetTsrFunc() |
1446 let g:MytsrFunc1_args = [] | 1462 bw |
1447 call feedkeys("A\<C-X>\<C-T>\<Esc>", "x") | 1463 call test_garbagecollect_now() |
1448 call assert_equal('sun', getline(1)) | 1464 new |
1449 call assert_equal([], g:MytsrFunc1_args) | 1465 set thesaurusfunc= |
1450 set thesaurusfunc=function('MytsrFunc1',[23]) | |
1451 wincmd w | 1466 wincmd w |
1452 call setline(1, 'sun') | |
1453 let g:MytsrFunc1_args = [] | |
1454 call feedkeys("A\<C-X>\<C-T>\<Esc>", "x") | |
1455 call assert_equal('sun', getline(1)) | |
1456 call assert_equal([[22, 1, ''], [22, 0, 'sun']], g:MytsrFunc1_args) | |
1457 %bw! | 1467 %bw! |
1458 | 1468 delfunc SetTsrFunc |
1459 " set 'thesaurusfunc' to a non-existing function | 1469 |
1460 func MytsrFunc2(findstart, base) | 1470 " set buffer-local 'thesaurusfunc' to a partial with dict. This used to |
1461 call add(g:MytsrFunc2_args, [a:findstart, a:base]) | 1471 " cause a crash. |
1462 return a:findstart ? 0 : ['sunday'] | 1472 func SetLocalTsrFunc() |
1463 endfunc | 1473 let params = {'thesaurus': function('g:DictTsrFunc')} |
1464 set thesaurusfunc=MytsrFunc2 | 1474 let &l:thesaurusfunc = params.thesaurus |
1465 call setline(1, 'ten') | 1475 endfunc |
1466 call assert_fails("set thesaurusfunc=function('NonExistingFunc')", 'E700:') | 1476 call SetLocalTsrFunc() |
1467 call assert_fails("let &thesaurusfunc = function('NonExistingFunc')", 'E700:') | 1477 call test_garbagecollect_now() |
1468 let g:MytsrFunc2_args = [] | 1478 call SetLocalTsrFunc() |
1469 call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x') | 1479 set thesaurusfunc= |
1470 call assert_equal([[1, ''], [0, 'ten']], g:MytsrFunc2_args) | |
1471 bw! | 1480 bw! |
1481 delfunc g:DictTsrFunc | |
1482 delfunc SetLocalTsrFunc | |
1472 | 1483 |
1473 " Vim9 tests | 1484 " Vim9 tests |
1474 let lines =<< trim END | 1485 let lines =<< trim END |
1475 vim9script | 1486 vim9script |
1476 | 1487 |
1477 # Test for using function() | 1488 # Test for using a def function with thesaurusfunc |
1478 def Vim9tsrFunc(val: number, findstart: number, base: string): any | 1489 def Vim9tsrFunc(val: number, findstart: number, base: string): any |
1479 add(g:Vim9tsrFunc_Args, [val, findstart, base]) | 1490 add(g:Vim9tsrFunc_Args, [val, findstart, base]) |
1480 return findstart ? 0 : [] | 1491 return findstart ? 0 : [] |
1481 enddef | 1492 enddef |
1482 set thesaurusfunc=function('Vim9tsrFunc',\ [60]) | 1493 set thesaurusfunc=function('Vim9tsrFunc',\ [60]) |
1484 setline(1, 'one') | 1495 setline(1, 'one') |
1485 g:Vim9tsrFunc_Args = [] | 1496 g:Vim9tsrFunc_Args = [] |
1486 feedkeys("A\<C-X>\<C-T>\<Esc>", 'x') | 1497 feedkeys("A\<C-X>\<C-T>\<Esc>", 'x') |
1487 assert_equal([[60, 1, ''], [60, 0, 'one']], g:Vim9tsrFunc_Args) | 1498 assert_equal([[60, 1, ''], [60, 0, 'one']], g:Vim9tsrFunc_Args) |
1488 bw! | 1499 bw! |
1489 | |
1490 # Test for using a lambda | |
1491 &thesaurusfunc = (a, b) => Vim9tsrFunc(61, a, b) | |
1492 new | only | |
1493 setline(1, 'two') | |
1494 g:Vim9tsrFunc_Args = [] | |
1495 feedkeys("A\<C-X>\<C-T>\<Esc>", 'x') | |
1496 assert_equal([[61, 1, ''], [61, 0, 'two']], g:Vim9tsrFunc_Args) | |
1497 bw! | |
1498 | |
1499 # Test for using a string(lambda) | |
1500 &thesaurusfunc = '(a, b) => Vim9tsrFunc(62, a, b)' | |
1501 new | only | |
1502 setline(1, 'two') | |
1503 g:Vim9tsrFunc_Args = [] | |
1504 feedkeys("A\<C-X>\<C-T>\<Esc>", 'x') | |
1505 assert_equal([[62, 1, ''], [62, 0, 'two']], g:Vim9tsrFunc_Args) | |
1506 bw! | |
1507 | |
1508 # Test for using a variable with a lambda expression | |
1509 var Fn: func = (a, b) => Vim9tsrFunc(63, a, b) | |
1510 &thesaurusfunc = Fn | |
1511 new | only | |
1512 setline(1, 'three') | |
1513 g:Vim9tsrFunc_Args = [] | |
1514 feedkeys("A\<C-X>\<C-T>\<Esc>", 'x') | |
1515 assert_equal([[63, 1, ''], [63, 0, 'three']], g:Vim9tsrFunc_Args) | |
1516 bw! | |
1517 | |
1518 # Test for using a string(variable with a lambda expression) | |
1519 Fn = (a, b) => Vim9tsrFunc(64, a, b) | |
1520 &thesaurusfunc = string(Fn) | |
1521 new | only | |
1522 setline(1, 'three') | |
1523 g:Vim9tsrFunc_Args = [] | |
1524 feedkeys("A\<C-X>\<C-T>\<Esc>", 'x') | |
1525 assert_equal([[64, 1, ''], [64, 0, 'three']], g:Vim9tsrFunc_Args) | |
1526 bw! | |
1527 END | 1500 END |
1528 call CheckScriptSuccess(lines) | 1501 call CheckScriptSuccess(lines) |
1529 | 1502 |
1530 " cleanup | 1503 " cleanup |
1531 set thesaurusfunc& | 1504 set thesaurusfunc& |