@@ -391,16 +391,21 @@ function complete_line(s::MIState)
391391 end
392392end
393393
394+ # Old complete_line return type: Vector{String}, String, Bool
395+ # New complete_line return type: NamedCompletion{String}, String, Bool
396+ # OR NamedCompletion{String}, Region, Bool
397+ #
394398# due to close coupling of the Pkg ReplExt `complete_line` can still return a vector of strings,
395399# so we convert those in this helper
396- function complete_line_named (args... ; kwargs... ):: Tuple{Vector{NamedCompletion},String,Bool}
397- result = complete_line (args... ; kwargs... ):: Union{Tuple{Vector{NamedCompletion},String,Bool},Tuple{Vector{String},String,Bool}}
398- if result isa Tuple{Vector{NamedCompletion},String,Bool}
399- return result
400- else
401- completions, partial, should_complete = result
402- return map (NamedCompletion, completions), partial, should_complete
403- end
400+ function complete_line_named (c, s, args... ; kwargs... ):: Tuple{Vector{NamedCompletion},Region,Bool}
401+ r1, r2, should_complete = complete_line (c, s, args... ; kwargs... ):: Union {
402+ Tuple{Vector{String}, String, Bool},
403+ Tuple{Vector{NamedCompletion}, String, Bool},
404+ Tuple{Vector{NamedCompletion}, Region, Bool},
405+ }
406+ completions = (r1 isa Vector{String} ? map (NamedCompletion, r1) : r1)
407+ r = (r2 isa String ? (position (s)- sizeof (r2) => position (s)) : r2)
408+ completions, r, should_complete
404409end
405410
406411# checks for a hint and shows it if appropriate.
@@ -426,14 +431,14 @@ function check_show_hint(s::MIState)
426431 return
427432 end
428433 t_completion = Threads. @spawn :default begin
429- named_completions, partial , should_complete = nothing , nothing , nothing
434+ named_completions, reg , should_complete = nothing , nothing , nothing
430435
431436 # only allow one task to generate hints at a time and check around lock
432437 # if the user has pressed a key since the hint was requested, to skip old completions
433438 next_key_pressed () && return
434439 @lock s. hint_generation_lock begin
435440 next_key_pressed () && return
436- named_completions, partial , should_complete = try
441+ named_completions, reg , should_complete = try
437442 complete_line_named (st. p. complete, st, s. active_module; hint = true )
438443 catch
439444 lock_clear_hint ()
@@ -448,21 +453,19 @@ function check_show_hint(s::MIState)
448453 return
449454 end
450455 # Don't complete for single chars, given e.g. `x` completes to `xor`
451- if length (partial) > 1 && should_complete
456+ if reg . second - reg . first > 1 && should_complete
452457 singlecompletion = length (completions) == 1
453458 p = singlecompletion ? completions[1 ] : common_prefix (completions)
454459 if singlecompletion || p in completions # i.e. complete `@time` even though `@time_imports` etc. exists
455- # The completion `p` and the input `partial ` may not share the same initial
460+ # The completion `p` and the region `reg ` may not share the same initial
456461 # characters, for instance when completing to subscripts or superscripts.
457462 # So, in general, make sure that the hint starts at the correct position by
458463 # incrementing its starting position by as many characters as the input.
459- startind = 1 # index of p from which to start providing the hint
460- maxind = ncodeunits (p)
461- for _ in partial
462- startind = nextind (p, startind)
463- startind > maxind && break
464- end
464+ maxind = lastindex (p)
465+ startind = sizeof (content (s, reg))
465466 if startind ≤ maxind # completion on a complete name returns itself so check that there's something to hint
467+ # index of p from which to start providing the hint
468+ startind = nextind (p, startind)
466469 hint = p[startind: end ]
467470 next_key_pressed () && return
468471 @lock s. line_modify_lock begin
@@ -491,25 +494,24 @@ function clear_hint(s::ModeState)
491494end
492495
493496function complete_line (s:: PromptState , repeats:: Int , mod:: Module ; hint:: Bool = false )
494- completions, partial , should_complete = complete_line_named (s. p. complete, s, mod; hint)
497+ completions, reg , should_complete = complete_line_named (s. p. complete, s, mod; hint)
495498 isempty (completions) && return false
496499 if ! should_complete
497500 # should_complete is false for cases where we only want to show
498501 # a list of possible completions but not complete, e.g. foo(\t
499502 show_completions (s, completions)
500503 elseif length (completions) == 1
501504 # Replace word by completion
502- prev_pos = position (s)
503505 push_undo (s)
504- edit_splice! (s, (prev_pos - sizeof (partial)) => prev_pos , completions[1 ]. completion)
506+ edit_splice! (s, reg , completions[1 ]. completion)
505507 else
506508 p = common_prefix (completions)
509+ partial = content (s, reg. first => min (bufend (s), reg. first + sizeof (p)))
507510 if ! isempty (p) && p != partial
508511 # All possible completions share the same prefix, so we might as
509- # well complete that
510- prev_pos = position (s)
512+ # well complete that.
511513 push_undo (s)
512- edit_splice! (s, (prev_pos - sizeof (partial)) => prev_pos , p)
514+ edit_splice! (s, reg , p)
513515 elseif repeats > 0
514516 show_completions (s, completions)
515517 end
@@ -830,12 +832,12 @@ function edit_move_right(m::MIState)
830832 refresh_line (s)
831833 return true
832834 else
833- completions, partial , should_complete = complete_line (s. p. complete, s, m. active_module)
834- if should_complete && eof (buf) && length (completions) == 1 && length (partial) > 1
835+ completions, reg , should_complete = complete_line (s. p. complete, s, m. active_module)
836+ if should_complete && eof (buf) && length (completions) == 1 && reg . second - reg . first > 1
835837 # Replace word by completion
836838 prev_pos = position (s)
837839 push_undo (s)
838- edit_splice! (s, (prev_pos - sizeof (partial) ) => prev_pos, completions[1 ]. completion)
840+ edit_splice! (s, (prev_pos - reg . second + reg . first ) => prev_pos, completions[1 ]. completion)
839841 refresh_line (state (s))
840842 return true
841843 else
@@ -2255,12 +2257,12 @@ setmodifiers!(c) = nothing
22552257
22562258# Search Mode completions
22572259function complete_line (s:: SearchState , repeats, mod:: Module ; hint:: Bool = false )
2258- completions, partial , should_complete = complete_line (s. histprompt. complete, s, mod; hint)
2260+ completions, reg , should_complete = complete_line (s. histprompt. complete, s, mod; hint)
22592261 # For now only allow exact completions in search mode
22602262 if length (completions) == 1
22612263 prev_pos = position (s)
22622264 push_undo (s)
2263- edit_splice! (s, (prev_pos - sizeof (partial) ) => prev_pos, completions[1 ]. completion)
2265+ edit_splice! (s, (prev_pos - reg . second - reg . first ) => prev_pos, completions[1 ]. completion)
22642266 return true
22652267 end
22662268 return false
0 commit comments