diff --git a/Project.toml b/Project.toml index c2985bd8..7791f0ff 100644 --- a/Project.toml +++ b/Project.toml @@ -6,6 +6,7 @@ version = "1.23.0" Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" Conda = "8f4d0f93-b110-5947-807f-2305c1781a2d" Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" +FuzzyCompletions = "fb4132e2-a121-4a70-b8a1-d5b831dcdcc2" InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240" JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" Markdown = "d6f4376e-aef5-505a-96c1-9c027394607a" diff --git a/deps/kspec.jl b/deps/kspec.jl index 283557cf..f340f911 100644 --- a/deps/kspec.jl +++ b/deps/kspec.jl @@ -49,11 +49,13 @@ end installkernel(name::AbstractString, options::AbstractString...; julia::Cmd, specname::AbstractString, - env=Dict()) + fuzzy_completion_mode::Bool=false + env::Dict{<:AbstractString}=Dict()) Install a new Julia kernel, where the given `options` are passed to the `julia` executable, the user-visible kernel name is given by `name` followed by the Julia version, and the `env` dictionary is added to the environment. +If `fuzzy_completion_mode` is `true`, then shift-tab completions will be done fuzzily. The new kernel name is returned by `installkernel`. For example: ``` @@ -85,7 +87,9 @@ installkernel( function installkernel(name::AbstractString, julia_options::AbstractString...; julia::Cmd = `$(joinpath(Sys.BINDIR,exe("julia")))`, specname::AbstractString = replace(lowercase(name), " "=>"-"), - env::Dict{<:AbstractString}=Dict{String,Any}()) + fuzzy_completion_mode::Bool = false, + env::Dict{<:AbstractString} = Dict{String,Any}(), + ) # Is IJulia being built from a debug build? If so, add "debug" to the description. debugdesc = ccall(:jl_is_debugbuild,Cint,())==1 ? "-debug" : "" @@ -100,6 +104,8 @@ function installkernel(name::AbstractString, julia_options::AbstractString...; ijulia_dir = get(ENV, "IJULIA_DIR", dirname(@__DIR__)) # support non-Pkg IJulia installs append!(kernelcmd_array, [joinpath(ijulia_dir,"src","kernel.jl"), "{connection_file}"]) + push!(env, "IJULIA_COMPLETION_MODE" => fuzzy_completion_mode ? "fuzzy" : "repl") + ks = Dict( "argv" => kernelcmd_array, "display_name" => name * " " * Base.VERSION_STRING * debugdesc, diff --git a/src/handlers.jl b/src/handlers.jl index e8fb828d..03f567b1 100644 --- a/src/handlers.jl +++ b/src/handlers.jl @@ -50,6 +50,7 @@ ind2chr(m::Msg, str::String, i::Integer) = i == 0 ? 0 : import REPL: REPLCompletions import REPL.REPLCompletions: sorted_keywords, emoji_symbols, latex_symbols +import FuzzyCompletions complete_type(::Type{<:Function}) = "function" complete_type(::Type{<:Type}) = "type" @@ -123,8 +124,12 @@ function complete_request(socket, msg) end codestart = find_parsestart(code, cursorpos) - comps_, positions = REPLCompletions.completions(code[codestart:end], cursorpos-codestart+1, current_module[]) - comps = unique!(REPLCompletions.completion_text.(comps_)) # julia#26930 + completion_mode = get(ENV, "IJULIA_COMPLETION_MODE", "repl") + completions, completion_text = completion_mode == "fuzzy" ? (FuzzyCompletions.completions, FuzzyCompletions.completion_text) : + (REPLCompletions.completions, REPLCompletions.completion_text) + comps_, positions = completions(code[codestart:end], cursorpos-codestart+1, current_module[]) + completion_mode == "fuzzy" && filter!(≥(0)∘FuzzyCompletions.score, comps_) # cut off too many candidates, they would be useless in most jupyter frontends + comps = unique!(completion_text.(comps_)) # julia#26930 # positions = positions .+ (codestart - 1) on Julia 0.7 positions = (first(positions) + codestart - 1):(last(positions) + codestart - 1) metadata = Dict()