terminal

AppleScript tricks: What to Do When the Frontmost Window Isn't Frontmost

The Problem: Scripts often target the current document window of an application. This is usually easily handled with something like…

Tell application "Finder" to get window 1

The problem with this approach is that it returns a useless window if the wrong kind of window is in front. In the Finder, this will often be a Get Info window, folder options window, or preferences. Some applications have special classes of windows to make this easier, but many do not. To find the frontmost window of these applications, you need to do this manually.

To make this work, you need to loop through your windows until you find one of the right type. You could do this by the name of the window (e.g. find Finder windows whose names don’t contain “Finder Preferences”), but that requires you to catalog the names of every non-standard window, and can cause problems if, for example, you have a folder named “Finder Preferences.”

A better approach is to identify a property that only the right kind of windows contain. So, for Finder windows, you can look for the folder of the window, as in…

Tell application "Finder"
        set theFolder to (path to desktop folder as alias)
        repeat with i from 0 to (count of windows)
                try
                        get folder of window i
                        set theFolder to result as alias
                        exit repeat
                end try
        end repeat
end tell

In this code, the “try” handler gracefully handles windows without the “folder” property. Likewise, by setting theFolder to the Desktop to begin with, it also handles the situation where there are no open windows.

Using this technique, the following script will open the current Finder window in a new tab in the frontmost Terminal window. If there isn’t a terminal window available, it opens a new window. The code gets pretty involved for the Terminal (including having to go to UI scripting to make a new tab), but it avoids the pitfalls of multiple open windows in each application, not all of which are useful folder or terminal windows.

on run
        get quoted form of POSIX path of my getCurrentFolder()
        my termScriptInNewTab("cd " & result)
end run
 
on termScriptInNewTab(cmd)
        tell application "Terminal"
                activate
                set termWins to count of windows
                set frontWin to 0
                repeat with i from 1 to (count of windows)
                        try
                                set tabCount to count of tabs of window i
                                set frontWin to i
                                exit repeat
                        end try
                end repeat
                if frontWin is 0 then
                        do script cmd
                else
                        set frontmost of window frontWin to true
                        tell application "System Events" to tell (first application process whose name is "Terminal") to keystroke "t" using {command down}
                        set xi to 0
                        repeat until (count of tabs of window 1) is (tabCount + 1)
                                if xi ≤ 4 then -- don't wait more than one second
                                        delay 0.25
                                else
                                        set xi to -1
                                        exit repeat
                                end if
                        end repeat
                        if xi is not -1 then
                                do script cmd in (last tab of window 1)
                        else
                                do script cmd
                        end if
                end if
        end tell
end termScriptInNewTab
 
on getCurrentFolder()
        tell application "Finder"
                set theFolder to (path to desktop folder as alias)
                repeat with i from 0 to (count of windows)
                        try
                                get folder of window i
                                set theFolder to result
                                exit repeat
                        end try
                end repeat
                return theFolder as alias
        end tell
end getCurrentFolder

Extra credit: How can you adapt the termScriptInNewTab handler to run the command in the first tab that isn’t busy, rather than a new tab?

Making Markdown + Textmate export just a little bit nicer

I tend to use Markdown syntax for most of my document creation needs. Then I use TextMate’s built-in Markdown support to convert to a Word document, RTF, PDF, etc… as necessary.

The one problem I have is that a lot of the so-called MultiMarkdown commands in TextMate leave me opening a file in my /tmp folder. If I forget to do a Save As… my document is lost forever. No good!

Here’s how you fix it…

Ensuring trouble-free backups from your Mac to not-a-Mac

My current project is to enable network backups of my Mac and my wife’s PC over the internet, so that we have an off-site backup of last resort, should our house burn down, fall over, and then sink into the swamp.

Anyone who’s used a Mac for a long time knows that transferring Mac-native files over the internet is fraught with peril. You risk losing type and creator codes and resource forks, as well as a number of other forms of metadata introduced with MacOS X. So my first step was to determine how I could safely encode my files so that they could make the trip to a foreign server (which would either by a Linux-type box on my web host, or an Amazon S3 account) and then back again, with the file intact for recovery.

Command line reference for Mac, Linux, Windows and Oracle

ss64.com hosts this awesome reference to every single command line program and option available in MacOS X, Linux (Bash), Windows and (ugh) Oracle.

Wonderful reference and a great companion to Apple’s shell scripting primer.

Visor: Terminal anywhere

Visor, the new application from Blacktree, creates a half-screen terminal window that pops up with the press of a hot key. This terminal is persistent, so when it’s in the background, it just keeps on going and going and going.

Very clever little hack, and extremely useful if you’re prone to bouncing between the terminal and your desktop.

The only problem I’ve had with it is that it’s only one window. So I invoke screen as soon as it starts up, and that pretty much takes care of it.

Thanks, Blacktree!

I have disabled comments due to an overwhelming amount of comment spam, that I cannot seem to stop, no matter how hard I try.

Syndicate content