@@ -697,9 +697,12 @@ function _complete_methods(ex_org::Expr, context_module::Module, shift::Bool)
697
697
return kwargs_flag, funct, args_ex, kwargs_ex
698
698
end
699
699
700
- function complete_methods (ex_org:: Expr , context_module:: Module = Main, shift:: Bool = false )
700
+ # cursor_pos: either :positional (complete either kwargs or positional) or :kwargs (beyond semicolon)
701
+ function complete_methods (ex_org:: Expr , context_module:: Module = Main, shift:: Bool = false , cursor_pos:: Symbol = :positional )
701
702
kwargs_flag, funct, args_ex, kwargs_ex = _complete_methods (ex_org, context_module, shift):: Tuple{Int, Any, Vector{Any}, Set{Symbol}}
702
703
out = Completion[]
704
+ # Allow more arguments when cursor before semicolon, even if kwargs are present
705
+ cursor_pos == :positional && kwargs_flag == 1 && (kwargs_flag = 0 )
703
706
kwargs_flag == 2 && return out # one of the kwargs is invalid
704
707
kwargs_flag == 0 && push! (args_ex, Vararg{Any}) # allow more arguments if there is no semicolon
705
708
complete_methods! (out, funct, args_ex, kwargs_ex, shift ? - 2 : MAX_METHOD_COMPLETIONS, kwargs_flag == 1 )
@@ -876,11 +879,13 @@ end
876
879
end
877
880
878
881
# Provide completion for keyword arguments in function calls
882
+ # Returns true if the current argument must be a keyword because the cursor is beyond the semicolon
879
883
function complete_keyword_argument! (suggestions:: Vector{Completion} ,
880
884
ex:: Expr , last_word:: String ,
881
- context_module:: Module ; shift:: Bool = false )
885
+ context_module:: Module ,
886
+ arg_pos:: Symbol ; shift:: Bool = false )
882
887
kwargs_flag, funct, args_ex, kwargs_ex = _complete_methods (ex, context_module, true ):: Tuple{Int, Any, Vector{Any}, Set{Symbol}}
883
- kwargs_flag == 2 && false # one of the previous kwargs is invalid
888
+ kwargs_flag == 2 && return false # one of the previous kwargs is invalid
884
889
885
890
methods = Completion[]
886
891
# Limit kwarg completions to cases when function is concretely known; looking up
@@ -919,7 +924,7 @@ function complete_keyword_argument!(suggestions::Vector{Completion},
919
924
for kwarg in kwargs
920
925
push! (suggestions, KeywordArgumentCompletion (kwarg))
921
926
end
922
- return kwargs_flag != 0
927
+ return kwargs_flag != 0 && arg_pos == :kwargs
923
928
end
924
929
925
930
function get_loading_candidates (pkgstarts:: String , project_file:: String )
@@ -1055,7 +1060,8 @@ function completions(string::String, pos::Int, context_module::Module=Main, shif
1055
1060
(kind (cur) in KSet " String Comment ErrorEofMultiComment" || inside_cmdstr) &&
1056
1061
return Completion[], 1 : 0 , false
1057
1062
1058
- if (n = find_prefix_call (cur_not_ws)) != = nothing
1063
+ n, arg_pos = find_prefix_call (cur_not_ws)
1064
+ if n != = nothing
1059
1065
func = first (children_nt (n))
1060
1066
e = Expr (n)
1061
1067
# Remove arguments past the first parse error (allows unclosed parens)
@@ -1072,15 +1078,15 @@ function completions(string::String, pos::Int, context_module::Module=Main, shif
1072
1078
# foo(x, TAB => list of methods signatures for foo with x as first argument
1073
1079
if kind (cur_not_ws) in KSet " ( , ;"
1074
1080
# Don't provide method completions unless the cursor is after: '(' ',' ';'
1075
- return complete_methods (e, context_module, shift), char_range (func), false
1081
+ return complete_methods (e, context_module, shift, arg_pos ), char_range (func), false
1076
1082
1077
1083
# Keyword argument completion:
1078
1084
# foo(ar TAB => keyword arguments like `arg1=`
1079
1085
elseif kind (cur) == K " Identifier"
1080
1086
r = char_range (cur)
1081
1087
s = string[intersect (r, 1 : pos)]
1082
1088
# Return without adding more suggestions if kwargs only
1083
- complete_keyword_argument! (suggestions, e, s, context_module; shift) &&
1089
+ complete_keyword_argument! (suggestions, e, s, context_module, arg_pos ; shift) &&
1084
1090
return sort_suggestions (), r, true
1085
1091
end
1086
1092
end
@@ -1168,18 +1174,20 @@ function find_str(cur::CursorNode)
1168
1174
end
1169
1175
1170
1176
# Is the cursor directly inside of the arguments of a prefix call (no nested
1171
- # expressions)?
1177
+ # expressions)? If so, return:
1178
+ # - The call node
1179
+ # - Either :positional or :kwargs, if the cursor is before or after the `;`
1172
1180
function find_prefix_call (cur:: CursorNode )
1173
1181
n = cur. parent
1174
- n != = nothing || return nothing
1182
+ n != = nothing || return nothing , nothing
1175
1183
is_call (n) = kind (n) in KSet " call dotcall" && is_prefix_call (n)
1176
1184
if kind (n) == K " parameters"
1177
- is_call (n. parent) || return nothing
1178
- n. parent
1185
+ is_call (n. parent) || return nothing , nothing
1186
+ n. parent, :kwargs
1179
1187
else
1180
1188
# Check that we are beyond the function name.
1181
- is_call (n) && cur. index > children_nt (n)[1 ]. index || return nothing
1182
- n
1189
+ is_call (n) && cur. index > children_nt (n)[1 ]. index || return nothing , nothing
1190
+ n, :positional
1183
1191
end
1184
1192
end
1185
1193
0 commit comments