Is it possible to implement own `.<tab>` autocomplete for `getindex` in REPL (without AbstractDict)

I have some datatype, for which I would like to have autocomplete for getindex/setindex!, e.g. myData[.<tab> should give me all the keys(myData).

So far, I get that I can subtype AbstractDict{Symbol,Any} to archive that. But is it also possible otherwise?

For example, it seems that I have to implement iterate for AbstractDict, whereas for my type there is no reasons for iterate.

Here is a minimal (working) example

struct Keyholder{T<:NamedTuple} <: AbstractDict{:Symbol, Any}
    data::T
end

Base.getindex(k::Keyholder, sym::Symbol) = getproperty(k.data, sym)
Base.iterate(k::Keyholder) = iterate(pairs(k.data))
Base.iterate(k::Keyholder, state) = iterate(pairs(k.data), state)

Base.keys(k::Keyholder) = keys(k.data)
Base.keytype(::Keyholder) = :Symbol
Base.length(k::Keyholder) = length(keys(k))

k = Keyholder( (;A = 1, B = 2) )
# k[:<tab>  gives :A  :B

PS: In my real application, I maybe would like to not be a subtype of AbstractDict, that’s why I care about this question :wink: Of course, giving up autocomplete is an easy solution which I would accept.

I think what you want is to overload propertynames for your type.

julia> struct A
           a::Int
       end

julia> Base.getproperty(a::A, s::Symbol) = s == :x ? getfield(a,:a) : nothing

julia> Base.propertynames(a::A) = (:x,)

julia> a.x
1

julia> a.a

julia>
2 Likes

Mh, I did that before and somehow I didn’t like it in my setup. I think one reason is that the struct I would like to autocomplete, might be user facing.
And that could lead to confusion for people who don’t know getfield.

But yes, propertynames is much easier!

Looking at your solution, I actually got the idea to append getproperty. That could work well, e.g.
Base.propertynames(a::A) = (:x, fieldnames(A)...) and getproperty accordingly. Thanks!