Applescript (osascript): opening split panes in iTerm 2 and performing commands

回眸只為那壹抹淺笑 提交于 2019-12-04 03:03:31

With the new nightly build it is quite nice. It seems to be missing in the public version, although it was implemented about a year ago: Source - AppleScriptTest.m

tell application "iTerm"
    activate
    select first terminal window

    # Create new tab
    tell current window
        create tab with default profile
    end tell

    # Split pane
    tell current session of current window
        split vertically with default profile
        split vertically with default profile
    end tell

    # Exec commands
    tell first session of current tab of current window
        write text "cd ~/Developer/master-node"
        write text "coffee"
    end tell
    tell second session of current tab of current window
        write text "gulp w"
    end tell
    tell third session of current tab of current window
    end tell
end tell

I had to search way too long for this, so maybe I can help somebody out with this (probably myself in a couple of weeks), because this was one of the first things I found. This solution even works with activated focus-follows-mouse, which is missing in the other answers.

As Dom pointed out, in the new 2.9 beta builds, the other answers won't work anymore. I was frustrated by not being able to automated this so I wrote a teamocil compatible command line tool that does exactly this:

https://github.com/TomAnthony/itermocil

It allows you to write YAML files for pre-configured sets of windows and panes, which can run pre-defined sets of commands for the given project.

Update: iTerm2 v3 has much-improved, but incompatible AppleScript support - see https://www.iterm2.com/documentation-scripting.html

To provide some background to @Joel's own answer:

iTerm 2's AppleScript support (as of iTerm 2 v1.0.0.201306220):

  • is incomplete: there is no support to script split panes - hence the OP is resorting to the suboptimal technique of sending keystrokes.

  • exhibits some bizarre behavior: when compiling (in AppleScript Editor) a tell "System Events" ... statement inside a tell application "iTerm" block, the prefix i term application is inexplicably inserted before the "System Events" - since the code below is not precompiled, this prefix is not included so as to avoid problems in the future.

  • has bugs / is inconsistent with its dictionary: what the dictionary describes as the exec command - which doesn't actually work - is in reality fulfilled by the write text command: it executes the argument passed or - if the argument has a trailing space - simply "types" the argument without submitting it.

Here's the solution with split panes based on the workaround (sending keystrokes) - a bash script invoking AppleScript code via osascript:

Limitations, due to panes not being part of the dictionary:

  • the other pane that is opened cannot be named
  • no command can be sent to the other pane
#!/usr/bin/env bash

projectFolder="$HOME/Desktop" # example
osascript <<-EOF
  tell application "iTerm"
    tell (make new terminal) # Create a new pseudo terminal...
      tell (launch session "Default session") # ... and open a session (window)
        # Name the new window (its original pane).
        set name to "Server"
        # Execute the 'cd' command in the original pane.
        write text "cd '$projectFolder'"
        # Create a new split pane, horizontally, by sending ⌘⇧-D 
        tell application "System Events" to keystroke "d" using {shift down, command down}
          # !! Note: We canNOT:
          #  - name this pane separately
          #  - execute a command in it.
        # Return to the original pane, by sending ⌘-[ 
        tell application "System Events" to keystroke "[" using {command down}
      end tell
    end tell
  end tell
EOF

starting from @mklement0, this is my script that open a new tab, split in 4 panels and run comands:

#!/usr/bin/env bash
osascript <<-EOF
    set cmds to {"rabbitmq-server", "mongod", "redis-server", "htop"}

    tell application "iTerm"
        activate
        set myterm to (current terminal)

        tell myterm
            launch session "Default Session"

            # split vertically
            tell application "System Events" to keystroke "d" using command down
            delay 1
            # previus panel
            tell application "System Events" to keystroke "[" using command down
            delay 1
            # split horizontally
            tell application "System Events" to keystroke "d" using {shift down, command down}
            delay 1
            # next panel
            tell application "System Events" to keystroke "]" using command down
            delay 1
            # split horizontally
            tell application "System Events" to keystroke "d" using {shift down, command down}

            set n to count of cmds
            repeat with i from 1 to n
                # next panel
                tell application "System Events" to keystroke "]" using command down
                delay 1
                tell the current session to write text (item i of cmds)
            end repeat
        end tell

    end tell  
EOF

In case it's helpful: I have the similar problem of wanting a key combo shortcut in iTerm to split panes and have the new pane inherit the title of the original session. I came up with the following, which solves that problem and relies less on sending keystrokes (though I'd love to eliminate them entirely).

tell application "iTerm"
    tell the current terminal
        tell the current session
            set the_name to get name
            tell i term application "System Events" to keystroke "d" using {command down, shift down}
        end tell

        tell the current session
            set name to the_name
        end tell
    end tell
end tell

I am using BetterTouchTool to bind a key combo -- namely, cmd+' -- to the execution of this AppleScript. (I find that it gets screwy for some key combos, I would naively guess because you are effectively holding that key combo down on top of whatever keystrokes the script sends. I haven't chased down how to define the keyboard shortcut in the preferences of iTerm itself. I suspect that might mitigate the issue.)

Okay, so I finally figured this out.

By sending keystrokes to the application, you can open and navigate split-pane.

tell i term application "System Events" to keystroke "D" using command down

tell i term application "System Events" to keystroke "]" using command down

An example sending commands to split pane and naming each pane. I use this to start my node application.

write text "cd $projectsFolder/$2.m"

write text "/usr/local/bin/frontend.sh $1 $2"

tell i term application "System Events" to keystroke "D" using command down

tell i term application "System Events" to keystroke "]" using command down

set name to "$2.api"

write text "cd $projectsFolder/$2.api"

write text "/usr/local/bin/backend.sh $1 $2"
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!