Skip to content

ffi: there is no theme enumeration export, so the shell reimplements the search #766

Description

@deblasis

Two independent reviews arrived at the same missing piece from opposite
directions: there is no way to ask libghostty what themes exist.

ghostty_surface_list_themes looks like it should be that call and is not.
It takes a *Surface, allocates an arena, installs input/scroll/resize
redirects, enters the alt screen, and returns an opaque picker handle. It is
the inline picker itself. Names reach the host one at a time through the
preview callback, and it returns null when zero themes are discovered.
Settings can also open with no surface at all, so it is unusable there even
setting the shape aside.

What that costs today

  • ThemeProvider.Refresh has to walk directories in C#, reimplementing the
    search order. It has now been widened to reuse ThemeSearchPath, but that
    is a second copy of a rule that lives in Zig.
  • BuiltinThemes.Names restates wintty-light / wintty-dark in C#,
    guarded by a test that scans the embedded wintty_theme.zig. The test is
    strong and fails closed, but it exists only because there is nothing to
    call.
  • The C# copy is unconditional while the Zig side gates on
    wintty_theme.enabled, so a non-Windows build of that assembly would offer
    two names nothing can resolve. Not reachable today; structurally possible.
  • ConfigService.ResolveThemePath still owns its own absolute/searchable/loop
    logic, so file resolution now exists in two shapes on the managed side.

What would fix it

An enumeration export over the same data both Zig browsers already use.
src/config/wintty_theme.zig exposes entries ({name, source}), and
src/cli/list_themes.zig plus src/cli/inline_theme_picker.zig both splice
it into their own element types. Something along the lines of an indexed
ghostty_config_theme_name(size_t) -> ghostty_string_s over static storage,
or a count-plus-index pair, would let the shell ask instead of infer.

That would delete BuiltinThemes.Names, its parity test and its csproj
resource entry, and would let ThemeProvider stop walking directories at all.

Related

Same family as the config-path question and the theme-is-builtin question:
every one of them is the shell guessing at something only the loader knows.
Two of those have already been answered by adding a narrow export rather than
by reimplementing the rule in C#, and that has worked well both times.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions