Is it possible to set separate fish color configurations for light and dark system theme?

Solution 1:

I'm not a Mac guy, so I can't give you the step-by-step here, but I can hopefully lay out the Fish parts and give you some pointers that might help out on the macOS side of things.

I'd break this down into:

  1. Something to notify all open Fish shell instances when the theme needs to change.

    This would be handled by a function that watches for a variable change. It needs to be in-memory at all times (as opposed to lazy-loaded). While you could create it in fish.config, my preference is to place it in ~/.config/fish/conf.d/update_theme.fish:

    function update_theme --on-variable macOS_Theme
        if [ "$macOS_Theme" = "dark" ]
            set_theme_dark
        else if [ "$macOS_Theme" = "light" ]
            set_theme_light
        end
    end
    
  2. We can then trigger a theme change in all open Fish instances via:

    set --universal macOS_Theme "dark"
    
  3. Detect when the macOS system theme changes -- This Ask Different Stack post led me to this Swift code that appears to be what you would need for this. Something like:

    DistributedNotificationCenter.default.addObserver(
        forName: Notification.Name("AppleInterfaceThemeChangedNotification"),
        object: nil,
        queue: nil) { (notification) in
            updateFishTheme()
    }
    
  4. The updateFishTheme() needs to be able to call Fish and set the global variable. The sample code there provides a shell function, which will probably work for this with modification. This SO answer also provides some sample "shell" code.

    There's also the possibility, it appears, of using run() per this SO answer.

    Again, no Mac here, so I just can't test this out and provide the actual code necessary.

  5. Once you can call the shell from that Swift function, use it to call:

    fish -c "set --universal macOS_Theme 'dark'" # or 'light'
    

    And all of your instances should update.