Skip to content

Commit

Permalink
Fix completion hint for sub/superscripts (JuliaLang#52402)
Browse files Browse the repository at this point in the history
Fix JuliaLang#52376

The completion hint starting offset was not computed considering the
case where the input and the completion do not share the same prefix,
which happens when completing into a subscript or a superscript. This
fixes that by iteratively going through the characters of the hint until
reaching that which marks the end of the input.
  • Loading branch information
Liozou committed Dec 6, 2023
1 parent f96585b commit a948e6d
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 12 deletions.
28 changes: 16 additions & 12 deletions stdlib/REPL/src/LineEdit.jl
Original file line number Diff line number Diff line change
Expand Up @@ -382,23 +382,27 @@ function check_for_hint(s::MIState)
return clear_hint(st)
end
completions, partial, should_complete = complete_line(st.p.complete, st, s.active_module)::Tuple{Vector{String},String,Bool}
isempty(completions) && return clear_hint(st)
# Don't complete for single chars, given e.g. `x` completes to `xor`
if length(partial) > 1 && should_complete
if length(completions) == 1
hint = only(completions)[sizeof(partial)+1:end]
if !isempty(hint) # completion on a complete name returns itself so check that there's something to hint
singlecompletion = length(completions) == 1
p = singlecompletion ? completions[1] : common_prefix(completions)
if singlecompletion || p in completions # i.e. complete `@time` even though `@time_imports` etc. exists
# The completion `p` and the input `partial` may not share the same initial
# characters, for instance when completing to subscripts or superscripts.
# So, in general, make sure that the hint starts at the correct position by
# incrementing its starting position by as many characters as the input.
startind = 1 # index of p from which to start providing the hint
maxind = ncodeunits(p)
for _ in partial
startind = nextind(p, startind)
startind > maxind && break
end
if startind maxind # completion on a complete name returns itself so check that there's something to hint
hint = p[startind:end]
st.hint = hint
return true
end
elseif length(completions) > 1
p = common_prefix(completions)
if p in completions # i.e. complete `@time` even though `@time_imports` etc. exists
hint = p[sizeof(partial)+1:end]
if !isempty(hint)
st.hint = hint
return true
end
end
end
end
return clear_hint(st)
Expand Down
11 changes: 11 additions & 0 deletions stdlib/REPL/test/repl.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1711,6 +1711,17 @@ fake_repl() do stdin_write, stdout_read, repl
end
@test LineEdit.state(repl.mistate).hint === nothing

# issue #52376
write(stdin_write, "\x15")
write(stdin_write, "\\_ailuj")
while LineEdit.state(repl.mistate).hint !== nothing
sleep(0.1)
end
@test LineEdit.state(repl.mistate).hint === nothing
s5 = readuntil(stdout_read, "\\_ailuj")
write(stdin_write, "\t")
s6 = readuntil(stdout_read, "ₐᵢₗᵤⱼ")

write(stdin_write, "\x15\x04")
Base.wait(repltask)
end
Expand Down

0 comments on commit a948e6d

Please sign in to comment.