Most of the projects I work on require about four Terminal tabs, two Atom windows, and Chrome open to localhost. It takes a nontrivial amount of time to open all that stuff up, so I normally automate these things.
Generally I'll use Alfred to run a terminal command: an alias to an AppleScript execution.
AppleScript
The way to open and manipulate applications on MacOS is with AppleScript, an idiosyncratic scripting language generally written using the pre-installed Script Editor
.
Here I'll go through the process of writing a script to open two directories in two different terminal windows, each with an additional tab, executive npm run dev
. We'll open one of these directories in Atom, and open up Google Chrome to http://localhost:3000
. To start an application with AppleScript, you use a tell
block and instruct the application by name to activate
.
tell application "Terminal"
activate
end tell
Tip: the character for comments in AppleScript is
#
, though theScript Editor
won't parse the change in syntax highlighting until you save or execute the script.
If the application is already open, this will bring it to the foreground. Inside this tell
block, we can continue issuing commands to our Terminal, we'll use do script
to change into our project directory.
#...
activate
do script "cd ~/Projects/Company/app-server"
#...
We can even be more explicit about which tab/window we want to exeute the script in:
#...
activate
do script "cd ~/Projects/Company/app-server" in tab 1 of front window
#...
Next, we'll want to open up a couple more tabs and windows. Add two function definitions to the bottom of our script:
#...
on makeTab()
tell application "System Events" to keystroke "t" using {command down}
delay 0.2
end makeTab
on makeWindow()
tell application "System Events" to keystroke "n" using {command down}
delay 0.2
end makeWindow
All these functions do is simulate a keypress (⌘N / ⌘T), and wait 0.2 seconds so the action has time to execute.
So, to finish off our terminal setup, I'll open up an extra window and two extra tabs, and executive npm run dev
by chaining shell commands. I'm adding an extra command to fullscreen our terminal sessions (just hitting ⌃⌘F), with some delay to give the animation time.
#...
activate
do script "cd ~/Projects/Company/app-server/" in tab 1 of front window
my makeTab()
do script "cd ~/Projects/Company/app-server/ ; npm run dev" in tab 2 of front window
tell application "System Events"
keystroke "f" using {control down, command down}
end tell
delay 1.5
my makeWindow()
delay 1.5
do script "cd ~/Projects/Company/app-client/" in tab 1 of front window
my makeTab()
do script "cd ~/Projects/Company/app-client/ ; npm run dev" in tab 2 of front window
#...
We need to open up Atom (still figuring out how to consistently get this in full-screen with two tabs):
#...
do shell script "/Applications/Atom.app/Contents/Resources/app/atom.sh ~/Projects/Company/app-server/"
#...
Finally, Google Chrome:
#...
tell application "Google Chrome"
activate
open location "http://localhost:3000"
delay 1
activate
end tell
end tell
And there we go! Now save this file to a meaningful directory. For me, that's ~/Development/AppleScripts/Company.scpt
.
Next step is to make this script executable by our user. Run the command chmod +x ~/Development/AppleScripts/Company.scpt
from your terminal.
Finally, it's time to define an alias.
Alias
Aliases aren't persistent, so we'll need to write a definition in a file that's executed everytime we launch a terminal session. For us, that's ~/.bash_profile
. Run nano ~/.bash_profile
.
Add the line:
alias Company='osascript ~/Development/AppleScripts/Company.scpt';
Tip: while you're here, you may want to define an alias for editing your bash_profile. Add:
alias bp='nano ~/.bash_profile; source ~/.bash_profile'
This is a two-letter shortcut to editing your bash profile and executing the changes.
Next, hit ⌃O then ⌃X to save and exit. To update your current terminal session, run source ~/.bash_profile
.
We're done! You can now run Company
from a terminal session to get straight into developing.
Stopping
You may find you have so many windows open while you work that it becomes laborious to even close them. I suggest an alias called stopwork
, which executes the following AppleScript:
tell application "Atom"
try # Improvement would be to catch specific error code thrown here
quit # This causes Atom to throw an error
end try
end tell
tell application "Activity Monitor"
quit
end tell
tell application "Terminal"
quit # You could figure out how to stop Terminal asking for confirmation
end tell
Awesome. With Alfred (Spotlight but 500x better) I can simply hit ⌘SPACE and type >Company, and I'm instantly working. And it's as easy as ⌘SPACE then >stopwork to quit everything.