@@ -697,9 +697,12 @@ function _complete_methods(ex_org::Expr, context_module::Module, shift::Bool)
697697 return kwargs_flag, funct, args_ex, kwargs_ex
698698end
699699
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 )
701702 kwargs_flag, funct, args_ex, kwargs_ex = _complete_methods (ex_org, context_module, shift):: Tuple{Int, Any, Vector{Any}, Set{Symbol}}
702703 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 )
703706 kwargs_flag == 2 && return out # one of the kwargs is invalid
704707 kwargs_flag == 0 && push! (args_ex, Vararg{Any}) # allow more arguments if there is no semicolon
705708 complete_methods! (out, funct, args_ex, kwargs_ex, shift ? - 2 : MAX_METHOD_COMPLETIONS, kwargs_flag == 1 )
@@ -876,11 +879,13 @@ end
876879end
877880
878881# 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
879883function complete_keyword_argument! (suggestions:: Vector{Completion} ,
880884 ex:: Expr , last_word:: String ,
881- context_module:: Module ; shift:: Bool = false )
885+ context_module:: Module ,
886+ arg_pos:: Symbol ; shift:: Bool = false )
882887 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
884889
885890 methods = Completion[]
886891 # Limit kwarg completions to cases when function is concretely known; looking up
@@ -919,7 +924,7 @@ function complete_keyword_argument!(suggestions::Vector{Completion},
919924 for kwarg in kwargs
920925 push! (suggestions, KeywordArgumentCompletion (kwarg))
921926 end
922- return kwargs_flag != 0
927+ return kwargs_flag != 0 && arg_pos == :kwargs
923928end
924929
925930function get_loading_candidates (pkgstarts:: String , project_file:: String )
@@ -1055,7 +1060,8 @@ function completions(string::String, pos::Int, context_module::Module=Main, shif
10551060 (kind (cur) in KSet " String Comment ErrorEofMultiComment" || inside_cmdstr) &&
10561061 return Completion[], 1 : 0 , false
10571062
1058- if (n = find_prefix_call (cur_not_ws)) != = nothing
1063+ n, arg_pos = find_prefix_call (cur_not_ws)
1064+ if n != = nothing
10591065 func = first (children_nt (n))
10601066 e = Expr (n)
10611067 # 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
10721078 # foo(x, TAB => list of methods signatures for foo with x as first argument
10731079 if kind (cur_not_ws) in KSet " ( , ;"
10741080 # 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
10761082
10771083 # Keyword argument completion:
10781084 # foo(ar TAB => keyword arguments like `arg1=`
10791085 elseif kind (cur) == K " Identifier"
10801086 r = char_range (cur)
10811087 s = string[intersect (r, 1 : pos)]
10821088 # 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) &&
10841090 return sort_suggestions (), r, true
10851091 end
10861092 end
@@ -1168,18 +1174,20 @@ function find_str(cur::CursorNode)
11681174end
11691175
11701176# 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 `;`
11721180function find_prefix_call (cur:: CursorNode )
11731181 n = cur. parent
1174- n != = nothing || return nothing
1182+ n != = nothing || return nothing , nothing
11751183 is_call (n) = kind (n) in KSet " call dotcall" && is_prefix_call (n)
11761184 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
11791187 else
11801188 # 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
11831191 end
11841192end
11851193
0 commit comments