@@ -40,6 +40,7 @@ struct MethodCompletion <: Completion
40
40
func
41
41
input_types:: Type
42
42
method:: Method
43
+ orig_method:: Union{Nothing,Method} # if `method` is a keyword method, keep the original method for sensible printing
43
44
end
44
45
45
46
struct BslashCompletion <: Completion
@@ -89,7 +90,7 @@ _completion_text(c::ModuleCompletion) = c.mod
89
90
_completion_text (c:: PackageCompletion ) = c. package
90
91
_completion_text (c:: PropertyCompletion ) = string (c. property)
91
92
_completion_text (c:: FieldCompletion ) = string (c. field)
92
- _completion_text (c:: MethodCompletion ) = sprint (io -> show (io, c . method))
93
+ _completion_text (c:: MethodCompletion ) = sprint (io -> show (io, isnothing (c . orig_method) ? c . method : c . orig_method :: Method ))
93
94
_completion_text (c:: BslashCompletion ) = c. bslash
94
95
_completion_text (c:: ShellCompletion ) = c. text
95
96
_completion_text (c:: DictCompletion ) = c. key
314
315
function should_method_complete (s:: AbstractString )
315
316
method_complete = false
316
317
for c in reverse (s)
317
- if c in [' ,' , ' (' ]
318
+ if c in [' ,' , ' (' , ' ; ' ]
318
319
method_complete = true
319
320
break
320
321
elseif ! (c in whitespace_chars)
@@ -465,34 +466,58 @@ end
465
466
466
467
# Method completion on function call expression that look like :(max(1))
467
468
function complete_methods (ex_org:: Expr , context_module:: Module = Main)
468
- args_ex = Any[]
469
469
func, found = get_value (ex_org. args[1 ], context_module):: Tuple{Any,Bool}
470
470
! found && return Completion[]
471
471
472
472
funargs = ex_org. args[2 : end ]
473
473
# handle broadcasting, but only handle number of arguments instead of
474
474
# argument types
475
+ args_ex = Any[]
476
+ kwargs_ex = Pair{Symbol,Any}[]
475
477
if ex_org. head === :. && ex_org. args[2 ] isa Expr
476
478
for _ in (ex_org. args[2 ]:: Expr ). args
477
479
push! (args_ex, Any)
478
480
end
479
481
else
480
482
for ex in funargs
481
- val, found = get_type (ex, context_module)
482
- push! (args_ex, val)
483
+ if isexpr (ex, :parameters )
484
+ for x in ex. args
485
+ n, v = isexpr (x, :kw ) ? (x. args... ,) : (x, x)
486
+ push! (kwargs_ex, n => first (get_type (v, context_module)))
487
+ end
488
+ elseif isexpr (ex, :kw )
489
+ n, v = (ex. args... ,)
490
+ push! (kwargs_ex, n => first (get_type (v, context_module)))
491
+ else
492
+ push! (args_ex, first (get_type (ex, context_module)))
493
+ end
483
494
end
484
495
end
485
496
486
497
out = Completion[]
487
- t_in = Tuple{Core. Typeof (func), args_ex... } # Input types
488
- na = length (args_ex)+ 1
489
498
ml = methods (func)
490
- for method in ml
499
+ # Input types and number of arguments
500
+ if isempty (kwargs_ex)
501
+ t_in = Tuple{Core. Typeof (func), args_ex... }
502
+ na = length (t_in. parameters):: Int
503
+ orig_ml = fill (nothing , length (ml))
504
+ else
505
+ isdefined (ml. mt, :kwsorter ) || return out
506
+ kwfunc = ml. mt. kwsorter
507
+ kwargt = NamedTuple{(first .(kwargs_ex)... ,), Tuple{last .(kwargs_ex)... }}
508
+ t_in = Tuple{Core. Typeof (kwfunc), kwargt, Core. Typeof (func), args_ex... }
509
+ na = length (t_in. parameters):: Int
510
+ orig_ml = ml # this method is supposed to be used for printing
511
+ ml = methods (kwfunc)
512
+ func = kwfunc
513
+ end
514
+
515
+ for (method:: Method , orig_method) in zip (ml, orig_ml)
491
516
ms = method. sig
492
517
493
518
# Check if the method's type signature intersects the input types
494
- if typeintersect (Base. rewrap_unionall (Tuple{(Base. unwrap_unionall (ms):: DataType ). parameters[1 : min (na, end )]. .. }, ms), t_in) != = Union{}
495
- push! (out, MethodCompletion (func, t_in, method))
519
+ if typeintersect (Base. rewrap_unionall (Tuple{(Base. unwrap_unionall (ms):: DataType ). parameters[1 : min (na, end )]. .. }, ms), t_in) != Union{}
520
+ push! (out, MethodCompletion (func, t_in, method, orig_method ))
496
521
end
497
522
end
498
523
return out
0 commit comments