Tabs in Terminal using Applescript on Leopard

I use screen to maintain open sessions to our servers at work. I’ve used iTerm in the past, but now that Terminal.app (on Leopard) has tabs I’d rather use it instead.

The script first checks if you have the window open already, and if you do, it’ll apply focus. If you don’t, then it launches a new Terminal window, puts 4 tabs in the window, and in each tab executes the screen command.

Note: Wordpress converted all my comments to start with a single dash, so if you’re copying-and-pasting this code you’ll need to fix the comments. All comments are meant to start with a double-dash.

There’s some bad coding conventions in there, like using global variables and not breaking out of the loop when we find what we want, but I simply don’t know how to do this in Applescript. This is my first real attempt at AS, and it has taken me long enough… though I will accept patches against this script if you want to clean it up ;)

-- `menu_click`, by Jacob Rus, September 2006
-- 
-- Accepts a list of form: `{"Finder", "View", "Arrange By", "Date"}`
-- Execute the specified menu item.  In this case, assuming the Finder 
-- is the active application, arranging the frontmost folder by date.

on menu_click(mList)
  local appName, topMenu, r

  -- Validate our input
  if mList's length < 3 then error "Menu list is not long enough"

  -- Set these variables for clarity and brevity later on
  set {appName, topMenu} to (items 1 through 2 of mList)
  set r to (items 3 through (mList's length) of mList)

  -- This overly-long line calls the menu_recurse function with
  -- two arguments: r, and a reference to the top-level menu
  tell application "System Events" to my menu_click_recurse(r, ¬
    ((process appName)'s (menu bar 1)'s (menu bar item topMenu)'s ¬
    (menu topMenu)))
end menu_click

on menu_click_recurse(mList, parentObject)
  local f, r

  -- `f` = first item, `r` = rest of items
  set f to item 1 of mList
  if mList's length > 1 then set r to (items 2 through (mList's length) ¬
    of mList)

  -- either actually click the menu item, or recurse again
  tell application "System Events"
    if mList's length is 1 then
      click parentObject's menu item f
    else
      my menu_click_recurse(r, (parentObject's (menu item f)'s (menu f)))
    end if
  end tell
end menu_click_recurse

-- Matthew Lambie, November 2007
-- http://lambie.org

-- Opens a Terminal with four tabs that then each reconnect to named screen 
-- sessions or if that window is already opened, reapply focus

global window_id
global window_name
set window_id to 0
set window_name to ""
set user to "mlambie"
set server to "hotrod"
set user_at to user & "@" & server

-- MAINLINE
tell application "Terminal"
  activate

  -- get every window id
  set w_ids to (id of every window)

  -- with each window id...
  repeat with w_id in w_ids

    -- have we found our target window_id?
    if window_id is equal to 0 then

      -- load this window's name
      set w_name to name of window id w_id

      -- is this the window we're looking for?
      if (texts 1 thru (count user_at) of w_name) is equal to user_at then
        set window_id to w_id
        set window_name to name of window id window_id
      end if
    end if
  end repeat

  -- if we have a window_id then we can give that window
  -- the focus, otherwise we need to make a new window
  -- with four tabs and execute the ssh/screen command in
  -- each of those four tab 

  if (window_id is not equal to 0) then
    -- give that window the focus
    set frontmost of window id window_id to true
  else

    -- make a new window with the execution of a trivial command
    do script "clear"

    -- load up the window id of the window we just created
    set window_id to id of first window whose frontmost is true

    -- make tabs 2, 3 and 4
    repeat with i from 1 to 3
      my menu_click({"Terminal", "Shell", "New Tab", "Pro"})
    end repeat

    -- for each of the four tabs we've now made
    repeat with i from 1 to 4

      -- build the command, then execute it
      set cmd to "clear; ssh -t " & server & " 'screen -d -R tfg_" & i & "'"
      do script cmd in tab i of window id window_id of application "Terminal"

    end repeat
  end if
end tell

4 Comments so far

  1. Fred Cavandar on December 12th, 2007

    Thanks for this script. Just upgraded to leopard and decided to tackle scripting terminal so I could launch specific named sessions via Quicksilver. This script is an excellent start for another applescript novice.

  2. keith on May 29th, 2009

    Seconded!! Thank you!!

  3. Rush on September 23rd, 2009

    This is a great! Helped me get going on applescript with terminal - monitoring for the production environment.

  4. Paul on October 22nd, 2009

    On Snow Leopard it says: Expected “,” but found a number on the line which reads

    if (texts 1 thru (count user_at) of w_name) is equal to user_at then

    How can I fix this?

Leave a Reply