Skip to content

Instantly share code, notes, and snippets.

@pmdarrow
Last active September 14, 2017 20:52
Show Gist options
  • Star 15 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save pmdarrow/96eb5fcc9c460336fc56 to your computer and use it in GitHub Desktop.
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"
/**
* 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
Copy link

bruth commented Apr 24, 2015

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?

@pmdarrow
Copy link
Author

pmdarrow commented May 5, 2015

@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;

...

@TomAnthony
Copy link

@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.

@pmdarrow
Copy link
Author

pmdarrow commented Oct 1, 2015

@TomAnthony your project looks great. Seems you've figured out the timing issues, I'm having all sorts of problems with that!

@rclayton-the-terrible
Copy link

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