Running Tests from MacVim in iTerm2 Version 3

Way back in 2011, I wrote a blog post showing how to Run Tests from MacVim via Terminal.app or iTerm.app. I’ve been using that setup for years without a problem, but when iTerm2 Version 3 was released, it stopped working. I’ve updated the AppleScript and am posting it here for anyone who wants to run tests in iTerm2 (Version 3) while writing code in Vim.

The Release Notes for Version 3 specifically point out that while the AppleScript has been improved, it’s not backward-compatible. After reading through the Scripting Documentation, I was able to modify the original run_command.applescript file so that it now works with iTerm2 Version 3 (but no longer works with older versions of iTerm2).

As I stated in my original post, I’m no AppleScript expert. I’ve only learned enough to get this working, and then to fix it when it broke. It works again, and that means I can get back to my preferred workflow of editing in Vim and running the tests in a terminal window.

Here’s the updated script:

on appIsRunning(appName)
  tell application "System Events" to (name of processes) contains appName
end appIsRunning

on execInModernItermTab(_window, _tab, _session, _command)
  tell application "iTerm"
    activate
    tell _tab
      select
    end
    tell _window
       select
    end tell
    tell current session of current window
      write text _command
    end tell
  end tell
end execInModernItermTab

on execInTerminalTab(_window, _tab, _command)
  tell application "Terminal"
    activate
    set frontmost of _window to true
    set selected of _tab to true
    do script _command in _tab
  end
end execInTerminalTab

on run argv
  set _command to item 1 of argv
  set _foundTab to false
  -- Second arguments shoul be the tty to look for
  if length of argv is 2
    if appIsRunning("iTerm2") then
      tell application "iTerm"
        set _foundTab to false
        repeat with w in windows
          tell w
            repeat with t in tabs
              tell t
                repeat with s in sessions
                  set _tty to (tty of s)
                  if _tty = (item 2 of argv)then
                    set _foundTab to true
                    set _session to s
                    set _tab to t
                    set _window to w
                    exit repeat
                  end if
                end repeat
              end tell
              if _foundTab then
                exit repeat
              end if
            end repeat
          end tell
          if _foundTab then
            exit repeat
          end if
        end repeat
      end tell
      if _foundTab then
        execInModernItermTab(_window, _tab, _session, _command)
      end if
    end if
    if not _foundTab and appIsRunning("Terminal") then
      tell application "Terminal"
        repeat with w in windows
          tell w
            repeat with t in tabs
              set _tty to (tty of t)
              if _tty = (item 2 of argv) then
                set _foundTab to true
                set _window to w
                set _tab to t
                exit repeat
              end if
            end repeat
          end tell
          if _foundTab then
            exit repeat
          end if
        end repeat
      end tell
      if _foundTab then
        execInTerminalTab(_window, _tab, _command)
      end if
    end if
  end if
end run

Hope this is helpful for you.