# foo.bar.\<TAB\> Completion Not Working

**URL:** <https://discourse.julialang.org/t/foo-bar-tab-completion-not-working/61052>\
**Category:** General Usage\
**Tags:** repl\
**Created:** [May 12, 2021, 11:21pm UTC](https://discourse.julialang.org/t/foo-bar-tab-completion-not-working/61052 "2021-05-12T23:21:11Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![rayegun](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rayegun/32/26729_2.png) [@rayegun](https://discourse.julialang.org/u/rayegun)\
**Post date:** [May 12, 2021, 11:21pm UTC](https://discourse.julialang.org/t/foo-bar-tab-completion-not-working/61052/1 "2021-05-12T23:21:12Z")

</div>

I’ve got a type

```julia
struct Configuration
    p::Ptr{configuration_t}
    key::id_t
end

```

which wraps a nested configuration type from C.

I can look up the subkeys of this type with `keys(c::Configuration)` , and I allow tab completion by overloading `Base.getproperty(c::Configuration, v::Symbol)` where `v` is one of the symbols returned by `keys` . `getproperty` will return a new `Configuration` struct with the same pointer, but the new key.

The problem I’m having is with `Base.propertynames` , or really with tab completion. At the first level this is fine. I can run `cf = Configuration()` and then `cf.<TAB>` and I get a list of the available properties.

**However** , if I take one of those properties, like `solve` and do `cf.solve.<TAB>` nothing happens. If I do `cf.solve` I get the correct object, and if I do `propertynames(cf.solve)` I get the correct list of symbols. Any idea where the disconnect is happening here? I’m not sure how I would debug the autocompletion, especially since propertynames works correctly.

The getproperty is:

```julia
function Base.getproperty(c::Configuration, v::Symbol)
    if v ∈ fieldnames(Configuration)
        return getfield(c, v)
    end
    s = String(v)
    k = subkey(c,s)
    k === nothing && error("Configuration has no field $s")
    return Configuration(c.p, k)
end

```

`subkey` gets the integer key for a string like “solve”.

The `propertynames` is:

```julia
function Base.propertynames(c::Configuration)
    return Symbol.(keys(c))
end

```

There’s not a super great MWE since there’s a lot of ccalls. I will say, though, that the simplest possible example

```julia
struct A
    i
end
x = A(A(1))
x.i.<TAB>

```

works just find and `x.i.<TAB>` becomes `x.i.i`.

---

<div class="post-metadata">

**Author:** ![rayegun](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rayegun/32/26729_2.png) [@rayegun](https://discourse.julialang.org/u/rayegun)\
**Post date:** [May 13, 2021, 1:19am UTC](https://discourse.julialang.org/t/foo-bar-tab-completion-not-working/61052/2 "2021-05-13T01:19:20Z")

</div>

It seems I’ve found the issue. getproperty is not type stable. The full function is

```julia
function Base.getproperty(c::Configuration, v::Symbol)
    if v ∈ fieldnames(Configuration)
        return getfield(c, v)
    end
    s = String(v)
    k = subkey(c,s)
    k === nothing && error("Configuration has no field $s")
    if checktype(c,k, configuration_type_value)
        if configuration_value_is_assigned(c, k)
            return configuration_value_get(c, k)
        else
            return nothing
        end
    end
    return Configuration(c.p, k)
end

```

And `nothing` is creating type instability which might be the source of the issue? I’m not sure it’s possible to make this type stable…

---

<div class="post-metadata">

**Author:** ![rayegun](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rayegun/32/26729_2.png) [@rayegun](https://discourse.julialang.org/u/rayegun)\
**Post date:** [May 13, 2021, 7:15pm UTC](https://discourse.julialang.org/t/foo-bar-tab-completion-not-working/61052/3 "2021-05-13T19:15:17Z")

</div>

Alright so removing the nothing doesn’t really help here. If I do like this:

```julia
function Base.getproperty(c::Configuration, v::Symbol)
    if v === :p
        return Base.getfield(c, :p)
    elseif v === :key
        return Base.getfield(c, :key)
    elseif v === :name
        return Base.getfield(c, :name)
    end
    s = String(v)
    k = subkey(c,s)
    k === nothing && error("type Configuration has no field $s")

    return Configuration(c.p, k, s)
end

```

I still can’t get auto-complete working. I assume it’s because this still isn’t _technically_ type stable? Is there any way to get nested auto-complete with an overloaded getproperty?
