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&