Last active
September 14, 2017 20:52
-
-
Save pmdarrow/96eb5fcc9c460336fc56 to your computer and use it in GitHub Desktop.
Launch iTerm 2 with a predefined tab & split configuration using Apple's "Javascript for Automation"
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* AppleScript to launch iterm2 terminals/tabs with configurable: | |
* ~ Name <name> | |
* ~ List of commands <cmds> | |
* ~ Split behavior horizontal(h) or vertical(v) <split> :: (h, v) | |
* | |
* Run from terminal with `osascript iterm-launcher.js`. | |
* Don't unfocus with the mouse/keyboard while executing the script. | |
* | |
* JS port of https://github.com/luismartingil/scripts/blob/master/iterm_launcher02.applescript | |
*/ | |
var layout = [ | |
[{ | |
name: 'Pane 1', | |
cmds: ['echo 1', 'ls'], | |
split: 'v' | |
}, { | |
name: 'Pane 2', | |
cmds: ['echo 2', 'ls'] | |
}], | |
[{ | |
name: 'Pane A', | |
cmds: ['echo A', 'ls'], | |
split: 'h' | |
}, { | |
name: 'Pane B', | |
cmds: ['echo B', 'ls'] | |
}] | |
]; | |
/****************************************************************/ | |
var SystemEvents = Application('System Events'); | |
var iTerm = Application('iTerm'); | |
// Returns the last pane that was created in iTerm | |
function lastPane() { | |
var len = iTerm.currentTerminal.sessions.length; | |
return iTerm.currentTerminal.sessions[len - 1]; | |
} | |
for (var i = 0; i < layout.length; i++) { | |
var tabItem = layout[i]; | |
// Create a new tab | |
iTerm.currentTerminal.launch({session: i + ''}); | |
for (var j = 0; j < tabItem.length; j++) { | |
var paneItem = tabItem[j]; | |
// Initialize a new pane | |
var pane = lastPane(); | |
pane.name = paneItem.name; | |
// Run the commands | |
for (var k = 0; k < paneItem.cmds.length; k++) { | |
pane.write({text: paneItem.cmds[k]}); | |
} | |
// Execute the split | |
if ('split' in paneItem) { | |
var splitChar = 'd'; | |
if (paneItem.split == 'h') { | |
splitChar = 'D'; | |
} | |
SystemEvents.keystroke(splitChar, {using: 'command down'}); | |
} | |
} | |
} |
@bruth I've had the same problem — the documentation on JXA is pretty awful. You should be able to do something like this:
// iterm.json
{
"layout": [
[{
"name": "Pane 1",
"cmds": ["echo 1", "ls"],
"split": "v"
}, {
"name": "Pane 2",
"cmds": ["echo 2", "ls"]
}],
[{
"name": "Pane A",
"cmds": ["echo A", "ls"],
"split": "h"
}, {
"name": "Pane B",
"cmds": ["echo B", "ls"]
}]
]
}
// iterm-launcher.js
var fileContents = $.NSString.stringWithContentsOfFile('iterm.json').js;
var layout = JSON.parse(fileContents).layout;
...
@pmdarrow I thought you may be interested in my recent project:
https://github.com/TomAnthony/itermocil
It is a Python script that writes Applescript to do the same thing in iTerm, and uses teamocil compatible YAML files for configuration.
@TomAnthony your project looks great. Seems you've figured out the timing issues, I'm having all sorts of problems with that!
Thank you so much. Spent an hour trying to figure this out!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is a convenient script, thank you for putting it together. I tried modifying it to read the
layout
data from a file in your home directory (and parse it as JSON), but I cannot seem to find clear documentation on how to read a file from disk. Any thoughts on this?