├── .gitignore ├── package.json ├── autotermrc.sample ├── yarn.lock └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "autoterm", 3 | "version": "0.1.0", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "dependencies": { 7 | "applescript": "^1.0.0", 8 | "lodash": "^4.17.19", 9 | "toml": "^2.3.1" 10 | }, 11 | "bin": { 12 | "autoterm": "index.js", 13 | "att": "index.js" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /autotermrc.sample: -------------------------------------------------------------------------------- 1 | # My Application 2 | [myapp] 3 | path="~/code/myapp" 4 | 5 | [myapp.app] 6 | command="./node_modules/.bin/ng serve" 7 | 8 | [myapp.mock-api] 9 | path="~/code/tdmc-mock-api" 10 | command="nodemon server.js" 11 | 12 | [myapp.terminal] 13 | command="code . && clear" 14 | 15 | # My Second Application 16 | [myapp2] 17 | path="~/code/myapp2" 18 | 19 | [myapp2.pagekite] 20 | command="pagekite.py 8081 fcoury.pagekite.me" 21 | 22 | [myapp2.server] 23 | command="PORT=8081 nodemon index.js" 24 | 25 | [myapp2.terminal] 26 | command="code ." 27 | 28 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | applescript@^1.0.0: 6 | version "1.0.0" 7 | resolved "https://registry.yarnpkg.com/applescript/-/applescript-1.0.0.tgz#bb87af568cad034a4e48c4bdaf6067a3a2701317" 8 | 9 | lodash@^4.17.19: 10 | version "4.17.19" 11 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b" 12 | 13 | toml@^2.3.1: 14 | version "2.3.1" 15 | resolved "https://registry.yarnpkg.com/toml/-/toml-2.3.1.tgz#f1c02ff327b586f3ac97d8e75eacf26b1daf0b06" 16 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env node 2 | 3 | const toml = require('toml'); 4 | const fs = require('fs'); 5 | const applescript = require('applescript'); 6 | const _ = require('lodash'); 7 | 8 | const home = process.env.HOME; 9 | const contents = fs.readFileSync(`${home}/.autotermrc`); 10 | const apps = toml.parse(contents); 11 | 12 | const app = process.argv[2]; 13 | 14 | if (!app) { 15 | console.error('usage: autoterm '); 16 | console.error(' apps:', Object.keys(apps).filter(app => app !== 'actions').join(', ')); 17 | process.exit(3); 18 | } 19 | 20 | if (apps[app]) { 21 | let appDef = apps[app]; 22 | let path; 23 | 24 | if (appDef.path) { 25 | path = appDef.path; 26 | appDef = _.omit(appDef, ['path']); 27 | } 28 | 29 | const childScript = makeScript(appDef, { path }); 30 | 31 | const script = ` 32 | tell application "iTerm" 33 | set theWindow to (current window) 34 | tell theWindow 35 | create tab with default profile 36 | tell current session of theWindow 37 | ${childScript} 38 | end tell 39 | end 40 | end tell 41 | `; 42 | 43 | applescript.execString(script, function(err, rtn) { 44 | if (err) { 45 | console.error('Error:', err); 46 | process.exit(1); 47 | } 48 | }); 49 | } else { 50 | console.error(`No app: ${app}`); 51 | console.error(' apps:', Object.keys(apps).filter(app => app !== 'actions').join(', ')); 52 | process.exit(2); 53 | } 54 | 55 | function makeCommand(cmd, options) { 56 | let command = []; 57 | options = options || {}; 58 | 59 | let path = cmd.path || options.path; 60 | 61 | if (path) { 62 | command.push(`cd ${path}`); 63 | } 64 | 65 | if (cmd.command) { 66 | command.push(cmd.command); 67 | } 68 | 69 | command = command.map(cmd => `write text " ${cmd}"\n`); 70 | 71 | return command.join(''); 72 | } 73 | 74 | function makeScript(commands, options) { 75 | let keys = Object.keys(commands); 76 | keys = [_.head(keys)].concat(_.reverse(_.tail(keys))); 77 | return keys.map((key, i) => { 78 | const cmd = commands[key]; 79 | let script = makeCommand(cmd, options); 80 | if (i > 0) { 81 | script = ` 82 | set newSplit to (split horizontally with default profile) 83 | tell newSplit 84 | ${script} 85 | end tell 86 | `; 87 | } 88 | return script; 89 | }).join("\n"); 90 | } 91 | --------------------------------------------------------------------------------