Nik's Blog

Geekery, witty insights, software (of dubious quality) and more!

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…

I’ve added the following command to all the relevant MultiMarkdown commands:

/Developer/Tools/SetFile -a T "$DST.doc"

(Adjust as necessary changing .doc to .rtf or whatever you need, same for the $DST file path variable if that’s different in a custom command)

This uses the SetFile command (free with Apple’s developer tools) to change the converted document into a stationary pad. When you open up a stationary pad, it will create a new, untitled, document, which will prompt you to save to a location the first time you hit save.

Here’s my custom Markdown bundle to convert to a Word document:

# first figure out a name for the result
NAME="${TM_FILENAME:-untitled}"
BASENAME="${NAME%.*}"
DST="/tmp/$BASENAME"
`MultiMarkdown.pl|SmartyPants.pl >"$DST.html"`
# textutil is included with Tiger
require_cmd textutil
textutil -convert doc -extension doc "$DST.html"
`# set the file as stationary so it opens as a new doc` `/Developer/Tools/SetFile -a T "$DST.doc"`
# Open it up in Word
open -a "Microsoft Word" "$DST.doc"

[b]Special Bonus Tip:[/b] If you choose “Auto Format” from Word’s Format menu, it will nicely convert the headers into styled headers so that you can keep your document formatted with style sheets, and will also clean up lists in the same fashion! Efficient!

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.

A few months ago, the Plasticsfuture blog ran an excellent article comparing the capabilities of darn near every backup and restore program on the Mac. The results were disheartening: Only SuperDuper! could precisely back up and restore a file (although, in my own testing, I found that ChronoSync was updated and can now handle the job).

However, my needs are somewhat different. A network backup requires that I only update changed files, and furthermore, I won’t be accessing them on a filesystem. So SuperDuper’s use of a disk image to perform network backups is straight out. So, too, is ChronoSync, since it can only back up to a network filesystem.

No, I need something that can encode individual files, ideally via a script or some other automated method. Furthermore, I’m mostly just concerned about archiving documents (I don’t want to pay for online storage of my whole hard drive!), so if permissions, ACLs (which I don’t use), or BSD flags are munged, that’s all right. This is truly a last-resort backup, so if I can get resource forks and extended attributes to back up, I’m pretty happy.

Now, according to Apple, a number of command-line utilities have been updated to deal correctly with extended attributes and resource forks – these include tar, cpio, ditto, and zip. There are also a handful of third-party archivers/compressors out there which also claim Mac compatibility such as the x7z (a Mac version of the 7-zip compression algorithm) and StuffIt compression programs, the xar archiver, and Interarchy’s “backup” format. (Note: Interarchy’s backup page is currently 404’ing, but suffice to say it’s an open format that attempts to encode files in such a way as to store all of Apple’s fancy metadata.)

So I figured I’d do what any red-blooded geek would do, and test all these programs to see if they did what they claimed to do. My test was pretty simple: I took a text file, assigned a Finder label and some comments, and added a resource fork and some custom extended attributes. If all these things made it through intact, I’d consider the tool good enough for my purposes.

The results were interesting. First off, every program I tested successfully maintained the resource fork, which is really the most important part of the file to keep around. Additionally, every program except for tar managed to keep the Finder label. As for extended attributes, only tar, the Interarchy backup format and cpio successfully kept the custom extended attributes. This is especially baffling given that the resource fork in MacOS X 10.4 is nothing more than an extended attribute!

The most troubling thing for me was that none of the programs I tested managed to maintain the “Spotlight Comments” I’d added. I frequently use these comments as a way to tag my files for Spotlight searching, so their loss is somewhat problematic. It turns out that these spotlight comments are stored in the invisible .DS_Store file in the same folder as the file I was backing up. So provided I restored (and backed up) the whole folder, that wouldn’t be a problem. Still, it would be nice to see it handle all that.

Update: I hadn’t originally tested it, since Apple hadn’t listed it on their OS X pages as a utility that had been updated to work with resource forks, but some online discussions led me to believe that the pax archiver had also been updated. Indeed, it has, and it successfully maintains resource forks, extended attributes, and Finder labels, just like cpio. It does, however, seem to have bugs when used on systems with ACLs enabled, and like everything else, it loses Finder comments. I have updated the discussion, below, accordingly.

So this leaves me with three solid options: The Interarchy Backup format, pax, and cpio archives. The latter two archive formats are fully compatible with other unix-like systems and can even be expanded using the graphical BOMArchiveHelper on the Mac, so they may be the best choice. Both archivers permit me to compress files in the archive, which is a nice bonus for network archiving. Of the two, pax has some nice advantages, including a larger file size limit on archives and some interesting command-line tricks including the ability to write out to different archive types. Cpio, on the other hand, seems to work on systems with ACLs enabled.

However, I suspect (although I haven’t tested this) that the Interarchy Backup format captures more Mac-specific metadata, since it was designed with exactly that goal in mind, and Apple’s programs are, well, less than entirely consistent in supporting these filesystem features. I do wish Apple could at least provide tools that were consistent and reliable.

It is worthwhile to note that none of the graphical Mac compression utilities managed to maintain extended attributes, not even Apple’s customer zip archiver (which is the same tool used when you archive files in the Finder) nor StuffIt, which has long been a Mac-friendly standby compression program. This leaves Mac users with essentially no easy options for compressing files prior to emailing them or posting them to an FTP site other than disk images (which aren’t cross-platform).

I’m disappointed that the xar archiver, which was designed precisely to handle metadata schemes on different systems, didn’t perform better. It is still a work in progress, so I left some bug reports, and I remain hopeful they will properly support extended attributes and comments in future releases. Since xar can also handle compression as well as encryption, it would be a fantastic solution for off-site backups.

Soon I’ll post how my backup system develops and works over the long-term. If you have any questions or comments, please feel free to sound off, below!

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!

Subscribe to RSS - terminal

@inik

inik: RT @thinkprogress: .@komenforthecure head says responses to Planned Parenthood decision are "very favorable." If your response is unfavo ... >
inik: @FluidApp I'm getting errors in a Fluid app Gmail and can't use chat either. Any ideas? >
inik: finished Five Children and It by E. (Edith) Nesbit et al. and gave it 5 stars http://t.co/mspysk1B #Kindle >
inik: How to use an obscure shell command to let your AppleScripts and shell scripts output rich text. http://t.co/3Y9dAHiH >
inik: Nicholas "Nik" Friedman TeBockhorst http://t.co/I6kGmcDg >

Google+

I love Seth's quote at the top. I think that's my new motto.. ; )

Powered by Plu.sr
>
Griping about OS X Lion? Here's two nifty tools that replace a variety of poorly supported third party tools: Command-line and Automator access to video and audio conversion. Super easy to use, and very flexible and supports any format that Quicktime can encode/decode. (So Perian is a must-install if you want to handle DivX/3viX, etc.)

Yes, ffmpeg, Handbrake and...
>
Fix Google Reader's horrible new interface with this user script! Now it fits nicely on my MacBook's small screen. >
Happy 11/11/11 11:11:11! >
What makes this ad awesome is not the true-to-life irony, because the idea is hardly innovative, but rather the excellent execution. Reminds me a bit of that excellent Nutri-Grain spec commercial. Quick delivery, good actors, hit all the high notes. Love it. >