Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Switch iTerm2 color preset automatic base on macOS dark mode.

The latest beta (3.5) includes separate color settings for light & dark mode. Toggling dark mode automatically switches colors.

Vist iTerm 2 homepage to download the beta. Thanks @stefanwascoding.


  1. Add switch_automatic.py to ~/Library/ApplicationSupport/iTerm2/Scripts/AutoLaunch with:
#!/usr/bin/env python3

import asyncio
import iterm2

async def main(connection):
    async with iterm2.VariableMonitor(connection, iterm2.VariableScopes.APP, "effectiveTheme", None) as mon:
        while True:
            # Block until theme changes
            theme = await mon.async_get()

            # Themes have space-delimited attributes, one of which will be light or dark.
            parts = theme.split(" ")
            if "dark" in parts:
                preset = await iterm2.ColorPreset.async_get(connection, "Dark Background")
            else:
                preset = await iterm2.ColorPreset.async_get(connection, "Light Background")

            # Update the list of all profiles and iterate over them.
            profiles=await iterm2.PartialProfile.async_query(connection)
            for partial in profiles:
                # Fetch the full profile and then set the color preset in it.
                profile = await partial.async_get_full_profile()
                await profile.async_set_color_preset(preset)

iterm2.run_forever(main)

Change Dark Background and Light Background to color presets you like.

  1. Enabled switch_automatic.py from Scripts menu.
@FradSer
Copy link
Author

FradSer commented Mar 2, 2021

👍Really helpful, thanks.

@jirikrepl
Copy link

jirikrepl commented Mar 4, 2021

👍 @d9i seems to be working great!

@IsidroMar95
Copy link

IsidroMar95 commented Apr 17, 2021

i got this error... why?
ended unexpectedly
image

@kazlauskis
Copy link

kazlauskis commented May 11, 2021

@d9i thanks!

@thomashexton
Copy link

thomashexton commented May 28, 2021

i got this error... why?
ended unexpectedly
image

I was getting this error too. However I resolved it by choosing some of the base themes. Solarized Light and Solarized Dark. See if that fixes it for you too? They may not be the exact themes you want though, but at least my eyes aren't blown out at night now.

@pxlshpr
Copy link

pxlshpr commented Jun 2, 2021

@d9i thank you, works like a charm

@arosca
Copy link

arosca commented Jun 12, 2021

👍 thanks

@SinisterStairs
Copy link

SinisterStairs commented Jun 18, 2021

There seems to be a bug with this script, where it spawns multiple processes that don't go away after iTerm2 has ended.

My laptop fans were constantly running and I saw bash was consuming 99% of a CPU. Looking more carefully I saw a screenful of this script running. After manually killing them all, CPU returned to normal.

I notice when I start up iTerm2, it launches two processes using ~/.config/iterm2/AppSupport/Scripts/AutoLaunch/auto_dark_mode.py. (I think that's normal, because one is the child of the other?)

But when you completely exit the iTerm2 application, those processes remain running. Then, if you launch iTerm2 again, two more processes are spawned for 4 total, and so on.

These processes aren't exiting when iTerm2 exits. I'm using iTerm2 on Mojave; I'll test it on M1/Big Sur as well.

[Edited for formatting.]

@SinisterStairs
Copy link

SinisterStairs commented Jun 18, 2021

If I open the script console and close my sessions (i.e. iTerm2 hasn't exited because the console is open) then quit, the processes get cleaned up.

But if I don't have the script console open and close my sessions (iTerm2 exits) or quit, the processes hang around.

EDIT2: I thought it might be related to my preferences, but disabling them didn't seem to fix it:

  • General | Closing | Quit when all windows are closed
  • Profiles | Session | After a session ends No Action

@plivox
Copy link

plivox commented Jun 19, 2021

Hello, here is my version if anyone is interested.

Automatic iTerm2 preset switching on MacOS

#!/usr/bin/env python3

import asyncio
import iterm2

THEME_LIGHT = "Tango Light"
THEME_DARK = "Tango Dark"


class AutoSwtichTheme:
    def __init__(self, connection, light="Light Background", dark="Dark Background"):
        self.connection = connection
        self.light = light
        self.dark = dark

    async def get_app(self):
        return await iterm2.async_get_app(self.connection)

    async def get_theme(self) -> str:
        parts = await (await self.get_app()).async_get_theme()
        if len(parts) <= 1:
            return parts[0]
        return ""

    async def set_color_preset(self, theme):
        preset = await iterm2.ColorPreset.async_get(
            self.connection, self.light if theme == "light" else self.dark
        )

        profiles = await iterm2.PartialProfile.async_query(self.connection)
        for partial in profiles:
            await (await partial.async_get_full_profile()).async_set_color_preset(
                preset
            )


async def quit(connection):
    while True:
        if not connection.websocket.open:
            exit(0)
        await asyncio.sleep(1)


async def main(connection):
    asyncio.ensure_future(quit(connection), loop=asyncio.get_event_loop())

    ast = AutoSwtichTheme(connection, THEME_LIGHT, THEME_DARK)
    await ast.set_color_preset(await ast.get_theme())

    async with iterm2.VariableMonitor(
        connection, iterm2.VariableScopes.APP, "effectiveTheme", None
    ) as mon:
        while True:
            # Block until theme changes
            theme = await mon.async_get()

            # Set preset if theme has changed
            await ast.set_color_preset(theme)


try:
    iterm2.run_forever(main)
except:
    print("Unable to connect on iTerm2 application")

@stefanwascoding
Copy link

stefanwascoding commented Oct 3, 2021

The latest beta (3.5) includes separate color settings for light & dark mode. Toggling dark mode automatically switches colors.

@plivox
Copy link

plivox commented Oct 3, 2021

The latest beta (3.5) includes separate color settings for light & dark mode. Toggling dark mode automatically switches colors.

Great!

@xplosionmind
Copy link

xplosionmind commented Dec 28, 2021

Hello everybody, this script is really helpful, but I find myself having to click on “Scripts > switch_automatic.py” when the system theme switches in order to make the iTerm theme change… shouldn’t it happen automatically as soon as the system theme changes? Am I doing something wrong?

@FradSer
Copy link
Author

FradSer commented Dec 29, 2021

@xplosionmind in ~/Library/ApplicationSupport/iTerm2/Scripts folder you can create a new folder AutoLaunch, then put the script into it, it will work always.
But the official solution is download latest beta (3.5) as @stefanwascoding said.

@xplosionmind
Copy link

xplosionmind commented Dec 29, 2021

in ~/Library/ApplicationSupport/iTerm2/Scripts folder you can create a new folder AutoLaunch, then put the script into it, it will work always.

Thanks! It now works wonderfully.


But the official solution is download latest beta (3.5) as @stefanwascoding said.

Does this mean that since 3.5 there won’t be any necessity for this script to be used?

@FradSer
Copy link
Author

FradSer commented Dec 30, 2021

@aravinds92
Copy link

aravinds92 commented Apr 6, 2022

Hello folks - I was able to get the background switching from dark to light whenever the system settings toggle. But the text color seems to reset to white every time. Is there a command I can use to set the text to different rgb combinations?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment