I like to tweak my workflow all the time. I often change something for a week, try it out and then either change back or move on to something else. I got used to tabbed terminals in Linux and even had mrxvt working under cygwin, so when I came to the Mac not having tabs in the Terminal bugged me. I tried several solutions and settled on iTerm. Life was good for a while. I got tired of using nohup to run long emerges in the background on the servers, so I learned about gnu screen. That led me to wonder if you could get labels for the various windows, and sure enough the hardstatus line will happily act as a tab bar for you as long as your not fond of clicking to change tabs (in the terminal? You shouldn't be). I had seen Visor and thought it was cool, so I tried it out for a while with Screen to give me tabs. There where some problems with Visor interacting weird with screen, so back to iTerm I went. When I updated to Leopard, I moved to Terminal.app, since it had tabs now. But it turns out I had grown to love the "Do what I'm typing in all tabs" feature. So I went back yet again. But iTerm didn't work as well for me under Leopard as it did under Tiger. So I got over not having the do in all tabs feature and lived with Terminal.app. Recently I realized that I was spending a lot of time 'setting up' my work environment. The steps go like this:
- Go to tab 1
- Stop script server
- Change directory to new project
- Restart script/server
- Go to tab 2
- Stop autotest
- Change directory to new project
- Start autotest
- Go to tab 3
- Change directory to new project
- Run sake gitrdone
- does svn up or git pull (depending on .git file)
- does rake db:migrate
- rake db:test:clone
- rake spec:db:fixtures:load
- rake notes
- svn status | grep ? or git status
- mate .
So yeah, thats a lot. Way to much to do manually (even with the awesome sake script). So I started looking around the web to see what others had done. I found this OnRails article which seems to have met with some serious frustration, and the associated links. The outlook did not look good. So back to iTerm... again. That still wasn't satisfying. Then I stumbled across something (I don't remember what) that mentioned screens -X and its -X stuff command. The way it works is this. -X tells screen to do one of its internal commands from the outside, so screen -X next would change the focused window by one, either form inside the screen session or from outside of it. stuff 'do this' is the screen command that sends 'do this' to the current screen. That got me thinking... what if screen could be used to do all the magic that Apples sucky Applescript in Terminal.app can't? So I started to fiddle and hack and read. Screen's documentation is the suck, though I did find this source This led to the creation of the following script
#!/usr/bin/env ruby
def find_or_create_by_id(window_id)
File.delete('/tmp/current_screen') if File.exists?("/tmp/current_screen")
`screen -p #{window_id} -X hardcopy /tmp/current_screen`
sleep(0.1)
unless File.exists?("/tmp/current_screen") && File.size("/tmp/current_screen") > 0
`screen -X screen`
return find_or_create_by_id(window_id)
end
return window_id
end
i = 0
find_or_create_by_id(i)
`screen -p #{i} -X stuff ''`
`screen -p #{i} -X stuff 'cd #{ARGV[0]}; ruby script/server --debugger'`
i += 1
find_or_create_by_id(i)
`screen -p #{i} -X stuff ''`
`screen -p #{i} -X stuff ''`
`screen -p #{i} -X stuff 'cd #{ARGV[0]}; sake git_r_done; autotest'`
i += 1
find_or_create_by_id(i)
`screen -p #{i} -X stuff 'cd #{ARGV[0]}; mate .'`
I drop that into my bin dir under the title hack and now as long as screen is running I can do hack ~/work/project/trunk and off I go. It is worth noting that since it sends a kill to whatever is running in the first and second screen tabs, you have to run it from either outside screen or from some tab other than the first or second.
I also found this article that showed my some other features of scripting screen and allowed me to write a script I call all which takes whatever you type after it and sends it to all open tabs in a screen session.
I've coupled this with my .screenrc file and the new version of Visor lets me have simple drop down terminal with all the power I need.