pythoniterm2

How does the iterm2 Python API determine which tab a script is running in?


I have a set of window tabs I use regularly, and when I start up iTerm2, I restore this using "Window->Restore Window Arrangement".

In .bashrc, I'd like to use the Iterm Python API to set the bash history filename to match the tab's title.

To do this, I wrote a Python script using the iterm python API to get the tab title:

  import iterm2
  async def main(connection):
    app = await iterm2.async_get_app(connection)
    window = app.current_window
    tab = app.current_terminal_window.current_tab
    title = (await tab.async_get_variable("titleOverride"))

  iterm2.run_until_complete(main)

However, this doesn't work as "current_tab" is the frontmost tab, which happens to be the last tab opened - not the tab the current .bashrc is running in.

For example, in the screenshot, the "current_tab" is "Apache", so all the instances of the script report it as the "current_tab", whereas what I need is 'Src', 'Bld', etc.

I've consulted the documentation and can't find a solution.

How can I do this?

enter image description here


Solution

  • Soooo, with a bit of help I was able to write a Python script which accomplished what I wanted, though it's the "opposite" way of what I'd intended: It creates the tabs and names them, rather than interpreting a tab.

    You just start up iTerm2 and run this in a shell. A new window will be opened and your tabs set up as you like them.

    Here's the script in case anyone else would like some inspiration:

    #!/usr/bin/env python3
    import iterm2
    import colorsys
    
    def hsv_to_rgb(h, s, v):
        r, g, b = colorsys.hsv_to_rgb(h/360, s, v)
        return int(r*255), int(g*255), int(b*255)
    
    async def main(connection):
        app = await iterm2.async_get_app(connection)
    
        # Create a new window
        window = await iterm2.Window.async_create(connection)
    
        # Get the initial tab (the extra one we want to close later)
        initial_tab = window.current_tab
    
        # Generate 8 colors
        colors = [
            iterm2.Color(*hsv_to_rgb(0, 1, 1)),    # Red
            iterm2.Color(*hsv_to_rgb(42, 1, 1)),   # Orange
            ...more colors here...
            iterm2.Color(*hsv_to_rgb(297, 1, 1)),  # Violet
        ]
    
        # Define tabs with their names and corresponding directories
        tabs = [
            {"name": "Src", "dir": "...directory for Src Tab...", "cmd": "...initial command for Src Tab...", "color": colors[0]},
            {"name": "Bld", "dir": "...directory for Bld Tab...", "cmd": "...initial command for Bld Tab...", "color": colors[1]},
            ... More Tabs Here ...
            {"name": "Sandbox", "dir": "...directory for Sandbox Tab...", "color": colors[7]}
        ]
    
        for tab_info in tabs:
            print("Handling Tab " + tab_info['name'])
            # Create a new tab
            tab = await window.async_create_tab()
            # Set the tab title
            await tab.async_set_title(tab_info["name"])
            # Get the session in the current tab
            session = tab.current_session
            # Set up a unique bash history file for this tab
            history_file = f"~/.bash_history_{tab_info['name'].lower().replace(' ', '_')}"
            # Send commands to set up the unique history file and change directory
            await session.async_send_text(f"export HISTFILE={history_file}\n")
            await session.async_send_text(f"history -r {history_file}\n")
            await session.async_send_text(f"cd {tab_info['dir']}\n")
            # Run initial command if specified
            if "cmd" in tab_info:
                await session.async_send_text(f"{tab_info['cmd']}\n")
            if "color" in tab_info:
                change = iterm2.LocalWriteOnlyProfile()
                change.set_tab_color(tab_info['color'])
                change.set_use_tab_color(True)
                await session.async_set_profile_properties(change)
            # Optional: Clear the screen for a clean start
            # await session.async_send_text("clear\n")
    
        # Close the initial tab
        if initial_tab:
            await initial_tab.async_close()
    
    # Run the script with retry=True
    iterm2.run_until_complete(main, retry=True)